JSON-Rohbericht maschinenlesbar
{
"data": {
"repo": {
"topics": [],
"is_fork": false,
"size_kb": 744010,
"has_wiki": true,
"homepage": null,
"languages": {
"C": 194496,
"Ruby": 2537,
"Shell": 5766,
"Swift": 9535004,
"Python": 9583,
"Makefile": 4040,
"JavaScript": 7811,
"Objective-C": 37152
},
"pushed_at": "2026-07-21T22:56:12Z",
"created_at": "2024-01-28T02:41:10Z",
"owner_type": "Organization",
"updated_at": "2026-07-21T22:56:15Z",
"description": "Vultisig iOS App",
"is_archived": false,
"is_disabled": false,
"license_spdx": "Apache-2.0",
"default_branch": "main",
"license_spdx_raw": "Apache-2.0",
"primary_language": "Swift",
"significant_languages": [
"Swift"
]
},
"owner": {
"blog": "vultisig.com",
"name": "Vultisig: Secure Crypto Vault",
"type": "Organization",
"login": "vultisig",
"company": null,
"location": null,
"followers": 132,
"avatar_url": "https://avatars.githubusercontent.com/u/157932671?v=4",
"created_at": "2024-01-28T01:22:46Z",
"is_verified": null,
"public_repos": 72,
"account_age_days": 906
},
"license": {
"state": "standard",
"spdx_id": "Apache-2.0",
"raw_spdx": "Apache-2.0",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "v1.42.67",
"kind": "patch",
"published_at": "2026-07-17T01:06:25Z"
},
{
"tag": "v1.42.66",
"kind": "patch",
"published_at": "2026-07-14T05:07:23Z"
},
{
"tag": "v1.41.65",
"kind": "patch",
"published_at": "2026-07-04T01:47:01Z"
},
{
"tag": "v1.41.64",
"kind": "patch",
"published_at": "2026-07-03T00:09:35Z"
},
{
"tag": "v1.40.63",
"kind": "patch",
"published_at": "2026-06-23T23:52:02Z"
},
{
"tag": "v1.40.62",
"kind": "patch",
"published_at": "2026-06-21T23:32:15Z"
},
{
"tag": "v1.39.61",
"kind": "patch",
"published_at": "2026-06-12T06:45:39Z"
},
{
"tag": "v1.39.60",
"kind": "patch",
"published_at": "2026-06-09T23:44:54Z"
},
{
"tag": "v1.38.59",
"kind": "patch",
"published_at": "2026-06-05T22:23:33Z"
},
{
"tag": "v1.38.58",
"kind": "patch",
"published_at": "2026-06-05T10:09:35Z"
},
{
"tag": "v1.37.57",
"kind": "patch",
"published_at": "2026-05-25T03:12:30Z"
},
{
"tag": "v1.37.56",
"kind": "patch",
"published_at": "2026-05-24T03:11:09Z"
},
{
"tag": "v1.36.55",
"kind": "patch",
"published_at": "2026-05-05T23:12:19Z"
},
{
"tag": "v1.36.54",
"kind": "patch",
"published_at": "2026-05-04T21:58:51Z"
},
{
"tag": "v1.36.53",
"kind": "patch",
"published_at": "2026-05-02T01:05:44Z"
},
{
"tag": "v1.36.52",
"kind": "patch",
"published_at": "2026-04-30T00:10:17Z"
},
{
"tag": "v1.36.51",
"kind": "patch",
"published_at": "2026-04-29T01:15:23Z"
},
{
"tag": "v1.35.50",
"kind": "patch",
"published_at": "2026-03-27T04:21:24Z"
},
{
"tag": "v1.35.49",
"kind": "patch",
"published_at": "2026-03-22T22:41:43Z"
},
{
"tag": "v1.34.48",
"kind": "patch",
"published_at": "2026-03-09T22:47:02Z"
},
{
"tag": "v1.34.47",
"kind": "patch",
"published_at": "2026-03-03T22:32:15Z"
},
{
"tag": "v1.34.46",
"kind": "patch",
"published_at": "2026-03-01T22:42:30Z"
},
{
"tag": "v1.33.45",
"kind": "patch",
"published_at": "2026-02-17T19:46:06Z"
},
{
"tag": "v1.33.44",
"kind": "patch",
"published_at": "2026-02-12T21:27:53Z"
},
{
"tag": "v1.33.43",
"kind": "patch",
"published_at": "2026-02-09T21:44:54Z"
},
{
"tag": "v1.33.42",
"kind": "patch",
"published_at": "2026-02-05T23:11:01Z"
},
{
"tag": "v1.33.41",
"kind": "patch",
"published_at": "2026-02-03T22:07:43Z"
},
{
"tag": "1.33.40",
"kind": "patch",
"published_at": "2026-02-01T19:47:43Z"
},
{
"tag": "1.33.39",
"kind": "patch",
"published_at": "2026-01-28T08:59:24Z"
},
{
"tag": "v1.32.38",
"kind": "patch",
"published_at": "2026-01-12T21:54:13Z"
},
{
"tag": "v1.32.37",
"kind": "patch",
"published_at": "2026-01-09T08:32:44Z"
},
{
"tag": "v1.32.36",
"kind": "patch",
"published_at": "2026-01-06T05:50:12Z"
},
{
"tag": "v1.32.35",
"kind": "patch",
"published_at": "2025-12-22T08:19:07Z"
},
{
"tag": "v1.31.34",
"kind": "patch",
"published_at": "2025-12-08T22:26:54Z"
},
{
"tag": "v1.31.32",
"kind": "patch",
"published_at": "2025-12-08T02:59:16Z"
},
{
"tag": "v1.31.31",
"kind": "patch",
"published_at": "2025-12-05T02:46:48Z"
},
{
"tag": "v1.31.30",
"kind": "patch",
"published_at": "2025-11-29T03:01:37Z"
},
{
"tag": "v1.30.29",
"kind": "patch",
"published_at": "2025-11-25T23:14:01Z"
},
{
"tag": "v1.29.28",
"kind": "patch",
"published_at": "2025-11-21T09:08:08Z"
},
{
"tag": "v1.29.27",
"kind": "patch",
"published_at": "2025-11-19T21:51:00Z"
},
{
"tag": "v1.29.26",
"kind": "patch",
"published_at": "2025-11-17T22:48:06Z"
},
{
"tag": "v1.29.25",
"kind": "patch",
"published_at": "2025-11-15T00:16:18Z"
},
{
"tag": "v1.29.24",
"kind": "patch",
"published_at": "2025-11-12T22:58:47Z"
},
{
"tag": "v1.28.23",
"kind": "patch",
"published_at": "2025-11-04T07:01:05Z"
},
{
"tag": "v1.28.22",
"kind": "patch",
"published_at": "2025-11-03T07:59:41Z"
},
{
"tag": "v1.28.21",
"kind": "patch",
"published_at": "2025-10-30T22:34:43Z"
},
{
"tag": "v1.28.20",
"kind": "patch",
"published_at": "2025-10-28T23:30:48Z"
},
{
"tag": "v1.27.19",
"kind": "patch",
"published_at": "2025-10-22T21:57:35Z"
},
{
"tag": "v1.27.18",
"kind": "patch",
"published_at": "2025-10-20T03:03:07Z"
},
{
"tag": "v1.27.17",
"kind": "patch",
"published_at": "2025-10-15T22:27:49Z"
},
{
"tag": "v1.27.16",
"kind": "patch",
"published_at": "2025-10-07T22:39:41Z"
},
{
"tag": "v1.26.15",
"kind": "patch",
"published_at": "2025-10-07T01:12:40Z"
},
{
"tag": "v1.26.14",
"kind": "patch",
"published_at": "2025-10-03T23:23:01Z"
},
{
"tag": "v1.26.13",
"kind": "patch",
"published_at": "2025-10-02T23:39:59Z"
},
{
"tag": "v1.26.12",
"kind": "patch",
"published_at": "2025-10-02T02:21:06Z"
},
{
"tag": "v1.26.11",
"kind": "patch",
"published_at": "2025-09-30T22:55:01Z"
},
{
"tag": "v1.26.10",
"kind": "patch",
"published_at": "2025-09-24T04:33:12Z"
},
{
"tag": "v1.26.9",
"kind": "patch",
"published_at": "2025-09-19T23:37:15Z"
},
{
"tag": "v1.25.8",
"kind": "patch",
"published_at": "2025-09-14T02:00:02Z"
},
{
"tag": "v1.25.7",
"kind": "patch",
"published_at": "2025-09-11T11:02:49Z"
},
{
"tag": "v1.25.6",
"kind": "patch",
"published_at": "2025-09-10T21:52:33Z"
},
{
"tag": "v1.25.5",
"kind": "patch",
"published_at": "2025-09-09T23:13:40Z"
},
{
"tag": "v1.25.0",
"kind": "minor",
"published_at": "2025-09-08T04:16:08Z"
},
{
"tag": "v1.24.3",
"kind": "patch",
"published_at": "2025-09-02T23:03:21Z"
},
{
"tag": "v1.24.2",
"kind": "patch",
"published_at": "2025-09-01T23:32:43Z"
},
{
"tag": "v1.24.0",
"kind": "minor",
"published_at": "2025-08-28T09:59:53Z"
},
{
"tag": "v1.23.5",
"kind": "patch",
"published_at": "2025-08-18T23:20:19Z"
},
{
"tag": "v1.23.4",
"kind": "patch",
"published_at": "2025-08-18T07:18:39Z"
},
{
"tag": "v1.23.3",
"kind": "patch",
"published_at": "2025-08-14T23:29:04Z"
},
{
"tag": "v1.23.2",
"kind": "patch",
"published_at": "2025-08-13T04:11:03Z"
},
{
"tag": "v1.23.1",
"kind": "patch",
"published_at": "2025-08-07T22:16:47Z"
},
{
"tag": "v1.23.0",
"kind": "minor",
"published_at": "2025-08-03T23:00:29Z"
},
{
"tag": "v1.22.3",
"kind": "patch",
"published_at": "2025-07-28T04:00:29Z"
},
{
"tag": "v1.22.2",
"kind": "patch",
"published_at": "2025-07-24T23:47:32Z"
},
{
"tag": "v1.22.1",
"kind": "patch",
"published_at": "2025-07-22T23:38:11Z"
},
{
"tag": "v1.22.0",
"kind": "minor",
"published_at": "2025-07-17T23:47:20Z"
},
{
"tag": "v1.21.2",
"kind": "patch",
"published_at": "2025-06-27T06:27:04Z"
},
{
"tag": "v1.21.1",
"kind": "patch",
"published_at": "2025-06-25T21:41:40Z"
},
{
"tag": "v1.21.0",
"kind": "minor",
"published_at": "2025-06-20T04:23:29Z"
},
{
"tag": "v1.20.2",
"kind": "patch",
"published_at": "2025-06-10T23:40:21Z"
},
{
"tag": "v1.20.1",
"kind": "patch",
"published_at": "2025-06-09T00:15:35Z"
},
{
"tag": "v1.20.0",
"kind": "minor",
"published_at": "2025-06-04T10:28:18Z"
},
{
"tag": "v1.19.0",
"kind": "minor",
"published_at": "2025-05-27T22:51:42Z"
},
{
"tag": "v1.18.2",
"kind": "patch",
"published_at": "2025-05-18T21:32:00Z"
},
{
"tag": "v1.18.1",
"kind": "patch",
"published_at": "2025-05-16T11:09:18Z"
},
{
"tag": "v1.18.0",
"kind": "minor",
"published_at": "2025-05-13T22:27:13Z"
},
{
"tag": "v1.17.4",
"kind": "patch",
"published_at": "2025-05-10T01:10:58Z"
},
{
"tag": "v1.17.3",
"kind": "patch",
"published_at": "2025-05-09T06:06:04Z"
},
{
"tag": "v1.17.2",
"kind": "patch",
"published_at": "2025-05-07T00:45:47Z"
},
{
"tag": "v1.17.1",
"kind": "patch",
"published_at": "2025-05-03T07:24:23Z"
},
{
"tag": "v1.17.0",
"kind": "minor",
"published_at": "2025-05-02T03:39:45Z"
},
{
"tag": "v1.16.1",
"kind": "patch",
"published_at": "2025-05-01T04:47:07Z"
},
{
"tag": "v1.16.0",
"kind": "minor",
"published_at": "2025-04-30T00:11:24Z"
},
{
"tag": "v1.15.3",
"kind": "patch",
"published_at": "2025-04-15T14:38:10Z"
},
{
"tag": "v1.15.2",
"kind": "patch",
"published_at": "2025-04-14T07:20:23Z"
},
{
"tag": "v1.15.1",
"kind": "patch",
"published_at": "2025-04-07T03:15:45Z"
},
{
"tag": "v1.15.0",
"kind": "minor",
"published_at": "2025-03-26T23:01:19Z"
},
{
"tag": "v1.14.0",
"kind": "minor",
"published_at": "2025-03-19T21:54:07Z"
},
{
"tag": "v1.13.4",
"kind": "patch",
"published_at": "2025-03-12T21:52:35Z"
},
{
"tag": "v1.13.0",
"kind": "minor",
"published_at": "2025-03-08T00:44:04Z"
}
],
"recent_commits": [
{
"oid": "9fc8f630bcfc6e1947d5b2d07ecf778bdd7fb16e",
"body": "…tput (#4851)\n\n`buildThorchainSwapPayload` derived `toAmountLimit` as\n`expectedAmountOut * (10000 - toleranceBps) / 10000`, but no production\ncaller ever passed `toleranceBps` — it defaulted to\n`SwapService.defaultThorchainToleranceBps` (0) at all four call sites. The\npayload therefore claimed a min\n[…]\ne memo yields \"0\", which honestly means \"no floor asserted\";\nfalling back to the expected output is precisely the bug being fixed.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(swap): derive toAmountLimit from the signed memo, not expected ou…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-21T22:35:11Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "137126da01e989d6d4edde0a4642b4c197740010",
"body": "… % from bps, reconciled total (#4864)\n\n* Shared effective-affiliate-bps function; % from bps not fiat division\n\nExtract the effective affiliate-bps computation into THORChainSwaps\n(discountedAffiliateBps + effectiveAffiliateFeeBps) and have the three\nquote-request builders (ThorchainService/Mayacha\n[…]\nch site (ranking/hash/signing/service construction) and tests.\n\nDisplay/enum-shape only; SwapPayloadBuilder and the signed memo/amount are\nuntouched. Ranking reads outAmount (already net), unaffected.",
"is_bot": false,
"headline": "fix(swap): itemize the Verify fee rows — affiliate-only Vultisig Fee,…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-21T22:25:33Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "d71d2f2c268dfff890a72abb0c24af9da78aebef",
"body": "…parate cards (#4865)\n\n* feat(defi): read the RUJI auto-compounding position size from the staking API\n\nRujira's RUJI staking pool holds two independent positions per account: a\nbonded one (manually-claimable USDC revenue) and an auto-compounding one\nbacked by the sRUJI receipt. The staking API repo\n[…]\neach locale's established withdraw/rewards terms.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(defi): surface RUJI's bonded and auto-compounding positions as se…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-21T22:01:31Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "516a0db78aa59e93726f81a80545b6cf4427b572",
"body": "…866)\n\n* fix(tron): stop overstating the network fee on free native transfers\n\ngetBlockInfo substituted coin.feeDefault (0.1 TRX) whenever the total\ncalculated fee was 0. But a *successfully computed* 0 happens only for a native\ntransfer with sufficient bandwidth, no memo, and an active destination \n[…]\n the decoupled case. Addresses\nCodeRabbit review.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(tron): block self-send + stop overstating network fee (#4863) (#4…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-21T21:54:33Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0db93831c5dfb98e8f50e440147a9b323095c760",
"body": "…(#4860)\n\nThe browser extension added XRPL off-chain message signing for dApps\n(GemWallet signMessage) over the shared MPC custom-message keysign. For a\nSecure (multi-device) Vault an iPhone acting as co-signer must reproduce\nthe initiator's exact message digest, or the derived message-ID diverges\na\n[…]\n against SHA-512-half vectors computed outside Swift, so they\npin cross-platform byte identity rather than re-deriving iOS's own output,\nplus precedence guards against the raw-bytes and EIP-712 paths.",
"is_bot": false,
"headline": "feat(keysign): co-sign XRPL custom messages with SHA-512-half digest …",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-20T22:09:22Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "24f3de91287e29359048b5cee812d7e4e03cc17e",
"body": "… EVM addresses (#4847)\n\n* fix(send): don't auto-switch chain for ambiguous Terra addresses\n\nTerra and Terra Classic share the bech32 HRP `terra`, so a `terra1…`\naddress decodes cleanly on both networks and carries no information about\nwhich one it belongs to. `AddressService.detectChain` resolved i\n[…]\non about the address. A\nvault holding both Terra chains still gets LUNA-or-LUNC decided for it,\nand the caller auto-advances past the chain display; a picker is the real\nfix and is tracked separately.",
"is_bot": false,
"headline": "fix(send): switch into the right chain family for ambiguous Terra and…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-20T22:06:06Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "2a35c5244f792b28114535a35a47d2591ab1b8bd",
"body": "…of dust (#4848)\n\n* fix(send): fill the full balance on Max instead of stranding a digit of dust\n\nCoin.getMaxValue truncated the computed max to decimals - 1, so every Max\nsend left one unit-of-last-place behind. Non-native tokens never reach the\nnative fee-refine path, making a token's Max exactly\n\n[…]\nng all three paths, the\nfull-6-decimal case, and the fee-exceeds-balance guard. Expectations are\nbuilt through the same formatToDecimal the production code uses, so they\nhold on comma-decimal locales.",
"is_bot": false,
"headline": "fix(send): fill the full balance on Max instead of stranding a digit …",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-20T22:00:55Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "84253aa7a60c95432c5fec20825864e7234f219f",
"body": "* fix(send): fill the full balance on Max instead of stranding a digit of dust\n\nCoin.getMaxValue truncated the computed max to decimals - 1, so every Max\nsend left one unit-of-last-place behind. Non-native tokens never reach the\nnative fee-refine path, making a token's Max exactly\nbalanceDecimal.tru\n[…]\nnloaded sentinel the second test fails, and the cap can\nthen tell the two states apart.\n\nNo production behavior change.\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(swap): size percentage presets by the asset's own precision (#4850)",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-20T21:58:34Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8330df466533479114b8f00221d2c104d40e70b1",
"body": "…page error (#4852)\n\nWhen THORChain or Maya simulates a swap whose output lands under the minimum-\noutput floor derived from the slippage tolerance, it rejects the quote with a\nbody like \"emit asset 42579895573 less than price limit 340083366993\". That fell\nthrough the classifier to `.serverError(me\n[…]\nalt message.\n\nLocalized in all 8 locales. Tests use the verbatim node bodies captured from\nlive THORChain and Mayanode rejections.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(swap): map the node's price-limit rejection to an actionable slip…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-20T21:50:13Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "9116522494afbd24406bff8caf2662e1330fee9b",
"body": "…eue + Limit Orders tab (Phases 1–3) (#4816)\n\n* feat(limit-swap): add THORChain limit-swap memo foundation (§0)\n\nPure-logic foundation for THORChain limit swaps (#4232 Phase 1):\n\n- buildLimitSwapMemo: native memo builder for `=<:ASSET:DEST:LIM/INTERVAL/0:AFFILIATE:FEE`.\n- validateLimitSwapInputs: pr\n[…]\nitSwapPayloadAssembler. The real\nreason gasLimit: 0 is safe is that gas/gasLimit are market-swap fee-\ndisplay fields the limit flow never reads.\n\n* refactor(limit-swap): drop limit-mode quote-refresh…",
"is_bot": false,
"headline": "feat(limit-swap): track resting limit orders against the THORChain qu…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-20T21:48:19Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3054c5c26fff87e73bdc8edf98ad4c8335e62e11",
"body": "* fix(substrate): surface RPC error details\n\nPreserve JSON-RPC error codes and prefer specific data reasons while retaining duplicate broadcast recovery. Remove the unreachable Bittensor catch and cover code 1010 plus message fallback.\n\nCo-Authored-By: Codex <noreply@anthropic.com>\n\n* refactor(rpc):\n[…]\nTransaction) via a shared BroadcastErrorClassifier.broadcastMethods\nset so the class and struct decoders stay in sync. Adds a regression test.\n\n---------\n\nCo-authored-by: Codex <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(substrate): surface RPC error details (#4845)",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-20T11:49:01Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4d020d190500a142f4901465a7eede954da5a3a6",
"body": "…guarantee (#4834)\n\n* feat(icons): rebuild the icon set on Icons V3, make the compiler the guarantee\n\nReplace Assets.xcassets/Icons wholesale with Icons V3 art under V3 names, and\nchange `Icon` to take an `ImageResource` instead of a `String` so a missing or\nmisspelled icon is a compile error rather\n[…]\nght from V3\n(all single-colour, template). Re-records the CreateVault snapshot for the\nearlier scan/import icon change.\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(icons): rebuild the icon set on Icons V3, make the compiler the …",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-17T23:39:19Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d3123dbe6ef1103937c272a8b1cd81f613af0acc",
"body": null,
"is_bot": false,
"headline": "chore(release): bump version to 1.42.67 (build 67) (#4833)",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-17T01:43:18Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7a253ac903f1d61fd7fcf39f2d46ce84a56a890c",
"body": "…4828 — iOS) (#4831)\n\n* fix(assets): align chain-osmo monotone badge with design system\n\nThree fills in the Osmosis chain badge drifted from the design source:\n\n- the flask body used #3D6195 at 70% fill-opacity; it is a solid\n #3E4A62 in the design\n- the lower-left arc used a literal `black` rather\n[…]\ned-color #02122B, preserves-vector-representation, and\ntemplate-rendering-intent \"original\" so it is never tinted. The symbol's\nframe is 32x32 at the origin, so no coordinate normalization was needed.",
"is_bot": false,
"headline": "fix(assets): reconcile monotone chain badge set with design source (#…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-16T23:38:49Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "798e79f6c328440bf3491b1abd76dbdca8f70fe7",
"body": "… balance refresh (#4824)\n\n* fix(wallet): refresh per-chain fiat when rates land, not only after a balance refresh\n\nThe VaultMain chain list renders `ChainRowModel.fiatBalance`, a *formatted\nstring* baked when `VaultDetailViewModel.rows` is assigned. Nothing recomputes\nit when a rate arrives: `RateP\n[…]\n the signal must follow the cache, not the write.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(wallet): refresh per-chain fiat when rates land, not only after a…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-16T23:36:25Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ee61608c31d8f5fe9ad960372bb1182023a21eea",
"body": "…in Xcode (#4823)\n\nThe .xcodeproj is gitignored and generated from project.yml via XcodeGen, so\nopening it directly can use a stale (or missing) project. 'make open' runs\ngenerate first, then opens VultisigApp.xcodeproj — one step for newcomers and\nafter any project.yml change.",
"is_bot": false,
"headline": "chore(make): add 'make open' target to regenerate + open the project …",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-16T23:26:34Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "760b210851e9bfe1a92ebaf19cc298f331a252ab",
"body": "… before the execution condition (#4825)\n\n* fix(limit-swap): honor the source chain the user entered the swap with\n\nEntering Swap from THORChain chain detail preselected THORChain on the\nMarket tab, but switching to Limit silently switched the source to BTC.\n\n`preferredLimitSourceChain` prefers a hi\n[…]\niven keyboard accessory is attached to\nthe outer VStack, not to the cards, so reordering siblings cannot resurrect\nthe merged-accessory bug; focus order is tap-driven and follows the new\nvisual order.",
"is_bot": false,
"headline": "fix(limit-swap): honor the entered source chain + put asset selection…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-16T23:24:05Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "8864ee983b6cd0d8eb2570bc886534c1ee1492f4",
"body": "…EVM balance (#4829)\n\n* fix(balances): stop Multicall3 partial failures zeroing EVM balances\n\nA partial Multicall3 failure silently persisted a 0 balance over a funded\ncoin. `aggregate3` is called with allowFailure = true, so an individual\nsub-call returning success = false does NOT throw — the batc\n[…]\nive\nbatch with a deliberately reverting sub-call.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(balances): stop a partial Multicall3 failure silently zeroing an …",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-16T23:16:40Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f470013bd665da0dc9a2607ba27a38f7cbd9165e",
"body": "…le) (#4818)\n\n* Step 1: bump VultisigCommonData pin to expose SignRipple\n\nBump the commondata Swift package pin from the dest-tag commit\n(2b92938) to c91f2ea, which adds `SignRipple { string raw_json }`\nat sign_ripple = 46 in KeysignPayload.sign_data. The new commit is a\nlinear descendant of the des\n[…]\n IOU value so the \"signed\" case matches its name.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(keysign): co-signer support for XRPL dApp transactions (SignRipp…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-16T23:07:14Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ef0b96a1708a900c1b5fc23af99ff5353c3c565f",
"body": "…ake it render on macOS (#4819)\n\n* fix(keygen): point the peer-discovery info pointer at \"Scan QR\" and make it render on macOS\n\nThe animated pointer in the keygen \"Scan the QR on your other devices\"\ninfo pop-up sat over empty space instead of the \"Scan QR\" button it\nexplains, and on macOS it did not\n[…]\ns as a steady\nfaint ring on the \"Scan QR\" button.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(keygen): point the peer-discovery info pointer at \"Scan QR\" and m…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-16T22:57:34Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "9076a4dcd8d3213f416fda8499b92e88a5bd26ab",
"body": "* feat(limit-swap): add THORChain limit-swap memo foundation (§0)\n\nPure-logic foundation for THORChain limit swaps (#4232 Phase 1):\n\n- buildLimitSwapMemo: native memo builder for `=<:ASSET:DEST:LIM/INTERVAL/0:AFFILIATE:FEE`.\n- validateLimitSwapInputs: pre-build validation (asset format, expiry hours\n[…]\n safe is that gas/gasLimit are market-swap fee-\ndisplay fields the limit flow never reads.\n\n* refactor(limit-swap): drop limit-mode quote-refresh countdown\n\nLimit orders execute at a fixed target pri…",
"is_bot": false,
"headline": "feat(swap): THORChain limit-order Place flow (#4232) (#4319)",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-15T23:25:52Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "1bef342ada346eb2e7966a417e6403a1e6156ae6",
"body": "… warning, success, backup guide) (#4763)\n\n* Step 1: redesign reshare entry screen with Start/Join option cards\n\nReplace the single centered ReshareView with a cross-platform\nReshareScreen matching the new Figma: left-aligned title and subtitle,\ndevices illustration with glow, and Start Reshare / Jo\n[…]\ntead of requiring every co-signer.\n\nCo-Authored-By: Codex <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>\nCo-authored-by: hailhydra <johnnyluo1980@gmail.com>",
"is_bot": false,
"headline": "feat(reshare): redesign the reshare flow to the new Figma (pre-flight…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-15T00:18:56Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "9b576caeca033dd787b330fa51486dee657a08ec",
"body": "…E+ mint (#4788) (#4807)\n\n* feat(swap): add dynamic THORChain secured-asset catalog\n\nPhase 1 of secured-asset discovery (#4788). Adds the source-of-truth\ncatalog that later feeds the swap destination picker:\n\n- ThorchainMainnetAPI: new `.securedAssets` endpoint -> /thorchain/securedassets\n- Thorchai\n[…]\nwap): fix SwapCoinSelectionLogic.sort call for static snapshot API\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nCo-authored-by: Johnny Luo <johnnyluo1980@gmail.com>",
"is_bot": false,
"headline": "feat(swap): discover THORChain secured assets + same-underlying SECUR…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-15T00:08:27Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "11726e9ac3a6c24222a8220d5c7c1666dde8e7b8",
"body": "…#4813)\n\n* perf(swap): stop double reloadCoins on chain tap\n\nTapping a chain in the swap coin picker fired reloadCoins twice: once\ndirectly from onSelect(chain:) and once from the\n.onChange(of: selectedChain) observer that the same assignment triggers.\nEach reload re-runs the full assemble+merge+sor\n[…]\nsCancelled before the memoized fast-path publish.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "perf(swap): fix chain-picker jank on rapid back-and-forth switching (…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-14T22:31:41Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "08ae49b3af82db8879fa1e2abdcea40f76565001",
"body": "iOS shipped only TRX + USDT on Tron; the desktop / SDK knownTokens\nregistry lists four. Add the missing three TRC-20 tokens so users can\nenable them from Choose Tokens without adding each as a custom token.\n\n- USDC TEkxiTehnzSmSe2XqrBj4w32RUN966rdz8 6dp usd-coin\n- USDD TXDk8mbtRbXeYuMNS83CfKP\n[…]\nisig-sdk packages/core/chain/coin/knownTokens. usdd & stusdt logos\nported from the shared core coin assets (usdc already present).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(tron): add USDC, USDD & stUSDT tokens (desktop parity) (#4812)",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-14T22:21:48Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "1bf10ed5fe551db9da42439395290d3e8050a42b",
"body": "* fix(defi): render cached Tron details immediately\n\n- hydrate dashboard balances and resources from warm cache\\n- defer portfolio balance refresh until detail data is populated\\n- cover Tron view model response mapping\\n\\nCo-Authored-By: Codex <noreply@anthropic.com>\n\n* fix(defi): align Tron dashbo\n[…]\nhboard matches the THORChain layout on iOS and macOS.\n\n* fix(defi): reduce Tron dashboard top inset\n\nRemove the stacked Screen top padding and use the same 16-point content inset across iOS and macOS.",
"is_bot": false,
"headline": "fix(defi): render cached Tron details immediately (#4809)",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-14T22:12:43Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c74e59ec1b7f3b1212a6c89d326a7958aa64e18f",
"body": null,
"is_bot": false,
"headline": "chore(release): bump version to 1.42.66 (build 66) (#4810)",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-14T05:36:22Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5209127eb522161b5b29511c0a190a09ca4e255a",
"body": null,
"is_bot": false,
"headline": "update gitignore",
"author_name": "Johnny Luo",
"author_login": "johnnyluo",
"committed_at": "2026-07-14T05:00:56Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c61c0cfe68224c78b733034c38fee4c99b56338f",
"body": "Restore the missing localized peer discovery guidance across all supported locales.\n\nCo-authored-by: Codex <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: restore peer discovery info description (#4808)",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-13T23:39:04Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "35c26a255c7143d6e967208b4674f8695ca8dfa4",
"body": "Prevent completed cards from retaining the in-progress layout when SwiftUI reuses a row, and cover the expansion policy with unit tests.\n\nCo-authored-by: Codex <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(history): derive transaction card expansion state (#4803)",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-13T22:21:11Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "6adb89efa8cccce42784422bb375f7a58bf1f30a",
"body": "…ance (#4794) (#4797)\n\n* fix(defi): read Staked RUJI amount from on-chain x/staking-x/ruji balance\n\nThe DeFi Staked RUJI card read the staked amount from the Rujira staking\nAPI's `bonded.amount`, which can return 0 even when the vault holds sRUJI\nreceipt tokens on-chain — so the card showed `0 RUJI`\n[…]\nlve tests to match the convention (Codex review).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(defi): read Staked RUJI amount from on-chain x/staking-x/ruji bal…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-13T17:22:17Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0d501352201db9c0907949834fc99e8b6f0e050f",
"body": "… (#4796) (#4798)\n\n* fix(solana): gate signAllTransactions N>1 before the keysign ceremony\n\nSolanaHelper.getPreSignedImageHash looped over all\nsignSolana.rawTransactions, so a multi-transaction Solana batch\n(signAllTransactions, N>1) relayed to an iOS co-signer ran the full\nmulti-device keysign cere\n[…]\nas a co-signer. Comment only; no\nbehavior change.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(solana): gate signAllTransactions N>1 before the keysign ceremony…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-13T11:31:14Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "bc23cde2467a3e7c043066e005f27eb72b136688",
"body": "…799)\n\n* feat(defi): curated bRUNE / ybRUNE tokens + liquid-bond contract\n\nAdd first-class Rujira bRUNE (Bonded RUNE, x/brune, 8dp) and its\nauto-compounding staking receipt ybRUNE (x/staking-x/brune, 8dp) as\ncurated TokensStore entries, plus the rujira-staking liquid-bond\ncontract constant.\n\n- Token\n[…]\nisting iOS idiom where sRUJI reuses xruji's logo.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(defi): bRUNE / ybRUNE curated tokens + stake/unstake (#4778) (#4…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-13T11:13:11Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "11ceae3a5902ed48fb57856529f5c91e99f5c66c",
"body": "…cate unknown vouchers (#4792)\n\n* Step 1: add modern IBC /denoms endpoint + CosmosIbcDenom model\n\nAdds CosmosAPI.Endpoint.ibcDenom(hash:) mapping to the modern ibc-go\nGET /ibc/apps/transfer/v1/denoms/{hash} path, which Terra Classic LCDs\nimplement (unlike the deprecated denom_traces path). Adds a Co\n[…]\no-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nCo-authored-by: hailhydra <johnnyluo1980@gmail.com>",
"is_bot": false,
"headline": "Fix TerraClassic IBC token display: resolve to symbol/icon/fiat, trun…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-13T11:12:49Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "74e47d990d2e3da8c5daa0f993c505637981d931",
"body": "… (#4790)\n\nThe broadcast error classifier mapped several non-duplicate rejections to\nthe duplicate-broadcast sentinel, which KeysignViewModel converts to a\nlocally computed hash and reports as success. A bare \"known\" matched every\n\"unknown ...\" message, \"nonce too high\" is a nonce gap (tx not accept\n[…]\nand\nRpcService (substrate, backing Polkadot + Bittensor). Collapse both into a\nshared BroadcastErrorClassifier that matches only true duplicate signals.\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(broadcast): stop dup-sentinel over-matching rejections as success…",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-13T10:29:17Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ef48729cca10c60aa0370b61a68bf949ea7f446b",
"body": "Base was excluded since KyberSwap's introduction with no documented\nreason. The SDK live-confirmed Kyber on Base and iOS's KyberSwapService\nalready maps .base -> \"base\", so this is a registry-only change.\n\nCloses #4793\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "Enable KyberSwap on Base (#4795)",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-12T09:49:53Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "f9db7a52ac021ad76497453a5fc7a06d8723d063",
"body": "* Slide address book selector background with the selection\n\nThe Send address-book picker's list selector was a hand-rolled two-button\nHStack where each cell drew its own background from an isSelected flag, so\nanimating the toggle just cross-faded the two static backgrounds on/off —\nthe highlight sw\n[…]\nt - 1 == -1); behavior unchanged for >= 1 option.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Slide address book selector background with the selection (#4780)",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-10T23:15:35Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8010648685d8b13ff14291d1d00618816cf1aa76",
"body": "… lookup error (#4791)\n\nfetchTokenAssociatedAccountByOwner already derives the classic-SPL and\nToken-2022 ATAs and confirms them via getAccountInfo when\ngetTokenAccountsByOwner returns an empty result (the common indexer-lag\ncase right after an ATA is created). But when the primary\ngetTokenAccountsB\n[…]\nnely-missing account still yields not-found, and a successful\nprimary lookup returns its account without probing the derived ATAs.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(solana): fall back to ATA derivation on a transient token-account…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-10T22:30:29Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b6b269f37bd7c5e0eef02bc1e3044ba22bc79eee",
"body": "… numeric fields (#4784)\n\nA keysign payload is untrusted data deserialized from a co-signer at the\nstart of a ceremony. BlockChainSpecific(from:) decoded chain-specific\nnumeric string fields with the trapping BigInt(stringLiteral:) initializer,\nwhich crashes on any non-numeric or empty string. A bug\n[…]\nmed (incl. explicit \"0\") compute_limit and priority_fee\nfor Solana, plus malformed-field cases for EVM and Polkadot.\n\ncloses #4782\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "[Fix] Harden BlockChainSpecific decoding of untrusted keysign payload…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-10T22:24:01Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "fd0d9f6bc45b4409883a61a8007a83606b98175e",
"body": "…al FAILED (#4789)\n\nTransient transport failures were mapped to .failed, which the status\npoller treats as terminal and isAlreadyOnChain treats as conclusive\nnegative evidence — a single network blip could permanently mark a live\nTHORChain/Maya tx as FAILED and poison the duplicate-broadcast net.\n\nN\n[…]\nling and\nthe duplicate-broadcast check keeps retrying. 429/5xx still map to\n.failed to surface the error; 404 stays .notFound.\n\nCovers Maya too — both route through THORChainTransactionStatusProvider.",
"is_bot": false,
"headline": "fix(thorchain): don't return timeout/network Midgard errors as termin…",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-10T22:19:09Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "293b1a60075020452cf382a450a14ab460c03313",
"body": "…68) (#4777)\n\n* Inline the Done overview into SigningKeysignScreen with a crossfade\n\nMake SigningKeysignScreen a single mounted container: a ZStack keyed on\ncoordinator.keysignFinished that renders KeysignView while signing and\ncrossfades in place to the flow's DoneScreen (SendDoneScreen/SwapDoneScr\n[…]\new (broadcasted + confirmed) to iterate the feel.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Unify keysign progress + overview into one crossfading container (#47…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-09T22:45:26Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4e99b1ce4d935981241b84477383993ca45d9957",
"body": "…dows (#4776)\n\nCosmos-family chains (Cosmos SDK, THORChain/Maya) sign the sha256 of a\ncustom message (Keplr ADR-36 signArbitrary over the StdSignDoc bytes),\nbut keysignMessages fell through to the keccak256 branch for them. The\nresulting digest — and the message-ID the relay derives from it —\ndiverg\n[…]\nustomMessageHex.ts: cosmos-family -> sha256, EdDSA -> raw,\neverything else (EVM, Tron) -> keccak256. EVM/EdDSA/Cardano/typed-data\nbehavior is unchanged.\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(keysign): sha256-hash cosmos custom messages to match Android/Win…",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-09T22:15:37Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "bb3f0c27e198f2ff0e79f87dc1c601bf11be4854",
"body": "…+ one keysign route/screen (#4775)\n\n* Step 1: FastVaultKeysignBootstrap off-screen session helper + unit tests\n\nAdds FastVaultKeysignBootstrap, which runs the fast-vault relay-session\nbootstrap (register -> wake -> await peer -> kickoff) off-screen and\nassembles the finished KeysignInput. Built on \n[…]\no-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nCo-authored-by: hailhydra <johnnyluo1980@gmail.com>",
"is_bot": false,
"headline": "Unify the keysign screen: fold fast-vault bootstrap into KeysignView …",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-09T00:22:37Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4ceedc97ff46b53c35d631cd441dccc9c95333cf",
"body": "…te Continue (#4765)\n\nExtract the XRP destination base-reserve check out of SendDetailsViewModel\nbehind a chain-agnostic `SendAmountValidator` protocol (an input snapshot ->\n`.ok` / `.invalid(message:blocksContinue:)`), implemented for XRP by\n`RippleDestinationReserveValidator` under Blockchain/Ripp\n[…]\nrTests proving the generic\n wiring blocks Continue independent of any chain.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nCo-authored-by: Johnny Luo <johnnyluo1980@gmail.com>",
"is_bot": false,
"headline": "feat(send): generic SendAmountValidator + animate inline warning + ga…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-09T00:10:11Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "69441d2d7992d6e61560b0b29a7b738beb95031a",
"body": "* feat(done): expand transaction details in place instead of pushing\n\nExtract the detail rows from SendCryptoSecondaryDoneView into a reusable\nheader-less/button-less TransactionDetailsCard that owns the\nadd-to-address-book flow, then convert DoneScreen's default\nDoneDetailContent slot to reveal tha\n[…]\no-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nCo-authored-by: hailhydra <johnnyluo1980@gmail.com>",
"is_bot": false,
"headline": "Expand transaction details in place on the Done screen (#4767) (#4772)",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-08T23:40:28Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "de097bfcac23cf094dd628c0f2f1cdffbb37b1b0",
"body": "…emo & tag+memo support (#4749)\n\n* feat(ripple): hand-rolled XLS-5d X-address codec pinned to canonical vectors\n\nXRPL X-addresses bundle a classic account ID with an optional 32-bit\ndestination tag. WalletCore validates and signs them inside its Ripple\nsigner but exposes no Swift codec, so autofilli\n[…]\nsts don't wire (RequireDest is covered in the threading tests).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(ripple): XRP Destination Tag as a first-class field + restored m…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-08T22:29:05Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b042ca975a65a8a2bf6c57c116c6bc5ac2ee172b",
"body": "…n base reserve (#4764)\n\n* refactor(ripple): extract owner-aware reserve math into RippleReserve\n\nPull the reserve computation getBalance did inline (reserve_base +\nOwnerCount x reserve_inc, seeds on missing server_state fields) into a\npure RippleReserve enum, sibling to RippleFee, and delegate getB\n[…]\nd it to stay exhaustive.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>\nCo-authored-by: Johnny Luo <johnnyluo1980@gmail.com>",
"is_bot": false,
"headline": "feat(ripple): inline send-form validation of XRP amount vs destinatio…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-08T00:11:18Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "00279c68c5994106fe82fc7394e12ac13184057d",
"body": "…nted static 1 XRP (#4748)\n\n* refactor(ripple): extract owner-aware reserve math into RippleReserve\n\nPull the reserve computation getBalance did inline (reserve_base +\nOwnerCount x reserve_inc, seeds on missing server_state fields) into a\npure RippleReserve enum, sibling to RippleFee, and delegate g\n[…]\nlled fee calc now also aborts quietly instead of surfacing a transport\nerror.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(ripple): owner-aware reserve for MAX send — remove the double-cou…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-07T23:14:33Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "5f145f9cba2fbf4a16903e2fc0538e76128713b0",
"body": "…ite (#4736)\n\n* test(figma-parity): reusable Figma-parity comparator + hermetic self-test\n\nAdd VultisigAppTests/FigmaParity/: FigmaParityComparator renders a SwiftUI\nview at exact px via ImageRenderer, diffs it against a committed Figma\nexport, and emits similarity + perceptual (1 - meanDelta) score\n[…]\nhe unchanged committed\nreference PNG, so no reference regeneration is needed.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "test(figma-parity): reusable Figma-parity harness + /figma skill rewr…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-07T23:00:10Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "21757eceb1f7b03deb2d0dccf9b71408c94ead43",
"body": "…alidation on the signed-fee source of truth (#4699)\n\n* fix(swap): co-signer network fee uses signed route gas, not the gasLimit floor\n\nOn a co-signed EVM aggregator swap (SwapKit/1inch/LiFi/Kyber ETH->token) the\nco-signer's Network fee under-displayed ~6-9x less than the vault actually pays\n(shows \n[…]\nture change\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nCo-authored-by: hailhydra <johnnyluo1980@gmail.com>",
"is_bot": false,
"headline": "fix(swap): unify EVM swap network fee across initiator, co-signer & v…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-07T22:51:34Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b2cfe10d8a01ece3a11d53dd2bb8e8c6b8056b80",
"body": "…matches the signed fee (#4762)\n\nTerra Classic prices its fee as `gasLimit × price (+ burn tax)`. The\ninitiator now simulates a dynamic per-tx gas limit (CosmosSpecific.gas_limit)\nand the signer signs that relayed `gas_wanted`, but `chainSpecific.gas` was\nstill priced at the fixed 300k limit. The si\n[…]\neeps its own\nsigner-side re-derivation (same latent display gap, separate follow-up).\n\nTests updated: baseGas scaling per denom, and the signer echoing the priced\n`gas` verbatim under a relayed limit.",
"is_bot": false,
"headline": "fix(terraClassic): price send fee at the dynamic gas limit so Verify …",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-07T22:32:12Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "b4fbda6dac33f264a38eb71bedad648cae617e7e",
"body": "…locked) (#4754)\n\n* Step 1: retry XRPL requests on transient node errors (same-host, no fallback)\n\nAdd a bounded same-host retry at the Ripple request layer. The default XRPL\nhost (xrplcluster.com) is a load-balanced pool; some backends run stale rippled\nand answer amendmentBlocked (HTTP 200 with re\n[…]\n, each\nwithout retrying.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>\nCo-authored-by: Johnny Luo <johnnyluo1980@gmail.com>",
"is_bot": false,
"headline": "fix(ripple): retry XRPL requests on transient node errors (amendmentB…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-06T23:26:21Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "38b21d20730fe8da9469a8f5e70c54681140141d",
"body": "…P txs (#4750)\n\n* feat(ripple): add SHA-512Half XRP transaction-hash helper\n\nAdd RippleHelper.signedTransactionHash(signedBlob:), computing the\ncanonical XRPL transaction identifying hash: SHA-512Half of the\n0x54584E00 (\"TXN\\0\") prefix + the serialized signed blob, rendered as\nuppercase hex. Pure fu\n[…]\ntput bytes; the\nsigning input, pre-image, and TSS/keysign flow are unchanged.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(ripple): compute the deterministic transaction hash for signed XR…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-06T22:57:41Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "cdcdc820c2b597d8875465b3c705be0d3d1ea11d",
"body": "…already-submitted results (#4746)\n\n* feat(ripple): classify XRPL submit engine results; gate broadcast on tesSUCCESS\n\nThe XRPL submit endpoint echoes tx_json.hash for every engine result, so\nthe previous hash-presence gate reported rejected submits (tem/tef/tel/\nter/tec engine results) as successfu\n[…]\natusProvider semantics, and an injectable\nbackoff so tests run without delay.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(ripple): gate broadcast on tesSUCCESS + verify-by-hash dedup for …",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-06T22:32:42Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "40f4905f82e51cd3bc58a83830217c6ead14e88a",
"body": "…lection gating, cache-first seed heal (#4745)\n\n* fix(defi): gate the Solana staking card on the position selection\n\nThe Solana stake segment rendered its full staking card for every\nvault, ignoring the per-vault position opt-in that THOR/Maya/Cosmos\nstaking honors — a vault that never selected the \n[…]\nel heal-then-seed\n(first entry can't seed, refresh heals, a fresh VM paints).\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(solana): staking DeFi fixes — validator 520 fallback, position-se…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-06T22:24:04Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "38f0d6e0aefb0e415decbf3188be826555dca5f0",
"body": "…738)\n\nOn the swap Join Keysign screen the \"To\" row showed keysignPayload.toAddress,\nwhich for a swap is the provider's router/inbound contract — not a user-facing\ndestination. Surface a \"To\" address only when the user directed the swap output\nto an external recipient (an address other than their ow\n[…]\ntion share one parser and one notion\n of address equality.\n- KeysignSwapConfirmView shows the external recipient instead of the raw router\n toAddress.\n\nCo-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(swap): don't show router address as To on join keysign screen (#4…",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-06T11:59:34Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e5c249e2ff63a2a5539cb48aca00753f5b78c5e5",
"body": null,
"is_bot": false,
"headline": "chore(release): bump version to 1.41.65 (build 65) (#4737)",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-04T02:00:43Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7ca8b30bff2c8aa0766a5db81a70462b20ce90a6",
"body": "…re (#4735)\n\n`TssKeysignResponse.getSignature()` builds an Ed25519 signature by reversing\n`r` and `s` (big-endian scalars from TSS) into little-endian and concatenating\nthem into R || S. It never left-padded the halves to 32 bytes.\n\ntss-lib emits `r`/`s` via Go's `hex.EncodeToString(bigInt.Bytes())`\n[…]\nh rebuilds bit-for-bit and\nverifies. Updates the custom-message EdDSA tests, which had pinned the old\nun-padded output using toy 2-byte values.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(keysign): pad EdDSA r/s to 32 bytes before assembling the signatu…",
"author_name": "Danial",
"author_login": "DanialV",
"committed_at": "2026-07-04T00:59:30Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8e47a673980f59cef4f12d7a98f2eb783143eb47",
"body": "…sic (#4733)\n\n* feat(cosmos): add CW20 token_info metadata query to the Cosmos resolver\n\nAdd a `{\"token_info\":{}}` wasm smart-query path so CW20 contract metadata\n(name, symbol, decimals) can be resolved from the chain's LCD — the same\nlookup the SDK/extension perform in getCw20MetaFromLCD:\n\n- Cosmo\n[…]\neview feedback on the PR.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>\nCo-authored-by: hailhydra <johnnyluo1980@gmail.com>",
"is_bot": false,
"headline": "feat(wallet): support adding custom CW20 tokens on Terra / Terra Clas…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-04T00:36:45Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "90346ca51284e662ff41d3da21f1d159353cfb83",
"body": "…' while providers load (#4732)\n\n* fix(swap): publish local token list before awaiting destination providers\n\nThe destination \"Select asset\" picker rendered \"No result found.\" with an\nempty search query until every remote destination-token provider returned.\nThe cached fetch path clears the spinner \n[…]\ne test hermetic); cold-cache\nsource-side publishes once without the registry.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(swap): destination asset picker no longer shows 'No result found.…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-04T00:20:47Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e73a6ac1b5f5062cb2476bddf72e7c79f69c9032",
"body": "Vault Settings -> Rename accepted a cleared text field: Save stayed\nenabled and persisted the empty string, leaving the vault with a blank\nname in Vault Details and the home vault selector.\n\nReuse the vault-creation validation path instead of a rename-only rule:\n\n- VaultNameValidator now trims white\n[…]\nng a duplicate entry to folders).\n- No new user-facing strings: enterVaultName and vaultNameExists\n already exist in all locales.\n\nCloses #4729\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(vault): reject empty/whitespace vault names in Rename Vault (#4731)",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-04T00:14:10Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "39eced8060738ba87f6fba0d34d8edfd3b3e9305",
"body": "* feat(zcash): add ZIP-317 conventional fee math\n\nByte-parity port of the SDK's zip317.ts (packages/core/chain/chains/utxo/\nfee/zip317.ts, landed in vultisig-sdk#773): conventional fee = 5,000 zats\nper logical action with a two-action grace window, where logical actions =\nmax(ceil(tx_in bytes / 150)\n[…]\n. Regression tests pin the Maya-shaped decode\nand the nil-flag gate behavior.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(zcash): re-plan memo txs to the ZIP-317 conventional fee (#4728)",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-04T00:07:59Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "85b23be375e83afd3653398abdba037fb0c562a1",
"body": "…re 4.7.0 auxiliaryData) (#4709)\n\n* feat(cardano): canonical CIP-20 memo CBOR encoder (pre-stage for #4708)\n\nAdd a pure, dependency-independent CIP-20 transaction-metadata encoder\n(label 674) that produces canonical CBOR { 674: { \"msg\": [chunks] } } with\n64-UTF-8-byte, codepoint-boundary chunking an\n[…]\neeA*auxLen.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nCo-authored-by: hailhydra <johnnyluo1980@gmail.com>",
"is_bot": false,
"headline": "feat(cardano): attach send memo on-chain as CIP-20 metadata (WalletCo…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-03T23:55:32Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "617d6f9b5e830b7bc8552aaa9b1a760c6f894bcf",
"body": null,
"is_bot": false,
"headline": "chore(release): bump version to 1.41.64 (#4725)",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-03T00:54:46Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0fa0df6d5415866d7bdc9a4272c54338f9d80cd6",
"body": "…ed gas limit (#4692)\n\n* fix(cosmos): enforce dynamic Akash fee floor for send + staking + dApp signing\n\niOS hard-coded the Akash fee at 3000 uakt, below Akash's own 0.025 uakt/gas\nnode minimum (5000 uakt at the 200k gas limit), so an ordinary send could be\nrejected on-chain with \"insufficient fee\".\n[…]\no-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nCo-authored-by: hailhydra <johnnyluo1980@gmail.com>",
"is_bot": false,
"headline": "feat(cosmos): dynamic Akash/Cosmos fees — safe floor + simulate-deriv…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-02T22:54:57Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b4ecf979b1d812f3fc58f820d087e0ad67dd33ad",
"body": "…ocal Network check + error/retry + iPad back button) (#4722)\n\n* fix(keygen): detect Local Network permission on iPad join, add error + escape hatch\n\nJoining a Local-mode (Bonjour/LAN) keygen on iPad hung forever on\n\"Discovering\" when iOS Local Network access was denied (or Wi-Fi / AP\nclient-isolati\n[…]\nare form; NetService keeps the trailing-dot form.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(keygen): iPad local-mode join no longer hangs on \"Discovering\" (L…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-02T22:42:32Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "1d7ad62eb8b7073bfd9362032345b1dcc5f8422d",
"body": "…r) (#4720)\n\n* feat(keysign): show fiat value on the co-sign send amount\n\nThe co-sign \"Send overview\" (\"Join transaction signing\") screen renders\nthrough the shared SendCryptoVerifySummary model + HeroCoinAmount, both of\nwhich carried fiat for the network fee but not for the amount. A co-signer\nsaw \n[…]\niat case (no\norphan gap). Previews updated to carry amountFiat.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(keysign): show fiat value on the send amount (co-sign + initiato…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-02T22:34:38Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "6b62986f8e78438c73ba636e4e3750eaf8af2f1e",
"body": null,
"is_bot": false,
"headline": "chore(deps): bump WalletCore to v4.7.0 (#4721)",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-02T01:53:28Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "160b784b96071602207fd7a411452063a7f1309e",
"body": "On iPad, the \"Use standard mode\" button (SwitchToLocalLink) at the bottom\nof the keygen Pair screen in local mode sat flush against the bottom edge.\nThe switchLink computed var applied bottom padding only under #if os(macOS),\nso iOS/iPadOS got zero. iPhone is masked by the home-indicator safe area,\n\n[…]\ndding the primary button directly above\n(bottomButton) already uses, while preserving the existing macOS value (24).\n\nCloses #4713\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(keygen): pad \"Use standard mode\" link on iPad Pair screen (#4719)",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-01T23:24:45Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b37eca71b0deca425da81155e9a21989b2f9a671",
"body": "…) (#4718)\n\nThe green checkmark ring rendered with a flat left edge on the Send/Swap\nverify screens. Checkbox draws the ring as a Circle().stroke on a 24x24\nframe; .stroke centers the 1pt line on the path, so ~0.5pt spills outside\nthe frame. The consent-checkbox row sits flush at the left edge of th\n[…]\ninside\nthe 24x24 bounds so it never overflows to be clipped. This fixes the clip\nfor every Checkbox usage without touching layout.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(ui): round the consent-checkbox circle on Send/Swap verify (#4715…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-01T23:24:07Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "208e2b6aea0421f6d325f30d6848b2dbf95b9d63",
"body": "The ⓘ info icon beside the \"Gas Limit\" label in the advanced-swap Gas\nLimit sub-sheet had no Button, tap gesture, or tooltip, so tapping it\ndid nothing — a fake interactive affordance. Per the maintainer's\ndecision, drop the dead icon rather than wire up a tooltip. With the\nicon gone the wrapping HStack becomes redundant, so collapse it to the\nbare label Text.\n\nCloses #4714\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(swap): remove dead Gas Limit info icon in advanced settings (#4717)",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-01T23:23:42Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "cbc76143257eb61b620c857ac17a13adddbead02",
"body": "…tion (#4711)\n\n* fix(swap): surface THORNode errors + guard secured-asset swap destination (#4321)\n\nSwapping into a THORChain secured asset (e.g. ETH-USDC) surfaced only a\ngeneric error while swapping out worked. Live mainnet testing confirms\nTHORNode requires a thor1... destination for a secured-as\n[…]\nflow and the error-surfacing logic are unchanged.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(swap): surface THORNode errors + guard secured-asset swap destina…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-01T23:21:24Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "828155f44deb8321a8a864d6ef5b3a013272b077",
"body": "…#4704)\n\nMandatory Rule 6: use .foregroundStyle(), not the deprecated .foregroundColor().\nMechanical 1:1 swap across 139 files (378 sites), behavior-identical for Color\narguments (Color conforms to ShapeStyle).\n\nNot changed:\n- foregroundColor(for:isEnabled:) helper funcs in PrimaryButtonStyle/IconBu\n[…]\n of scope (follow-up: migrate to Theme.colors.*).\n\nPart of the iOS code-quality audit (Phase A — convention sweeps).\n\nCloses #4703\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: replace deprecated .foregroundColor with .foregroundStyle (…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-01T23:08:13Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "67ee4a95aeb85851aa23b19c80e4b69ea2186b1c",
"body": "…ck) (#4702)\n\nReplace the byte-identical onChange { asyncAfter(0.5) { focusedField = newValue } }\n@FocusState workaround copy-pasted across 10 screens with a single\n.delayedFocus(from:to:delay:) View extension (behavior-identical, default 0.5s delay).\n\nSites: 9 FunctionTransaction screens (Amount, T\n[…]\ngate, TonStake) + Wallet VaultServerBackupScreen.\n\nPart of the iOS code-quality audit (Phase A — convention sweeps).\n\nCloses #4700\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: extract shared delayedFocus modifier (de-dupe FocusState ha…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-01T23:04:27Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "16b65f5a8ad3142f92d61f13eae5a8f8558763b4",
"body": "…705)\n\nThe delegate form hardcoded a 1 SOL minimum active delegation. That value\nis a feature-gate-activated network constant, not a permanent one, and the\nVultisig RPC proxy blocks getStakeMinimumDelegation, so it could not be read\nthrough the normal path.\n\nRead it directly from a public Solana nod\n[…]\ne-parity; it is deliberately NOT routed through the custom-RPC override\n(which would repoint signing/broadcast too).\n\ncloses #4694\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(solana): fetch min-delegation dynamically from a public node (#4…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-07-01T12:29:20Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "42853ab0f7a22bf5a70da2330694f934f2cfe774",
"body": "Per-token unit prices below one cent (e.g. LUNC ~$0.00006, USTC ~$0.0054)\nwere displayed as \"$0.00\", hiding the real price from users.\n\niOS keeps the rate full-precision end-to-end (no data-source pre-scaling\nto undo, unlike Android), so this is a pure display-layer change:\n\n- Add Decimal.formatToFi\n[…]\nings are unaffected: a tiny holding still shows \"$0.00\".\nParity with Android's asPrice fix (vultisig-android #5111).\n\nCloses #4688\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(tokens): show sub-cent token prices instead of $0.00 (#4701)",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-06-30T23:51:53Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4be9133c25a444bf450391e3b5b5c18bd0643ef5",
"body": "* feat(swap): add Jupiter Solana swap provider (Phase 1: routing + quote/swap, no fee)\n\nWire Jupiter as a swap provider for on-Solana token swaps (SOL<->SPL,\nSPL<->SPL). Jupiter is added to the Solana provider list and is Solana-only\nsame-chain: cross-chain pairs drop it automatically via the SwapCo\n[…]\nixture used a\nfee-owner-style value. (CodeRabbit)\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(swap): Jupiter Solana swap provider (#4669) (#4696)",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-06-30T23:09:05Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "530ed9ff2a7e68b5d8fd69778d6201e32a129ae7",
"body": "…thdraw) (#4690)\n\n* feat(solana): staking foundation — models + RPC read layer\n\n* feat(solana): validator metadata seam (Stakewiz, swappable)\n\n* feat(solana): delegate (stake) flow\n\n* feat(solana): deactivate (unstake) + withdraw\n\n* feat(solana): move stake / redelegate (guided, cross-epoch)\n\n* feat\n[…]\nng the cache-first paint shipped for the segment.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(solana): native staking on the DeFi tab (delegate / unstake / wi…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-06-30T23:08:33Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c43c8f0301d652d48e4dd036cb339737113fbc93",
"body": "Removes the unused Share Vault QR feature: the screen, its view model,\nthe QR rendering components, the public-key export model, and the\nnow-unused ImageFileDocument utility. Also removes the Settings toolbar\nentry point, its route/router/builder wiring, and the shareVaultQR\nlocalization keys from all locale files.",
"is_bot": false,
"headline": "chore: remove Share Vault QR screen (#4698)",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-06-30T02:45:53Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e01813b36e2fb3d81f4b617eb0480e2955739324",
"body": "…rrors (#4686)\n\nCompleteness: add 62 missing keys per locale (QBTC claim flow, Cosmos\nstaking errors, Cardano/validator errors, tx status, tier copy); rebuild\nstale Korean (ships in language picker); remove 11 dead renamed keys.\nFix live bug: noUnencryptedVaultsToImport used in code but missing from\n[…]\nan orphan %d.\n\nValidated: plutil-clean, sorted, full key parity, 0 format-spec mismatches.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>\nCo-authored-by: Johnny Luo <johnnyluo1980@gmail.com>",
"is_bot": false,
"headline": "i18n: fill 62 missing iOS keys, rebuild Korean, fix ~83 translation e…",
"author_name": "paaao",
"author_login": "realpaaao",
"committed_at": "2026-06-30T01:32:22Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "9fd2c76ee863d1749da580b7e114f7e974351dfd",
"body": "…695)\n\n* feat(qbtc): derive Bitcoin/QBTC claim accounts on the fly (#4679)\n\nThe QBTC claim flow blocked with `.missingCoin` unless both the Bitcoin\nand QBTC chains were already enabled in the vault. Derive the two native\ncoins in-memory from the vault's own keys (the pure, non-persisting\nCoinFactory\n[…]\n enabled,\n and the derive-when-not-enabled case.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(qbtc): derive Bitcoin/QBTC claim accounts on the fly (#4679) (#4…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-06-29T23:16:26Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "30fb0739143949c709936f5f61f1b116e493456d",
"body": "…call3 (#4693)\n\n* perf(balance): run price + balance fetching concurrently (#4673)\n\nBalance fetching was gated behind a full price fetch: updateBalances awaited\nfetchPrices(vault:) before the per-coin balance task group ran, so a slow or\nfailing price provider froze all balances even though balances\n[…]\no it fails if balances ever await prices\n first.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "perf(balance): decouple price fetching + batch EVM balances via Multi…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-06-29T23:10:05Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f79b92f9497356b7287f3df276777404e9eeb6bc",
"body": "* feat(banners): global TTL-based promo-banner dismissal\n\nReplace the mixed promo-banner dismissal storage (app-wide permanent\n@AppStorage(\"appClosedBanners\") + per-vault permanent Vault.closedBanners)\nwith one global, per-device store keyed by a stable banner intent id.\n\n- PromoBannerDismissalStore\n[…]\nunder one\n lock to close the lost-update window.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(banners): global TTL-based promo-banner dismissal (#4691)",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-06-29T22:58:33Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8119be05aea4bb627a0882b6c9bf14c7e347a5ae",
"body": "At zero or insufficient from-balance the swap quote details were hidden\nbehind a blocking error tooltip: updateQuotes assigned the quote then\nthrew balanceError, which set self.error, and SwapDetailsSummary hid the\nwhole provider/fee/price-impact block while SwapDetailsScreen swapped the\nflip button\n[…]\nte is unchanged.\n- Localization: add swapInsufficientTokenBalance (\"Insufficient %@\n balance\") to all 7 locale files and re-sort.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(swap): show quote details without sufficient balance (#4658)",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-06-29T22:41:22Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "aff668e475be2db6d1e8d0aa0114910f72b1afe3",
"body": "… (#4644)\n\n* refactor(defi): generalize yield integration behind DefiYieldProvider\n\nExtract the DeFi-tab USDC-yield integration into a generic, provider-driven\nframework and migrate Circle onto it. Introduces the DefiYieldProvider\nprotocol + factory, shared YieldVault/Deposit/Withdraw shells and vie\n[…]\n-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nCo-authored-by: Johnny Luo <johnnyluo1980@gmail.com>",
"is_bot": false,
"headline": "refactor(defi): generalize yield integration behind DefiYieldProvider…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-06-29T22:35:17Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "1ba1014ca3a93b7251f6b984986265a4c0278e46",
"body": "…LDSA-44 key (#4685)\n\nGenerating an MLDSA-44 key is a one-time action. The Advanced settings\n\"Post-Quantum Key\" row was always shown; tapping it on a vault that\nalready had the key surfaced an \"already generated\" notice. Hide the row\nentirely once the vault has the key instead.\n\n- Guard dilithiumKey\n[…]\nlt.publicKeyMLDSA44 == nil (matches\n the existing reshareVaultRow pattern in this screen).\n- Remove the now-unreachable DilithiumAlreadyGeneratedSheet, its state,\n and its localization keys (en/ko).",
"is_bot": false,
"headline": "feat(settings): hide Post-Quantum Key option when vault already has M…",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-06-29T10:57:32Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "6e4576c083f4173d9840deeeace5d1c8a90daa34",
"body": "…684)\n\nThe QBTC claim flow signs its BTC ECDSA round exclusively via DKLS\n(QBTCClaimRoundRunner / QBTCClaimSecureVaultRoundDriver). GG20 keyshares\ncan't take part in that ceremony, so a GG20 vault that reached keysign\nhung and failed with \"DKLS sign message exhaust retries: fail to\ndownload setup me\n[…]\ndView.\n- QBTCClaimEligibilityChecker short-circuits to .ineligible (no network)\n so the promo banner / Claim button never appear for GG20 vaults.\n- Localize the new title/detail across all 8 locales.",
"is_bot": false,
"headline": "fix(qbtc): block GG20 vaults from QBTC claim with a clear message (#4…",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-06-29T10:55:47Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "73124a8e547ac7441a85f8a854efbc51a09fdf29",
"body": "… (#4675)\n\nLI.FI's estimate.toAmount (dstAmount) is already net of the integrator\nfee, which LI.FI takes from the source token and marks included: true.\nThe ranking branch subtracted it again, understating LI.FI's ranked\nvalue by ~0.5% and flipping provider selection away from LI.FI on\nnear-ties at the in-band preference boundary.\n\nPass dstAmount through unchanged (same as 1inch/Kyber) and update the\nranking test vector that encoded the double-counted value.\n\nCloses #4674",
"is_bot": false,
"headline": "fix(swap): stop double-counting LI.FI integrator fee in quote ranking…",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-06-28T23:15:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a261fd452fcdbce41ff22a1aedff8aeaa574c6b9",
"body": "Co-authored-by: Claude <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(assets): use jpg for qbtc coin icon (#4677)",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-06-28T00:11:40Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "85530353727a69e0e25e5f94a31d0d93ec49c2b5",
"body": "* feat(defi): TON staking on the DeFi tab (#4653)\n\nMove TON nominator-pool staking out of the generic Functions (FunctionCall)\nflow and into a dedicated TON section on the DeFi tab, reusing the same generic\nDefiChain staked-positions screens that THORChain / Maya / Cosmos already use.\n\n- Register .t\n[…]\n from the implementation, not invalid form state.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(defi): TON staking on the DeFi tab (#4653) (#4654)",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-06-25T22:11:26Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c1e6151184728ca83c84d6e0e2900e4315d0095e",
"body": "Render an MLDSA key row in the Keys section of the vault Details card\nwhen the vault has a non-empty publicKeyMLDSA44, reusing the existing\ncopyable vaultKeyRow helper for parity with the ECDSA/EdDSA rows\n(including the shared/exported isForSharing view). The row is hidden\nfor vaults without an MLDSA key.\n\nAdds the \"MLDSA\" localization key to all 7 locale files.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(vault): show MLDSA key in vault details screen (#4651) (#4652)",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-06-25T21:58:08Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "1917b6a122369d723498cd43432def3145dc4e57",
"body": "…le pools (#4615) (#4616)\n\n* Add NativePoolAsset model + pool-id parsing for dynamic swap eligibility\n\nPure types + the synchronous eligibility predicate, no I/O. NativePoolAsset\nnormalizes a /pools asset id (CHAIN.TICKER-0XCONTRACT) into {chain, ticker,\nlowercased contract, isAvailable, isTradingHa\n[…]\n the halt gate reflects the network the quote actually deposits on.\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nCo-authored-by: hailhydra <johnnyluo1980@gmail.com>",
"is_bot": false,
"headline": "feat(swap): dynamic THORChain/Maya swap eligibility from live Availab…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-06-24T23:52:15Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f62c588e8da5dd78cda2722e0d1b804abe28fc72",
"body": "…/unfreeze & resources sheet (#4648)\n\n* fix(defi): match Figma + adopt shared staking pattern for TRON freeze/unfreeze & resources sheet\n\n- FilledSegmentedControl: add optional icon/iconSelectedTint to the type\n protocol (defaulted to nil so ScannerMode is unchanged) and a .filledPill\n size matchi\n[…]\n-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nCo-authored-by: Johnny Luo <johnnyluo1980@gmail.com>",
"is_bot": false,
"headline": "fix(defi): match Figma + adopt shared staking pattern for TRON freeze…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-06-24T23:31:27Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f36cb9d3809d7ca4597fdcc1529b57c1ac330de3",
"body": "…en (#4641)\n\nThe swap keysign confirmation screen showed from/to coin, amounts,\nprovider and fees but had no destination address, so a co-signer\n(non-initiating device) could not verify where funds go before signing.\n\nAdd a read-only destination-address row fed from KeysignPayload.toAddress\n(the pro\n[…]\ng the existing row styling and the localized \"to\" label. Display\nonly; no change to keysign payload construction, TSS, or signing.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(keysign): show swap destination address on co-signer confirm scre…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-06-24T23:05:16Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "cb3347fb38551de4701371eba93b737a3b89acd8",
"body": null,
"is_bot": false,
"headline": "release v1.40.63 (#4646)",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-06-24T00:10:10Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "34f0ac8f509dad5dc671213aa1105b5a0de1f658",
"body": "…s (#4645)\n\nLiFi swaps sourced from Solana omitted the integrator/fee params because\n`Coin.isLifiFeesSupported` only returned true for EVM chains. That left\nSolana routes uncharged while the UI still computed and displayed a ~0.5%\nfee that was never collected, and denied VULT holders their tier disc\n[…]\n.\nEVM-source routes (including Cronos/Hyperliquid) already charged the fee\nand are unaffected.\n\nAdds LiFiFeesSupportedTests pinning EVM + Solana as fee-charging and\nnon-LiFi source chains as excluded.",
"is_bot": false,
"headline": "fix(swap): charge VULT-discounted LiFi integrator fee on Solana route…",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-06-23T23:20:34Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "0e50592598dfe5dc8cfe38086f58e7f3a4e7662e",
"body": "…en catalog refresh-on-open (#4643)\n\n* fix(swap): SwapKit provider gate fail-closed on cold cache miss + token catalog refresh-on-open\n\nTwo SwapKit cache reliability fixes.\n\nProvider gate: SwapKitProviderCache.isEnabled(chain:) now fails CLOSED on the\nno-snapshot edge. On a cold launch where the fir\n[…]\nack, pointing to SwapKitProviderCache.isEnabled for the rationale.\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nCo-authored-by: Johnny Luo <johnnyluo1980@gmail.com>",
"is_bot": false,
"headline": "fix(swap): SwapKit provider gate fail-closed on cold cache miss + tok…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-06-23T22:27:09Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4c7af45e5c3829483f5b4c0976b76d3b61360d80",
"body": "…0bps (#4642)\n\nAmong swap quotes already within the provider-preference band (economically\nequivalent on net destination output), prefer the one with lower source-chain\ngas before applying provider preference — but only when BOTH compared quotes\nexpose gas in the same native-wei unit (same-chain EVM\n[…]\n the preference band from 100bps to 50bps so a \"preferred\"\nprovider can no longer be handed up to 1% (2x the 50bps affiliate fee).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(swap): in-band lower-gas tie-break + tighten preference band to 5…",
"author_name": "Gaston",
"author_login": "gastonm5",
"committed_at": "2026-06-23T21:52:02Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "44b3535af42fd9c31fbed169e031fd70f3e583b7",
"body": "…636)\n\nThe keysign Rive animation exposes a `progessPercentage` bar, but\n`KeysignAnimationView` never bound it — only `KeygenAnimationView` did.\nThe bar therefore stayed empty during signing. For standard Send the\ncoin-logo glow filled that area so it looked populated, but swap and\ncustom-message fl\n[…]\ny\n- SendCryptoKeysignView: pass-through `progress` parameter\n- KeysignView: feed `viewModel.signingProgress` into the signing view\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(keysign): fill signing progress bar for swap & custom message (#4…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-06-23T21:46:47Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4089931199b42ed60df8d5349328816c4173c20c",
"body": "…erance-v2\n\nfix(swap): default THORChain tolerance_bps to 0 so Auto swaps aren't rejected",
"is_bot": false,
"headline": "Merge pull request #4640 from vultisig/fix/thorchain-swap-auto-no-tol…",
"author_name": "paaao",
"author_login": "realpaaao",
"committed_at": "2026-06-23T14:26:57Z",
"body_truncated": false,
"is_coding_agent": false
}
],
"releases_count": 100,
"commits_last_year": 1740,
"latest_release_at": "2026-07-17T01:06:25Z",
"latest_release_tag": "v1.42.67",
"releases_from_tags": false,
"days_since_last_push": 0,
"active_weeks_last_year": 52,
"days_since_latest_release": 5,
"mean_days_between_releases": 4.6
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": false,
"health_percentage": 62,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": true
},
"ecosystem": {
"packages": []
},
"popularity": {
"forks": 22,
"stars": 40,
"watchers": 4,
"fork_history": {
"days": [
{
"date": "2024-03-17",
"count": 1
},
{
"date": "2024-05-22",
"count": 1
},
{
"date": "2024-06-12",
"count": 1
},
{
"date": "2024-06-18",
"count": 1
},
{
"date": "2024-07-29",
"count": 1
},
{
"date": "2024-09-04",
"count": 1
},
{
"date": "2024-10-08",
"count": 1
},
{
"date": "2024-12-18",
"count": 1
},
{
"date": "2025-02-14",
"count": 1
},
{
"date": "2025-03-15",
"count": 1
},
{
"date": "2025-04-19",
"count": 1
},
{
"date": "2025-05-02",
"count": 1
},
{
"date": "2025-07-12",
"count": 1
},
{
"date": "2025-11-15",
"count": 1
},
{
"date": "2026-03-16",
"count": 1
},
{
"date": "2026-03-20",
"count": 1
},
{
"date": "2026-03-25",
"count": 1
},
{
"date": "2026-04-18",
"count": 1
},
{
"date": "2026-04-30",
"count": 1
},
{
"date": "2026-05-01",
"count": 1
},
{
"date": "2026-05-07",
"count": 1
},
{
"date": "2026-07-19",
"count": 1
}
],
"complete": true,
"collected": 22,
"total_forks": 22
},
"star_history": {
"days": [
{
"date": "2024-04-18",
"count": 1
},
{
"date": "2024-04-19",
"count": 1
},
{
"date": "2024-05-01",
"count": 1
},
{
"date": "2024-06-16",
"count": 1
},
{
"date": "2024-07-04",
"count": 1
},
{
"date": "2024-07-07",
"count": 1
},
{
"date": "2024-07-10",
"count": 1
},
{
"date": "2024-08-12",
"count": 1
},
{
"date": "2024-08-15",
"count": 1
},
{
"date": "2024-08-20",
"count": 1
},
{
"date": "2024-08-29",
"count": 1
},
{
"date": "2024-09-04",
"count": 1
},
{
"date": "2024-09-07",
"count": 1
},
{
"date": "2024-09-23",
"count": 1
},
{
"date": "2025-03-29",
"count": 1
},
{
"date": "2025-04-19",
"count": 1
},
{
"date": "2025-04-21",
"count": 1
},
{
"date": "2025-05-28",
"count": 1
},
{
"date": "2025-06-13",
"count": 1
},
{
"date": "2025-07-30",
"count": 1
},
{
"date": "2025-08-07",
"count": 1
},
{
"date": "2025-10-14",
"count": 1
},
{
"date": "2025-10-15",
"count": 1
},
{
"date": "2025-12-03",
"count": 1
},
{
"date": "2026-01-25",
"count": 1
},
{
"date": "2026-02-25",
"count": 1
},
{
"date": "2026-03-23",
"count": 1
},
{
"date": "2026-04-08",
"count": 1
},
{
"date": "2026-04-20",
"count": 1
},
{
"date": "2026-04-21",
"count": 1
},
{
"date": "2026-04-30",
"count": 1
},
{
"date": "2026-05-04",
"count": 1
},
{
"date": "2026-05-07",
"count": 1
},
{
"date": "2026-05-19",
"count": 1
},
{
"date": "2026-05-22",
"count": 1
},
{
"date": "2026-05-28",
"count": 1
},
{
"date": "2026-06-03",
"count": 1
},
{
"date": "2026-06-10",
"count": 1
},
{
"date": "2026-06-14",
"count": 1
},
{
"date": "2026-07-21",
"count": 1
}
],
"complete": true,
"collected": 40,
"total_stars": 40
},
"open_issues_and_prs": 23
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [],
"has_llms_txt": false,
"has_dockerfile": false,
"has_mcp_signal": false,
"bootstrap_files": [
"Makefile"
],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [],
"toolchain_manifests": [],
"largest_source_bytes": 78072,
"source_files_sampled": 1876,
"oversized_source_files": 3,
"agent_instruction_files": [
"AGENTS.md",
"CLAUDE.md"
],
"agent_instruction_max_bytes": 7403
},
"dependencies": {
"manifests": [
"VultisigApp/Gemfile"
],
"advisories": {
"error": null,
"scope": "repository_graph",
"source": "osv",
"findings": [
{
"name": "addressable",
"direct": false,
"version": "2.8.8",
"severity": "high",
"ecosystem": "rubygems",
"cvss_score": 7.5,
"advisory_ids": [
"GHSA-h27x-rffw-24p4"
],
"fixed_version": "2.9.0",
"advisory_count": 1,
"oldest_advisory_days": 105
},
{
"name": "faraday",
"direct": false,
"version": "1.8.0",
"severity": "high",
"ecosystem": "rubygems",
"cvss_score": 7.5,
"advisory_ids": [
"GHSA-33mh-2634-fwr2",
"GHSA-98m9-hrrm-r99r"
],
"fixed_version": "2.14.3",
"advisory_count": 2,
"oldest_advisory_days": 162
},
{
"name": "json",
"direct": false,
"version": "2.18.0",
"severity": "high",
"ecosystem": "rubygems",
"cvss_score": 8.2,
"advisory_ids": [
"GHSA-3m6g-2423-7cp3"
],
"fixed_version": "2.19.2",
"advisory_count": 1,
"oldest_advisory_days": 124
},
{
"name": "jwt",
"direct": false,
"version": "2.10.2",
"severity": "high",
"ecosystem": "rubygems",
"cvss_score": 7.4,
"advisory_ids": [
"GHSA-c32j-vqhx-rx3x"
],
"fixed_version": "3.2.0",
"advisory_count": 1,
"oldest_advisory_days": 64
},
{
"name": "excon",
"direct": false,
"version": "0.112.0",
"severity": "moderate",
"ecosystem": "rubygems",
"cvss_score": 6.5,
"advisory_ids": [
"GHSA-48rx-c7pg-q66r"
],
"fixed_version": "1.5.0",
"advisory_count": 1,
"oldest_advisory_days": 11
}
],
"collected": true,
"malicious": [],
"truncated": false,
"by_severity": {
"high": 4,
"moderate": 1
},
"advisory_count": 6,
"affected_count": 5,
"assessed_count": 105,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 0,
"direct_affected_count": 0
},
"ecosystems": [
"rubygems"
],
"dependencies": [
{
"name": "fastlane",
"manifest": "VultisigApp/Gemfile",
"ecosystem": "rubygems",
"version_constraint": "2.229.1"
},
{
"name": "ostruct",
"manifest": "VultisigApp/Gemfile",
"ecosystem": "rubygems",
"version_constraint": null
}
],
"all_dependencies": {
"error": null,
"source": "github-sbom",
"packages": [
{
"name": "fastlane",
"direct": true,
"version": "2.229.1",
"ecosystem": "rubygems"
},
{
"name": "ostruct",
"direct": true,
"version": "0.6.3",
"ecosystem": "rubygems"
},
{
"name": "@cosmjs/crypto",
"direct": false,
"version": "0.39.0",
"ecosystem": "npm"
},
{
"name": "@cosmjs/encoding",
"direct": false,
"version": "0.39.0",
"ecosystem": "npm"
},
{
"name": "@cosmjs/math",
"direct": false,
"version": "0.39.0",
"ecosystem": "npm"
},
{
"name": "@cosmjs/utils",
"direct": false,
"version": "0.39.0",
"ecosystem": "npm"
},
{
"name": "@noble/ciphers",
"direct": false,
"version": "2.2.0",
"ecosystem": "npm"
},
{
"name": "@noble/curves",
"direct": false,
"version": "2.2.0",
"ecosystem": "npm"
},
{
"name": "@noble/hashes",
"direct": false,
"version": "2.2.0",
"ecosystem": "npm"
},
{
"name": "@scure/base",
"direct": false,
"version": "2.2.0",
"ecosystem": "npm"
},
{
"name": "@scure/bip39",
"direct": false,
"version": "2.2.0",
"ecosystem": "npm"
},
{
"name": "base64-js",
"direct": false,
"version": "1.5.1",
"ecosystem": "npm"
},
{
"name": "cosmjs-types",
"direct": false,
"version": "0.11.0",
"ecosystem": "npm"
},
{
"name": "readonly-date-esm",
"direct": false,
"version": "2.0.0",
"ecosystem": "npm"
},
{
"name": "abbrev",
"direct": false,
"version": "0.1.2",
"ecosystem": "rubygems"
},
{
"name": "addressable",
"direct": false,
"version": "2.8.8",
"ecosystem": "rubygems"
},
{
"name": "artifactory",
"direct": false,
"version": "3.0.17",
"ecosystem": "rubygems"
},
{
"name": "atomos",
"direct": false,
"version": "0.1.3",
"ecosystem": "rubygems"
},
{
"name": "aws-eventstream",
"direct": false,
"version": "1.4.0",
"ecosystem": "rubygems"
},
{
"name": "aws-partitions",
"direct": false,
"version": "1.1211.0",
"ecosystem": "rubygems"
},
{
"name": "aws-sdk-core",
"direct": false,
"version": "3.241.4",
"ecosystem": "rubygems"
},
{
"name": "aws-sdk-kms",
"direct": false,
"version": "1.121.0",
"ecosystem": "rubygems"
},
{
"name": "aws-sdk-s3",
"direct": false,
"version": "1.213.0",
"ecosystem": "rubygems"
},
{
"name": "aws-sigv4",
"direct": false,
"version": "1.12.1",
"ecosystem": "rubygems"
},
{
"name": "babosa",
"direct": false,
"version": "1.0.4",
"ecosystem": "rubygems"
},
{
"name": "base64",
"direct": false,
"version": "0.2.0",
"ecosystem": "rubygems"
},
{
"name": "bigdecimal",
"direct": false,
"version": "4.0.1",
"ecosystem": "rubygems"
},
{
"name": "CFPropertyList",
"direct": false,
"version": "3.0.8",
"ecosystem": "rubygems"
},
{
"name": "claide",
"direct": false,
"version": "1.1.0",
"ecosystem": "rubygems"
},
{
"name": "colored",
"direct": false,
"version": "1.2",
"ecosystem": "rubygems"
},
{
"name": "colored2",
"direct": false,
"version": "3.1.2",
"ecosystem": "rubygems"
},
{
"name": "commander",
"direct": false,
"version": "4.6.0",
"ecosystem": "rubygems"
},
{
"name": "csv",
"direct": false,
"version": "3.3.5",
"ecosystem": "rubygems"
},
{
"name": "declarative",
"direct": false,
"version": "0.0.20",
"ecosystem": "rubygems"
},
{
"name": "digest-crc",
"direct": false,
"version": "0.7.0",
"ecosystem": "rubygems"
},
{
"name": "domain_name",
"direct": false,
"version": "0.6.20240107",
"ecosystem": "rubygems"
},
{
"name": "dotenv",
"direct": false,
"version": "2.8.1",
"ecosystem": "rubygems"
},
{
"name": "emoji_regex",
"direct": false,
"version": "3.2.3",
"ecosystem": "rubygems"
},
{
"name": "excon",
"direct": false,
"version": "0.112.0",
"ecosystem": "rubygems"
},
{
"name": "faraday",
"direct": false,
"version": "1.8.0",
"ecosystem": "rubygems"
},
{
"name": "faraday-cookie_jar",
"direct": false,
"version": "0.0.8",
"ecosystem": "rubygems"
},
{
"name": "faraday-em_http",
"direct": false,
"version": "1.0.0",
"ecosystem": "rubygems"
},
{
"name": "faraday-em_synchrony",
"direct": false,
"version": "1.0.1",
"ecosystem": "rubygems"
},
{
"name": "faraday-excon",
"direct": false,
"version": "1.1.0",
"ecosystem": "rubygems"
},
{
"name": "faraday-httpclient",
"direct": false,
"version": "1.0.1",
"ecosystem": "rubygems"
},
{
"name": "faraday-net_http",
"direct": false,
"version": "1.0.2",
"ecosystem": "rubygems"
},
{
"name": "faraday-net_http_persistent",
"direct": false,
"version": "1.2.0",
"ecosystem": "rubygems"
},
{
"name": "faraday-patron",
"direct": false,
"version": "1.0.0",
"ecosystem": "rubygems"
},
{
"name": "faraday-rack",
"direct": false,
"version": "1.0.0",
"ecosystem": "rubygems"
},
{
"name": "faraday_middleware",
"direct": false,
"version": "1.2.1",
"ecosystem": "rubygems"
},
{
"name": "fastimage",
"direct": false,
"version": "2.4.0",
"ecosystem": "rubygems"
},
{
"name": "fastlane-sirp",
"direct": false,
"version": "1.0.0",
"ecosystem": "rubygems"
},
{
"name": "gh_inspector",
"direct": false,
"version": "1.1.3",
"ecosystem": "rubygems"
},
{
"name": "google-apis-androidpublisher_v3",
"direct": false,
"version": "0.54.0",
"ecosystem": "rubygems"
},
{
"name": "google-apis-core",
"direct": false,
"version": "0.11.3",
"ecosystem": "rubygems"
},
{
"name": "google-apis-iamcredentials_v1",
"direct": false,
"version": "0.17.0",
"ecosystem": "rubygems"
},
{
"name": "google-apis-playcustomapp_v1",
"direct": false,
"version": "0.13.0",
"ecosystem": "rubygems"
},
{
"name": "google-apis-storage_v1",
"direct": false,
"version": "0.31.0",
"ecosystem": "rubygems"
},
{
"name": "google-cloud-core",
"direct": false,
"version": "1.8.0",
"ecosystem": "rubygems"
},
{
"name": "google-cloud-env",
"direct": false,
"version": "1.6.0",
"ecosystem": "rubygems"
},
{
"name": "google-cloud-errors",
"direct": false,
"version": "1.5.0",
"ecosystem": "rubygems"
},
{
"name": "google-cloud-storage",
"direct": false,
"version": "1.47.0",
"ecosystem": "rubygems"
},
{
"name": "googleauth",
"direct": false,
"version": "1.8.1",
"ecosystem": "rubygems"
},
{
"name": "highline",
"direct": false,
"version": "2.0.3",
"ecosystem": "rubygems"
},
{
"name": "http-cookie",
"direct": false,
"version": "1.0.8",
"ecosystem": "rubygems"
},
{
"name": "httpclient",
"direct": false,
"version": "2.9.0",
"ecosystem": "rubygems"
},
{
"name": "jmespath",
"direct": false,
"version": "1.6.2",
"ecosystem": "rubygems"
},
{
"name": "json",
"direct": false,
"version": "2.18.0",
"ecosystem": "rubygems"
},
{
"name": "jwt",
"direct": false,
"version": "2.10.2",
"ecosystem": "rubygems"
},
{
"name": "logger",
"direct": false,
"version": "1.7.0",
"ecosystem": "rubygems"
},
{
"name": "mini_magick",
"direct": false,
"version": "4.13.2",
"ecosystem": "rubygems"
},
{
"name": "mini_mime",
"direct": false,
"version": "1.1.5",
"ecosystem": "rubygems"
},
{
"name": "multi_json",
"direct": false,
"version": "1.19.1",
"ecosystem": "rubygems"
},
{
"name": "multipart-post",
"direct": false,
"version": "2.4.1",
"ecosystem": "rubygems"
},
{
"name": "mutex_m",
"direct": false,
"version": "0.3.0",
"ecosystem": "rubygems"
},
{
"name": "nanaimo",
"direct": false,
"version": "0.4.0",
"ecosystem": "rubygems"
},
{
"name": "naturally",
"direct": false,
"version": "2.3.0",
"ecosystem": "rubygems"
},
{
"name": "nkf",
"direct": false,
"version": "0.2.0",
"ecosystem": "rubygems"
},
{
"name": "optparse",
"direct": false,
"version": "0.8.1",
"ecosystem": "rubygems"
},
{
"name": "os",
"direct": false,
"version": "1.1.4",
"ecosystem": "rubygems"
},
{
"name": "plist",
"direct": false,
"version": "3.7.2",
"ecosystem": "rubygems"
},
{
"name": "public_suffix",
"direct": false,
"version": "7.0.2",
"ecosystem": "rubygems"
},
{
"name": "rake",
"direct": false,
"version": "13.3.1",
"ecosystem": "rubygems"
},
{
"name": "representable",
"direct": false,
"version": "3.2.0",
"ecosystem": "rubygems"
},
{
"name": "retriable",
"direct": false,
"version": "3.1.2",
"ecosystem": "rubygems"
},
{
"name": "rexml",
"direct": false,
"version": "3.4.4",
"ecosystem": "rubygems"
},
{
"name": "rouge",
"direct": false,
"version": "3.28.0",
"ecosystem": "rubygems"
},
{
"name": "ruby2_keywords",
"direct": false,
"version": "0.0.5",
"ecosystem": "rubygems"
},
{
"name": "rubyzip",
"direct": false,
"version": "2.4.1",
"ecosystem": "rubygems"
},
{
"name": "security",
"direct": false,
"version": "0.1.5",
"ecosystem": "rubygems"
},
{
"name": "signet",
"direct": false,
"version": "0.21.0",
"ecosystem": "rubygems"
},
{
"name": "simctl",
"direct": false,
"version": "1.6.10",
"ecosystem": "rubygems"
},
{
"name": "sysrandom",
"direct": false,
"version": "1.0.5",
"ecosystem": "rubygems"
},
{
"name": "terminal-notifier",
"direct": false,
"version": "2.0.0",
"ecosystem": "rubygems"
},
{
"name": "terminal-table",
"direct": false,
"version": "3.0.2",
"ecosystem": "rubygems"
},
{
"name": "trailblazer-option",
"direct": false,
"version": "0.1.2",
"ecosystem": "rubygems"
},
{
"name": "tty-cursor",
"direct": false,
"version": "0.7.1",
"ecosystem": "rubygems"
},
{
"name": "tty-screen",
"direct": false,
"version": "0.8.2",
"ecosystem": "rubygems"
},
{
"name": "tty-spinner",
"direct": false,
"version": "0.9.3",
"ecosystem": "rubygems"
},
{
"name": "uber",
"direct": false,
"version": "0.1.0",
"ecosystem": "rubygems"
},
{
"name": "unicode-display_width",
"direct": false,
"version": "2.6.0",
"ecosystem": "rubygems"
},
{
"name": "word_wrap",
"direct": false,
"version": "1.0.0",
"ecosystem": "rubygems"
},
{
"name": "xcodeproj",
"direct": false,
"version": "1.27.0",
"ecosystem": "rubygems"
},
{
"name": "xcpretty",
"direct": false,
"version": "0.4.1",
"ecosystem": "rubygems"
},
{
"name": "xcpretty-travis-formatter",
"direct": false,
"version": "1.0.1",
"ecosystem": "rubygems"
}
],
"collected": true,
"truncated": false,
"total_count": 105,
"direct_count": 2,
"indirect_count": 103
}
},
"maintainership": {
"issues": {
"open_prs": 3,
"merged_prs": 2508,
"open_issues": 20,
"closed_ratio": 0.991,
"closed_issues": 2185,
"closed_unmerged_prs": 133
},
"bus_factor": 2,
"bot_contributors": 1,
"top_contributors": [
{
"type": "User",
"login": "enriquesouza",
"commits": 2519,
"avatar_url": "https://avatars.githubusercontent.com/u/1700699?v=4"
},
{
"type": "User",
"login": "johnnyluo",
"commits": 2199,
"avatar_url": "https://avatars.githubusercontent.com/u/749608?v=4"
},
{
"type": "User",
"login": "Rockindash",
"commits": 1784,
"avatar_url": "https://avatars.githubusercontent.com/u/13535088?v=4"
},
{
"type": "User",
"login": "gastonm5",
"commits": 564,
"avatar_url": "https://avatars.githubusercontent.com/u/7192634?v=4"
},
{
"type": "User",
"login": "flypaper0",
"commits": 545,
"avatar_url": "https://avatars.githubusercontent.com/u/5384197?v=4"
},
{
"type": "User",
"login": "realpaaao",
"commits": 47,
"avatar_url": "https://avatars.githubusercontent.com/u/167348323?v=4"
},
{
"type": "User",
"login": "Dolloong",
"commits": 21,
"avatar_url": "https://avatars.githubusercontent.com/u/151611992?v=4"
},
{
"type": "User",
"login": "0x-suzume",
"commits": 15,
"avatar_url": "https://avatars.githubusercontent.com/u/265643117?v=4"
},
{
"type": "User",
"login": "Vaulty-bot",
"commits": 13,
"avatar_url": "https://avatars.githubusercontent.com/u/257854823?v=4"
},
{
"type": "User",
"login": "jpthor",
"commits": 10,
"avatar_url": "https://avatars.githubusercontent.com/u/41815753?v=4"
}
],
"contributors_sampled": 27,
"top_contributor_share": 0.325
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"objective-c-xcode.yml"
],
"has_docs_dir": false,
"linter_configs": [],
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"security_signals": {
"lockfiles": [
"Gemfile.lock",
"package-lock.json"
],
"scorecard": {
"checks": [
{
"name": "Binary-Artifacts",
"score": 0,
"reason": "binaries present in source code",
"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": 10,
"reason": "29 out of 29 merged PRs checked by a CI test -- score normalized to 10",
"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": 8,
"reason": "Found 26/30 approved changesets -- score normalized to 8",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 10,
"reason": "project has 4 contributing companies or organizations",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
},
{
"name": "Dangerous-Workflow",
"score": 10,
"reason": "no dangerous workflow patterns detected",
"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 1 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": 10,
"reason": "all dependencies are pinned",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
},
{
"name": "SAST",
"score": 0,
"reason": "SAST tool is not run on all commits -- score normalized to 0",
"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": 0,
"reason": "Project has not signed or included provenance with any releases.",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
},
{
"name": "Token-Permissions",
"score": 0,
"reason": "detected GitHub workflow tokens with excessive permissions",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
},
{
"name": "Vulnerabilities",
"score": 4,
"reason": "6 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "9fc8f630bcfc6e1947d5b2d07ecf778bdd7fb16e",
"ran_at": "2026-07-22T03:21:14Z",
"aggregate_score": 4.3,
"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": "2026-07-21T23:12:34Z",
"oldest_open_prs": [
{
"number": 4734,
"created_at": "2026-07-03T18:09:19Z",
"last_comment_at": "2026-07-03T18:09:48Z",
"last_comment_author": "coderabbitai"
},
{
"number": 4849,
"created_at": "2026-07-20T11:25:27Z",
"last_comment_at": "2026-07-21T15:01:45Z",
"last_comment_author": "gastonm5"
},
{
"number": 4857,
"created_at": "2026-07-20T18:52:56Z",
"last_comment_at": "2026-07-20T18:53:32Z",
"last_comment_author": "coderabbitai"
}
],
"last_merged_pr_at": "2026-07-21T22:56:11Z",
"ci_last_conclusion": "SUCCESS",
"oldest_open_issues": [
{
"number": 2122,
"created_at": "2025-04-30T05:57:01Z",
"last_comment_at": "2025-04-30T06:04:52Z",
"last_comment_author": "jpthor"
},
{
"number": 4309,
"created_at": "2026-05-05T17:04:17Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 4325,
"created_at": "2026-05-07T19:58:54Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 4375,
"created_at": "2026-05-17T17:44:15Z",
"last_comment_at": "2026-05-18T16:38:28Z",
"last_comment_author": "gastonm5"
},
{
"number": 4655,
"created_at": "2026-06-25T15:55:57Z",
"last_comment_at": "2026-07-05T22:46:33Z",
"last_comment_author": "johnnyluo"
},
{
"number": 4755,
"created_at": "2026-07-06T18:51:40Z",
"last_comment_at": "2026-07-09T03:30:22Z",
"last_comment_author": "johnnyluo"
},
{
"number": 4756,
"created_at": "2026-07-06T18:59:52Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 4757,
"created_at": "2026-07-06T18:59:53Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 4758,
"created_at": "2026-07-06T18:59:54Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 4760,
"created_at": "2026-07-07T05:47:51Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 4769,
"created_at": "2026-07-08T13:48:12Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 4800,
"created_at": "2026-07-13T11:20:46Z",
"last_comment_at": "2026-07-13T23:40:29Z",
"last_comment_author": "johnnyluo"
},
{
"number": 4817,
"created_at": "2026-07-15T17:19:06Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 4838,
"created_at": "2026-07-18T05:51:06Z",
"last_comment_at": "2026-07-21T14:50:12Z",
"last_comment_author": "gastonm5"
},
{
"number": 4846,
"created_at": "2026-07-20T07:22:22Z",
"last_comment_at": "2026-07-20T09:54:16Z",
"last_comment_author": "realpaaao"
},
{
"number": 4853,
"created_at": "2026-07-20T12:59:46Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 4854,
"created_at": "2026-07-20T12:59:48Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 4856,
"created_at": "2026-07-20T18:24:57Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 4858,
"created_at": "2026-07-20T19:33:35Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 4861,
"created_at": "2026-07-21T06:46:27Z",
"last_comment_at": "2026-07-21T06:49:37Z",
"last_comment_author": "realpaaao"
}
]
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/vultisig/vultisig-ios",
"host": "github.com",
"name": "vultisig-ios",
"owner": "vultisig"
},
"metrics": {
"overall": {
"key": "overall",
"band": "moderate",
"name": "Overall health",
"note": null,
"notes": [],
"value": 68,
"inputs": {
"security": 54,
"vitality": 96,
"community": 48,
"governance": 73,
"engineering": 61
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "excellent",
"name": "Vitality",
"value": 96,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "excellent",
"name": "Development activity",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"commits_last_year": 1740,
"human_commit_share": 1,
"days_since_last_push": 0,
"active_weeks_last_year": 52
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 0 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 0
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "52/52 weeks with commits",
"points": 36,
"status": "met",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 52
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "1740 commits in the last year",
"points": 18,
"status": "met",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 1740
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "30 commit(s) and 1 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": null,
"notes": [],
"value": 90,
"inputs": {
"releases_count": 100,
"latest_release_tag": "v1.42.67",
"releases_from_tags": false,
"days_since_latest_release": 5,
"mean_days_between_releases": 4.6
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "100 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 100
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 5 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 5
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~4.6 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 4.6
}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "Project has not signed or included provenance with any releases.",
"points": 0,
"status": "missed",
"details": [],
"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": 0,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "last human commit 0 days ago",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_maintained",
"params": {
"days": 0
}
}
],
"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": 48,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "at_risk",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 40,
"inputs": {
"forks": 22,
"stars": 40,
"watchers": 4,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "below_threshold"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "40 stars",
"points": 25.8,
"status": "partial",
"details": [
{
"code": "stars",
"params": {
"count": 40
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "22 forks",
"points": 11,
"status": "partial",
"details": [
{
"code": "forks",
"params": {
"count": 22
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "4 watchers",
"points": 2.7,
"status": "partial",
"details": [
{
"code": "watchers",
"params": {
"count": 4
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "moderate",
"name": "Community health",
"note": null,
"notes": [],
"value": 57,
"inputs": {
"has_readme": true,
"has_license": true,
"has_contributing": false,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 22.5,
"status": "met",
"details": [],
"max_points": 22.5
},
{
"key": "license",
"name": "License",
"detail": "recognized license (Apache-2.0)",
"points": 22.5,
"status": "met",
"details": [
{
"code": "license_standard",
"params": {}
},
{
"code": "license_spdx",
"params": {
"spdx": "Apache-2.0"
}
}
],
"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": 6.3,
"status": "met",
"details": [],
"max_points": 6.3
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "good",
"name": "Sustainability & Governance",
"value": 73,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "moderate",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 64,
"inputs": {
"bus_factor": 2,
"contributors_sampled": 27,
"top_contributor_share": 0.325
},
"components": [
{
"key": "bus_factor",
"name": "Bus factor",
"detail": "2 contributor(s) cover half of all commits",
"points": 25.2,
"status": "partial",
"details": [
{
"code": "bus_factor",
"params": {
"count": 2
}
}
],
"max_points": 54
},
{
"key": "commit_distribution",
"name": "Commit distribution",
"detail": "top contributor authored 32% of commits",
"points": 15.2,
"status": "partial",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 32
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "27 contributors",
"points": 13.5,
"status": "met",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 27
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "project has 4 contributing companies or organizations",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "excellent",
"name": "Issue & PR responsiveness",
"note": null,
"notes": [],
"value": 95,
"inputs": {
"merged_prs": 2508,
"open_issues": 20,
"closed_issues": 2185,
"issue_closed_ratio": 0.991,
"closed_unmerged_prs": 133
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "99% of issues closed",
"points": 46.3,
"status": "partial",
"details": [
{
"code": "issues_closed_share",
"params": {
"share": 99
}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "2508/2641 decided PRs merged",
"points": 36.3,
"status": "partial",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 2508,
"decided": 2641
}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 26/30 approved changesets -- score normalized to 8",
"points": 12,
"status": "partial",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "moderate",
"name": "Ownership & stewardship",
"note": null,
"notes": [],
"value": 63,
"inputs": {
"followers": 132,
"owner_type": "Organization",
"is_verified": null,
"owner_login": "vultisig",
"public_repos": 72,
"account_age_days": 906
},
"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": "132 followers of vultisig",
"points": 15.3,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 132,
"login": "vultisig"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "72 public repos, account ~2 yr old",
"points": 18,
"status": "partial",
"details": [
{
"code": "public_repos",
"params": {
"count": 72
}
},
{
"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": "moderate",
"name": "Engineering Quality",
"value": 61,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "moderate",
"name": "Engineering practices",
"note": null,
"notes": [],
"value": 68,
"inputs": {
"has_ci": true,
"has_tests": true,
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": "1 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 1
}
}
],
"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": null,
"points": 0,
"status": "missed",
"details": [],
"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": "29 out of 29 merged PRs checked by a CI test -- score normalized to 10",
"points": 20,
"status": "met",
"details": [],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "moderate",
"name": "Documentation",
"note": null,
"notes": [],
"value": 50,
"inputs": {
"topics": [],
"has_wiki": true,
"homepage": null,
"has_readme": true,
"has_docs_dir": false,
"has_description": true
},
"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": 10,
"status": "met",
"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": "moderate",
"name": "Security",
"value": 54,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "at_risk",
"name": "Security posture",
"note": "Excluded from scoring (no data or not applicable): Packaging. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"packaging"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 43,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 17,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 1,
"scorecard_aggregate": 4.3
},
"components": [
{
"key": "binary_artifacts",
"name": "Binary-Artifacts",
"detail": "binaries present in source code",
"points": 0,
"status": "missed",
"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": "29 out of 29 merged PRs checked by a CI test -- score normalized to 10",
"points": 2.5,
"status": "met",
"details": [],
"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 26/30 approved changesets -- score normalized to 8",
"points": 6,
"status": "partial",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 4 contributing companies or organizations",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "dangerous_workflow",
"name": "Dangerous-Workflow",
"detail": "no dangerous workflow patterns detected",
"points": 10,
"status": "met",
"details": [],
"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 1 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": "all dependencies are pinned",
"points": 5,
"status": "met",
"details": [],
"max_points": 5
},
{
"key": "sast",
"name": "SAST",
"detail": "SAST tool is not run on all commits -- score normalized to 0",
"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": "Project has not signed or included provenance with any releases.",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "detected GitHub workflow tokens with excessive permissions",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "vulnerabilities",
"name": "Vulnerabilities",
"detail": "6 existing vulnerabilities detected",
"points": 3,
"status": "partial",
"details": [],
"max_points": 7.5
}
]
},
{
"key": "dependency_advisories",
"band": "excellent",
"name": "Dependency advisories",
"note": "Excluded from scoring (no data or not applicable): Indirect dependencies free of known advisories, No advisories left outstanding. Remaining weights renormalized. Matched 105 resolved dependencies against OSV. This repository publishes no package the index resolves, so the repository dependency graph was assessed instead. That graph mixes development and test pins with shipped dependencies, so only the declared runtime dependencies are scored; transitive findings are reported as context and excluded from the score. Reachability is not analyzed.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"indirect_dependencies_free_of_known_advisories",
"no_advisories_left_outstanding"
]
}
},
{
"code": "weights_renormalized",
"params": {}
},
{
"code": "advisories_scope_repository",
"params": {
"assessed": 105
}
},
{
"code": "advisories_repo_graph_caveat",
"params": {}
},
{
"code": "advisories_reachability",
"params": {}
}
],
"value": 100,
"inputs": {
"source": "osv",
"advisories": 6,
"affected_packages": 5,
"assessed_packages": 105,
"unassessed_packages": 0,
"affected_by_severity": "high 4, moderate 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": "transitive set not separable from development and test dependencies in this scope",
"points": 0,
"status": "excluded",
"details": [
{
"code": "advisories_scope_not_separable",
"params": {}
}
],
"max_points": 25
},
{
"key": "no_advisories_left_outstanding",
"name": "No advisories left outstanding",
"detail": "no advisory carries a publication date",
"points": 0,
"status": "excluded",
"details": [
{
"code": "advisories_no_publication_date",
"params": {}
}
],
"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": 105,
"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": 5
},
"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": "excellent",
"name": "AI Readiness",
"value": 86,
"weight": 0,
"metrics": [
{
"key": "ai_agent_context",
"band": "excellent",
"name": "Agent context & guidance",
"note": null,
"notes": [],
"value": 85,
"inputs": {
"has_llms_txt": false,
"legible_history_share": 0.99,
"agent_instruction_files": [
"AGENTS.md",
"CLAUDE.md"
],
"agent_instruction_max_bytes": 7403
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": "AGENTS.md, CLAUDE.md",
"points": 45,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "AGENTS.md, CLAUDE.md"
}
}
],
"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": "99 of 100 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 99,
"sampled": 100
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "good",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 81,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [
"Gemfile.lock",
"package-lock.json"
],
"has_dockerfile": false,
"typed_language": true,
"bootstrap_files": [
"Makefile"
],
"has_devcontainer": false,
"has_linter_config": false,
"typecheck_configs": [],
"agent_commit_share": 0.77,
"toolchain_manifests": [],
"dependency_bot_commit_share": 0
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": "Makefile",
"points": 18,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "Makefile"
}
}
],
"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": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": "Swift (statically typed)",
"points": 11,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "Swift"
}
}
],
"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": "77 of the last 100 commits agent-authored or agent-credited",
"points": 10,
"status": "met",
"details": [
{
"code": "agent_authored_commits",
"params": {
"count": 77,
"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": "all dependencies are pinned",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "excellent",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"primary_language": "Swift",
"largest_source_bytes": 78072,
"source_files_sampled": 1876,
"oversized_source_files": 3
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "Swift (statically typed)",
"points": 45,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "Swift"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "3/1876 source files over 60KB",
"points": 54.9,
"status": "partial",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 1876,
"oversized": 3
}
}
],
"max_points": 55
}
]
}
],
"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": [],
"report_type": "repository",
"generated_at": "2026-07-22T03:22:11.840475Z",
"schema_version": "0.26.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/v/vultisig/vultisig-ios.svg",
"full_name": "vultisig/vultisig-ios",
"license_state": "standard",
"license_spdx": "Apache-2.0"
}