Public record
Software health reportschema 0.27.0 · metrics 1.13.0 · 2026-07-27 20:56 UTC

satoraHQ / satora-sdk

TypeScript · Rust · C#MIT★ 6 stars⑂ 4 forkssince Dec 2025View on GitHub ↗

satoraHQ/satora-sdk holds a health index of 50 out of 100, placing it in the Moderate band. It scores highest on Vitality (93/100) and lowest on Community & Adoption (31/100). It was last updated 5 days ago. A single contributor accounts for most of its recent work.

50
overall / 100
Moderate

Software health index

Metrics are grouped into weighted categories on one standardized 1–100 scale. Overall starts as their weighted mean; when public evidence triggers the High-Risk Jurisdiction Policy, the rating is adjusted and receives an At risk ceiling of 49. AI Readiness sits outside the overall score.

50
Excellent85-100Exemplary; meets essentially all checked criteria
Good70-84Healthy; minor gaps
Moderate50-69Acceptable with notable gaps; review recommended
At risk30-49Significant weaknesses; adoption warrants caution
Critical1-29Severe problems (abandoned, single-maintainer, no hygiene)
VitalityCommunity &AdoptionSustainability &GovernanceEngineeringQualitySecurityAI Readiness

Score profile

Each axis is a category. The shape matters more than the average — a healthy subject fills the whole shape, while a spike-and-crater profile means strength in one dimension is masking risk in another.

Ownership

satoraOrganization
27 followers25 public repossince Jul 2024

This repository is backed by an organization — shared, accountable stewardship that can outlive any single maintainer.

Package ecosystems

RegistryPackageVersionDownloads / moVersionsLast publishTags
npm@lendasat/lendaswap-sdk-purepoints to another repo — not scored0.4.03,089566 days agolendaswapbitcoinswaparkarkadereact-native

Metrics by category

Vitality

Is the project alive — is code being written and are releases shipping?

93Excellent · 22% of overall
How it's scored
36/36Push recency — last push 5 days ago
24.2/36Commit cadence — 35/52 weeks with commits
18/18Commit volume — 576 commits in the last year
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Inputs used
commits_last_year576
human_commit_share0.87
days_since_last_push5
active_weeks_last_year35

Release discipline

100Excellent
How it's scored
27/27Ships releases — 14 releases published
36/36Release recency — latest release 34 days ago
27/27Release cadence — a release every ~3.2 days
0/10OpenSSF Scorecard: Signed-Releases — no data
Inputs used
releases_count14
latest_release_tagv0.2.44
releases_from_tagsno
days_since_latest_release34
mean_days_between_releases3.2
Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.

Community & Adoption

Does the project have users, downloads, attention, and a welcoming setup for contributors?

31At risk · 18% of overall
How it's scored
11.3/60Stars — 6 stars
4/25Forks — 4 forks
0/15Watchers — 0 watchers
Inputs used
forks4
stars6
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
How it's scored
22.5/22.5README
22.5/22.5License — recognized license (MIT)
0/18CONTRIBUTING guide
0/13.5Code of conduct
0/7.2Issue template
0/6.3PR template
Inputs used
has_readmeyes
has_licenseyes
has_contributingno
has_issue_templateno
has_code_of_conductno
has_pull_request_templateno

Sustainability & Governance

Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?

32At risk · 24% of overall
How it's scored
9/54Bus factor — 1 contributor(s) cover half of all commits
5.9/22.5Commit distribution — top contributor authored 74% of commits
4.1/13.5Contributor breadth — 3 contributors
10/10OpenSSF Scorecard: Contributors — project has 3 contributing companies or organizations -- score normalized to 10
Inputs used
bus_factor1
contributors_sampled3
top_contributor_share0.738
How it's scored
0/46.8Issue resolution — 0% of issues closed
12.8/38.3PR acceptance — 1/3 decided PRs merged
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Inputs used
merged_prs1
open_issues1
closed_issues0
issue_closed_ratio0
closed_unmerged_prs2
How it's scored
30/30Ownership backing — organization-owned
0/20Verified domain
10.4/25Owner reach — 27 followers of satoraHQ
14.4/25Track record — 25 public repos, account ~2 yr old
Inputs used
followers27
owner_typeOrganization
is_verified
owner_loginsatoraHQ
public_repos25
account_age_days754

Engineering Quality

Are baseline engineering and documentation practices in place?

46At risk · 20% of overall
How it's scored
0/24CI workflows
24/24Tests present
16/16Linter config — biome.json
0/9.6Pre-commit hooks
0/6.4.editorconfig
0/20OpenSSF Scorecard: CI-Tests — no data
Inputs used
has_cino
has_testsyes
has_editorconfigno
has_linter_configyes
has_precommit_configno
Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.

Documentation

40At risk
How it's scored
30/30README
0/25Documentation directory
0/15Documentation / homepage site
0/10Repository description
0/10Topics
10/10Wiki
Inputs used
topics
has_wikiyes
homepage
has_readmeyes
has_docs_dirno
has_descriptionno

Security

Are visible security and supply-chain practices strong, without unresolved high-risk jurisdiction exposure?

45At risk · 16% of overall
How it's scored
7.5/7.5Binary-Artifacts — no binaries found in the repo
3.8/7.5Branch-Protection — branch protection is not maximal on development and all release branches
0/2.5CI-Tests — no data
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/30 approved changesets -- score normalized to 0
2.5/2.5Contributors — project has 3 contributing companies or organizations -- score normalized to 10
0/10Dangerous-Workflow — no data
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5License — license file detected
7.5/7.5Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
0/5Packaging — no data
0/5Pinned-Dependencies — no data
0/5SAST — no SAST tool detected
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — no data
0/7.5Token-Permissions — no data
0/7.5Vulnerabilities — 37 existing vulnerabilities detected
Inputs used
sourceopenssf_scorecard
checks_evaluated12
scorecard_versionv5.5.0
checks_inconclusive6
scorecard_aggregate3.5
Excluded from scoring (no data or not applicable): ci_tests, dangerous_workflow, packaging, pinned_dependencies, signed_releases, token_permissions. Remaining weights renormalized.
How it's scored
35/35Direct dependencies free of known advisories — no direct dependency carries a known advisory
10/25Indirect dependencies free of known advisories — 1 affected: ws 8.20.1 (high 7.5)
40/40No advisories left outstanding — no advisory has been public longer than 90 days
Inputs used
sourceosv
advisories1
affected_packages1
assessed_packages82
unassessed_packages0
affected_by_severityhigh 1
direct_affected_packages0
Matched the npm:@lendasat/lendaswap-sdk-pure@0.4.0 runtime dependency closure — what installing the published package pulls in — 82 packages. Reachability is not analyzed.

AI Readiness

How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score.

71Good · 0% of overall
How it's scored
0/45Agent instructions — no CLAUDE.md / AGENTS.md / editor rules
0/15Machine-readable docs (llms.txt)
40/40Legible commit history — 84 of 87 human commits state their intent (structured subject or explanatory body)
Inputs used
has_llms_txtno
legible_history_share0.966
agent_instruction_files
agent_instruction_max_bytes
How it's scored
18/18One-command bootstrap — Justfile, dotnet-sdk/Justfile
22/22Automated tests
11/11Lint / format config — biome.json
11/11Static type checking — ts-pure-sdk/tsconfig.json, ts-sdk/packages/escrow-client/tsconfig.json, ts-sdk/packages/escrow/tsconfig.json, ts-sdk/packages/swap/tsconfig.json
10/10Reproducible environment — lockfile
0/10Demonstrated agent practice — no agent-authored commits among the last 100
0/8Automated maintenance — no automated dependency updates observed
0/10OpenSSF Scorecard: Pinned-Dependencies — no data
Inputs used
has_nixno
has_testsyes
lockfilesCargo.lock, package-lock.json, pnpm-lock.yaml
has_dockerfileno
typed_languageyes
bootstrap_filesJustfile, dotnet-sdk/Justfile
has_devcontainerno
has_linter_configyes
typecheck_configsts-pure-sdk/tsconfig.json, ts-sdk/packages/escrow-client/tsconfig.json, ts-sdk/packages/escrow/tsconfig.json, ts-sdk/packages/swap/tsconfig.json
agent_commit_share0
toolchain_manifestscore/Cargo.toml, dotnet-sdk/Satora.Sdk.Cli/Satora.Sdk.Cli.csproj, dotnet-sdk/Satora.Sdk.Tests/Satora.Sdk.Tests.csproj, dotnet-sdk/Satora.Sdk/Satora.Sdk.csproj, dotnet-sdk/native/Cargo.toml, rust-sdk/Cargo.toml
dependency_bot_commit_share0
Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Pinned-Dependencies. Remaining weights renormalized.
How it's scored
45/45Type-checkable code — TypeScript (statically typed)
54.3/55Manageable file sizes — 3/222 source files over 60KB
Inputs used
primary_languageTypeScript
largest_source_bytes211,665
source_files_sampled222
oversized_source_files3
How it's scored
40/40API schema (OpenAPI/GraphQL/proto) — rust-sdk/openapi.json, ts-pure-sdk/openapi.json
0/20MCP server
40/40Runnable examples — examples
Inputs used
example_dirsexamples
has_mcp_signalno
api_schema_filesrust-sdk/openapi.json, ts-pure-sdk/openapi.json

Key facts

6GitHub stars
3contributors
576commits, last 12 months
5days since last push
14releases
1bus factor
1open issues
crates.io, npmpackage ecosystems

Data collection warnings

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • Could not fetch crates package 'lendaswap-core' from its registry
  • Could not fetch crates package 'lendaswap-sdk' from its registry
  • npm package '@lendasat/lendaswap-sdk-pure' points at a different repository (https://github.com/satoraHQ/lendaswap-sdk); excluded from ecosystem scoring
  • Could not fetch crates package 'satora-sdk-ffi' from its registry
  • Could not fetch nuget package 'Satora.Sdk' from its registry
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

More detail

Star and fork history 0 ★ / 4 ⇿
0Stars
4Forks

When each star and fork was added, collected from GitHub and bucketed by day. Cumulative growth sits directly above the daily additions it is made of, so the two read against each other: steady organic accretion looks nothing like an abrupt, short-lived burst. Where that difference is measurable, it is reported as growth authenticity.

1223344412026-012026-032026-04
OpenSSF Scorecard 3.5 / 10
3.5aggregate

Independent, tool-agnostic security assessment from the open-source OpenSSF Scorecard. Each check rewards a security practice, not a specific vendor's tool. Checks Scorecard could not determine are marked n/a and excluded from the security score (never counted as zero).Scorecard v5.5.0 · 2026-07-27 20:56 UTC

10Binary-Artifactsno binaries found in the repo
5Branch-Protectionbranch protection is not maximal on development and all release branches
n/aCI-Testsno pull request found
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/30 approved changesets -- score normalized to 0
10Contributorsproject has 3 contributing companies or organizations -- score normalized to 10
n/aDangerous-Workflowno workflows found
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
n/aPackagingpackaging workflow not detected
n/aPinned-Dependenciesno dependencies found
0SASTno SAST tool detected
0Security-Policysecurity policy file not detected
n/aSigned-Releasesno releases found
n/aToken-PermissionsNo tokens found
0Vulnerabilities37 existing vulnerabilities detected
Direct dependencies 63
RegistryPackageVersion constraintManifest
crates.ioanyhow1core/Cargo.toml
crates.iothiserror1.0core/Cargo.toml
crates.iohex0.4core/Cargo.toml
crates.ioserde1core/Cargo.toml
crates.ioserde_json1core/Cargo.toml
crates.iolog0.4core/Cargo.toml
crates.iorand0.8core/Cargo.toml
crates.iosha20.10core/Cargo.toml
crates.iobip392.1.0core/Cargo.toml
crates.iobitcoin0.32.2core/Cargo.toml
crates.iominiscript12core/Cargo.toml
crates.ioark-restcore/Cargo.toml
crates.ioark-rscore/Cargo.toml
crates.ionostr0.40.0core/Cargo.toml
crates.iofutures0.3core/Cargo.toml
crates.ioreqwest0.12core/Cargo.toml
crates.iogetrandom0.2core/Cargo.toml
crates.iogetrandom_latest0.3core/Cargo.toml
crates.iorust_decimal1core/Cargo.toml
crates.iorust_decimal_macros1core/Cargo.toml
crates.iotime0.3core/Cargo.toml
crates.iouuid1.0core/Cargo.toml
crates.iosqlx0.8core/Cargo.toml
crates.iobip392rust-sdk/Cargo.toml
crates.iobitcoin0.32rust-sdk/Cargo.toml
crates.iohex0.4rust-sdk/Cargo.toml
crates.ioreqwest0.13rust-sdk/Cargo.toml
crates.ioserde1rust-sdk/Cargo.toml
crates.ioserde_json1rust-sdk/Cargo.toml
crates.iosha20.10rust-sdk/Cargo.toml
crates.iothiserror1rust-sdk/Cargo.toml
crates.iotiny-keccak2rust-sdk/Cargo.toml
crates.iotracing0.1rust-sdk/Cargo.toml
crates.iourl2rust-sdk/Cargo.toml
crates.ioalloy1rust-sdk/Cargo.toml
crates.ioalloy-provider1rust-sdk/Cargo.toml
crates.iorand0.8rust-sdk/Cargo.toml
crates.iotokio1rust-sdk/Cargo.toml
crates.ioark-bdk-wallet0.10rust-sdk/Cargo.toml
crates.ioark-rs0.10.1rust-sdk/Cargo.toml
crates.ioesplora-client0.11rust-sdk/Cargo.toml
crates.iorustls0.23rust-sdk/Cargo.toml
npm@arkade-os/sdk^0.4.45ts-pure-sdk/package.json
npm@noble/curves^2.2.0ts-pure-sdk/package.json
npm@noble/hashes^2.2.0ts-pure-sdk/package.json
npm@scure/base^2.0.0ts-pure-sdk/package.json
npm@scure/bip32^2.0.1ts-pure-sdk/package.json
npm@scure/bip39^2.0.1ts-pure-sdk/package.json
npm@scure/btc-signer^2.0.1ts-pure-sdk/package.json
npm@zerodev/sdk^5.5.0ts-pure-sdk/package.json
npmdexie^4.4.2ts-pure-sdk/package.json
npmopenapi-fetch^0.17.0ts-pure-sdk/package.json
npmviem2.52.2ts-pure-sdk/package.json
NuGetMicrosoft.NET.Test.Sdk17.11.1dotnet-sdk/Satora.Sdk.Tests/Satora.Sdk.Tests.csproj
NuGetxunit2.9.2dotnet-sdk/Satora.Sdk.Tests/Satora.Sdk.Tests.csproj
NuGetxunit.runner.visualstudio2.8.2dotnet-sdk/Satora.Sdk.Tests/Satora.Sdk.Tests.csproj
crates.iobitcoin0.32dotnet-sdk/native/Cargo.toml
crates.iolendaswap-sdkdotnet-sdk/native/Cargo.toml
crates.ioserde_json1dotnet-sdk/native/Cargo.toml
crates.iothiserror1dotnet-sdk/native/Cargo.toml
crates.iotokio1dotnet-sdk/native/Cargo.toml
crates.iouniffi0.29dotnet-sdk/native/Cargo.toml
crates.iourl2dotnet-sdk/native/Cargo.toml
All dependencies not collected

The resolved dependency set could not be collected for this report: GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Dependency advisories 1

Installing npm:@lendasat/lendaswap-sdk-pure@0.4.0 pulls in 82 packages, direct and transitive: 1 carry known advisories, of which 0 are direct dependencies.

PackageVersionRelationSeverityAdvisoriesFixed in
ws8.20.1indirecthigh18.21.0

An advisory means the version recorded in the dependency graph falls inside an advisory’s affected range. Reachability is not analysed, and the graph includes development and test pins — a finding may concern tooling rather than shipped software.

Raw JSON report machine-readable
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 2475,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "C#": 231243,
        "Just": 12299,
        "Rust": 667749,
        "JavaScript": 1413,
        "TypeScript": 1302662
      },
      "pushed_at": "2026-07-22T01:43:30Z",
      "created_at": "2025-12-03T04:32:56Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-22T01:43:35Z",
      "description": null,
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "TypeScript",
      "significant_languages": [
        "TypeScript",
        "Rust",
        "C#"
      ]
    },
    "owner": {
      "blog": "https://satora.io",
      "name": "satora",
      "type": "Organization",
      "login": "satoraHQ",
      "company": null,
      "location": null,
      "followers": 27,
      "avatar_url": "https://avatars.githubusercontent.com/u/174571718?v=4",
      "created_at": "2024-07-03T02:58:57Z",
      "is_verified": null,
      "public_repos": 25,
      "account_age_days": 754
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.2.44",
          "kind": "patch",
          "published_at": "2026-06-23T07:38:44Z"
        },
        {
          "tag": "v0.2.43",
          "kind": "patch",
          "published_at": "2026-06-23T06:57:18Z"
        },
        {
          "tag": "v0.2.42",
          "kind": "patch",
          "published_at": "2026-06-18T02:42:05Z"
        },
        {
          "tag": "v0.2.41",
          "kind": "patch",
          "published_at": "2026-06-18T01:50:53Z"
        },
        {
          "tag": "v0.2.40",
          "kind": "patch",
          "published_at": "2026-06-05T11:24:38Z"
        },
        {
          "tag": "v0.2.39",
          "kind": "patch",
          "published_at": "2026-06-04T22:51:37Z"
        },
        {
          "tag": "v0.2.38",
          "kind": "patch",
          "published_at": "2026-06-01T06:01:14Z"
        },
        {
          "tag": "v0.2.37",
          "kind": "patch",
          "published_at": "2026-06-01T05:31:02Z"
        },
        {
          "tag": "v0.2.36",
          "kind": "patch",
          "published_at": "2026-05-27T09:07:18Z"
        },
        {
          "tag": "v0.2.35",
          "kind": "patch",
          "published_at": "2026-05-25T22:16:11Z"
        },
        {
          "tag": "v0.2.34",
          "kind": "patch",
          "published_at": "2026-05-20T04:30:56Z"
        },
        {
          "tag": "v0.2.33",
          "kind": "patch",
          "published_at": "2026-05-20T04:22:57Z"
        },
        {
          "tag": "v0.2.32",
          "kind": "patch",
          "published_at": "2026-05-15T12:53:38Z"
        },
        {
          "tag": "v0.2.31",
          "kind": "patch",
          "published_at": "2026-05-15T11:55:54Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "2bba19673d3ad56eac5f9f67c2a8089752f0cba4",
          "body": "feat(rust-sdk): scaffold Rust client SDK\n- Hand-written types validated against openapi.json\n- reqwest client with health and version endpoints\n- wiremock unit tests and ignored live integration tests\n- export-openapi-sdk just recipe copies spec into rust-sdk\n\nchore(just): delegate fmt/test/lint to \n[…]\ntor key\n\nchore(sdk): add pure sdk changeset\n\nfix: satisfy CI formatting checks\n\nchore: Delete a couple of unused files\n\nchore: Delete a couple of unused files\n\nfix(dotnet-sdk): sync generated bindings",
          "is_bot": false,
          "headline": "feat(rust-sdk): Add Rust client SDK",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-22T01:42:58Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b7cf97122448b399fe2c01d77a0c00473db2ebb7",
          "body": null,
          "is_bot": false,
          "headline": "fix: use workspace protocol for pure SDK link",
          "author_name": "Lucas Soriano del Pino",
          "author_login": "luckysori",
          "committed_at": "2026-07-21T02:50:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4309c7babd3d5d99995897ffc0b87505ccb3d26e",
          "body": null,
          "is_bot": true,
          "headline": "Release SDKs (pure v0.4.0, @satora ~v0.0.5)",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-07-21T02:09:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "534fad50cf0eb6a051038c24dc7c2640c26dae03",
          "body": null,
          "is_bot": false,
          "headline": "test(e2e): link wrapper SDK to local pure SDK",
          "author_name": "Lucas Soriano del Pino",
          "author_login": "luckysori",
          "committed_at": "2026-07-20T13:09:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d3341ff24b071e36b9db70c6a77f0aede93957c6",
          "body": null,
          "is_bot": false,
          "headline": "fix(sdk): sign EVM collab refunds with depositor key",
          "author_name": "Lucas Soriano del Pino",
          "author_login": "luckysori",
          "committed_at": "2026-07-20T13:09:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bfcfe83612d709bbbe6cb03460d8ab06045d8809",
          "body": "The watch callback fired 'void #reconcileChain(chainId)' on every block/log\nevent, so a fast chain or slow RPC stacked overlapping reconciles — each doing a\ngetLogs per tracked ref — amplifying rate limits, and the discarded promise made\na transient RPC failure an unhandled rejection.\n\nRoute block-e\n[…]\n a single queued rerun to pick up changes that arrived\nmid-run, and a .catch so a background failure can't crash. register/refresh still\nawait #reconcileChain directly.\n\nAddresses a PR review finding.",
          "is_bot": false,
          "headline": "fix(@satora/swap): coalesce EVM block-event reconciles",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-19T23:42:53Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "dda79969a3a5052df514ae6ab4ed886cf8094af7",
          "body": "#refreshManagers refreshed every manager, so the default client (which builds\nArkade + Bitcoin + EVM managers) would call a ledger's clock source — e.g. Arkade\nor Bitcoin MTP via the API — even when no HTLC on that ledger is being observed\n(no swaps, or an EVM-only Lightning direction). A down endpoint then failed\nstartTracking for a ledger nothing depended on. Refresh only the managers that\nhave a registered leg.\n\nAddresses a PR review finding.",
          "is_bot": false,
          "headline": "fix(@satora/swap): refresh only ledgers with a registered leg",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-19T23:42:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d6cc57ec7cceaccdc534bf17b528240bf63db41c",
          "body": "…red chain\n\nregister() stored the ref then #ensureWatch/#reconcileChain returned silently when\nno reader existed for the chain, so state/clock stayed undefined and the tracker\nwaited on that leg forever with no signal. Throw a clear error naming the chain and\nthe fix (withEvmRpcUrls) instead of stalling silently.\n\nAddresses a PR review finding.",
          "is_bot": false,
          "headline": "fix(@satora/swap): throw when registering an EVM HTLC on an unconfigu…",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-19T23:42:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "62c2f312d844e9dddc374c99ed56a88a71abec3f",
          "body": "The observer found a spent vtxo via spentBy/isSpent/state but then returned only\nits .spentBy field, so a spend exposed solely via arkTxId (spentBy empty) was\nmissed — a spent-but-settled vtxo kept reading 'confirmed' forever, never\nemitting spent_claim/spent_refund or recovering the preimage.\n\nMirr\n[…]\nondition witness carries the\nrevealed preimage. Prefer arkTxId, fall back to spentBy (the checkpoint tx, which\nalso reveals it) so a spend under either field is caught.\n\nAddresses a PR review finding.",
          "is_bot": false,
          "headline": "fix(@satora/swap): key Arkade spend detection on arkTxId, not spentBy",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-19T23:42:53Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7020bad087cf7e2c33a2fe4408c1587f2600fb0f",
          "body": "startTracking assigned #tracker before awaiting tracker.startTracking(), so a\npartway failure (a ledger register/refresh erroring on an RPC/indexer hiccup)\nleft #tracker pointing at a half-registered tracker. subscribeToActions() then\nstopped guarding (it only checks #tracker != undefined), and a re\n[…]\nrtial tracker's registrations and\nlisteners. Stop and clear the tracker in the catch before rethrowing, so a\nretry starts clean and subscribe still reports not-started.\n\nAddresses a PR review finding.",
          "is_bot": false,
          "headline": "fix(@satora/swap): tear down the partial tracker if startTracking fails",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-19T23:42:53Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e944e979f2305c089fd9e433a2aa7d8b0c366ab7",
          "body": "SwapTracker.stop() cleared the timer, event listeners and subscribers but left\nevery leg in #swaps registered with its manager. A manager's register() can start\na long-lived watch torn down only by unregister() (e.g. EvmContractManager's\nper-chain block watch), so a stopped tracker kept watching blo\n[…]\nh startTracking: unregister every still-tracked leg\n(mirroring #untrack) and clear #swaps. The managers are not owned here, so they\nare unregistered but never disposed.\n\nAddresses a PR review finding.",
          "is_bot": false,
          "headline": "fix(@satora/swap): unregister tracked legs when tracking stops",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-19T23:42:53Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ac3d1f059f75492ccef3772f44ab05551aa7558a",
          "body": "Adds a chain-derived \"what should the client do next?\" model so consumers don't\nre-infer UX from the raw 16-state SwapStatus. Per-ledger ContractManagers\n(Arkade, EVM, Bitcoin) observe each HTLC purely on-chain — never trusting the\nserver — and a SwapTracker maps observations to a status (deriveSwap\n[…]\n0 lock, handled by length alongside the\n32-byte SHA-256 the other directions use.\n\nTracking is on by default with smart RPC/esplora/Arkade defaults, overridable\nand disableable via the Client builder.",
          "is_bot": false,
          "headline": "feat(@satora/swap): derived next-action model with observe-mode tracking",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-19T23:42:53Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "33bc719f57a398bbc847295e9eb61fea06eca2d7",
          "body": "… types\n\nAligns @arkade-os/sdk across the pure SDK and escrow packages, and regenerates\nthe OpenAPI-derived types — picking up the btc_to_arkade and Lightning swap\nresponse fields the action model reads.",
          "is_bot": false,
          "headline": "chore(client-sdk): align @arkade-os/sdk to ^0.4.45 and regenerate API…",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-19T23:42:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b4cf0009c3af7ff84dc8e2c888c078744a589947",
          "body": "e2e-ts now loads sqliteStorageFactory via @satora/swap/node, which resolves\nbetter-sqlite3 through the ts-sdk workspace. pnpm 10 only compiles native\naddons for allowlisted packages, and ts-sdk had no onlyBuiltDependencies, so\nbetter-sqlite3's binding was never built -> 'Could not locate the bindings\nfile' at runtime. Add the allowlist (mirroring the frontend workspace).",
          "is_bot": false,
          "headline": "fix(e2e): build better-sqlite3 in the ts-sdk workspace",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-13T00:38:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f9a571650491fcec292248055c49700ed2f3d57d",
          "body": null,
          "is_bot": false,
          "headline": "chore: add overwrite for legacy constructor",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-13T00:38:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "740eae602b869dc185249e5cd79854752f1ecb82",
          "body": "Pin viem to exactly 2.52.2 in the app, ts-pure-sdk, and e2e — matching the\nfrontend's existing pnpm override — so every install context resolves one\nviem and the SDK/app boundary types dedupe instead of clashing (app 2.52.2 vs\npure-ts-sdk 2.53.1). Updates the standalone ts-pure-sdk + e2e lockfiles.",
          "is_bot": false,
          "headline": "chore: align viem to 2.52.2 across workspaces",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-13T00:38:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c0ccb943705e076d34b63c9955cd0a79fe5021b6",
          "body": "…tent\n\n- @satora/swap (minor): now a standalone drop-in wrapper client; new features\n  land here. Recommended package going forward.\n- @lendasat/lendaswap-sdk-pure (patch): recommend @satora/swap; record the\n  intent to deprecate the legacy package and migrate consumers over. Stays\n  fully supported during the transition.",
          "is_bot": false,
          "headline": "changeset: @satora/swap standalone client + legacy SDK deprecation in…",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-13T00:38:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f3b7033cfe1ed8ee8c2921ccb868edc87ec6d7f5",
          "body": "Point the developer docs and marketing site at @satora/swap (install\ncommands, imports, npm links, landing-page code samples) — it's the drop-in\nconsumers should build against now.\n\n- satora_website/docs/*.mdx + llms-full.txt: switch to @satora/swap; add a\n  setup callout that migrating is just a pa\n[…]\nlegacy package.\n- swap/README.md: describe Client/ClientBuilder as wrappers, not verbatim.\n\nNote: llms-full.txt is generated; edited here for consistency but the docs\nbuild regenerates it canonically.",
          "is_bot": false,
          "headline": "docs: recommend @satora/swap; note the legacy SDK still works",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-13T00:38:42Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "54882a1d381c31be507e430634a267c4c07fe642",
          "body": null,
          "is_bot": false,
          "headline": "chore: make sure to always build new sdk aswell",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-13T00:38:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c23d52ca82c2b5d4622d773ee4e0d13b52fa8f83",
          "body": "client-sdk/examples/pure-ts was never typechecked (runs via tsx, absent\nfrom CI) and had drifted against the current SDK API (btc_expected_sats,\nbtc_to_evm, claimingAddress no longer exist). Nothing references it, and\nscripts/e2e-ts is the living, typecheck-clean usage reference. A broken\nexample misleads integrators, so remove it.",
          "is_bot": false,
          "headline": "chore: remove rotted, unreferenced pure-ts example",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-13T00:38:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7e33f7bedf51385f78fe6a5c0facfc7aced8b5d8",
          "body": "Replace the bare re-export with a real Client/ClientBuilder that own an\ninternal @lendasat/lendaswap-sdk-pure client and forward the full public\nsurface to it (uniform Parameters/ReturnType passthrough). index.ts shadows\nClient/ClientBuilder so it's a drop-in replacement; every delegator is a\nmigration checkpoint for a future native impl. Bump the legacy dep 0.2.38 ->\n0.3.0 to cover the full method surface.",
          "is_bot": false,
          "headline": "feat(@satora/swap): standalone drop-in Client wrapping the legacy client",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-13T00:38:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7e5dffdb8da88e8fe646f3e67ffcfc1fb7584e50",
          "body": "Expose an optional `invoice_description` on the lightning->evm and\nlightning->arkade swap endpoints (and SDK). Falls back to a branded\ndefault; an explicit empty string blanks it. Bridged swaps name the\ndestination chain. Adds a changeset for the pure SDK.\n\nResolves satoraHQ/swap#717",
          "is_bot": false,
          "headline": "feat: custom Lightning invoice description",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-09T03:59:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "13653f1075b0ac91627f71b692af988688654d97",
          "body": null,
          "is_bot": false,
          "headline": "chore: regenerate openapi specs",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-09T00:56:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b8728a1ac8a07840ce0b476cd0a43ecc1d625a35",
          "body": null,
          "is_bot": true,
          "headline": "Release SDKs (pure v0.3.0, @satora ~v0.0.5)",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-07-09T00:12:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6a022b71517caf287e2bd6ebe3f7f5abcff69480",
          "body": "Add POST /swap/bulk-status to fetch the status of many swaps in one\nrequest. It returns only each swap's status (not the full per-direction\ndetails), so the whole batch is served by a single database query. Unknown\nIDs are returned in not_found rather than failing the call; duplicate IDs\nare de-duplicated. Capped at 100 IDs per request.\n\nExpose it in the pure TS SDK as client.getBulkStatus(ids).",
          "is_bot": false,
          "headline": "feat(swap): add bulk swap-status endpoint and SDK getBulkStatus",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T10:14:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bd6ad0bdf2eca609bc3bd60c435034bb785bc3c6",
          "body": "The SDK migrated to pnpm (committed pnpm-lock.yaml, pnpm node_modules),\nbut the generate/build/typecheck recipes still ran npm. Running npm install\nover pnpm's node_modules layout crashes npm's arborist. Switch them to pnpm.",
          "is_bot": false,
          "headline": "fix(client-sdk): use pnpm in ts-pure-sdk build recipes",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T10:14:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a14fdc5a02c481e2fa05db35ef53582e480680f8",
          "body": null,
          "is_bot": true,
          "headline": "Release SDKs (pure v0.3.0-rc.2, @satora ~v0.0.5-rc.0)",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-07-08T06:01:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c82f504908b1737bb822281d552ee3660f0a5713",
          "body": "…SH env",
          "is_bot": false,
          "headline": "sdk: keep version.ts committed, inject commit hash from GIT_COMMIT_HA…",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T05:59:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f8175d067a1e15a77e1517942b93a842613f7317",
          "body": null,
          "is_bot": false,
          "headline": "sdk: export SDK_COMMIT_HASH captured at build time",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T05:59:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d4de3bca843c21e6ddd5b4a4b5beb9341b711061",
          "body": null,
          "is_bot": false,
          "headline": "chore: format .changeset files",
          "author_name": "Lucas Soriano del Pino",
          "author_login": "luckysori",
          "committed_at": "2026-07-08T05:03:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9ddf27f4dbbb84c53057fbde841301e24cd69dd0",
          "body": null,
          "is_bot": true,
          "headline": "Release SDKs (pure v0.3.0-rc.1, @satora ~v0.0.5-rc.0)",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-07-08T04:28:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "55875dcd28aac26e18b585cae88b12cbb693a442",
          "body": null,
          "is_bot": false,
          "headline": "sdk: exclude tool-managed .changeset dir from biome",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T04:25:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6e8b8dc934c6036d131c90a27c7235898afb5556",
          "body": null,
          "is_bot": false,
          "headline": "sdk: update index test to assert exported SDK_VERSION",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T04:25:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "469f607dafd9f4c62e7c6f34f25bf84b6afc4933",
          "body": null,
          "is_bot": false,
          "headline": "sdk: export real SDK_VERSION instead of stale VERSION const",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T04:25:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2c3be0bf7aac2d7fa57ecef39084fa640362706b",
          "body": null,
          "is_bot": true,
          "headline": "Release SDKs (pure v0.3.0-rc.0, @satora ~v0.0.5-rc.0)",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-07-08T01:52:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "efcf47f6714e5f01914f0c517aae2e97517729cd",
          "body": "This reverts commit ad55f079f2bb42e4cc8f77375b7c09c9c6115b05.",
          "is_bot": false,
          "headline": "Revert \"Release SDKs (pure v0.3.0-rc.0.0, @satora ~v0.0.5-rc.0.0)\"",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T01:50:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cf38d9502adc0b15b96920739342a8e316cc3a5c",
          "body": null,
          "is_bot": true,
          "headline": "Release SDKs (pure v0.3.0-rc.0.0, @satora ~v0.0.5-rc.0.0)",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-07-08T01:37:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "02c385f628a56ccefe85a05ce6db2f3e6410df37",
          "body": null,
          "is_bot": false,
          "headline": "chore: add changesets for the euroe SDK changes",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T00:34:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6263e1bbc9db9d86fc9d0e6452afb59c374f1378",
          "body": "For source-pinned BTC->EVM/CCTP quotes, net_target scaled the already\nbridge-fee-netted DEX output by the BTC-side fee ratio r, so the flat CCTP fee\ngot multiplied by r and delivery was overstated by fee*(1-r). Scale the gross\noutput by r, then subtract the full bridge fee. Extracted netTargetSourcePinned\n+ a unit test.",
          "is_bot": false,
          "headline": "fix(sdk): stop discounting the flat CCTP fee by the BTC-side fee ratio",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T00:34:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2b898621c93b0c5a141879370f97ed1ef595cd1b",
          "body": null,
          "is_bot": false,
          "headline": "refactor: DexAmount carries strong U256 via serde; drop parse_direction",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T00:34:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7472ef29f0d21dfe26e7270f5925d87d1288f413",
          "body": null,
          "is_bot": false,
          "headline": "refactor: rename minimum_fee_scaled -> proportional_fee_millionths",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T00:34:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6669d3febfabb2a0fa7569c718ca7689ce4c40f3",
          "body": null,
          "is_bot": false,
          "headline": "refactor: strong types for BridgeRate::Cctp fee fields",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T00:34:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "50df329f529a80396872665856024a0a51ed53e9",
          "body": null,
          "is_bot": false,
          "headline": "docs: update doc according to PR comment",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T00:34:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8477432a088ad4f844640b960647651cfcc66013",
          "body": "Per review (Lucas): the flag is CCTP-specific — it selects Circle's ATA-creation\nfee tier for non-EVM (Solana) recipients — so prefix it. Wire field + SDK send\nsite + regenerated client only; the sibling bridge_recipient_setup and the SDK's\nshared recipientSetup param are unchanged.",
          "is_bot": false,
          "headline": "refactor: rename /dex-quote recipient_setup -> cctp_recipient_setup",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T00:34:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d0ef78a0ad0c8b6d43b96b6db96b6e590fc78418",
          "body": "Bump across ts-pure-sdk, scripts/e2e-ts, the pure-ts example, and the frontend\n(via the SDK's optional dep); refresh all lockfiles. 12.11.1 is still\nNODE_MODULE_VERSION-specific, so the e2e's Node-22 pin (.nvmrc/run.sh) stays.",
          "is_bot": false,
          "headline": "chore: bump better-sqlite3 to ^12.11.1",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T00:34:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f3cae33ae53eb7a7b0a191881ae8d665b71840dd",
          "body": "For a target-pinned BTC→CCTP bridge quote, evmSmallest is the user's pinned\ndelivered amount (the server grosses up expected_amount_in, not the output), so\ntarget_amount = evmSmallest + bridgeFee overshot the pin and broke the contract\nthat net_target_amount == target_amount when targetAmount is provided. Only add\nthe bridge fee for source-pinned quotes; target-pinned echoes the pin. Keyed on\nthe same predicate as the net_target branch.",
          "is_bot": false,
          "headline": "fix(sdk): don't gross target-pinned bridge quotes by the bridge fee",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T00:34:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2860ca73e329964381fc175e3fbb629ee67c516b",
          "body": "The sponsored-userOp claim path built the Solana mint recipient as\n`bridgeRecipient ?? \"\"`, so a missing ATA round-tripped an empty string to\nthe server and failed opaquely in solana_pubkey_to_bytes32. The claim() early\npaths guard this, but the userOp branch never crosses that guard — add an\nactionable client-side error before the request. Defense-in-depth; the\nstandard flow always supplies the recipient.",
          "is_bot": false,
          "headline": "fix(sdk): guard missing bridgeRecipient on Solana userOp claim",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T00:34:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e9072106c2db202f86c56cae22a2cc8d475a2cdd",
          "body": "getQuote/composeQuote and the CCTP/OFT bridge-token lists route Solana and\nbridge-only chains (Base, Optimism, …), but Chain only allowed the narrow wire\nset — so tsc failed (solana-cctp.test) and consumers needed casts.\n\nWiden Chain to the SDK superset (Solana + CCTP bridge ids); add WireChain (the\n[…]\ntCctpBridgeTokens/getUsdt0BridgeTokens. Compose already\nremaps bridge targets to the Arbitrum hub, so the request body narrows to\nWireChain by construction. tsc is green unfiltered; no consumer casts.",
          "is_bot": false,
          "headline": "fix(sdk): split public Chain from wire type for Solana/bridge quotes",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T00:34:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "fed4dfa8add78197379f12b051b775452edd4f6c",
          "body": "…both directions\n\n/dex-calldata builds the full coordinator batch for CCTP targets (USDC →\nOptimism/Base/Solana): swap to hub USDC + cctp::build_bridge_calls, driven by\nthe `to` Token with a typed BridgeRecipient enum (Evm / Solana{ata, wallet?}).\n\nBoth swap directions now route Uniswap for liquid p\n[…]\nserOps;\nOFT/USDT0 stays on the legacy path pending the LZ-fee self-fund.\n\nVerified on mainnet: Optimism CCTP claim via EntryPoint v0.7 (~484k gas);\nEURe -> BTC inbound swap-and-lock settled via LI.FI.",
          "is_bot": false,
          "headline": "feat: CCTP bridge claims via sponsored userOp; LI.FI/Uniswap routing …",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T00:34:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "be1c2367b2de3a98ddf0b1c60e0d225bf7d2789a",
          "body": "claim() now publishes redeemAndExecute as a paymaster-sponsored 7702\nUserOp for same-chain Arbitrum EVM DEX swaps, fetching LI.FI calldata\nfrom /dex-calldata/fund instead of the legacy server-submit (which built\nUniswap calldata at a fixed 1.5M gas and reverted for LI.FI-only targets\nlike EURe). The\n[…]\nty test) and\nclaimViaUserOp; wires AA config in the frontend. Eligible claims require\nAA or throw — no silent fallback to the broken legacy path. Verified on\nmainnet: EURe settled via EntryPoint v0.7.",
          "is_bot": false,
          "headline": "feat(sdk): client-side sponsored-userOp claim for Arbitrum DEX swaps",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T00:34:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5944d7892aa4a21f452769d26338d92c8a6c4d72",
          "body": null,
          "is_bot": false,
          "headline": "feat(ts-sdk): add cache referral, swap pairs and chain config",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T00:34:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "93a4fdc5c1031ee59e59f87a7893b9832c7a20b6",
          "body": "/dex-quote gains recipient_setup, which folds the higher flat_with_setup\nforwardFee for a fresh non-EVM recipient. compose resolves non-EVM Solana\ntargets (base58 token bridged via the Arbitrum CCTP pivot) and threads\nbridgeRecipientSetup; the getQuote gate opens BTC→Solana. /quote stays as\nthe compat path + fallback. Verified e2e: Solana no-setup + setup parity\nvs legacy, exact bridge_fee match.",
          "is_bot": false,
          "headline": "feat: compose BTC→Solana CCTP quotes (incl. ATA-setup fee)",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T00:34:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f2ca32344098eb0c8665eadff0e06d5d4b2f1883",
          "body": "New GET /referral-fee primitive resolves a referral code to its extra-fee\nrate (decimal fraction; 400 over the key's cap) via resolve_swap_fees.\nThe SDK fetches it in composeQuote and adds it to the per-pair fee, so\ngetQuote composes referral'd quotes instead of falling back to /quote —\nonly Solana and bridgeRecipientSetup remain on legacy. Verified e2e:\nendpoint + compose markup match legacy /quote exactly.",
          "is_bot": false,
          "headline": "feat: compose referral/extra-fee pricing via /referral-fee",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T00:34:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7b3158d2eab133b2cc06dd3a88b6b927d61c84d8",
          "body": "getQuote now composes client-side for BTC<->EVM (direct, bridged, or\nLightning) and falls back to /quote only for referral/extra-fee pricing,\nSolana, and foreign EVM<->EVM. Same response shape; some values are more\naccurate (Lightning Boltz fee, EURe).\n\n/dex-quote surfaces bridge_fee (the amount it \n[…]\nss target_amount\nmatching legacy's contract, instead of re-deriving it. Documents\nminimum_fee_scaled as a millionths rate. Parity e2e now diffs against the\nraw /quote so it stays meaningful post-fold.",
          "is_bot": false,
          "headline": "feat(sdk): fold composeQuote into getQuote; surface bridge_fee",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T00:34:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "62ef1b757b1826ea7f9fe0b0db56f12d0054beab",
          "body": "A non-hub EVM chain (not in /chain-config) is reached by bridging: the\nHTLC settles in tBTC on Arbitrum, the DEX leg crosses Arbitrum<->dest, and\nswap-pair/network-fee legs key off Arbitrum. Hub chains (Arb/Poly/Eth)\nstill route direct, so e.g. USDC@Polygon skips the bridge. /dex-quote folds\nthe bridge fee into the amounts. Adds unit + e2e (USDC@Optimism) coverage.",
          "is_bot": false,
          "headline": "feat(sdk): route composeQuote through Arbitrum for bridge chains",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T00:34:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "84977535c82597770c42c76683aac8cec0d49ded",
          "body": "Nothing consumed hops / requires_multiple_user_ops, and the single hop\nmis-reported the DEX-leg output (delivered, not gross). Pricing only\nneeds end-to-end amounts + bridge_rate; per-leg execution structure\nbelongs on /dex-calldata when inbound multi-op forces it. Removes the\nDexQuoteHop type and regenerates the SDK + OpenAPI.",
          "is_bot": false,
          "headline": "refactor(dex-quote): drop unused hops from the response",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T00:34:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2dcb2cc1528c6c6e586b4611ee48a1dbfa645280",
          "body": "Drive bridging off from/to: a cross-chain dex-quote re-prices the\nhub-native DEX leg and returns a BridgeRate tagged by protocol\n(Cctp { ... } / LayerZero {}), so the SDK can compose bridged quotes\nclient-side. Adds chain_id mappings to the CCTP/OFT bridge enums.",
          "is_bot": false,
          "headline": "feat(dex-quote): expose per-bridge fee rates",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-07-08T00:34:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2e0c2ba39ed1f8bbd8824f3ce8aef0dc0fbad12d",
          "body": null,
          "is_bot": false,
          "headline": "chore: add changeset file",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-06T00:38:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "868cc374695c946fe3ec4692acfdaa2a66c4530c",
          "body": null,
          "is_bot": false,
          "headline": "chore: add sdk redmeas",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-06T00:38:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "131370c66e752aa110b4291ba0e8284b0be72b73",
          "body": null,
          "is_bot": false,
          "headline": "refactor(sdk): align changeset script names across workspaces",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-02T20:10:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f154d34ba4d9ec4872aa20cc6ac4af4da9672958",
          "body": "Add a parameterized just recipe wrapping the (interactive) Changesets CLI per\nSDK workspace, with passthrough for subcommands (add, add --empty, status).\n\nInclude an empty changeset for the Changesets adoption itself — tooling-only,\nso no version bump/publish, but it satisfies changeset-check.yml.",
          "is_bot": false,
          "headline": "chore(sdk): add `just changeset` recipe + empty changeset for setup",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-02T20:10:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "60f33c545ee90bd474bd312c5d421d073b93ba93",
          "body": "Adopt Changesets for @lendasat/lendaswap-sdk-pure (client-sdk/ts-pure-sdk)\nand @satora/* (client-sdk/ts-sdk) — versions and CHANGELOG.md are generated\nfrom per-PR changeset files.\n\nRelease paths (both bump + write changelog via `changeset version`):\n- Standalone SDK release, independent of backend:\n\n[…]\ns with the `no-changeset` label; release/* exempt).\n\nRemove the old lockstep satora-SDK workflows (draft/create_release_satora_sdk)\nand repoint subtree/mirror repo slugs from lendasat/* to satoraHQ/*.",
          "is_bot": false,
          "headline": "ci: manage SDK releases with Changesets",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-07-02T20:10:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "452c7a5b4b152d368aa541fb825e5d97e6c7c7b9",
          "body": "- SDK v0.2.44 (patch bump)\n- frontend v0.2.48 (patch bump)",
          "is_bot": true,
          "headline": "Release combined bump",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-06-23T07:38:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6216238e7d82b046df0c91a80e983c7b143d9a18",
          "body": null,
          "is_bot": false,
          "headline": "fix(sdk): keep ESM build browser-compatible",
          "author_name": "Lucas Soriano del Pino",
          "author_login": "luckysori",
          "committed_at": "2026-06-23T07:35:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "66d8ed176703c4164d00ec2703dd7fc4d2ec914e",
          "body": "- SDK v0.2.43 (patch bump)\n- frontend v0.2.47 (patch bump)\n- backend vlendaswap@0.2.47 (patch bump)",
          "is_bot": true,
          "headline": "Release combined bump",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-06-23T06:56:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d010ebe41f6119e316d94484745efca6fc20cf18",
          "body": null,
          "is_bot": true,
          "headline": "Release Satora SDKs version 0.0.4",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-06-23T03:52:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d347554733cf7cd9cc1c9a6c7985fcd42742484c",
          "body": null,
          "is_bot": false,
          "headline": "Allow zero-fee releases through verification",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-06-23T03:47:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "057352848bc65669046ef7b5f5b0e75ee98df461",
          "body": null,
          "is_bot": false,
          "headline": "Skip fee output for zero-fee escrow releases",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-06-23T03:47:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d1504bf918eaa73271e614cab11abfc7cb3f227d",
          "body": null,
          "is_bot": false,
          "headline": "chore: bump deps as I saw a security warning in downstream app",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-06-22T23:20:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "65410e6556a6c5e314708db55e0f4ec98661a96e",
          "body": null,
          "is_bot": false,
          "headline": "fix(sdk): keep native addons external so ESM /node loads at runtime",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-06-22T05:06:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d5dff888bf4f7c120711c0c7eab6a18a99ea35e8",
          "body": null,
          "is_bot": false,
          "headline": "fix(sdk): inject createRequire so ESM /node entry loads better-sqlite3",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-06-22T01:53:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fb10f0710f1ff3f0785dbcf90212a026ea003743",
          "body": "Aligns @lendasat/lendaswap-sdk-pure on pnpm (the package manager the frontend\nand client-sdk/ts-sdk workspaces already use), removing the mixed npm/pnpm\nsetup that caused lockfile drift and cross-tool confusion.\n\n- Replace package-lock.json with pnpm-lock.yaml generated via `pnpm import`,\n  preservi\n[…]\n2e-ts (file: deps, e2e-only) and publish-sdks.yml registry ops\n(version/pack/publish) intentionally stay on npm.\n\nVerified locally: pnpm install --frozen-lockfile, build, lint, and all 139\ntests pass.",
          "is_bot": false,
          "headline": "chore: migrate ts-pure-sdk to pnpm, align package managers",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-06-22T01:42:13Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9ad230868a46dd95598855316be71fb61909e7c9",
          "body": null,
          "is_bot": false,
          "headline": "chore: export and generate openapi client",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-06-22T00:56:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7456530492f3ddd3a81470684d991e4d7184e961",
          "body": null,
          "is_bot": false,
          "headline": "chore: formatting",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-06-22T00:56:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2b884f39143cc499da039b9ed1540e3dc27fd998",
          "body": null,
          "is_bot": false,
          "headline": "docs: update composeQuote scope comments to match current implementation",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-06-22T00:56:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1b550af70af6bc7b30ed8e9c83c55cf7c955572d",
          "body": null,
          "is_bot": false,
          "headline": "chore: remove comment",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-06-22T00:56:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "64cf5bcbac0b4be88e72e3dd949714c61664eafd",
          "body": null,
          "is_bot": false,
          "headline": "test(sdk): unit-cover direct-pegged compose-quote conversions",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-06-22T00:56:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "091a52bd14acd1623dbe6c8b4151b8f31224c3a3",
          "body": "composeQuote can now price a swap whose EVM side *is* the chain's\nBTC-pegged pivot (BTC <-> tBTC, BTC <-> WBTC) — there's no DEX hop, so\nit short-circuits the /dex-quote call and converts BTC sats <-> pegged\nbase units directly. This was the codex P2: previously such a request\nsent /dex-quote a same\n[…]\ncy\n  applies the WBTC/BTC rate, so they differ by the peg spread by design.\n- Also adds the earlier EVM->BTC into Arkade/Lightning coverage and the\n  non-null-assertion cleanup in the DEX-leg helpers.",
          "is_bot": false,
          "headline": "feat(sdk): composeQuote handles direct BTC<->pegged pivot + peg rate",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-06-22T00:56:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4471a89ec83e3e5a0c9debafead8f863d1d64c29",
          "body": null,
          "is_bot": false,
          "headline": "fix: openapi and linter",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-06-22T00:56:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c102e0fe0f1bab931e18f1c225d3ee1d6bf798a0",
          "body": null,
          "is_bot": false,
          "headline": "fix: formatting",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-06-22T00:56:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "db3916f8b62457c98d95451384ea448de22168f9",
          "body": "Fourth and final cell of the BTC<->EVM Arbitrum/Polygon matrix.\nUser pins target BTC sats; /dex-quote runs exact_out with the pivot\namount as the output target; the returned expected_amount_in is the\nrequired source token amount.\n\ncomposeEvmToBtc refactored to mirror composeBtcToEvm: shared\nfee/min/\n[…]\n) ratio the DEX\n                 quote carries\n\nNote: not run in this session (slow connection). Verify with\n`just e2e-ts compose-quote-parity`; `git bisect` per-commit\nremains supported by the split.",
          "is_bot": false,
          "headline": "feat(sdk): composeQuote EVM->BTC target-pinned",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-06-22T00:56:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "08b8adc770798c3e5bfd3b1e4f09e581698c70ad",
          "body": "Third cell of the matrix (the first two were BTC<->EVM source-pinned).\nUser pins the target token amount; /dex-quote runs exact_out (pivot\n-> target); the required pivot amount divides into BTC sats; fees\nadd on the BTC side.\n\ncomposeBtcToEvm refactored to share fee/min/max/protocol/net-amount\nmath \n[…]\nches.\n\nNote: e2e parity tests for the new direction were not run in this\nsession (slow connection). Run `just e2e-ts compose-quote-parity`\nto verify; `git bisect` per-commit is supported by the split.",
          "is_bot": false,
          "headline": "feat(sdk): composeQuote BTC->EVM target-pinned",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-06-22T00:56:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1def251421542d9d95b54e07265d4035ceb43d27",
          "body": "Hand-written type layer:\n- src/types/ — Chain, QuoteResponse, SwapPairsResponse, DexQuoteResponse,\n  NetworkFeesResponse, ChainConfigResponse, Token, TokenAmount, etc.\n- fromWire*() translators sit between the OpenAPI codegen and the\n  SDK type so future wire-vs-SDK divergence has one place to land\n\n[…]\ngetSwapPairs()/getArkadeToLightningQuote()\nroute their payloads through fromWire*() so the hand-written types\nare the only public shape consumers see — structurally identical\ntoday, no external break.",
          "is_bot": false,
          "headline": "feat(sdk): hand-written types + composeQuote v0 (BTC<->EVM Arb/Polygon)",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-06-22T00:56:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d4d6b6a140584c8e6fdc804dc1d5af40e52fa702",
          "body": "Switch @lendasat/lendaswap-sdk-pure and @satora/swap from tsc (ESM-only,\nimport-only exports) to tsup, emitting both an ESM and a self-contained CJS\nbuild with matching `exports` conditions (import -> .js, require -> .cjs).\n\nThe SDK bundles its dependencies into both formats so the CJS output never\n\n[…]\np; the declaration tree resolves independently.\n\nThe @satora/swap wrapper keeps the SDK external and stays a thin re-export\nshim, so consumers resolve a single copy of the SDK through its own exports.",
          "is_bot": false,
          "headline": "build: ship dual ESM+CJS builds for the swap SDK and wrapper",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-06-22T00:52:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "db3b5e7949d23ed0d051a9ae7fc78e8edcc857d5",
          "body": null,
          "is_bot": true,
          "headline": "Release Satora SDKs version 0.0.3",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-06-19T06:52:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e73c304e56a386fc2f20ef658eba7384afb331df",
          "body": null,
          "is_bot": true,
          "headline": "Release Satora SDKs version 0.0.2",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-06-19T06:30:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "90b7414dea246a3c70b40936b621b4cb4eb76c3f",
          "body": null,
          "is_bot": false,
          "headline": "chore: regenerate sdk client",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-06-18T23:44:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8d7d985c980ea621d23c6e233054ca3394022529",
          "body": "undici rejects fetch with Error(\"fetch failed\") and the real reason\n(ECONNREFUSED/ETIMEDOUT) on error.cause. Inspect the whole error, not\njust .message, and treat the undici wording + common network codes as\ntransient so broadcast hiccups in the Node SDK retry instead of failing\nfast.",
          "is_bot": false,
          "headline": "fix: retry Node fetch failures in broadcast retry",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-06-18T22:53:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f51bae255e6f812ec593e2d21733f44495084f2e",
          "body": null,
          "is_bot": false,
          "headline": "fix: poll and retry evm-to-btc onchain claim",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-06-18T22:53:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1c79d04a6904b84eb5358797c98c09d38fe04677",
          "body": "- SDK v0.2.42 (patch bump)\n- frontend v0.2.46 (patch bump)\n- backend vlendaswap@0.2.46 (patch bump)",
          "is_bot": true,
          "headline": "Release combined bump",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-06-18T02:41:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c3bd10d9f481f014d73f35cff6bf6e9859815ecc",
          "body": null,
          "is_bot": false,
          "headline": "chore: bump arkade-sdk",
          "author_name": "bonomat",
          "author_login": "bonomat",
          "committed_at": "2026-06-18T02:32:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "203ace1f0ba2a16c3a3e6a0de347d310f371a92c",
          "body": "- SDK v0.2.41 (patch bump)\n- frontend v0.2.45 (patch bump)\n- backend vlendaswap@0.2.45 (patch bump)",
          "is_bot": true,
          "headline": "Release combined bump",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-06-18T01:50:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "286827b6e4a2672fd6742e7fda70e4b620bbe661",
          "body": "Change-Id: Ic56f666defc9a1bf2be0688907d4a788fd7e5175",
          "is_bot": false,
          "headline": "chore: bump satora sdk versions to 0.0.1",
          "author_name": "Lucas Soriano del Pino",
          "author_login": "luckysori",
          "committed_at": "2026-06-10T06:02:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "aaf9a4ebcc66c3f2e04e25ba450308823479f2f4",
          "body": "Change-Id: I7700c024d882819598d5a77629324f2ad370bcde",
          "is_bot": false,
          "headline": "fix: reject duplicate release outputs",
          "author_name": "Lucas Soriano del Pino",
          "author_login": "luckysori",
          "committed_at": "2026-06-10T05:32:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7576f2d1fa1cbab14d8e23dc588c096e9647d034",
          "body": "Change-Id: I2f36389fbad84fc117304951f93db70be5d8fd94",
          "is_bot": false,
          "headline": "chore: use Arkade terminology in escrow SDK",
          "author_name": "Lucas Soriano del Pino",
          "author_login": "luckysori",
          "committed_at": "2026-06-10T05:32:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "26fbf5b5c1e87c7158653b72a7cc61c3117e01bb",
          "body": null,
          "is_bot": false,
          "headline": "feat(escrow-client): smart withdraw + classifyDestination, with tests",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-06-10T05:32:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ad217fd9a9becc328ad11159f44b7e04f622985b",
          "body": null,
          "is_bot": false,
          "headline": "feat(escrow-client): add withdrawToArkade (offchain ark transfer)",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-06-10T05:32:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6de6a4870ed2ee15089f9ef4560b55c4d5b8437b",
          "body": null,
          "is_bot": false,
          "headline": "docs(escrow-client): add how-to readme",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-06-10T05:32:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "439174b0c263e50d875ff799d05377ea9dac3471",
          "body": "…quote helper",
          "is_bot": false,
          "headline": "feat(escrow-client): lightning withdrawal to invoice/LNURL/address + …",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-06-10T05:32:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "44da2f206370fa5e59d4d3dc959cf5d9ca331f71",
          "body": null,
          "is_bot": false,
          "headline": "feat(escrow-client): @satora/escrow-client funding/withdrawal flows",
          "author_name": "Philipp",
          "author_login": "bonomat",
          "committed_at": "2026-06-10T05:32:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 14,
      "commits_last_year": 576,
      "latest_release_at": "2026-06-23T07:38:44Z",
      "latest_release_tag": "v0.2.44",
      "releases_from_tags": false,
      "days_since_last_push": 5,
      "active_weeks_last_year": 35,
      "days_since_latest_release": 34,
      "mean_days_between_releases": 3.2
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": false,
      "has_contributing": false,
      "health_percentage": 37,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "@lendasat/lendaswap-sdk-pure",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "lendaswap",
            "bitcoin",
            "swap",
            "ark",
            "arkade",
            "react-native"
          ],
          "ecosystem": "npm",
          "matches_repo": false,
          "registry_url": "https://www.npmjs.com/package/@lendasat/lendaswap-sdk-pure",
          "is_deprecated": false,
          "latest_version": "0.4.0",
          "repository_url": "https://github.com/satoraHQ/lendaswap-sdk",
          "versions_count": 56,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 2,
          "monthly_downloads": 3089,
          "first_published_at": "2026-01-29T05:34:12.500000Z",
          "latest_published_at": "2026-07-21T02:10:46.089000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 6
        }
      ]
    },
    "popularity": {
      "forks": 4,
      "stars": 6,
      "watchers": 0,
      "fork_history": {
        "days": [
          {
            "date": "2026-01-29",
            "count": 1
          },
          {
            "date": "2026-02-24",
            "count": 1
          },
          {
            "date": "2026-04-23",
            "count": 1
          },
          {
            "date": "2026-04-24",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 4,
        "total_forks": 4
      },
      "star_history": null,
      "open_issues_and_prs": 2
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "examples"
      ],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [
        "Justfile",
        "dotnet-sdk/Justfile"
      ],
      "api_schema_files": [
        "rust-sdk/openapi.json",
        "ts-pure-sdk/openapi.json"
      ],
      "has_devcontainer": false,
      "typecheck_configs": [
        "ts-pure-sdk/tsconfig.json",
        "ts-sdk/packages/escrow-client/tsconfig.json",
        "ts-sdk/packages/escrow/tsconfig.json",
        "ts-sdk/packages/swap/tsconfig.json"
      ],
      "toolchain_manifests": [
        "core/Cargo.toml",
        "dotnet-sdk/Satora.Sdk.Cli/Satora.Sdk.Cli.csproj",
        "dotnet-sdk/Satora.Sdk.Tests/Satora.Sdk.Tests.csproj",
        "dotnet-sdk/Satora.Sdk/Satora.Sdk.csproj",
        "dotnet-sdk/native/Cargo.toml",
        "rust-sdk/Cargo.toml"
      ],
      "largest_source_bytes": 211665,
      "source_files_sampled": 222,
      "oversized_source_files": 3,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "core/Cargo.toml",
        "rust-sdk/Cargo.toml",
        "ts-pure-sdk/package.json",
        "ts-sdk/package.json"
      ],
      "advisories": {
        "error": null,
        "scope": "published_package",
        "source": "osv",
        "findings": [
          {
            "name": "ws",
            "direct": false,
            "version": "8.20.1",
            "severity": "high",
            "ecosystem": "npm",
            "cvss_score": 7.5,
            "advisory_ids": [
              "GHSA-96hv-2xvq-fx4p"
            ],
            "fixed_version": "8.21.0",
            "advisory_count": 1,
            "oldest_advisory_days": 42
          }
        ],
        "collected": true,
        "malicious": [],
        "truncated": false,
        "by_severity": {
          "high": 1
        },
        "advisory_count": 1,
        "affected_count": 1,
        "assessed_count": 82,
        "malicious_count": 0,
        "assessed_package": "npm:@lendasat/lendaswap-sdk-pure@0.4.0",
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "crates",
        "npm"
      ],
      "dependencies": [
        {
          "name": "anyhow",
          "manifest": "core/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "thiserror",
          "manifest": "core/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1.0"
        },
        {
          "name": "hex",
          "manifest": "core/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.4"
        },
        {
          "name": "serde",
          "manifest": "core/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "serde_json",
          "manifest": "core/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "log",
          "manifest": "core/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.4"
        },
        {
          "name": "rand",
          "manifest": "core/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.8"
        },
        {
          "name": "sha2",
          "manifest": "core/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.10"
        },
        {
          "name": "bip39",
          "manifest": "core/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "2.1.0"
        },
        {
          "name": "bitcoin",
          "manifest": "core/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.32.2"
        },
        {
          "name": "miniscript",
          "manifest": "core/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "12"
        },
        {
          "name": "ark-rest",
          "manifest": "core/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "ark-rs",
          "manifest": "core/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "nostr",
          "manifest": "core/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.40.0"
        },
        {
          "name": "futures",
          "manifest": "core/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.3"
        },
        {
          "name": "reqwest",
          "manifest": "core/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.12"
        },
        {
          "name": "getrandom",
          "manifest": "core/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.2"
        },
        {
          "name": "getrandom_latest",
          "manifest": "core/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.3"
        },
        {
          "name": "rust_decimal",
          "manifest": "core/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "rust_decimal_macros",
          "manifest": "core/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "time",
          "manifest": "core/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.3"
        },
        {
          "name": "uuid",
          "manifest": "core/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1.0"
        },
        {
          "name": "sqlx",
          "manifest": "core/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.8"
        },
        {
          "name": "bip39",
          "manifest": "rust-sdk/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "2"
        },
        {
          "name": "bitcoin",
          "manifest": "rust-sdk/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.32"
        },
        {
          "name": "hex",
          "manifest": "rust-sdk/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.4"
        },
        {
          "name": "reqwest",
          "manifest": "rust-sdk/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.13"
        },
        {
          "name": "serde",
          "manifest": "rust-sdk/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "serde_json",
          "manifest": "rust-sdk/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "sha2",
          "manifest": "rust-sdk/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.10"
        },
        {
          "name": "thiserror",
          "manifest": "rust-sdk/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "tiny-keccak",
          "manifest": "rust-sdk/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "2"
        },
        {
          "name": "tracing",
          "manifest": "rust-sdk/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.1"
        },
        {
          "name": "url",
          "manifest": "rust-sdk/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "2"
        },
        {
          "name": "alloy",
          "manifest": "rust-sdk/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "alloy-provider",
          "manifest": "rust-sdk/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "rand",
          "manifest": "rust-sdk/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.8"
        },
        {
          "name": "tokio",
          "manifest": "rust-sdk/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "ark-bdk-wallet",
          "manifest": "rust-sdk/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.10"
        },
        {
          "name": "ark-rs",
          "manifest": "rust-sdk/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.10.1"
        },
        {
          "name": "esplora-client",
          "manifest": "rust-sdk/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.11"
        },
        {
          "name": "rustls",
          "manifest": "rust-sdk/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.23"
        },
        {
          "name": "@arkade-os/sdk",
          "manifest": "ts-pure-sdk/package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.4.45"
        },
        {
          "name": "@noble/curves",
          "manifest": "ts-pure-sdk/package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.2.0"
        },
        {
          "name": "@noble/hashes",
          "manifest": "ts-pure-sdk/package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.2.0"
        },
        {
          "name": "@scure/base",
          "manifest": "ts-pure-sdk/package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.0.0"
        },
        {
          "name": "@scure/bip32",
          "manifest": "ts-pure-sdk/package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.0.1"
        },
        {
          "name": "@scure/bip39",
          "manifest": "ts-pure-sdk/package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.0.1"
        },
        {
          "name": "@scure/btc-signer",
          "manifest": "ts-pure-sdk/package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.0.1"
        },
        {
          "name": "@zerodev/sdk",
          "manifest": "ts-pure-sdk/package.json",
          "ecosystem": "npm",
          "version_constraint": "^5.5.0"
        },
        {
          "name": "dexie",
          "manifest": "ts-pure-sdk/package.json",
          "ecosystem": "npm",
          "version_constraint": "^4.4.2"
        },
        {
          "name": "openapi-fetch",
          "manifest": "ts-pure-sdk/package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.17.0"
        },
        {
          "name": "viem",
          "manifest": "ts-pure-sdk/package.json",
          "ecosystem": "npm",
          "version_constraint": "2.52.2"
        },
        {
          "name": "Microsoft.NET.Test.Sdk",
          "manifest": "dotnet-sdk/Satora.Sdk.Tests/Satora.Sdk.Tests.csproj",
          "ecosystem": "nuget",
          "version_constraint": "17.11.1"
        },
        {
          "name": "xunit",
          "manifest": "dotnet-sdk/Satora.Sdk.Tests/Satora.Sdk.Tests.csproj",
          "ecosystem": "nuget",
          "version_constraint": "2.9.2"
        },
        {
          "name": "xunit.runner.visualstudio",
          "manifest": "dotnet-sdk/Satora.Sdk.Tests/Satora.Sdk.Tests.csproj",
          "ecosystem": "nuget",
          "version_constraint": "2.8.2"
        },
        {
          "name": "bitcoin",
          "manifest": "dotnet-sdk/native/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.32"
        },
        {
          "name": "lendaswap-sdk",
          "manifest": "dotnet-sdk/native/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": null
        },
        {
          "name": "serde_json",
          "manifest": "dotnet-sdk/native/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "thiserror",
          "manifest": "dotnet-sdk/native/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "tokio",
          "manifest": "dotnet-sdk/native/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "uniffi",
          "manifest": "dotnet-sdk/native/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.29"
        },
        {
          "name": "url",
          "manifest": "dotnet-sdk/native/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "2"
        }
      ],
      "all_dependencies": {
        "error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
        "source": null,
        "packages": [],
        "collected": false,
        "truncated": false,
        "total_count": null,
        "direct_count": null,
        "indirect_count": null
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 1,
        "merged_prs": 1,
        "open_issues": 1,
        "closed_ratio": 0,
        "closed_issues": 0,
        "closed_unmerged_prs": 2
      },
      "bus_factor": 1,
      "bot_contributors": 1,
      "top_contributors": [
        {
          "type": "User",
          "login": "bonomat",
          "commits": 354,
          "avatar_url": "https://avatars.githubusercontent.com/u/224613?v=4"
        },
        {
          "type": "User",
          "login": "luckysori",
          "commits": 108,
          "avatar_url": "https://avatars.githubusercontent.com/u/9418575?v=4"
        },
        {
          "type": "User",
          "login": "mentioneddd",
          "commits": 18,
          "avatar_url": "https://avatars.githubusercontent.com/u/95380067?v=4"
        }
      ],
      "contributors_sampled": 3,
      "top_contributor_share": 0.738
    },
    "quality_signals": {
      "has_ci": false,
      "has_tests": true,
      "ci_workflows": [],
      "has_docs_dir": false,
      "linter_configs": [
        "biome.json"
      ],
      "has_editorconfig": false,
      "has_linter_config": true,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "Cargo.lock",
        "package-lock.json",
        "pnpm-lock.yaml"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 5,
            "reason": "branch protection is not maximal on development and all release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": null,
            "reason": "no pull request found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 10,
            "reason": "project has 3 contributing companies or organizations -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": null,
            "reason": "no workflows found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": null,
            "reason": "packaging workflow not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": null,
            "reason": "no dependencies found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "no SAST tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": null,
            "reason": "No tokens found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 0,
            "reason": "37 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "2bba19673d3ad56eac5f9f67c2a8089752f0cba4",
        "ran_at": "2026-07-27T20:56:25Z",
        "aggregate_score": 3.5,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": null,
      "oldest_open_prs": [
        {
          "number": 5,
          "created_at": "2026-07-05T23:59:30Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-02-16T00:56:42Z",
      "ci_last_conclusion": null,
      "oldest_open_issues": [
        {
          "number": 3,
          "created_at": "2026-04-23T20:34:08Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/satoraHQ/satora-sdk",
    "host": "github.com",
    "name": "satora-sdk",
    "owner": "satoraHQ"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 50,
      "inputs": {
        "security": 45,
        "vitality": 93,
        "community": 31,
        "governance": 32,
        "engineering": 46
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "excellent",
        "name": "Vitality",
        "value": 93,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "excellent",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 88,
            "inputs": {
              "commits_last_year": 576,
              "human_commit_share": 0.87,
              "days_since_last_push": 5,
              "active_weeks_last_year": 35
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 5 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 5
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "35/52 weeks with commits",
                "points": 24.2,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 35
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "576 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 576
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "releases_count": 14,
              "latest_release_tag": "v0.2.44",
              "releases_from_tags": false,
              "days_since_latest_release": 34,
              "mean_days_between_releases": 3.2
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "14 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 14
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 34 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 34
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~3.2 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 3.2
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "maintained",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": null,
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": 5,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "last human commit 5 days ago",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_maintained",
                    "params": {
                      "days": 5
                    }
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "at_risk",
        "name": "Community & Adoption",
        "value": 31,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 15,
            "inputs": {
              "forks": 4,
              "stars": 6,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "6 stars",
                "points": 11.3,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 6
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "4 forks",
                "points": 4,
                "status": "partial",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 4
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "at_risk",
        "name": "Sustainability & Governance",
        "value": 32,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 29,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 3,
              "top_contributor_share": 0.738
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 74% of commits",
                "points": 5.9,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 74
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "3 contributors",
                "points": 4.1,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 3
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 3 contributing companies or organizations -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "critical",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 13,
            "inputs": {
              "merged_prs": 1,
              "open_issues": 1,
              "closed_issues": 0,
              "issue_closed_ratio": 0,
              "closed_unmerged_prs": 2
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "0% of issues closed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 0
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "1/3 decided PRs merged",
                "points": 12.8,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 1,
                      "decided": 3
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "moderate",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 55,
            "inputs": {
              "followers": 27,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "satoraHQ",
              "public_repos": 25,
              "account_age_days": 754
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "organization-owned",
                "points": 30,
                "status": "met",
                "details": [
                  {
                    "code": "owner_organization",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "27 followers of satoraHQ",
                "points": 10.4,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 27,
                      "login": "satoraHQ"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "25 public repos, account ~2 yr old",
                "points": 14.4,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 25
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 2
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "at_risk",
        "name": "Engineering Quality",
        "value": 46,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_ci_tests"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 50,
            "inputs": {
              "has_ci": false,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": true,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": "biome.json",
                "points": 16,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "biome.json"
                    }
                  }
                ],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "at_risk",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": false,
              "has_description": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "at_risk",
        "name": "Security",
        "value": 45,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): CI-Tests, Dangerous-Workflow, Packaging, Pinned-Dependencies, Signed-Releases, Token-Permissions. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "ci_tests",
                    "dangerous_workflow",
                    "packaging",
                    "pinned_dependencies",
                    "signed_releases",
                    "token_permissions"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 35,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 12,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 6,
              "scorecard_aggregate": 3.5
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection is not maximal on development and all release branches",
                "points": 3.8,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 3 contributing companies or organizations -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no workflows found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow not detected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "no dependencies found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "no SAST tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "No tokens found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "37 existing vulnerabilities detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "dependency_advisories",
            "band": "excellent",
            "name": "Dependency advisories",
            "note": "Matched the npm:@lendasat/lendaswap-sdk-pure@0.4.0 runtime dependency closure — what installing the published package pulls in — 82 packages. Reachability is not analyzed.",
            "notes": [
              {
                "code": "advisories_scope_published",
                "params": {
                  "package": "npm:@lendasat/lendaswap-sdk-pure@0.4.0",
                  "assessed": 82
                }
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 85,
            "inputs": {
              "source": "osv",
              "advisories": 1,
              "affected_packages": 1,
              "assessed_packages": 82,
              "unassessed_packages": 0,
              "affected_by_severity": "high 1",
              "direct_affected_packages": 0
            },
            "components": [
              {
                "key": "direct_dependencies_free_of_known_advisories",
                "name": "Direct dependencies free of known advisories",
                "detail": "no direct dependency carries a known advisory",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "no_direct_advisories",
                    "params": {}
                  }
                ],
                "max_points": 35
              },
              {
                "key": "indirect_dependencies_free_of_known_advisories",
                "name": "Indirect dependencies free of known advisories",
                "detail": "1 affected: ws 8.20.1 (high 7.5)",
                "points": 10,
                "status": "partial",
                "details": [
                  {
                    "code": "advisories_affected",
                    "params": {
                      "count": 1,
                      "packages": "ws 8.20.1 (high 7.5)"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "no_advisories_left_outstanding",
                "name": "No advisories left outstanding",
                "detail": "no advisory has been public longer than 90 days",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "advisories_none_stale",
                    "params": {
                      "days": 90
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "malicious_dependencies",
            "band": "excellent",
            "name": "Malicious dependencies",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "source": "osv",
              "meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
              "packages": [],
              "red_flag": false,
              "assessed_packages": 82,
              "malicious_packages": 0,
              "direct_malicious_packages": 0,
              "withdrawn_malicious_packages": 0,
              "installable_malicious_packages": 0
            },
            "components": [
              {
                "key": "no_dependency_reported_as_a_malicious_package",
                "name": "No dependency reported as a malicious package",
                "detail": "no dependency is reported as a malicious package",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "no_malicious_dependencies",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 3
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "good",
        "name": "AI Readiness",
        "value": 71,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "at_risk",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.966,
              "agent_instruction_files": [],
              "agent_instruction_max_bytes": null
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "no CLAUDE.md / AGENTS.md / editor rules",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_instructions",
                    "params": {}
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "84 of 87 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 84,
                      "sampled": 87
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "good",
            "name": "Verify loop (build / test / typecheck)",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Pinned-Dependencies. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_pinned_dependencies"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 80,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "Cargo.lock",
                "package-lock.json",
                "pnpm-lock.yaml"
              ],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [
                "Justfile",
                "dotnet-sdk/Justfile"
              ],
              "has_devcontainer": false,
              "has_linter_config": true,
              "typecheck_configs": [
                "ts-pure-sdk/tsconfig.json",
                "ts-sdk/packages/escrow-client/tsconfig.json",
                "ts-sdk/packages/escrow/tsconfig.json",
                "ts-sdk/packages/swap/tsconfig.json"
              ],
              "agent_commit_share": 0,
              "toolchain_manifests": [
                "core/Cargo.toml",
                "dotnet-sdk/Satora.Sdk.Cli/Satora.Sdk.Cli.csproj",
                "dotnet-sdk/Satora.Sdk.Tests/Satora.Sdk.Tests.csproj",
                "dotnet-sdk/Satora.Sdk/Satora.Sdk.csproj",
                "dotnet-sdk/native/Cargo.toml",
                "rust-sdk/Cargo.toml"
              ],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "Justfile, dotnet-sdk/Justfile",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Justfile, dotnet-sdk/Justfile"
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": "biome.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "biome.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "ts-pure-sdk/tsconfig.json, ts-sdk/packages/escrow-client/tsconfig.json, ts-sdk/packages/escrow/tsconfig.json, ts-sdk/packages/swap/tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "ts-pure-sdk/tsconfig.json, ts-sdk/packages/escrow-client/tsconfig.json, ts-sdk/packages/escrow/tsconfig.json, ts-sdk/packages/swap/tsconfig.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "no agent-authored commits among the last 100",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_authored_commits",
                    "params": {
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "no dependencies found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 99,
            "inputs": {
              "primary_language": "TypeScript",
              "largest_source_bytes": 211665,
              "source_files_sampled": 222,
              "oversized_source_files": 3
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "TypeScript (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "TypeScript"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "3/222 source files over 60KB",
                "points": 54.3,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 222,
                      "oversized": 3
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "good",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 80,
            "inputs": {
              "example_dirs": [
                "examples"
              ],
              "has_mcp_signal": false,
              "api_schema_files": [
                "rust-sdk/openapi.json",
                "ts-pure-sdk/openapi.json"
              ]
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": "rust-sdk/openapi.json, ts-pure-sdk/openapi.json",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "rust-sdk/openapi.json, ts-pure-sdk/openapi.json"
                    }
                  }
                ],
                "max_points": 40
              },
              {
                "key": "mcp_server",
                "name": "MCP server",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": "examples",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "examples"
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "Could not fetch crates package 'lendaswap-core' from its registry",
    "Could not fetch crates package 'lendaswap-sdk' from its registry",
    "npm package '@lendasat/lendaswap-sdk-pure' points at a different repository (https://github.com/satoraHQ/lendaswap-sdk); excluded from ecosystem scoring",
    "Could not fetch crates package 'satora-sdk-ffi' from its registry",
    "Could not fetch nuget package 'Satora.Sdk' from its registry",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-27T20:56:30.983855Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/s/satoraHQ/satora-sdk.svg",
  "full_name": "satoraHQ/satora-sdk",
  "license_state": "standard",
  "license_spdx": "MIT"
}

Scores are signals, not warranties. They reflect publicly visible practices on GitHub — not a code audit, and not a security guarantee.

Missing data is excluded and weights renormalized, never scored as zero. Methodology is versioned and open: metrics v1.13.0, schema v0.27.0 — full methodology · metrics wiki.

How one result sits in the wider record: aggregate statisticsnpm.