Звіт у форматі JSON машиночитний
{
"data": {
"repo": {
"topics": [],
"is_fork": false,
"size_kb": 250256,
"has_wiki": true,
"homepage": null,
"languages": {
"Ruby": 1739,
"Shell": 7601,
"Kotlin": 11573842,
"JavaScript": 2413
},
"pushed_at": "2026-07-21T23:56:28Z",
"created_at": "2024-04-22T02:25:31Z",
"owner_type": "Organization",
"updated_at": "2026-07-21T23:56:30Z",
"description": "Vultisig Android App",
"is_archived": false,
"is_disabled": false,
"license_spdx": "Apache-2.0",
"default_branch": "main",
"license_spdx_raw": "Apache-2.0",
"primary_language": "Kotlin",
"significant_languages": [
"Kotlin"
]
},
"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.0.114",
"kind": "patch",
"published_at": "2026-07-14T10:27:19Z"
},
{
"tag": "v1.0.113",
"kind": "patch",
"published_at": "2026-07-06T00:28:02Z"
},
{
"tag": "v1.0.112",
"kind": "patch",
"published_at": "2026-07-03T01:12:42Z"
},
{
"tag": "v1.0.111",
"kind": "patch",
"published_at": "2026-06-29T00:00:15Z"
},
{
"tag": "v1.0.110",
"kind": "patch",
"published_at": "2026-06-25T23:39:44Z"
},
{
"tag": "v1.0.109",
"kind": "patch",
"published_at": "2026-06-21T23:33:46Z"
},
{
"tag": "v1.0.108",
"kind": "patch",
"published_at": "2026-06-12T09:33:43Z"
},
{
"tag": "v1.0.107",
"kind": "patch",
"published_at": "2026-06-05T22:10:32Z"
},
{
"tag": "v1.0.106",
"kind": "patch",
"published_at": "2026-06-05T09:48:20Z"
},
{
"tag": "v1.0.105",
"kind": "patch",
"published_at": "2026-06-04T02:37:50Z"
},
{
"tag": "v1.0.104",
"kind": "patch",
"published_at": "2026-06-03T23:36:15Z"
},
{
"tag": "v1.0.103",
"kind": "patch",
"published_at": "2026-05-19T06:42:54Z"
},
{
"tag": "v1.0.102",
"kind": "patch",
"published_at": "2026-05-14T10:22:16Z"
},
{
"tag": "v1.0.101",
"kind": "patch",
"published_at": "2026-04-28T04:08:48Z"
},
{
"tag": "v1.0.100",
"kind": "patch",
"published_at": "2026-04-25T06:42:34Z"
},
{
"tag": "v1.0.99",
"kind": "patch",
"published_at": "2026-04-23T01:41:00Z"
},
{
"tag": "v1.0.98",
"kind": "patch",
"published_at": "2026-03-26T06:06:48Z"
},
{
"tag": "v1.0.97",
"kind": "patch",
"published_at": "2026-03-17T21:57:22Z"
},
{
"tag": "v1.0.96",
"kind": "patch",
"published_at": "2026-02-26T21:57:20Z"
},
{
"tag": "v1.0.95",
"kind": "patch",
"published_at": "2026-02-03T09:48:16Z"
},
{
"tag": "v1.0.94",
"kind": "patch",
"published_at": "2026-02-02T22:33:39Z"
},
{
"tag": "v1.0.93",
"kind": "patch",
"published_at": "2026-01-15T21:49:05Z"
},
{
"tag": "v1.0.92",
"kind": "patch",
"published_at": "2026-01-15T00:44:19Z"
},
{
"tag": "v1.0.91",
"kind": "patch",
"published_at": "2026-01-13T23:00:24Z"
},
{
"tag": "v1.0.90",
"kind": "patch",
"published_at": "2026-01-07T22:03:48Z"
},
{
"tag": "v1.0.89",
"kind": "patch",
"published_at": "2025-12-11T23:33:15Z"
},
{
"tag": "v1.0.88",
"kind": "patch",
"published_at": "2025-12-09T23:14:30Z"
},
{
"tag": "v1.0.87",
"kind": "patch",
"published_at": "2025-11-29T01:50:15Z"
},
{
"tag": "v1.0.86",
"kind": "patch",
"published_at": "2025-11-26T23:56:24Z"
},
{
"tag": "v1.0.85",
"kind": "patch",
"published_at": "2025-11-26T05:26:24Z"
},
{
"tag": "v1.0.84",
"kind": "patch",
"published_at": "2025-11-18T09:06:56Z"
},
{
"tag": "v1.0.83",
"kind": "patch",
"published_at": "2025-11-15T05:32:41Z"
},
{
"tag": "v1.0.82",
"kind": "patch",
"published_at": "2025-11-03T23:25:04Z"
},
{
"tag": "v1.0.81",
"kind": "patch",
"published_at": "2025-10-28T08:25:37Z"
},
{
"tag": "v1.0.80",
"kind": "patch",
"published_at": "2025-10-27T08:49:49Z"
},
{
"tag": "v1.0.79",
"kind": "patch",
"published_at": "2025-10-21T01:14:52Z"
},
{
"tag": "v1.0.78",
"kind": "patch",
"published_at": "2025-10-18T23:32:48Z"
},
{
"tag": "v1.0.77",
"kind": "patch",
"published_at": "2025-10-09T09:34:50Z"
},
{
"tag": "v1.0.76",
"kind": "patch",
"published_at": "2025-10-07T22:38:11Z"
},
{
"tag": "v1.0.75",
"kind": "patch",
"published_at": "2025-10-07T00:46:28Z"
},
{
"tag": "v1.0.74",
"kind": "patch",
"published_at": "2025-10-02T05:59:03Z"
},
{
"tag": "v1.0.73",
"kind": "patch",
"published_at": "2025-09-15T22:51:48Z"
},
{
"tag": "v1.0.72",
"kind": "patch",
"published_at": "2025-09-08T05:59:44Z"
},
{
"tag": "v1.0.71",
"kind": "patch",
"published_at": "2025-08-22T09:42:30Z"
},
{
"tag": "v1.0.70",
"kind": "patch",
"published_at": "2025-08-20T07:01:35Z"
},
{
"tag": "v1.0.69",
"kind": "patch",
"published_at": "2025-08-05T01:17:42Z"
},
{
"tag": "v1.0.68",
"kind": "patch",
"published_at": "2025-08-04T09:54:47Z"
},
{
"tag": "v1.0.66",
"kind": "patch",
"published_at": "2025-08-01T10:48:34Z"
},
{
"tag": "v1.0.65",
"kind": "patch",
"published_at": "2025-07-21T23:23:20Z"
},
{
"tag": "v1.0.64",
"kind": "patch",
"published_at": "2025-07-18T10:10:05Z"
},
{
"tag": "v1.0.63",
"kind": "patch",
"published_at": "2025-07-17T00:32:26Z"
},
{
"tag": "v1.0.62",
"kind": "patch",
"published_at": "2025-07-06T22:54:54Z"
},
{
"tag": "v1.0.61",
"kind": "patch",
"published_at": "2025-07-04T10:24:17Z"
},
{
"tag": "v1.0.60",
"kind": "patch",
"published_at": "2025-07-03T11:59:26Z"
},
{
"tag": "v1.0.59",
"kind": "patch",
"published_at": "2025-06-21T00:47:02Z"
},
{
"tag": "v1.0.58",
"kind": "patch",
"published_at": "2025-06-11T23:05:23Z"
},
{
"tag": "v1.0.57",
"kind": "patch",
"published_at": "2025-05-29T01:14:05Z"
},
{
"tag": "v1.0.56",
"kind": "patch",
"published_at": "2025-05-16T06:52:59Z"
},
{
"tag": "v1.0.55",
"kind": "patch",
"published_at": "2025-05-07T06:53:30Z"
},
{
"tag": "v1.0.54",
"kind": "patch",
"published_at": "2025-05-01T15:02:48Z"
},
{
"tag": "v1.0.53",
"kind": "patch",
"published_at": "2025-04-30T22:55:33Z"
},
{
"tag": "v1.0.52",
"kind": "patch",
"published_at": "2025-04-29T21:59:27Z"
},
{
"tag": "v1.0.51",
"kind": "patch",
"published_at": "2025-04-28T10:41:26Z"
},
{
"tag": "v1.0.50",
"kind": "patch",
"published_at": "2025-04-25T10:08:09Z"
},
{
"tag": "v1.0.49",
"kind": "patch",
"published_at": "2025-04-14T08:22:51Z"
},
{
"tag": "v1.0.48",
"kind": "patch",
"published_at": "2025-04-07T06:52:19Z"
},
{
"tag": "v1.0.47",
"kind": "patch",
"published_at": "2025-03-23T23:54:14Z"
},
{
"tag": "v1.0.46",
"kind": "patch",
"published_at": "2025-03-20T22:03:00Z"
},
{
"tag": "v1.0.45",
"kind": "patch",
"published_at": "2025-03-19T23:00:19Z"
},
{
"tag": "v1.0.44",
"kind": "patch",
"published_at": "2025-03-13T21:26:05Z"
},
{
"tag": "v1.0.43",
"kind": "patch",
"published_at": "2025-03-12T05:52:02Z"
},
{
"tag": "v1.0.42",
"kind": "patch",
"published_at": "2025-02-27T00:15:07Z"
},
{
"tag": "v1.0.41",
"kind": "patch",
"published_at": "2025-02-13T21:36:11Z"
},
{
"tag": "v1.0.40",
"kind": "patch",
"published_at": "2025-02-13T07:36:52Z"
},
{
"tag": "v1.0.39",
"kind": "patch",
"published_at": "2025-02-06T01:53:18Z"
},
{
"tag": "v1.0.38",
"kind": "patch",
"published_at": "2025-01-22T23:14:51Z"
},
{
"tag": "v1.0.37",
"kind": "patch",
"published_at": "2025-01-09T22:00:21Z"
},
{
"tag": "v1.0.36",
"kind": "patch",
"published_at": "2024-12-09T23:07:13Z"
},
{
"tag": "v1.0.35",
"kind": "patch",
"published_at": "2024-12-04T22:20:09Z"
},
{
"tag": "v1.0.34",
"kind": "patch",
"published_at": "2024-11-20T23:29:57Z"
},
{
"tag": "v1.0.33",
"kind": "patch",
"published_at": "2024-11-14T02:27:51Z"
},
{
"tag": "v1.0.32",
"kind": "patch",
"published_at": "2024-11-02T00:26:04Z"
},
{
"tag": "v1.0.31",
"kind": "patch",
"published_at": "2024-10-30T23:30:10Z"
},
{
"tag": "v1.0.30",
"kind": "patch",
"published_at": "2024-10-18T22:16:09Z"
},
{
"tag": "v1.0.29",
"kind": "patch",
"published_at": "2024-10-14T11:37:29Z"
},
{
"tag": "v1.0.27",
"kind": "patch",
"published_at": "2024-10-08T21:14:06Z"
},
{
"tag": "v1.0.26",
"kind": "patch",
"published_at": "2024-10-07T00:17:56Z"
},
{
"tag": "v1.0.25",
"kind": "patch",
"published_at": "2024-09-26T08:43:58Z"
},
{
"tag": "v1.0.24",
"kind": "patch",
"published_at": "2024-09-25T22:48:58Z"
},
{
"tag": "v1.0.23",
"kind": "patch",
"published_at": "2024-09-16T22:32:55Z"
},
{
"tag": "v1.0.22",
"kind": "patch",
"published_at": "2024-09-11T10:57:37Z"
},
{
"tag": "v1.0.21",
"kind": "patch",
"published_at": "2024-09-11T01:46:46Z"
},
{
"tag": "v1.0.20",
"kind": "patch",
"published_at": "2024-09-05T05:28:24Z"
},
{
"tag": "v1.0.19",
"kind": "patch",
"published_at": "2024-09-02T05:54:20Z"
},
{
"tag": "v1.0.18",
"kind": "patch",
"published_at": "2024-08-28T22:08:39Z"
},
{
"tag": "v1.0.17",
"kind": "patch",
"published_at": "2024-08-24T00:55:56Z"
},
{
"tag": "v1.0.16",
"kind": "patch",
"published_at": "2024-08-18T02:38:27Z"
},
{
"tag": "v1.0.15",
"kind": "patch",
"published_at": "2024-08-11T02:39:54Z"
},
{
"tag": "v1.0.14",
"kind": "patch",
"published_at": "2024-08-06T06:13:57Z"
},
{
"tag": "v1.0.13",
"kind": "patch",
"published_at": "2024-08-03T06:19:06Z"
}
],
"recent_commits": [
{
"oid": "2c230ced6fed249f439e9fbca9c707458f369ce1",
"body": "…#5360)\n\n* fix(cardano): recover loser device on duplicate-broadcast rejection\n\nOn a multi-device Cardano keysign the losing device rebroadcasts the peer's\nbyte-identical signed tx and Ogmios rejects it with \"All inputs are spent.\nTransaction has probably already been included\". The old recovery req\n[…]\n\n every recovery path rethrows instead of reporting an untrackable success.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(cardano): recover loser device on duplicate-broadcast rejection (…",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-21T23:56:25Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f939c3e06b9fd77c5e25b450b1072b39b1c5f5d0",
"body": null,
"is_bot": false,
"headline": "chore: bump targetSdk to 36 (#5370)",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-21T23:34:05Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cf94f1910c4af079807c6e6f222f914207a646ce",
"body": "* fix(solana): count Solana swap priority fee once, not twice\n\ncalculateDefaultFees added a computed priority fee on top of a base-fee\nconstant that already bundled the floor priority fee, roughly doubling\nthe displayed swap fee. Use a genuine base-only signature-fee constant so\nthe priority fee is \n[…]\ncom>\n\n* address review comments: clarify single-signer scope in fee comment\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(solana): count swap priority fee once, not twice (#5359)",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-21T22:54:00Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "11182faa0c5cc8d764ae1a2b836070f8a81a978e",
"body": "Co-authored-by: Vaulty-bot <vaulty-bot@vultisig.com>",
"is_bot": false,
"headline": "style: apply ktfmt formatting (#5365) (#5367)",
"author_name": "Vaulty",
"author_login": "Vaulty-bot",
"committed_at": "2026-07-21T11:41:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b42df2d93610d1d7ec1bc8378cc857661f8e6845",
"body": "…reen (#5354)\n\n* fix(deposit): correct From/To/pool on Mint LP transaction-complete screen\n\nA MayaChain Mint (add-liquidity) deposit reached the Transaction-complete\nscreen with three display defects versus the pre-sign Function overview:\n\n- From showed the raw chain address instead of \"VaultName (a\n[…]\nrim the test comment to what toUiTransactionInfo() actually asserts.\n\nCo-Authored-By: aminsato <Amin.saradar@yahoo.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(deposit): correct From/To/pool on Mint LP transaction-complete sc…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-21T10:05:59Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "6091a9a4ea6c5e9b2ce7e0b3a36d967db025a942",
"body": "Co-authored-by: Vaulty-bot <vaulty-bot@vultisig.com>",
"is_bot": false,
"headline": "style: apply ktfmt formatting (#5328) (#5362)",
"author_name": "Vaulty",
"author_login": "Vaulty-bot",
"committed_at": "2026-07-21T09:47:10Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "219fce05ef874ade8a9b53ee785e40cb4b465848",
"body": "* fix: check swap inbound status before signing\n\n* fix: address swap preflight review\n\n* address review comments\n\n- default gasRate/gasRateUnits to empty to keep the shared inbound model\n from decode-failing (and false-blocking) when Maya omits gas fields\n- assert isSigning resets to false on the b\n[…]\nross tests as\nUncaughtExceptionsBeforeTest. The VM already injects ioDispatcher for\nexactly this reason (withVaultLabels uses it).\n\n---------\n\nCo-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: check swap inbound status before signing (#5342)",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-21T09:26:07Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0a0a65182ae7978305462dd526354c8afebef855",
"body": "The Schnorr initiator regenerated and re-uploaded a fresh setup message\non every retry because its upload branch lacked the `attempt == 0` guard\nthat DklsKeysign and MldsaKeysign already use. A peer still mid-protocol\non the previous setup message would then desync, signing against a\ndifferent sessi\n[…]\noad on the first attempt so retries fall through to\nthe existing download branch and reuse the setup message already on the\nrelay.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(keysign): reuse Schnorr setup message on retry (#5327) (#5353)",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-20T22:50:59Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b59e8dac91b1bde3ac6b9f0e9865ed06059c771d",
"body": "* fix(swap): dispatch SwapKit UTXO signer by chain, not txType\n\nJoining a SwapKit swap sourced from Dogecoin/BitcoinCash/Dash/Zcash and\ninitiated on another client (e.g. the browser extension) failed with\n\"Unsupported SwapKit txType for signing\" or silently signed with the\nwrong signer. SwapKit's wi\n[…]\nch test\n\nCodeRabbit flagged e.message!! as a potential NPE if the exception carries\nno message; use a null-safe assertion instead so a missing message fails\nthe assertion cleanly rather than throwing.",
"is_bot": false,
"headline": "fix(swap): resolve SwapKit UTXO signer by chain, not txType (#5346)",
"author_name": "Roman",
"author_login": "rkokhatskyi",
"committed_at": "2026-07-20T22:44:42Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "ec951cb358101e67afe8a12b48dd8ca4e83323f1",
"body": "* feat(icons): adopt Icons V3 for 29 icons at parity with iOS #4834\n\nSwap 29 UI drawables to their Icons V3 geometry, taken byte-for-byte from\nthe V3 art iOS shipped in #4834 (its imageset SVGs). Because Android resolves\ndrawables by filename through R, each file is edited in place under its\nexistin\n[…]\nfixes the aspect distortion\nwithout changing any rendered icon size.\n\nCo-Authored-By: aminsato <Amin.saradar@yahoo.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(icons): adopt Icons V3 across UI drawables (42 icons) (#5352)",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-20T22:41:10Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "7500e69997e5a14ec446d32b8077f4e504e80f68",
"body": "…#5350)\n\nTwo same-shaped bugs where a per-chain lookup silently returned a wrong\nvalue instead of failing:\n\n- String.getChain() resolved any unknown ticker to ThorChain, so a rename\n upstream could misroute a secured-asset withdrawal. It now throws; the\n DepositFormViewModel catch surfaces a user \n[…]\n and the chain-variable symbol display sites through it, and marked the\n WalletCore accessors as unsafe for display/amount math.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(chain): make Coins the single source for chain identity (#5323) (…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-20T10:28:08Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "fd65ee0144e6b98903626483c86d5dc26f4e4006",
"body": "* feat(solana): sign and broadcast dApp transaction batches\n\nsignAllTransactions/signAndSendAllTransactions batches were hashed and\nsigned in full by the keysign ceremony, but assembly only delivered the\nfirst transaction, so the whole batch died with an opaque Signing Error\nafter the user had alrea\n[…]\nPayload test helper\ninstead of a near-identical solPayload, and add direct coverage for\nSigningHelper.getSignedTransactions' batch-vs-single routing, which was\npreviously only exercised through mocks.",
"is_bot": false,
"headline": "feat(solana): sign and broadcast dApp transaction batches (#5265)",
"author_name": "Roman",
"author_login": "rkokhatskyi",
"committed_at": "2026-07-20T10:22:10Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "dca2b35ab385f416b9b0c3df290e6d5f6a9695bd",
"body": "…(#5349)\n\nXRPL (GemWallet signMessage) custom messages sign SHA-512-half — the\nfirst 32 bytes of SHA-512 — of the message bytes. Android's custom-message\nkeysign had no Ripple branch, so a `chain: Ripple` message fell through to\nkeccak256 and diverged from the initiator's digest, so a Secure-Vault\nA\n[…]\nsetup message and co-signing 404'd.\n\nAdd `toSha512ByteArray()` and a `Chain.Ripple` branch to the digest `when`,\nmirroring the shared contract in vultisig-windows getCustomMessageHex.ts.\n\nCloses #5341",
"is_bot": false,
"headline": "feat(ripple): SHA-512-half digest for XRPL custom-message co-signing …",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-20T10:01:10Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "d67248a4a05e7ec4bb22bd1651b5e63a38a6e974",
"body": "…21) (#5332)\n\n* fix(swap): stop zeroing the SwapKit swap fee on Cardano (#5321)\n\nCardano is classified as TokenStandard.UTXO, so `isSwapKitUtxoSwap` in\nSwapQuotePipeline.buildSuccess treated ADA like a PSBT-broadcast UTXO chain\nand zeroed the displayed swap fee — understating the fee on ADA SwapKit \n[…]\ntValueToString dependency from SwapQuotePipeline.\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): keep SwapKit swap fee zeroed on Cardano, hide the row (#53…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-19T23:27:47Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "1c1f9553e552583756065ae93e7da2fb9249d13f",
"body": "…39) (#5340)\n\nThe swap overview suppressed the \"on <chain>\" indicator on native assets,\nso a native From asset (e.g. BTC) showed no chain while a token To asset\n(e.g. USDC on Ethereum) did — an inconsistent read of the two sides. Gate\nthe indicator on isSwap alone so both rows communicate their chain.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(swap): show chain indicator on both swap-overview token rows (#53…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-19T12:27:14Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "90b361570bde76e749d92502c4792ca1952a3374",
"body": "…(#5338)\n\n* fix(substrate): stop reporting success on a malformed broadcast body (#5320)\n\nA truncated or proxy-mangled author_submitExtrinsic response decodes to\n(null, null) under the production explicitNulls=false config. That null was\nindistinguishable from the intended \"duplicate -> resolve to k\n[…]\n\nCo-Authored-By: aminsato <Amin.saradar@yahoo.com>\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(substrate): stop reporting success on a malformed broadcast body …",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-19T12:19:15Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0cc3bb3ba70c537da6ecbb8576299408f9c28670",
"body": "…ddress) (#5333) (#5336)\n\n* fix: format swap complete screen From/To as VaultName (Address) (#5333)\n\nThe swap Transaction-complete screen rendered From/To as bare\ntruncated addresses, unlike Send/Deposit which already show\nVaultName (Address). Resolve src/dst vault names in KeysignViewModel\nvia the \n[…]\n-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Vaulty-bot <vaulty-bot@vultisig.com>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Swap complete screen: From/To addresses not formatted as VaultName (A…",
"author_name": "Vaulty",
"author_login": "Vaulty-bot",
"committed_at": "2026-07-19T10:24:28Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "486e9f95930fcf7921772e587341cefdf0abf19c",
"body": "…ined devices (#5329) (#5330)\n\n* style: apply ktfmt formatting (#5329)\n\n* fix: resolve CI compile error in SwapTransactionBuilder (#5329)\n\nquote.fees is a TokenValue with no 'token' back-reference, so\nquote.fees.token.{chain.id,contractAddress,decimal} failed to compile.\nThe swap-fee coin context is\n[…]\n-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Vaulty-bot <vaulty-bot@vultisig.com>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Swap overview: Network Fee & Swap Fee differ between initiator and jo…",
"author_name": "Vaulty",
"author_login": "Vaulty-bot",
"committed_at": "2026-07-18T23:48:05Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "296a9ce42bf15f72660e564230c0946fa0da167a",
"body": "* feat(swap): make THORChain secured assets discoverable in swap picker\n\nSecured assets (btc-btc, eth-usdc-..., etc.) were only shown in the\nswap destination picker if the vault already held a balance, since the\nTHORChain token catalog had no secured-asset entries. Populate the\ncatalog from THORChai\n[…]\ne file), which could let a double-tap on two same-ticker rows\nleak a stale selection into a later, unrelated picker visit. Fixed with\na per-visit UUID plus a re-entrancy guard in SelectAssetViewModel.",
"is_bot": false,
"headline": "Make THORChain secured assets discoverable in the swap picker (#5271)",
"author_name": "Roman",
"author_login": "rkokhatskyi",
"committed_at": "2026-07-18T23:37:05Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "38c8f7b29798f0d6678126898598ddd4292f03a1",
"body": "\"Max\" captured the balance and gas fee once at tap time and never\nre-clamped when either moved before submit — a cached balance correcting\ndownward after network hydration, or EVM gas rising. The stale-high\nsnapshot then exceeded what was actually spendable and submit validation\nrejected it as \"insu\n[…]\nive token-balance shortfall to its own error\nstring without the \"with fees\" framing that wrongly implied reserving\ntokens for gas.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(send): re-clamp Max to current balance/fee at submit (#5316) (#5325)",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-18T10:16:15Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "5ce9389124542b847cb481d32a86332792b602cc",
"body": "…314) (#5324)\n\n* fix(keysign): recover DKLS-family signature from relay on failure (#5314)\n\nA DKLS-family keysign device whose local session never reaches\n`isFinished` — e.g. when a final-round relay message is lost to a\ntransport error — would fail with \"signatures empty\" even though the\npeer alrea\n[…]\nresume.\nApplied to all three DKLS-family classes.\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(keysign): recover DKLS-family signature from relay on failure (#5…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-18T09:57:04Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3060455294e4b5461aeb444fed491b546682e286",
"body": "…#5312)\n\n* fix(evm): stop persisting a failed balance read as a real 0 (#5308)\n\nA funded EVM account showed 0/$0.00 after a single transient network\nfailure, and that zero was written to Room over the last-known balance,\nsurviving app restarts until a successful refresh — reading as \"my funds\ndisapp\n[…]\npick.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>\nCo-authored-by: Roman <32820910+rkokhatskyi@users.noreply.github.com>",
"is_bot": false,
"headline": "fix(evm): stop persisting a failed balance read as a real 0 (#5308) (…",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-18T06:28:31Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ebf95647819a2ff7aa6e9c34a4702256bcb9c1d0",
"body": "…ir (#5311)\n\n* fix(swap): drop late quote resolved for a different amount on the same pair\n\napplyQuoteResult's late-result guard only checked isLiveInputQuotable\n(\"is something quotable now\"), never whether the resolved fetch matched\nthe amount now in the field. A fetch queued for an earlier amount \n[…]\n Claude Opus 4.8 <noreply@anthropic.com>\n\n* fix(swap): reject superseded quote results\n\n* fix(swap): bind quotes to routing settings\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(swap): drop late quote resolved for a different amount on same pa…",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-18T00:48:47Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0eeacd873c302de6386e05c108507568e0179283",
"body": "* fix(thorchain): label Unbond confirmation \"Unbonding\" with formatted From/To (#5301)\n\nThe THORChain Unbond \"Function overview\" confirmation mislabeled the action\nas \"You're sending\" and showed the From/To vault address as a raw thor1…\nstring.\n\nThe node-management Unbond flow builds its DepositTran\n[…]\nsolation.\n\nCo-Authored-By: Claude Opus 4.8 <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(thorchain): Unbond confirmation label + formatted From/To (#5306)",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-17T09:13:17Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d630679314bd2d75ebb8cbca8912258d301fa2d4",
"body": "hypurrscan only serves HyperEVM txs under an /evm/tx/ prefix; its bare\n/tx/<hash> path — what the generic explorer path produced — errors with\n\"Unexpected error (code=358)\". Switch the Hyperliquid base to\nhyperevmscan.io, an Etherscan-style explorer whose /tx/ and /address/\npaths resolve through the existing generic cases, fixing both\ntransaction and address links without special-casing.",
"is_bot": false,
"headline": "fix(hyperliquid): point explorer links at hyperevmscan (#5305) (#5307)",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-16T11:49:11Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0eabdd7c45ad556291955fd61910bbc99ce1fe47",
"body": "* fix(swap): stop placeholder skeletons blinking on empty amount\n\nThe destination/fee skeletons flashed true→false on form open and on a\npair/destination change because isLoading was raised unconditionally: the\ninput onEach fired for the empty-field emission, and the slippageBps /\nexternalRecipient \n[…]\n\nCo-Authored-By: aminsato <Amin.saradar@yahoo.com>\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): stop placeholder skeletons blinking on empty amount (#5297)",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-16T11:39:17Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "781cad4ca4d2d648425bf7c443ed8eea05d0ec1d",
"body": "* feat(keysign/ripple): co-sign dApp XRPL transactions (SignRipple)\n\nCarry a dApp-supplied XRPL transaction (via the extension's GemWallet\nprovider) to the Secure Vault co-signer verbatim and sign its raw JSON\nthrough WalletCore's rawJson path, so every device produces byte-identical\nsigning bytes m\n[…]\nd verify_transaction_consent_dapp_transaction across all 10 locales.\n\nCo-Authored-By: aminsato <Amin.saradar@yahoo.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(keysign): co-sign dApp XRPL transactions (SignRipple) #5298 (#5303)",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-16T10:34:38Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "12064887514b316d640f27ca9a03aed639711ff2",
"body": "SEI is EVM-compatible (chainId 1329, secp256k1, 0x addresses, derivation\npath m/44'/60'/0'/0/0). It was mapped to WalletCore's native CoinType.SEI,\nwhose raw derivationPath() is the Cosmos path m/44'/118'/0'/0/0 — papered\nover with compatibleType/compatibleDerivationPath/compatibleChainId\noverrides \n[…]\nvation path consistent across platforms.\n\nAdds SeiEvmCoinTypeTest pinning Chain.Sei -> ETHEREUM, path m/44'/60', and\nchainId 1329.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(sei): map SEI to the Ethereum coin type (#5300)",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-15T12:17:27Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "aa09c08783ece755822803fe09f1a258d9d8b17c",
"body": "…ntil amount entered (#5294) (#5295)\n\n* fix: TRON un/freeze fee loads on entry & Continue gated on amount (#5294)\n\nThe TRON Freeze/Unfreeze screens reuse the shared SendForm. Their gas-fee\npipeline returned early when the amount field was empty, so isGasFeeLoading\nnever cleared — leaving the fee row\n[…]\ny@anthropic.com>\n\n---------\n\nCo-authored-by: Vaulty-bot <vaulty-bot@vultisig.com>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nCo-authored-by: aminsato <amin.saradar@yahoo.com>",
"is_bot": false,
"headline": "TRON Unfreeze/Freeze: Continue disabled & Network Fee stuck loading u…",
"author_name": "Vaulty",
"author_login": "Vaulty-bot",
"committed_at": "2026-07-15T10:19:12Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8b67e7c266fa25c23b5d4625a59151e9828bd47c",
"body": "* feat: add USDC, USDD & stUSDT Tron tokens for desktop parity (#5286)\n\nAdd USDC, USDD and stUSDT TRC-20 tokens to the built-in Tron token\nregistry so they appear in the \"Choose Tokens\" screen with balances,\nUSD prices and logos, matching the desktop token set.\n\n- Add USDC (usd-coin), USDD (usdd) an\n[…]\nn (ios parity)\n\n---------\n\nCo-authored-by: Vaulty-bot <vaulty-bot@vultisig.com>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nCo-authored-by: hailhydra <johnnyluo1980@gmail.com>",
"is_bot": false,
"headline": "Tron: add USDC, USDD & stUSDT tokens (desktop parity) (#5286) (#5287)",
"author_name": "Vaulty",
"author_login": "Vaulty-bot",
"committed_at": "2026-07-15T00:57:43Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d7b262714fe4adce893c1a2b50b77dbbbb55cc91",
"body": "…ating (#5275) (#5284)\n\n* fix(thorchain): auto-discover bRUNE/ybRUNE and correct stale identities\n\nA fresh wallet only ever seeds native RUNE, so getRefreshTokens' enabledDenoms\ngate dropped a newly received bRUNE/ybRUNE bank denom before it could reach the\ncanonicalization block — the tokens only s\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(thorchain): bRUNE/ybRUNE follow-ups — discovery, pricing & swap g…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-14T23:06:17Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3ed662c94bde4fe75ba7d60d7e6e39e5b9c6b872",
"body": "* fix(keysign): friendly message for unfunded Cosmos accounts\n\nA Cosmos SDK code=9 (ErrUnknownAddress) broadcast rejection - the\nfee-payer account has no on-chain presence, e.g. a never-funded QBTC\nvault - fell through to the generic broadcast-rejected copy, which\ninterpolates the node's raw_log ver\n[…]\nrted locales.\n\n* fix(keysign): clarify Dutch \"fund the wallet\" wording\n\n\"Schakel ... in\" reads as \"switch on/enable\", not \"top up\" - switch to\n\"Vul de wallet eerst aan\" per CodeRabbit review on #5292.",
"is_bot": false,
"headline": "fix(keysign): friendly message for unfunded Cosmos accounts (#5292)",
"author_name": "Roman",
"author_login": "rkokhatskyi",
"committed_at": "2026-07-14T22:21:10Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "4ba569f8147b3f206898ac557dcb414e06233422",
"body": "…0 (#5276) (#5288)\n\nRippleApi.getBalance() swallowed every non-cancellation exception into\nBigInteger.ZERO, so a network timeout was indistinguishable from a\ngenuinely empty account and the UI committed a false $0.00 — reading as\n\"the funds disappeared\".\n\nLet the failure propagate: AccountsRepositor\n[…]\nnstead of\nflattening it into an IllegalStateException with no cause, so the\ntransport kind (timeout / no connectivity) survives for classification.\n\nCo-authored-by: hailhydra <johnnyluo1980@gmail.com>",
"is_bot": false,
"headline": "fix(ripple): propagate balance fetch failures instead of showing $0.0…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-14T12:28:57Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "7d6eb0c815c91edeb09e1fb58d7c573439a68f7d",
"body": null,
"is_bot": false,
"headline": "chore: bump version to 1.0.114 (#5289)",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-14T10:29:42Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "90c4fda6fe026833522478c386fb261c7c49bea9",
"body": "…d) (#5277) (#5281)\n\n* fix(ripple): treat expired/unconfirmed XRP tx as neutral, not Error (#5277)\n\nXRPL returns a txnNotFound error response for a tx that never reached a\nvalidating node before its LastLedgerSequence. getTsStatus deserialized\nstrictly into the success shape and threw MissingFieldEx\n[…]\n-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Vaulty-bot <vaulty-bot@vultisig.com>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "XRP send shows 'Error' when tx expired/never confirmed (no funds move…",
"author_name": "Vaulty",
"author_login": "Vaulty-bot",
"committed_at": "2026-07-14T10:06:32Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "335682e4633bb1b58181a3d45a552e427d921769",
"body": "…(#5280)\n\nWhen the OS reclaims the process, tapping a keysign push notification\ncold-starts MainActivity and replays the full branded AnimatedSplash\nbefore the keysign flow appears, so the cold path looks like the app\nrestarting from scratch — unlike the warm onNewIntent path which shows\nno splash.\n\n[…]\n destination resolves\n(isLoading) rather than starting on the stale Route.Home default, then\nroute straight into the keysign flow.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(keysign): skip branded splash on notification cold start (#5269) …",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-14T09:56:57Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0ec13342c1c4e34ebad3a9c7e871cc3d9fc307b7",
"body": "…rongly shows \"Add to Address Book\" (#5272) (#5278)\n\n* fix(keysign): resolve To-address to vault name via pubkey-derived address on joined devices (#5272)\n\nThe To field resolved dstVaultName by matching the destination only against\neach vault's enabled coins. On a joined co-signer the destination co\n[…]\n-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Vaulty-bot <vaulty-bot@vultisig.com>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Joined device doesn't resolve To-address to saved vault/contact and w…",
"author_name": "Vaulty",
"author_login": "Vaulty-bot",
"committed_at": "2026-07-14T09:53:25Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "451bedbc54b367965fd86672f0ad775c60319965",
"body": "…e fee is ready (#5270) (#5273)\n\n* style: apply ktfmt formatting (#5270)\n\n* fix: re-arm gas-fee loading state on recomputes (#5270)\n\nisGasFeeLoading was only ever set false, so the shimmer + disabled\nContinue happened only on the first estimate. Add collectGasFeeLoading()\nto set it back to true when\n[…]\n-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Vaulty-bot <vaulty-bot@vultisig.com>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Send: Network Fee shows nothing while loading; Continue enabled befor…",
"author_name": "Vaulty",
"author_login": "Vaulty-bot",
"committed_at": "2026-07-14T09:50:17Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3e4ad01e6d5df798f73eb51f048b016af913f25b",
"body": "…(#5283)\n\n* fix(tron): operation-aware Verify header for freeze/unfreeze (#5274)\n\nTRON freeze/unfreeze routes through the Send form and carries its\noperation only as an internal memo prefix (FREEZE:/UNFREEZE:<resource>).\nBy the Verify layer no operation signal survived, so the last\npre-signing check\n[…]\n\nCo-Authored-By: aminsato <Amin.saradar@yahoo.com>\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): operation-aware Verify header for freeze/unfreeze (#5274) …",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-14T09:42:25Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0c9e64e9bf7feb126274877ae89bc3410053dc70",
"body": "…success (#5266)\n\n* fix(broadcast): on-chain verify Cosmos/QBTC code-32 before reporting success\n\nThe joined-device duplicate-broadcast recovery trusted a Cosmos code=32\n(account sequence mismatch) blindly and returned the local hash as success —\nso a sequence consumed by an unrelated tx surfaced a \n[…]\nunded / Failed; only Pending / NotFound / TimedOut propagate the rejection.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(broadcast): on-chain verify Cosmos/QBTC code-32 before reporting …",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-13T22:23:38Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "965aebc72b70d6948fd2d393fa9121c9f2f61f90",
"body": "…g (#5267)\n\n* fix(cardano): emit Conway-era 4-element tx envelope with is_valid flag\n\nWalletCore's compileWithSignatures emits the legacy 3-element Cardano\nenvelope [body, witness_set, aux_data]. Conway-era nodes reject it and\nrequire the 4-element form [body, witness_set, is_valid, aux_data].\n\nSpli\n[…]\n SwapKitCardanoSigner's walker. Also\nhardens extractCardanoTransactionBody.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(cardano): emit Conway-era 4-element tx envelope with is_valid fla…",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-13T22:23:23Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c1bb9b50ce92502b5eb39741f295b8bec28d281f",
"body": "…(#5264)\n\n* fix(thorchain): treat bRUNE as an LP token so it's excluded from asset pickers\n\nThe `isLpToken` equality check for `x/brune` sat under the `Chain.MayaChain`\nbranch, but `x/brune` is a THORChain bank denom — so the check was unreachable\nand bRUNE was never filtered out of the swap/asset-s\n[…]\n\nCo-Authored-By: aminsato <Amin.saradar@yahoo.com>\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(thorchain): add bRUNE & ybRUNE (display, pricing, LP exclusion) …",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-13T11:07:43Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "72ae8b96314145462b1b1b5be373c03b593352a5",
"body": "…246)\n\n* fix(solana): sign dApp raw transactions over their original bytes\n\nCo-signing a dApp-supplied raw Solana transaction decoded it into\nWalletCore's representation and re-serialized it before hashing and\nsigning. That re-encode is not guaranteed to reproduce the original\nbytes for a v0 message\n[…]\nature-count decode into a small\ndocumented helper so parseRawTransaction reads as pure structure, and\nreplace the magic 64 with a named SIGNATURE_LENGTH constant that also\nguards the signature splice.",
"is_bot": false,
"headline": "fix(solana): sign dApp raw transactions over their original bytes (#5…",
"author_name": "Roman",
"author_login": "rkokhatskyi",
"committed_at": "2026-07-12T22:49:44Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "2f0e6368089a8786f18d20d972e338a9a5f3fb31",
"body": "* feat(solana): staking foundation + validator-metadata seam (Phases 1-2 of #5078)\n\nPhase 1 — Foundation: Solana stake-account/validator/epoch models, staking\nconfig, and RPC + caching read layer (getVoteAccounts / getProgramAccounts /\ngetEpochInfo / getMinimumBalanceForRentExemption). No UI, no sig\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(solana): native staking on the DeFi tab (epic #5078) (#5239)",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-12T22:37:57Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0d7c97c7af4d9bcefcd4df598e36a2fb1723ede4",
"body": "… RequireDest gate) (#5247)\n\n* feat(ripple): dedicated XRP Destination Tag field (+ X-addr autofill, RequireDest gate)\n\nAdds first-class XRPL destination-tag support to the XRP send flow, mirroring\nthe iOS combo design (vultisig-ios#4749).\n\n- Sync commondata submodule to include RippleSpecific.desti\n[…]\nwe\n intentionally keep it as free text rather than claim exact iOS parity.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(ripple): dedicated XRP Destination Tag field (+ X-addr autofill,…",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-12T09:57:59Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c2f0b5073e45ec28dc5382a801ef4b9f77c3e22d",
"body": "…wn Confirmed (#5263)\n\nEvery TON send is signed with IGNORE_ACTION_PHASE_ERRORS, so a transfer that\ncan't be paid for (e.g. value+fees exceed balance under PAY_FEES_SEPARATELY) is\nsilently skipped instead of aborting: the wallet tx lands un-aborted with the\nseqno consumed but no funds moved. TonStat\n[…]\ng-sdk#1119).\n\nCovered by 13 unit tests, including the exact aborted:false + no_funds:true case\nand a verbatim production toncenter payload decoded through the real\nserialization pipeline.\n\nFixes #5249",
"is_bot": false,
"headline": "fix(ton): detect action-phase failures so failed transfers aren't sho…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-12T09:26:51Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "b8c8d71487537e4563d7015f13562c5b4cd6a98d",
"body": "* fix(deposit): remove duplicate Amount row on Function overview (#5216)\n\nThe amount is already shown in the \"You're sending\" header\n(SwapToken) at the top of the summary card. The separate \"Amount\"\nrow below repeated the same value, adding redundant visual noise.\n\nRemove the row and the now-unused \n[…]\nmissal is\npreserved, and the opt-in stays scoped to this one screen.\n\nCo-Authored-By: aminsato <Amin.saradar@yahoo.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(reshare): adopt new Figma reshare-flow entry (#5175) (#5222)",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-12T09:23:41Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "04170b107747ea384ef531b8719483a54110a47c",
"body": "Base's provider-table arm has offered only LIFI/THORCHAIN/SWAPKIT since\nthe table was created (#4313), while iOS and the SDK both quote 1inch and\nKyberSwap on Base. Both are same-chain aggregators (sameChainOnly), so the\narm now matches the BSC/Avalanche EVM pattern via the shared\nthorchainPlusEvmAggregators / evmAggregators sets.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(swap): enable 1inch and KyberSwap on Base (#5255, #5256) (#5259)",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-12T08:47:02Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "507cba016837e5ce2f13f6c2c1a89c3944257d7d",
"body": "…5261)\n\n* fix(thorchain): read on-chain sRUJI receipt for Staked RUJI amount (#5258)\n\nThe DeFi Staked RUJI amount was read from the Rujira GraphQL `bonded`\nfield, which returns 0 even when the vault holds x/staking-x/ruji receipt\ntokens on-chain — so real positions showed 0. Two root causes:\n\n- `sta\n[…]\n\nCo-Authored-By: aminsato <Amin.saradar@yahoo.com>\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(thorchain): read on-chain sRUJI receipt for Staked RUJI amount (#…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-12T08:16:22Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a00400372a68114a382563ed7a64325224338591",
"body": "…ing (#5260) (#5262)\n\nCo-authored-by: Vaulty-bot <vaulty-bot@vultisig.com>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: add horizontal padding to I understand button on Backups onboard…",
"author_name": "Vaulty",
"author_login": "Vaulty-bot",
"committed_at": "2026-07-12T07:35:41Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "3e878b29321701825efa4e9d64f0307e8014612e",
"body": "…#5257)\n\n* fix(ton): apply wallet-level bounceable to every TonConnect message\n\nMulti-message TonConnect swaps (e.g. STON.fi) never finished co-signing:\nthe joiner polled GET /router/setup-message forever (404). In DKLS keysign\nthe setup message is keyed by md5(pre-image-hash), so a co-signer that\nc\n[…]\nce flag for pool comments to match the initiator.\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(ton): apply wallet-level bounceable to every TonConnect message (…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-12T06:42:13Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "7020dcc4e6d5d460ada4f67f6148b2bb91b9c7ee",
"body": "…s success (#5254)\n\n* fix(broadcast): verify tx on-chain before reporting dedup rejections as success\n\nThe per-chain broadcast dedup heuristics accepted string evidence without an\non-chain check, so genuine rejections surfaced as success (issue #5250):\n\n- EVM: drop the bare \"known\" match (also match\n[…]\nccess\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>\nCo-authored-by: Roman <32820910+rkokhatskyi@users.noreply.github.com>",
"is_bot": false,
"headline": "fix(broadcast): verify tx on-chain before treating dedup rejections a…",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-12T06:27:51Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "114c81e0f33019c2e2e1a629398d0d2cb144e9ed",
"body": "…253)\n\nRippleStatusProvider marked a tx Confirmed on RPC-level status==\"success\",\nwhich for the XRPL `tx` method only means the tx was found. That reported\nvalidated tec* failures (fee burned, no funds delivered) as Confirmed, and\nmade not-yet-validated txs terminally Confirmed even if later dropped\n[…]\n AND meta.TransactionResult==\"tesSUCCESS\";\ntec* -> Failed(code); unvalidated or meta-absent -> keep polling. Mirrors the\nSolana finalized gate.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(ripple): gate Confirmed on validated + meta.TransactionResult (#5…",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-10T22:14:34Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ccfa1fd7f81c07a6bfc68d4c0668a0554f49b5fa",
"body": "getTokenAssociatedAccountByOwner made a single getTokenAccountsByOwner call\nand treated an empty or failed response as \"no token account\". Right after an\nATA is created the indexer can lag, which gave the sender a false \"missing\ntoken account\" error and made the recipient path try to recreate an ATA\n[…]\ned-token addresses and confirm existence with a direct getAccountInfo\nlookup before concluding the account is missing. A normal successful lookup is\nunchanged. Mirrors iOS SolanaService.\n\nCloses #5224",
"is_bot": false,
"headline": "fix(solana): fall back to ATA derivation when the indexer lags (#5245)",
"author_name": "Roman",
"author_login": "rkokhatskyi",
"committed_at": "2026-07-09T23:06:52Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "5366edb53509182ca1b66524d87778e0f623f432",
"body": "The inbound keysign payload mapper parsed the Solana `compute_limit`\nfield with a throwing `toBigInteger()`, so a peer sending a non-numeric\nstring crashed the receiving device with an uncaught NumberFormatException\nduring a keysign ceremony. The sibling `priority_fee` field already fails\nsoft; mirror it with `toBigIntegerOrNull()` so malformed input falls back\nto the default compute-unit limit. Valid values, including an explicit 0,\nare parsed unchanged.",
"is_bot": false,
"headline": "fix(solana): fail soft on malformed inbound compute_limit (#5244)",
"author_name": "Roman",
"author_login": "rkokhatskyi",
"committed_at": "2026-07-09T23:03:48Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "06f9c23244d61a17a263fa2d6145d2075683e911",
"body": "* feat(keysign): animate signing → broadcast → result transitions\n\nThe broadcast flow advanced between states with hard screen cuts. Wrap the\ntwo render seams in Compose transitions so it reads as one screen updating\nin place:\n\n- KeysignView: AnimatedContent over a coarse phase key (progress/finishe\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(keysign): animate signing → broadcast → result transitions (#5232)",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-09T10:47:51Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "bd850632851dabf8a1cde9c49a819e0c84127518",
"body": "The Verify/Send overview screen rendered the Memo row whenever tx.memo\nwas non-null, so an empty-string memo produced a blank Memo label with\nno value, wasting vertical space in the summary card.\n\nGuard the row with isNullOrBlank() so it only appears when a memo is\nactually present. Also adds a PreviewActivity entry (verify_send_empty_memo)\ncovering the empty-memo case.\n\nFixes #5234\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(send): hide Memo row on Send overview when memo is blank (#5243)",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-09T09:43:30Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "301920c80ef1aaea210ef129ca019ddbadca0bd6",
"body": "… (#5240)\n\nThe custom-message keysign path (SigningHelper.getKeysignMessages) keccak256'd\nthe message for every non-EdDSA chain. But cosmos-family chains (THORChain,\nMaya, Cosmos, ...) sign the sha256 of the message — Keplr ADR-36 signArbitrary\nover the StdSignDoc bytes — so Android's digest, and th\n[…]\n> raw, everything else (EVM, Tron) -> keccak256.\n\nAdds ByteArray.toSha256ByteArray() and unit tests covering the cosmos sha256 path.\n\nCo-authored-by: ahdzib-maya <ahdzib-maya@users.noreply.github.com>",
"is_bot": false,
"headline": "fix(keysign): sha256-hash cosmos custom messages instead of keccak256…",
"author_name": "Itzamna",
"author_login": "ahdzib-maya",
"committed_at": "2026-07-09T02:00:43Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "8ef5ce9921beb418fd78deca35576513e4105f7a",
"body": "…5233)\n\nSolanaStatusProvider treated a non-null err as an immediately terminal\nFailed result regardless of confirmation level. Roughly 5% of Solana\nblocks at processed/confirmed never finalize (they can be forked out\nand re-included with a different outcome), so a transient err observed\nat that earl\n[…]\ntrictly\ninside the finalized case.\n\nRestructure the dispatch so err is only consulted once confirmationStatus\nis finalized; confirmed/processed/null all report Pending regardless of\nerr, matching iOS.",
"is_bot": false,
"headline": "fix(solana): gate tx-status err check to finalized commitment only (#…",
"author_name": "Roman",
"author_login": "rkokhatskyi",
"committed_at": "2026-07-09T01:39:17Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "b31f74066b05bc15e7b01657c91ec75e49bd8030",
"body": "The Cosmos bank endpoint returns every denom for an address in one\nresponse, but the balance layer calls it once per token — each picking a\nsingle denom and discarding the rest — so opening the Select asset sheet\nfired ~N identical GET /cosmos/bank/v1beta1/balances/{address} requests.\n\nAdd a shared \n[…]\ntrip whether the\ncalls arrive concurrently or back-to-back. getBalance is only used for\nbalance display and token discovery — never the signing/fee path — so a\nshort cache carries no correctness risk.",
"is_bot": false,
"headline": "fix(cosmos): coalesce per-token bank-balance requests (#5161) (#5230)",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-09T00:17:49Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "86fa0e9ebd9872d92c54a2cefb0dae778a6919aa",
"body": "…string (#5229)\n\n* fix(solana): throw on blockhash RPC error instead of returning empty string\n\ngetRecentBlockHash logged a JSON-RPC error response and returned \"\" instead\nof throwing, unlike the adjacent malformed/missing-result branch a few lines\nbelow it, which already throws. The empty string th\n[…]\nerror: ...\" reads\nas an internal detail rather than something a user should see. Reword to\nmatch the plain \"<Chain> RPC error: <message>\" idiom used elsewhere in the\napi package (DashApi, CardanoApi).",
"is_bot": false,
"headline": "fix(solana): throw on blockhash RPC error instead of returning empty …",
"author_name": "Roman",
"author_login": "rkokhatskyi",
"committed_at": "2026-07-08T10:56:02Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "94412cd269ad9d853428629cd4413e4d488c74ae",
"body": "…200)\n\n* fix(thorchain): unbond MAX/percentage use bonded amount, not wallet balance\n\nThe THORChain unbond form reused the generic Send form with the wallet's\nspendable RUNE account, so MAX/percentage and the submit-time balance check\noperated on the wallet balance (max bondable) instead of the amou\n[…]\nnthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nCo-authored-by: Vaulty-bot <vaulty-bot@vultisig.com>\nCo-authored-by: Johnny Luo <johnnyluo1980@gmail.com>",
"is_bot": false,
"headline": "fix(thorchain): unbond MAX uses bonded amount, not wallet balance (#5…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-08T10:21:11Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "bb90193467e3b8f681a5308444f1c703a8914033",
"body": "* fix(deposit): remove duplicate Amount row on Function overview (#5216)\n\nThe amount is already shown in the \"You're sending\" header\n(SwapToken) at the top of the summary card. The separate \"Amount\"\nrow below repeated the same value, adding redundant visual noise.\n\nRemove the row and the now-unused \n[…]\n\nCo-Authored-By: aminsato <Amin.saradar@yahoo.com>\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(deposit): remove duplicate Amount row on Function overview (#5221)",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-08T09:39:22Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "60163b4297db26d6ab73393b61884c89604e5889",
"body": "…y matches signed fee (#5218)\n\n* fix(terraClassic): price send fee at the effective gas limit so Verify matches the signed fee\n\nPorts vultisig-ios#4762. TerraClassicTax.baseGas already prices the base at\nthe (effective) gas limit up front, so chainSpecific.gas is the final fee.\nDrop the redundant sc\n[…]\n\n\n* docs(keysign): update stale fee-helper KDoc for Cardano/Cosmos branches\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(terraClassic): price send fee at the effective gas limit so Verif…",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-08T09:39:03Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3e90f123652a3a499de6948921d9c905240ad831",
"body": "…#5220)\n\nReplace the bespoke Scaffold + VsTopAppBar + ad-hoc 16dp padding with the\nstandard V3Scaffold so the screen matches the app-wide V3 content inset\n(24dp horizontal / 12dp vertical), topbar, and background. The bottom CTA\npadding now references the V3Scaffold companion constants.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(referral): migrate Create Referral screen to V3Scaffold (#5219) (…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-08T00:36:17Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "746b311913a47c8055c9d987c92f09bca5ca813c",
"body": "…08) (#5215)\n\nRippleApi.getBalance already returns the owner-aware, reserve-net balance\n(base + OwnerCount * increment reserves subtracted live from server_state),\nso the account tokenValue reaching ChainValidationService.checkIsReapable is\nalready net of the true on-chain reserve.\n\ncheckIsReapable \n[…]\nales\nand cover the XRP MAX / reserve-band cases in ChainValidationServiceTest.\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(ripple): stop double-counting XRP reserve in reaping warning (#52…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-08T00:15:34Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "862b755961be81e0b1a1f556adc79d6c88ab9e58",
"body": "…86) (#5214)\n\n* fix(send): reject hex/scientific-notation amounts before signing (#5186)\n\nThe send amount field's InputTransformation blocks non-decimal characters\nfrom IME and paste, but a `vultisig://send?...&amount=1e5` deeplink writes\nthe amount into the field programmatically via setTextAndPlac\n[…]\n\nCo-Authored-By: aminsato <Amin.saradar@yahoo.com>\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(send): reject hex/scientific-notation amounts before signing (#51…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-07T10:07:31Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "10b963c770a34bfaf43407180b296f813d5d0c1f",
"body": "…5213)\n\nThe coin badge used width()/height(), which the header card's fixed\n118dp height clamped down — so the badge rendered small and fully\ncontained instead of the large, edge-bleeding badge in the Figma spec.\n\nSwitch to requiredWidth/requiredHeight so the drawable keeps its\nintended 200.78×206 size and its concentric gold ring bleeds past the\ncard edge (clipped by the card's rounded shape), matching the design.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(qbtc): size Claimable QBTC header badge to match Figma (#5072) (#…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-07T10:04:44Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "fc1af83ef408b7fe53036027162117ad2953080c",
"body": "* feat(cosmos): honor relayed CosmosSpecific.gas_limit in the SignDoc (#5112)\n\nReads the relayed per-tx gas limit (commondata CosmosSpecific.gas_limit, field\n7) and uses it as the signed fee gas limit when an initiator sets one, falling\nback to the static per-chain limit otherwise. The value is part\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): honor relayed CosmosSpecific.gas_limit (#5112) (#5191)",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-07T09:21:26Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "1d3ee3c18a72433591e6ed87b0929b9f699c6c56",
"body": "…never detected (#5162) (#5192)\n\n* fix(swap): resolve Omniston (TON) swap settlement on-chain (#5162)\n\nA same-chain TON swap routed through Omniston deposits the source jettons\ninto an escrow; SwapKit's /track only sees the deposit leg and reports\n`completed` with `fromAsset == toAsset`, so the app \n[…]\n-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Vaulty-bot <vaulty-bot@vultisig.com>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Omniston (TON) swap shown as successful when escrow refunds — refund …",
"author_name": "Vaulty",
"author_login": "Vaulty-bot",
"committed_at": "2026-07-07T05:18:22Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e37765f490582c96659c6f49ddd815c1de9a345e",
"body": "* feat(ton): gate TON DeFi staking and remove generic-deposit stake path\n\nTON staking now lives exclusively on the DeFi tab. Add Chain.Ton to the\nDeFi-supported / crypto-connection sets, and drop it from isDepositSupported +\nthe generic deposit option list so Stake/Unstake no longer surface in the\nF\n[…]\n\n* style: rewrap comment in TonDeFiBalanceService\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(ton): TON nominator-pool staking on the DeFi tab (#5041) (#5133)",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-07T01:56:38Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a5ab0f4e870d6f5c915c508f2f5c00ac73a7e8e7",
"body": "…ast failure (#5207)\n\nXRPL echoes the deterministic tx_json.hash back regardless of engine result.\nPreviously a rejected submit returned the engine message as a fake txid, so the\nkeysign persisted a garbage hash instead of surfacing the failure.\n\nPort the iOS RippleService classification into Ripple\n[…]\nef*) throws a typed\n RippleBroadcastException carrying the engine code + message.\n- broadcastTransaction does HTTP in a try (rewrapping non-broadcast errors),\n then classifies the result outside it.",
"is_bot": false,
"headline": "fix(ripple): stop returning the error string as the tx hash on broadc…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-07T01:56:08Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "45f9d14523fca22d9bf60f5c2589581bcee6fc79",
"body": "The swap \"Transaction pending\" done screen renders the Track button only\nwhen getSwapProgressLink() returns a non-blank URL. For EVM/Solana swaps\nthat link was gated behind the affiliate swapFee parsing as a BigInteger,\nbut EVMSwapQuoteJson.swapFee defaults to \"\" and \"\".toBigIntegerOrNull()\nis null.\n[…]\n the link\nfrom the src chain + tx hash (both always present for a broadcast swap).\nSwapKit-routed swaps are unaffected: they return earlier from the\ntrack.swapkit.dev branch before reaching this code.",
"is_bot": false,
"headline": "fix(swap): decouple Track link from parseable swapFee (#5206)",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-07T01:20:49Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "3d78bb3044505c73e8d4f7e747fa0284ffa8727e",
"body": "…s (#5204)\n\nThe foreground \"Join transaction\" banner popped in with no entrance\nanimation whenever a new signing request arrived. `key(qrCodeData)`\ndisposes and recreates the overlay AnimatedVisibility on each new\nrequest, so the node is born with `visible == true` and the\n`visible: Boolean` overloa\n[…]\nthe reserved-space expand) run on the freshly keyed node.\nThe key(qrCodeData) is kept, preserving the swipe-offset reset behavior.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(banner): restore Join-transaction banner slide-in for new request…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-07T01:12:46Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "127213368b9d8c03dcf8e1b2cfa8fc0976ac0bc4",
"body": "…5203)\n\nThe Export Vaults flow could leave the user with a broken 0 KB archive:\na 1-character backup password validated as Valid (only non-empty +\nmatching were checked), and any export failure left the empty file SAF\nhad already created on disk with only a transient, generic snackbar.\n\n- Enforce a \n[…]\nrings for the two new messages across all locales.\n- Add regression tests for length validation and failure cleanup.\n\nCloses #5197\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(backup): validate PIN length and clean up failed vault exports (#…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-06T12:15:02Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "29615c6689450ca20d0a24c4427c4c146b79e4c8",
"body": "…199)\n\nKeysignTxStatusPoller (which binds the running foreground service) and\nKeysignFlowViewModel.complete() (which cancels its notification) each\ninjected their own TransactionStatusServiceManager. Without a shared\nscope, completion cancelled a never-bound instance and the notification\nwas left showing after the transaction settled.",
"is_bot": false,
"headline": "fix(keysign): scope tx-status notification manager as a singleton (#5…",
"author_name": "Roman",
"author_login": "rkokhatskyi",
"committed_at": "2026-07-06T11:06:51Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ae1acc81cd5a37616c5024a60eda124a82a58b64",
"body": "…(#5198)\n\n* fix(tokens): require connectivity and retry on token-refresh failure\n\nToken discovery work now sets a NetworkType.CONNECTED constraint and\nreturns Result.retry() when a chain refresh fails, instead of a\nconstraint-free request that runs offline and either fails permanently\nor silently dr\n[…]\n-tokens read failure path\n\nTokenRefreshWorkerTest only exercised getRefreshTokens() throwing;\nadd a case for vaultRepository.getEnabledTokens() throwing, the other\nretryOrFail() call site in doWork().",
"is_bot": false,
"headline": "fix(tokens): require connectivity and retry on token-refresh failure …",
"author_name": "Roman",
"author_login": "rkokhatskyi",
"committed_at": "2026-07-06T10:57:03Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "4d772b9c4c12336cea76046b2b8c20be5887244b",
"body": "…5195)\n\n#5121 reports the SwapKit EVM verify-screen Network Fee as understated —\ntaken from SwapKit's near-zero `fees[].inbound` placeholder instead of the\noracle-priced broadcast gas, with the same understatement feeding the\ngas-sufficiency check. Tracing the code, that does not hold on Android: a\n\n[…]\nted Fees\" row; Network Fee and Total are the oracle bond.\n\nThis is the Android mirror of the iOS parity test in vultisig-ios#4723.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "test(swap): pin SwapKit EVM network fee to the oracle bond (#5121) (#…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-06T10:29:03Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3338603636f4c159d13f3da5089323a58fc935cf",
"body": "…#5174) (#5190)\n\nLocks the #5115 fix (PR #5156): getFeeForMessage already folds the\nComputeBudget priority fee into the message fee, so the send estimate is\nmessageFee + rentExemption — never messageFee + priority + rent.\n\nThe path was previously untestable because constructing SolanaFeeService\ntrig\n[…]\n native SOL, SPL (with/without recipient token account), and\nthe swap default path's micro-lamports-per-CU to lamports conversion.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "test(solana): guard send fee estimate against priority double-count (…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-06T09:46:56Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c625e621dee75ab4389155d9812601f20b0d97ff",
"body": "Co-authored-by: Vaulty-bot <vaulty-bot@vultisig.com>",
"is_bot": false,
"headline": "style: apply ktfmt formatting (#5187) (#5189)",
"author_name": "Vaulty",
"author_login": "Vaulty-bot",
"committed_at": "2026-07-06T09:38:15Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f5e76e9ca320c12d5af826e04fe8294a47d8fc21",
"body": "…(#5172)\n\n* fix(swap): show refund/failure reason on the transaction done screen (#5152)\n\nWhen a swap is refunded or fails, the app already resolves a human-readable\nreason (e.g. \"deposits are paused for asset (ETH.USDT…)\") and carries it on\nTransactionStatus.Refunded/Failed. The done screen — the e\n[…]\n\nCo-Authored-By: aminsato <Amin.saradar@yahoo.com>\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): show refund/failure reason on the transaction done screen …",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-06T09:17:36Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8c867fa53405720f1e7a1d4f0285adf6c93930af",
"body": null,
"is_bot": false,
"headline": "chore: bump version to 1.0.113 (#5183)",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-06T00:35:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b8bfe1275f39198c6211d564b9c1b5016ed0f2be",
"body": "* fix(qbtc): block claim co-sign when the vault password is empty\n\nNeither the password sheet's Confirm button nor the ViewModel guarded\nagainst a blank password, so the IME \"Go\" action (and, on an unmodified\nbutton, a tap) could reach the server co-sign call with nothing typed.\nDisable Confirm whil\n[…]\na password of only spaces through to the co-sign call.\nSwitch both the ViewModel guard and the sheet's canSubmit check to\nisBlank() so an all-whitespace entry is rejected the same way an empty\none is.",
"is_bot": false,
"headline": "fix(qbtc): block claim co-sign when the vault password is empty (#5182)",
"author_name": "Roman",
"author_login": "rkokhatskyi",
"committed_at": "2026-07-05T23:50:22Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "4d6d587ce3891bed0a056a3108c509730ca7d6b2",
"body": "* fix(send): block XRP/DOT sends that would fall below the chain reserve\n\nMAX and manually-entered near-full sends on Polkadot and XRP could pass\nclient-side validation, run the full MPC signing ceremony, and still get\nrejected on-chain because the existential deposit / account reserve was\nonly ever\n[…]\nunderlying cause. Log it via Timber so a\ntransient RPC failure stays debuggable, matching the BTC-like plan\nerror path in the same file.\n\n---------\n\nCo-authored-by: hailhydra <johnnyluo1980@gmail.com>",
"is_bot": false,
"headline": "fix(send): block XRP/DOT sends below the chain reserve (#5180)",
"author_name": "Roman",
"author_login": "rkokhatskyi",
"committed_at": "2026-07-05T23:35:15Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "45d1173e62e700fb0f333d16d67def0b7706e647",
"body": "* fix(keysign): reach a terminal state on a hashless broadcast\n\nA successful broadcast that yields no tx hash (Broadcasted.txHash is\nnullable; orKnownHash returns null when both the RPC hash and the local\ntx hash are blank) left signingState stuck at the last signing state —\nan infinite spinner with\n[…]\now before the terminal state lands and invite a\n force-retry double-send).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(keysign): reach a terminal state on a hashless broadcast (#5170)",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-05T23:05:48Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3278ed057b55c0b53ca28bd0e367c24d805a03dd",
"body": "…kup (#5177)\n\n* fix(backup): wait for the vault list before writing an all-vaults backup\n\nBackupPasswordViewModel and BackupPasswordRequestViewModel loaded the vault\nlist asynchronously in init but backupAllVaults/backupWithoutPassword read it\nfrom a plain var with no guard, so a backup requested be\n[…]\n performs; poll with coVerify's\n timeout instead of asserting immediately after completing the gate.\n- Switch the new tests from kotlin.test to Kotest assertions per the\n project's test conventions.",
"is_bot": false,
"headline": "fix(backup): wait for the vault list before writing an all-vaults bac…",
"author_name": "Roman",
"author_login": "rkokhatskyi",
"committed_at": "2026-07-05T23:04:51Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "27286e02007c769da33303db85c0ffc96fdcfff5",
"body": "…re 4.7.0) (#5169)\n\n* feat(cardano): attach send memo on-chain as CIP-20 metadata (label 674)\n\nCardano's send memo was previously typed by the user but silently dropped at\nsigning time (the TODO in CardanoHelper). WalletCore 4.7.0 exposes the native\nCardano.SigningInput.auxiliary_data field, so we c\n[…]\neply@anthropic.com>\n\n* clarify memo field is optional in GasFeeOrchestrator\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(cardano): attach send memo on-chain as CIP-20 metadata (WalletCo…",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-05T22:47:50Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "5dec8d9b082c1c5bd004175ef7462fedb2ba0535",
"body": "…s (#5171)\n\n* fix(ripple): populate the canonical transaction hash on signed XRP txs\n\nRippleHelper.getSignedTransaction returned an empty transactionHash,\nunlike every other chain helper. The empty hash left XRP sends\nuntrackable (status polling, explorer deep-links) and also disabled the\nduplicate-\n[…]\ndoc\n\nThe hash prefix is 0x54584E00 (TXN + zero byte), not a trailing space.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(ripple): populate the canonical transaction hash on signed XRP tx…",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-05T11:44:51Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e5f3c966a63ca24e834e56911496b3efff8f41ea",
"body": "WalletCore's `zip_0317` planner sizes an OP_RETURN output at a flat ~34\nbytes and ignores `byteFee`, so ZEC memo transactions (MayaChain-routed\nswaps carry the swap instruction in an OP_RETURN; sends with memo too)\nplan one logical action short — e.g. 15,000 zats where the network\nrequires 20,000. E\n[…]\ne plan-level golden\nvectors mirror iOS against the same wallet-core 4.7.0 pin.\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(zcash): re-plan memo txs to the ZIP-317 conventional fee (#5165)",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-05T01:59:11Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "2980c449b725b2428a2cadc458c1579062306535",
"body": "…ic (#5164)\n\n* feat(terra): support adding custom CW20 tokens on Terra / Terra Classic\n\nLet users add a custom CW20 token by pasting the contract address on\nthe custom-token screen — parity with the extension and iOS (#4733).\nSearchTokenUseCase previously dispatched only EVM / SOL / Kujira, so a\nter\n[…]\nay consistent.\n\nAddresses CodeRabbit review feedback on the PR.\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(terra): support adding custom CW20 tokens on Terra / Terra Class…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-04T23:21:52Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "1d7406ab4d2120c29eea94fcd2e7d334f62ec099",
"body": "… SUI sign (#5168)\n\nPulls in commondata updates:\n- feat(keysign): add CosmosSpecific.gas_limit for relayed dynamic gas\n- feat(tokens): rebrand TON native token to GRAM\n- feat: SUI signing support\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(commondata): bump submodule for cosmos gas_limit, GRAM rebrand,…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-04T22:45:54Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "685be91ce729b8db10b176ae3f977c445784f9ab",
"body": "…5160)\n\nTHORChain's only Cosmos Hub pool is native ATOM, but the provider table\noffered THORCHAIN for every GaiaChain coin. Selecting an IBC token like\nrKUJI as the destination sent `GAIA.rKUJI-ibc/...` to Thornode, which\ndeterministically 400s with \"bad to asset: invalid symbol\" — surfaced as\nthe m\n[…]\napError, so any\n remaining path that reaches the node reports the route as unsupported\n rather than suggesting an amount change.\n\nCloses #5113\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(swap): stop offering unroutable Cosmos IBC tokens on THORChain (#…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-04T10:23:01Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "65b6c2bf05caca005edd8f86cb5cf93651bb46c9",
"body": "…ly fails (#5158)\n\n* fix(keysign): stop joined device faking a txid when broadcast genuinely fails\n\nrecoverJoinedDeviceBroadcast swallowed every non-cancellation exception on a\njoined (co-signing) device and returned the locally computed hash, showing a\nsuccess screen + explorer link for a transacti\n[…]\ns; never recover for the initiator or a blank hash;\npropagate cancellation.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(keysign): stop joined device faking a txid when broadcast genuine…",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-04T10:14:44Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "fddab24a709420048e621a147ab0d57c50618b21",
"body": "The \"enable post-quantum key\" (Dilithium/MLDSA keygen) option in advanced\nvault settings was shown for GG20 vaults, but a GG20 vault can't run the\nDKLS-based keygen — it must migrate to DKLS first. The option was gated on\n`libType != KeyImport`, which let GG20 through.\n\nGate it on `libType == DKLS` \n[…]\nt import, and GG20 vaults are now excluded. Since the settings screen\nfilters out `isEnabled = false` items, the row is hidden for GG20 vaults.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(settings): hide post-quantum keygen for legacy GG20 vaults (#5157)",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-04T01:00:33Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "7723ed5208ebb06c1bb760912e4bb8ddf53c3030",
"body": "* feat(qbtc): add \"New quantum security\" intro screen before claim (#5074)\n\nIntroduces the onboarding/explainer screen that precedes the QBTC claim\nflow. The hero area plays the quantum_key_pair Rive animation inside a\ndashed frame, followed by three explainer rows (generate key pair, link\nto vault,\n[…]\naim routing, dilithium\nkeygen enablement, and intro navigation.\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(qbtc): \"New quantum security\" intro screen before claim (#5123)",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-03T09:47:02Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3bddbc03114f3c9d94fea04d42fab557cbc3bdfc",
"body": "…#5156)\n\ngetFeeForMessage already includes the prioritization fee, because the\nserialized message carries the ComputeBudget (SetComputeUnitPrice /\nSetComputeUnitLimit) instructions. calculateFees then added a second\npriority term on top, so the displayed SOL network fee was\nbase + 2x priority + rent\n[…]\nbase + 100000 priority at the 1,000,000 uLam/CU floor).\n\nTake the RPC message fee as the full base+priority and only add\nrent-exemption on top.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(solana): stop double-counting priority fee in send fee estimate (…",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-03T09:22:29Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "6ac25725603872d1bd62fd8502dd01fc52f48675",
"body": "…ing parity (#5154)",
"is_bot": false,
"headline": "chore(deps): bump wallet-core 4.6.13 -> 4.7.0 for cross-platform sign…",
"author_name": "paaao",
"author_login": "realpaaao",
"committed_at": "2026-07-03T07:53:43Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7fead7ab650673fc3949b9e5acfb52d469e0d673",
"body": "Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: bump version to 1.0.112 (#5153)",
"author_name": "hailhydra",
"author_login": "johnnyluo",
"committed_at": "2026-07-03T01:19:12Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "d3f2d2d1b352483408181ff56c3fe4347f9f557e",
"body": "…top it covering home content (#5134) (#5144)\n\nThe \"Join transaction\" foreground banner had two blocking-popup UX flaws:\n\n- Dismissal was wired to horizontal drag only, so the natural swipe-up\n did nothing and the banner read as non-dismissable. Switch to\n detectDragGestures and accept an upward f\n[…]\npushed down while the banner is\n shown; the overlay itself is unchanged, preserving its status-bar bleed\n and rounded-corner gradient reveal.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(keysign): make Join-transaction banner swipe-up dismissable and s…",
"author_name": "Amin",
"author_login": "aminsato",
"committed_at": "2026-07-02T23:02:16Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "90d5e5f96865e8ac3d61bd76b74b4e281e19017e",
"body": "…ching master (#5138) (#5139)\n\n* style: apply ktfmt formatting (#5138)\n\n* fix: revert out-of-scope comment reformat in JupiterSwapQuoteJson (#5138)\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n* style: apply ktfmt formatting (#5138)\n\n* fix: canonicalize TON addresses before\n[…]\n-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Vaulty-bot <vaulty-bot@vultisig.com>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "TON: wrong jetton balance shown first jetton wallet taken without mat…",
"author_name": "Vaulty",
"author_login": "Vaulty-bot",
"committed_at": "2026-07-02T11:55:08Z",
"body_truncated": true,
"is_coding_agent": true
}
],
"releases_count": 100,
"commits_last_year": 1412,
"latest_release_at": "2026-07-14T10:27:19Z",
"latest_release_tag": "v1.0.114",
"releases_from_tags": false,
"days_since_last_push": 0,
"active_weeks_last_year": 52,
"days_since_latest_release": 7,
"mean_days_between_releases": 4.5
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": false,
"health_percentage": 50,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": true
},
"ecosystem": {
"packages": []
},
"popularity": {
"forks": 16,
"stars": 21,
"watchers": 2,
"fork_history": {
"days": [
{
"date": "2024-05-22",
"count": 1
},
{
"date": "2024-06-12",
"count": 1
},
{
"date": "2025-02-05",
"count": 1
},
{
"date": "2025-02-09",
"count": 1
},
{
"date": "2025-03-09",
"count": 1
},
{
"date": "2025-12-17",
"count": 1
},
{
"date": "2026-01-21",
"count": 1
},
{
"date": "2026-03-05",
"count": 1
},
{
"date": "2026-03-16",
"count": 1
},
{
"date": "2026-03-26",
"count": 1
},
{
"date": "2026-04-02",
"count": 1
},
{
"date": "2026-04-27",
"count": 1
},
{
"date": "2026-05-05",
"count": 2
},
{
"date": "2026-07-08",
"count": 1
},
{
"date": "2026-07-20",
"count": 1
}
],
"complete": true,
"collected": 16,
"total_forks": 16
},
"star_history": {
"days": [
{
"date": "2024-04-22",
"count": 1
},
{
"date": "2024-05-25",
"count": 1
},
{
"date": "2024-05-28",
"count": 1
},
{
"date": "2024-06-15",
"count": 1
},
{
"date": "2024-08-12",
"count": 1
},
{
"date": "2024-09-02",
"count": 1
},
{
"date": "2024-11-24",
"count": 1
},
{
"date": "2025-04-21",
"count": 1
},
{
"date": "2025-06-21",
"count": 1
},
{
"date": "2025-07-11",
"count": 1
},
{
"date": "2025-10-14",
"count": 1
},
{
"date": "2025-12-08",
"count": 1
},
{
"date": "2026-01-19",
"count": 1
},
{
"date": "2026-01-30",
"count": 1
},
{
"date": "2026-04-21",
"count": 1
},
{
"date": "2026-05-01",
"count": 1
},
{
"date": "2026-05-07",
"count": 1
},
{
"date": "2026-05-11",
"count": 1
},
{
"date": "2026-05-14",
"count": 1
},
{
"date": "2026-05-28",
"count": 1
},
{
"date": "2026-07-20",
"count": 1
}
],
"complete": true,
"collected": 21,
"total_stars": 21
},
"open_issues_and_prs": 28
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [],
"has_llms_txt": false,
"has_dockerfile": false,
"has_mcp_signal": false,
"bootstrap_files": [],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [],
"toolchain_manifests": [
"app/build.gradle.kts",
"build.gradle.kts",
"data/build.gradle.kts"
],
"largest_source_bytes": 154512,
"source_files_sampled": 1718,
"oversized_source_files": 8,
"agent_instruction_files": [
"AGENTS.md",
"CLAUDE.md"
],
"agent_instruction_max_bytes": 19254
},
"dependencies": {
"manifests": [
"Gemfile",
"app/build.gradle.kts",
"build.gradle.kts",
"data/build.gradle.kts"
],
"advisories": {
"error": null,
"scope": "repository_graph",
"source": "osv",
"findings": [
{
"name": "faraday",
"direct": false,
"version": "1.10.5",
"severity": "high",
"ecosystem": "rubygems",
"cvss_score": 7.5,
"advisory_ids": [
"GHSA-98m9-hrrm-r99r"
],
"fixed_version": "2.14.3",
"advisory_count": 1,
"oldest_advisory_days": 32
},
{
"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": 2,
"moderate": 1
},
"advisory_count": 3,
"affected_count": 3,
"assessed_count": 95,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 0,
"direct_affected_count": 0
},
"ecosystems": [
"maven",
"rubygems"
],
"dependencies": [
{
"name": "fastlane",
"manifest": "Gemfile",
"ecosystem": "rubygems",
"version_constraint": "2.229.1"
},
{
"name": "ostruct",
"manifest": "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": "abbrev",
"direct": false,
"version": "0.1.2",
"ecosystem": "rubygems"
},
{
"name": "addressable",
"direct": false,
"version": "2.9.0",
"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.1201.0",
"ecosystem": "rubygems"
},
{
"name": "aws-sdk-core",
"direct": false,
"version": "3.241.2",
"ecosystem": "rubygems"
},
{
"name": "aws-sdk-kms",
"direct": false,
"version": "1.119.0",
"ecosystem": "rubygems"
},
{
"name": "aws-sdk-s3",
"direct": false,
"version": "1.210.1",
"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.10.5",
"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-multipart",
"direct": false,
"version": "1.2.0",
"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-retry",
"direct": false,
"version": "1.0.4",
"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.19.2",
"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.5",
"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": 95,
"direct_count": 2,
"indirect_count": 93
}
},
"maintainership": {
"issues": {
"open_prs": 4,
"merged_prs": 2630,
"open_issues": 24,
"closed_ratio": 0.991,
"closed_issues": 2537,
"closed_unmerged_prs": 155
},
"bus_factor": 2,
"bot_contributors": 1,
"top_contributors": [
{
"type": "User",
"login": "aminsato",
"commits": 1098,
"avatar_url": "https://avatars.githubusercontent.com/u/32006742?v=4"
},
{
"type": "User",
"login": "johnnyluo",
"commits": 571,
"avatar_url": "https://avatars.githubusercontent.com/u/749608?v=4"
},
{
"type": "User",
"login": "yvebe",
"commits": 403,
"avatar_url": "https://avatars.githubusercontent.com/u/14962060?v=4"
},
{
"type": "User",
"login": "JaimeToca",
"commits": 288,
"avatar_url": "https://avatars.githubusercontent.com/u/11850271?v=4"
},
{
"type": "User",
"login": "Vaulty-bot",
"commits": 198,
"avatar_url": "https://avatars.githubusercontent.com/u/257854823?v=4"
},
{
"type": "User",
"login": "yevhen1sec",
"commits": 179,
"avatar_url": "https://avatars.githubusercontent.com/u/173691873?v=4"
},
{
"type": "User",
"login": "rkokhatskyi",
"commits": 172,
"avatar_url": "https://avatars.githubusercontent.com/u/32820910?v=4"
},
{
"type": "User",
"login": "realpaaao",
"commits": 37,
"avatar_url": "https://avatars.githubusercontent.com/u/167348323?v=4"
},
{
"type": "User",
"login": "LucasFernandes01",
"commits": 18,
"avatar_url": "https://avatars.githubusercontent.com/u/25087381?v=4"
},
{
"type": "User",
"login": "gomesalexandre",
"commits": 14,
"avatar_url": "https://avatars.githubusercontent.com/u/17035424?v=4"
}
],
"contributors_sampled": 16,
"top_contributor_share": 0.368
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"android.yml"
],
"has_docs_dir": true,
"linter_configs": [],
"has_editorconfig": true,
"has_linter_config": false,
"has_precommit_config": false
},
"security_signals": {
"lockfiles": [
"Gemfile.lock"
],
"scorecard": {
"checks": [
{
"name": "Binary-Artifacts",
"score": 9,
"reason": "binaries present in source code",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
},
{
"name": "Branch-Protection",
"score": 1,
"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": "30 out of 30 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": 9,
"reason": "Found 28/30 approved changesets -- score normalized to 9",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 6,
"reason": "project has 2 contributing companies or organizations -- score normalized to 6",
"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": 10,
"reason": "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 19 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": 0,
"reason": "dependency not pinned by hash detected -- score normalized to 0",
"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": 7,
"reason": "3 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "2c230ced6fed249f439e9fbca9c707458f369ce1",
"ran_at": "2026-07-22T03:21:00Z",
"aggregate_score": 5.1,
"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-22T00:06:27Z",
"oldest_open_prs": [
{
"number": 5331,
"created_at": "2026-07-19T02:00:22Z",
"last_comment_at": "2026-07-21T23:58:05Z",
"last_comment_author": "johnnyluo"
},
{
"number": 5364,
"created_at": "2026-07-21T10:27:52Z",
"last_comment_at": "2026-07-21T10:28:10Z",
"last_comment_author": "coderabbitai"
},
{
"number": 5368,
"created_at": "2026-07-21T11:30:44Z",
"last_comment_at": "2026-07-21T11:31:05Z",
"last_comment_author": "coderabbitai"
},
{
"number": 5369,
"created_at": "2026-07-21T11:42:59Z",
"last_comment_at": "2026-07-21T21:46:25Z",
"last_comment_author": "Vaulty-bot"
}
],
"last_merged_pr_at": "2026-07-21T23:56:25Z",
"ci_last_conclusion": "SUCCESS",
"oldest_open_issues": [
{
"number": 4006,
"created_at": "2026-04-06T02:01:59Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 4154,
"created_at": "2026-04-23T01:21:17Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 4331,
"created_at": "2026-04-30T09:37:31Z",
"last_comment_at": "2026-05-18T10:17:04Z",
"last_comment_author": "realpaaao"
},
{
"number": 5079,
"created_at": "2026-06-28T20:20:55Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 5080,
"created_at": "2026-06-28T20:42:53Z",
"last_comment_at": "2026-07-09T09:20:49Z",
"last_comment_author": "Vaulty-bot"
},
{
"number": 5210,
"created_at": "2026-07-06T18:59:55Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 5211,
"created_at": "2026-07-06T18:59:57Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 5212,
"created_at": "2026-07-06T18:59:58Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 5227,
"created_at": "2026-07-08T08:08:00Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 5235,
"created_at": "2026-07-08T14:29:56Z",
"last_comment_at": "2026-07-08T23:48:09Z",
"last_comment_author": "johnnyluo"
},
{
"number": 5252,
"created_at": "2026-07-10T08:36:17Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 5317,
"created_at": "2026-07-18T05:18:21Z",
"last_comment_at": "2026-07-19T10:11:05Z",
"last_comment_author": "johnnyluo"
},
{
"number": 5318,
"created_at": "2026-07-18T05:18:24Z",
"last_comment_at": "2026-07-20T07:33:01Z",
"last_comment_author": "realpaaao"
},
{
"number": 5334,
"created_at": "2026-07-19T07:32:46Z",
"last_comment_at": "2026-07-20T07:43:48Z",
"last_comment_author": "realpaaao"
},
{
"number": 5335,
"created_at": "2026-07-19T07:43:13Z",
"last_comment_at": "2026-07-20T07:43:47Z",
"last_comment_author": "realpaaao"
},
{
"number": 5343,
"created_at": "2026-07-20T07:22:23Z",
"last_comment_at": "2026-07-20T09:52:11Z",
"last_comment_author": "johnnyluo"
},
{
"number": 5344,
"created_at": "2026-07-20T07:50:08Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 5345,
"created_at": "2026-07-20T07:50:20Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 5348,
"created_at": "2026-07-20T08:36:54Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 5356,
"created_at": "2026-07-20T15:20:06Z",
"last_comment_at": null,
"last_comment_author": null
}
]
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/vultisig/vultisig-android",
"host": "github.com",
"name": "vultisig-android",
"owner": "vultisig"
},
"metrics": {
"overall": {
"key": "overall",
"band": "good",
"name": "Overall health",
"note": null,
"notes": [],
"value": 71,
"inputs": {
"security": 61,
"vitality": 96,
"community": 43,
"governance": 72,
"engineering": 74
},
"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": 1412,
"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": "1412 commits in the last year",
"points": 18,
"status": "met",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 1412
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "30 commit(s) and 19 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.0.114",
"releases_from_tags": false,
"days_since_latest_release": 7,
"mean_days_between_releases": 4.5
},
"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 7 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 7
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~4.5 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 4.5
}
}
],
"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": 43,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "at_risk",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 31,
"inputs": {
"forks": 16,
"stars": 21,
"watchers": 2,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "below_threshold"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "21 stars",
"points": 21.1,
"status": "partial",
"details": [
{
"code": "stars",
"params": {
"count": 21
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "16 forks",
"points": 9.8,
"status": "partial",
"details": [
{
"code": "forks",
"params": {
"count": 16
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "2 watchers",
"points": 0,
"status": "missed",
"details": [
{
"code": "watchers",
"params": {
"count": 2
}
}
],
"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": 72,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "moderate",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 59,
"inputs": {
"bus_factor": 2,
"contributors_sampled": 16,
"top_contributor_share": 0.368
},
"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 37% of commits",
"points": 14.2,
"status": "partial",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 37
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "16 contributors",
"points": 13.5,
"status": "met",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 16
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "project has 2 contributing companies or organizations -- score normalized to 6",
"points": 6,
"status": "partial",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "excellent",
"name": "Issue & PR responsiveness",
"note": null,
"notes": [],
"value": 96,
"inputs": {
"merged_prs": 2630,
"open_issues": 24,
"closed_issues": 2537,
"issue_closed_ratio": 0.991,
"closed_unmerged_prs": 155
},
"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": "2630/2785 decided PRs merged",
"points": 36.1,
"status": "partial",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 2630,
"decided": 2785
}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 28/30 approved changesets -- score normalized to 9",
"points": 13.5,
"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": "good",
"name": "Engineering Quality",
"value": 74,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "good",
"name": "Engineering practices",
"note": null,
"notes": [],
"value": 74,
"inputs": {
"has_ci": true,
"has_tests": true,
"has_editorconfig": true,
"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": 6.4,
"status": "met",
"details": [],
"max_points": 6.4
},
{
"key": "openssf_scorecard_ci_tests",
"name": "OpenSSF Scorecard: CI-Tests",
"detail": "30 out of 30 merged PRs checked by a CI test -- score normalized to 10",
"points": 20,
"status": "met",
"details": [],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "good",
"name": "Documentation",
"note": null,
"notes": [],
"value": 75,
"inputs": {
"topics": [],
"has_wiki": true,
"homepage": null,
"has_readme": true,
"has_docs_dir": true,
"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": 25,
"status": "met",
"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": 61,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "moderate",
"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": 51,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 17,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 1,
"scorecard_aggregate": 5.1
},
"components": [
{
"key": "binary_artifacts",
"name": "Binary-Artifacts",
"detail": "binaries present in source code",
"points": 6.8,
"status": "partial",
"details": [],
"max_points": 7.5
},
{
"key": "branch_protection",
"name": "Branch-Protection",
"detail": "branch protection is not maximal on development and all release branches",
"points": 0.8,
"status": "partial",
"details": [],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "30 out of 30 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 28/30 approved changesets -- score normalized to 9",
"points": 6.8,
"status": "partial",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 2 contributing companies or organizations -- score normalized to 6",
"points": 1.5,
"status": "partial",
"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": "update tool detected",
"points": 7.5,
"status": "met",
"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 19 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": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"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": "3 existing vulnerabilities detected",
"points": 5.2,
"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 95 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": 95
}
},
{
"code": "advisories_repo_graph_caveat",
"params": {}
},
{
"code": "advisories_reachability",
"params": {}
}
],
"value": 100,
"inputs": {
"source": "osv",
"advisories": 3,
"affected_packages": 3,
"assessed_packages": 95,
"unassessed_packages": 0,
"affected_by_severity": "high 2, 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": 95,
"malicious_packages": 0,
"direct_malicious_packages": 0,
"withdrawn_malicious_packages": 0,
"installable_malicious_packages": 0
},
"components": [
{
"key": "no_dependency_reported_as_a_malicious_package",
"name": "No dependency reported as a malicious package",
"detail": "no dependency is reported as a malicious package",
"points": 100,
"status": "met",
"details": [
{
"code": "no_malicious_dependencies",
"params": {}
}
],
"max_points": 100
}
]
},
{
"key": "high_risk_jurisdiction_exposure",
"band": "excellent",
"name": "High-Risk Jurisdiction Exposure",
"note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
"notes": [
{
"code": "jurisdiction_evidence_limits",
"params": {}
}
],
"value": 100,
"inputs": {
"meaning": "self-published location evidence; not nationality or citizenship",
"red_flag": false,
"exposures": [],
"policy_countries": [
"Russia",
"Iran",
"North Korea"
],
"review_only_matches": 0,
"assessed_self_published_locations": 3
},
"components": [
{
"key": "policy_exposure_multiplier",
"name": "Policy exposure multiplier",
"detail": "no confirmed policy-scope location match",
"points": 100,
"status": "met",
"details": [
{
"code": "jurisdiction_no_match",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
},
{
"key": "ai_readiness",
"band": "good",
"name": "AI Readiness",
"value": 79,
"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": 1,
"agent_instruction_files": [
"AGENTS.md",
"CLAUDE.md"
],
"agent_instruction_max_bytes": 19254
},
"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": "100 of 100 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 100,
"sampled": 100
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "moderate",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 66,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [
"Gemfile.lock"
],
"has_dockerfile": false,
"typed_language": true,
"bootstrap_files": [],
"has_devcontainer": false,
"has_linter_config": false,
"typecheck_configs": [],
"agent_commit_share": 0.71,
"toolchain_manifests": [
"app/build.gradle.kts",
"build.gradle.kts",
"data/build.gradle.kts"
],
"dependency_bot_commit_share": 0
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": "app/build.gradle.kts, build.gradle.kts, data/build.gradle.kts (toolchain convention, no task runner)",
"points": 12.6,
"status": "partial",
"details": [
{
"code": "toolchain_convention",
"params": {
"files": "app/build.gradle.kts, build.gradle.kts, data/build.gradle.kts"
}
}
],
"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": "Kotlin (statically typed)",
"points": 11,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "Kotlin"
}
}
],
"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": "71 of the last 100 commits agent-authored or agent-credited",
"points": 10,
"status": "met",
"details": [
{
"code": "agent_authored_commits",
"params": {
"count": 71,
"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": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "excellent",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"primary_language": "Kotlin",
"largest_source_bytes": 154512,
"source_files_sampled": 1718,
"oversized_source_files": 8
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "Kotlin (statically typed)",
"points": 45,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "Kotlin"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "8/1718 source files over 60KB",
"points": 54.7,
"status": "partial",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 1718,
"oversized": 8
}
}
],
"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:21:28.441383Z",
"schema_version": "0.26.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/v/vultisig/vultisig-android.svg",
"full_name": "vultisig/vultisig-android",
"license_state": "standard",
"license_spdx": "Apache-2.0"
}