Skip to content

feat(networks): 85 of the 87 CLPR networks, 93 mainnets: 9 chain packages, Chainflip, STRATO, Arc (stacked on #12) - #13

Merged
shayansal merged 36 commits into
mainfrom
feat/networks-85-of-87
Oct 7, 2026
Merged

shayansal merged 36 commits into
mainfrom
feat/networks-85-of-87

Conversation

@shayansal

@shayansal shayansal commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #12 (feat/kit-all-platforms), which isn't merged yet. This PR's base is that branch, so the diff shows only the networks work. Once #12 merges, retarget this PR to main; GitHub does that on its own when the base branch is deleted.

Clip Wallet now covers 85 of the 87 CLPR networks on mainnet and 93 mainnets in total, across 26 families. It does not cover Canton and Mixin: neither has a model in which a self-custodial key wallet can hold and move funds. The coverage is computed from the wallet's own catalogue by packages/engine/test/networks87.test.ts, not written by hand.

This ports the 30 non-merge commits of the earlier networks87 work onto the public history. The commits are linearised (the merge commits are dropped), each signed by shayan@coldai.org. Seven commits are added on top: two fixes for the public base, the docs, two gitleaks ignore commits, and two CodeQL fixes.

What's in it

  • 9 new chain packages, each with Apache-2.0 LICENSE and NOTICE and repository links to ColdAI-org/clip-wallet:

    Package Networks
    chains-cosmos Osmosis, dYdX, ZIGChain, Provenance, THORChain, Initia
    chains-tron TRON
    chains-xrpl XRP Ledger
    chains-stacks Stacks
    chains-fuel Fuel
    chains-bitcoincash Bitcoin Cash
    chains-multiversx MultiversX
    chains-icp Internet Computer
    chains-antelope Vaulta, Telos, XPR Network

    Each module serializes transactions itself. The official SDKs are dev dependencies only, used for byte-for-byte cross-checks.

  • Chainflip (State Chain, Perseverance) in chains-substrate. STRATO mainnet and Helium testnet, and Arc mainnet, in chains-evm.

  • Vault derivations for 12 families: cosmos, provenance, thorchain, initia, tron, xrpl, antelope (canonical K1 signatures), multiversx, icp, stacks, fuel and bitcoincash. Each is checked for the public test phrase against the ecosystem's own SDK.

  • 1Mask providers, under the wallet's own identity (it never poses as Keplr, TronLink, Xaman and so on):

    • a Keplr-compatible API at window.clipwallet.cosmos
    • TIP-1193 with TIP-6963 for TRON
    • XLS-72d (Wallet Standard) for the XRP Ledger
    • SIP-030 with WBIP-004 for Stacks
    • a FuelConnector
    • Bitcoin Cash over WalletConnect (wc2-bch-bcr)
    • MultiversX, best effort, through sdk-dapp's undocumented custom-provider hook
    • Antelope and ICP are send and receive only.
  • Dapp matrix rows for Cosmos, TRON, Stacks, Fuel, XRPL, Chainflip and MultiversX (docs/r1/dapp-matrix.md). Stacks and XRPL pass end to end on testnet; the others pass connect and sign and wait for testnet funds.

  • Notes and tests: docs/r1/networks87.md and packages/engine/test/networks87.test.ts.

  • Docs site:

    • a new Networks reference page;
    • new dapp guides (Cosmos, TRON, XRP Ledger, Stacks, Fuel, Bitcoin Cash, MultiversX), with typechecked snippets;
    • Chainflip in the Polkadot guide, STRATO in the EVM guide and bch in the WalletConnect table;
    • the chain-module and vault derivation tables;
    • the family counts across the site.
  • README: the network table gains the new families and their matrix results, and the counts are updated (85 of 87, 26 families, 93 mainnets).

Public-repo rules applied to every commit

  • Apache-2.0 manifests, LICENSE and NOTICE.
  • Crypto-critical dependencies pinned exactly (the harness rule).
  • vitest ~4.1.11.
  • The Low audit fixes kept.
  • Each commit amended as Schayan Salehi <shayan@coldai.org>, SSH-signed, with the Co-Authored-By trailer.

Two fixes the public base needed:

  • chains-cosmos tests get @types/node, because vitest 4 no longer brings it in.
  • The derivation-path test added with the Low fixes checks FAMILIES.length instead of 14. All 26 families match.

CodeQL counted some existing trailing-slash regexes as new alerts, because the new code now reaches them. They are replaced with linear scans, with the same results:

  • backup-client
  • chains-cosmos
  • chains-hedera
  • CoinGecko prices
  • route, through a shared withoutTrailingSlashes()

route's short ledger name drops a trailing "(…)" with indexOf.

Verification (local, macOS arm64, Node 24)

Check Result
pnpm install --frozen-lockfile, pnpm harness ok (2167 source files, 0 warnings); check-manifests, sync-template ok
pnpm -r typecheck ok
pnpm -r test ok. New packages: cosmos 34, tron 28, xrpl 43, stacks 22, fuel 42, bitcoincash 15, multiversx 32, icp 13, antelope 22. Also substrate 47, evm 95, vault 190, 1mask 217, engine 69, extension-kit 67
extension build + Playwright e2e 22 passed, 1 skipped, 1 flaky. In two of three full runs one test timed out (link.spec once, calls.spec once) while the machine was under heavy load. Both pass alone and in the other runs. The same link.spec timeout happened once on #12, whose CI e2e is green
docs build + link check 229 pages, no broken links, nothing unsafe; docs snippet tests 29/29
pnpm pack-all 46 tarballs
pnpm kit:e2e --dapp all checks passed (76). Extension 12.3 MB unpacked / 4.1 MB zip; desktop out 24.9 MB, mac-arm64 zip 115.3 MB; mobile Hermes bundles 27.0 MB each
pnpm kit:e2e:scaffold-hbar all checks passed
gitleaks git on the new commits no leaks. 8 reviewed false positives were added to .gitleaksignore: public keys, XRPL object ids and Initia feature names
history scan one generic hit: npm's "glob … security vulnerabilities" deprecation notice in pnpm-lock.yaml, which is already in main's lockfile

CI

All 11 checks are green:

  • CodeQL
  • packages
  • extension e2e
  • mobile
  • services
  • kit e2e
  • reproducible build
  • desktop on macOS, Windows and Linux

Needs the owner

  • Testnet funds for the remaining matrix levels. These are listed in docs/r1/dapp-matrix-funding.md: OSMO, Nile TRX, Fuel testnet ETH, Perseverance FLIP, devnet EGLD, chipnet BCH and TESTICP, plus a Jungle4 account. Most faucets need a captcha or an account.
  • A WalletConnect project id for the Bitcoin Cash (wc2-bch-bcr) matrix row.
  • Claims to avoid. "All 87 CLPR networks" isn't true. The accurate wording is "85 of the 87 (all except Canton and Mixin) and 93 mainnets".
  • The internal review covered the first 14 families. The 12 newer ones need the external audit before any mainnet build.

🤖 Generated with Claude Code

Schayan Salehi and others added 30 commits October 6, 2026 21:57
…nd canonical Antelope signatures

The CLPR networks Clip didn't cover yet need their own keys. New Family members (core, additive; config
NETWORK_FAMILIES and 1Mask's wire list follow): cosmos (coin 118: Osmosis, dYdX, ZIGChain), provenance (505),
thorchain (931), initia (60, ethsecp256k1), tron, xrpl, antelope (Vaulta, Telos, XPR Network), multiversx, icp,
stacks, fuel and bitcoincash.

- vault: each family at its ecosystem wallet's standard path and curve (Keplr/Leap per chain-registry slip44,
  TronLink, xrpl.js/Ledger Live, TokenPocket, xPortal, Plug/dfx, Leather/Xverse, Fuel Wallet, Electron Cash), address
  encodings in src/encodings87.ts (bech32, base58check, Ripple base58, PUB_K1, principal + account identifier,
  c32check, Fuel b256 with the fuels-ts checksum, CashAddr).
- vault: Antelope accepts only canonical K1 signatures; signEcdsaCanonical retries with an RFC 6979 extra-entropy
  counter (as WharfKit bumps its personalisation), still deterministic.
- test/families87.test.ts: "abandon … about" cross-checked against cosmjs, xrpl.js, TronWeb, WharfKit (verify +
  recover), MultiversX sdk-core, @dfinity/identity-secp256k1, @stacks/wallet-sdk, fuels-ts and libauth, plus the
  published cosmos1… and CashAddr spec vectors.
- core: optional ChainModule.receiveAddress(ctx) for families whose address is spelled per network or lives on chain.
- engine/extension-kit: ETAs and fixture curves for the new families; engine wiring skips a family without a module.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sh + 11 languages)

One section per new package in en/n87.ts and locales/n87/<code>.ts, spread into the catalog and each locale,
so the chain-module streams add their ids and translations without touching the same lines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
STRATO runs SolidVM, but its nodes take signed legacy Ethereum transactions (EIP-155) through eth_sendRawTransaction:
a value transfer moves the native USDST and a call's selector is matched to the SolidVM function (strato-platform
techdocs transactions-and-fees.md and json-rpc.md; EthereumTX in blockapps-data Transaction.hs). So a self-custodial
EVM key holds and sends USDST there. Checked live on 2026-10-06: eth_chainId 0x7030addddcf2 (mainnet) and
0xb165855668ca (Helium), eth_gasPrice 0x0, USDST decimals 18.

- networks: both as legacy-gas specs with a new `flatFee` (the flat 0.01 USDST, or a voucher, the network charges
  per transaction outside gas, kept even when the transaction fails).
- decode: the flat charge is added to the fee and shown as its own line (bg.label.networkCharge, bg.evm.flatFee in
  English and the 11 languages).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ells

Receive used the vault's one address per family. The networks87 families spell it per network (Cosmos bech32
prefixes, Stacks SP/ST, CashAddr bitcoincash:/bchtest:) or keep it on chain (Antelope account names), so the
extension background and the engine ask the module's optional receiveAddress(ctx) and group targets by what it
returns; lazily loaded modules forward it. Family labels for the twelve new families (bare network names).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ilies

- Arc mainnet went live on 2026-09-16: chain 5042, USDC as native gas (18 decimals), rpc.mainnet.arc.io and
  explorer.arc.io per docs.arc.io "Connect to Arc" (eth_chainId 0x13b2 checked 2026-10-06). The testnet entry moves to
  the documented rpc.testnet.arc.io / explorer.testnet.arc.io (the old RPC host still answers and stays as fallback).
- extension-kit fixture mode: address patterns, schemes and paths for the twelve new families (resolveRecipient asks
  every family's isAddress).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@clip-wallet/chains-fuel: Fuel Ignition (fuel:9889) and the testnet (fuel:0), ids from the connector standard's
numeric chain ids (no CAIP-2 namespace exists), both GraphQL endpoints checked with chain { consensusParameters }.

- m/44'/1179993420'/i'/0/0, secp256k1; address = SHA-256 of the uncompressed key with the fuels-ts checksum.
- Script transactions serialized by hand from the specs (tx-format, transaction-id); bytes, ids, min/max gas and
  message hashes compared with fuels-ts (devDependency only) for transfers, token sends, contract calls with all
  policies, and message coins.
- buildTransfer: coinsToSpend, return-zero script, gas measured by dry run, max fee from the spec formula at
  estimateGasPrice(10). A testnet transfer built and signed this way passed dryRun(utxoValidation) and one went
  through fuels-ts Fuel and the connector to submitAndAwaitStatus.
- decode: plain transfers from inputs/outputs; contract-calling scripts dry-run, flows from CALL/TRANSFER/
  TRANSFER_OUT receipts (simulated); predicates, non-script transactions and failed dry runs are blind; change to
  someone else or no change is a danger warning. Messages per fuels-ts hashMessage; unreadable plain strings are blind.
- finalize: verify, check the recovery id recovers the key, r || s with the recovery bit in s, then submit.
- Balances: ETH plus the bridged USDC/USDT/FUEL from Fuel's verified-assets list.

1Mask (new files, wiring left to router/index): a dependency-free FuelConnector that announces itself with the
FuelConnector event under the wallet's identity and sits at window.clipwallet.fuel, and its background dispatcher;
tested alone and under the real fuels-ts Fuel manager. Matrix page e2e/matrix/dapps/fuel.ts (testnet).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…covery)

Stacks mainnet (stacks:1) and testnet (stacks:2147483648) on Hiro's keyless API, at m/44'/5757'/0'/0/i
(Leather, Xverse), addresses spelled per network (SP/ST, receiveAddress).

- Hand-written SIP-005: c32check, Clarity values (hex and SIP-030 JSON), post-conditions (incl. SIP-040
  originator mode and SIP-045 staking/PoX conditions), payloads, sighash chain (initial sighash = txid of the
  cleared tx; presign = SHA-512/256(sighash ‖ 0x04 ‖ fee ‖ nonce)), VRS signatures; bytes, txids and digests
  cross-checked against @stacks/transactions 7.6 and signed transactions against its verifyOrigin().
- Methods are SIP-030's: stx_transferStx, stx_transferSip10Ft, stx_transferSip9Nft, stx_callContract,
  stx_deployContract, stx_signTransaction, stx_signMessage ("\x17Stacks Signed Message:\n", RSV) and
  stx_signStructuredMessage (SIP-018). Post-conditions become lines and balance changes; allow mode is a danger.
- Balances: STX, curated sBTC / USDCx / aeUSDC (bridged, own keys), other SIP-010 tokens spam-checked.
- 1Mask: window.clipwallet.stacks (request → JSON-RPC response, SIP-030 error codes) registered on
  window.wbip_providers as "clipwallet.stacks" with the wallet's own identity (what @stacks/connect v8 lists and
  resolves); never window.StacksProvider/LeatherProvider/XverseProviders. createStacksDispatcher for the router.
- Matrix page dapps/stacks.ts: @stacks/connect request() + verifyMessageSignatureRsv, testnet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the Nile matrix page

TRON mainnet, Nile and Shasta as a ChainModule with hand-written protobuf (no TronWeb at runtime; @noble/curves,
@noble/hashes, @scure/base only).

- Networks: Reown's CAIP-2 ids tron:0xcd8690dc (Nile, default), tron:0x94a9059e (Shasta), tron:0x2b6653dc
  (mainnet); fromChainId also takes the ChainAgnostic draft's decimal form. Keyless TronGrid plus api.nileex.io,
  api.tronstack.io and tron-rpc.publicnode.com, with fallback.
- Accounts: m/44'/195'/0'/0/i, base58check T… addresses (TronWeb known answers); signing is refused when the
  account's owner/active permission doesn't give this key the threshold (the public test account on Nile was
  taken over exactly that way).
- Transactions: TransferContract and TRC-20 transfer built locally (ref block = latest, 10 min expiration, fee
  limit from the energy estimate); txID = sha256(raw_data), r||s||v with v = 27 + recovery, verified and
  recovered before broadcasthex, confirmed with gettransactioninfobyid.
- decode trusts only the hex: txID and raw_data JSON must match it, the reference block must be on this network.
  TRX/TRC-10/TRC-20 transfers, transferFrom, approve (unlimited-approval warning), Stake 2.0 freeze/unfreeze/
  withdraw/cancel, delegate/undelegate, votes, reward claims and AccountPermissionUpdate (account-takeover) in
  plain words; other calldata shows contract + selector, blind. The fee is the most TRX it can burn now:
  bandwidth, account opening (1.1 TRX), memo fee and energy, capped by the fee limit.
- Messages: TIP-104 signMessageV2 (keccak of "\x19TRON Signed Message:\n" + length), checked against
  TronWeb's verifyMessageV2.
- 1Mask: window.clipwallet.tron implements TIP-1193 with eth_requestAccounts (TIP-1102), eth_chainId and
  wallet_switchEthereumChain (TIP-3326), announced via TIP-6963 with the wallet's own identity, plus the TronWeb
  signing subset TIP-1193 delegates to (trx.sign, trx.signMessageV2). Background dispatcher
  createTronDispatcher (not wired yet). Never sets isTronLink, window.tronLink or window.tronWeb.
- Matrix page dapps/tron.ts (Nile): TIP-6963 connect, signMessageV2 verified with Trx.verifyMessageV2, a 1-sun
  TronWeb-built send to the black-hole address (TRON refuses self-transfers).
- i18n: 19 bg.tron.* ids in English and the 11 languages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… in plain words)

@clip-wallet/chains-multiversx: devnet (mvx:D), testnet (mvx:T) and mainnet (mvx:1), the ChainAgnostic / WalletConnect
`mvx` ids; public gateway + API endpoints, no key. Accounts at m/44'/508'/0'/0'/i' (xPortal, sdk-core), erd1 bech32.

- Transactions serialized exactly as sdk-core's TransactionComputer signs them (field order, omitted empty fields,
  base64 data, keccak256 for the hash-signing option, guardian/relayer); messages as MessageComputer
  ("\x17Elrond Signed Message:\n" + length, keccak256). Tests check the bytes against @multiversx/sdk-core 16, and the
  devnet gateway accepted the signatures (simulate with checkSignature).
- decode: EGLD sends and notes, ESDTTransfer / ESDTNFTTransfer / MultiESDTNFTTransfer, staking-provider delegate /
  unDelegate / claimRewards / withdraw / reDelegateRewards, SetGuardian / GuardAccount / ChangeOwnerAddress as
  account-takeover dangers, other contract calls named with an unknown-call caution, the rest blind; fee from the
  network config, relayed fees as sponsored, a gateway dry run (simulate) for single transactions.
- WalletConnect methods mvx_signTransaction(s) / mvx_signMessage; buildTransfer sends EGLD or ESDTs with sdk-core's
  gas, confirms through process-status, and every gateway rejection comes back in plain words.
- Balances: EGLD plus registered fungible ESDTs; USDC (USDC-c76f1f / devnet USDC-350c4e) as bridged "usdc.mvx",
  unregistered and look-alike tokens marked spam.
- No injected provider: sdk-dapp has no wallet discovery a third-party extension can use under its own identity
  (README has the sources); WalletConnect is the route.
- core: bg.multiversx.* messages in English and 11 languages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… transfers over a hand-written IC agent)

@clip-wallet/chains-icp: IC mainnet (icp:737ba355e855bd4b61279056603e0550, the proposed CAIP-2 id from the root key)
and "icp:test", mainnet restricted to DFINITY's test ledgers (TESTICP with a no-login faucet, ckTESTBTC,
ckSepoliaUSDC, ckSepoliaETH): there's no public IC test network for ledger transfers. Boundary node icp-api.io, no
key. Accounts at m/44'/223'/0'/0/i (Plug, dfx), the self-authenticating principal.

- A minimal IC HTTPS client: CBOR (incl. the indefinite maps boundary nodes answer with), representation-independent
  request ids, signed envelopes (DER key + 64-byte r||s over SHA-256("\x0Aic-request" || request id)), anonymous v3
  queries, the synchronous v4 call with a pre-signed v3 read_state for 202s (two payloads, one approval), and the
  request status read out of the certificate. Certificates and query signatures are NOT verified (README and code
  say so); no reply is used for a security decision.
- Candid for exactly the ledger types (Account, TransferArg, TransferResult and its errors, the ICP ledger's legacy
  transfer to an account identifier); decode re-encodes the arg and refuses anything that isn't byte-identical.
- Recipients: principals, ICRC-1 account text (all TextualEncoding.md examples) or 64-hex account identifiers
  (ICP/TESTICP only, with a note that exchanges use them); fee read with icrc1_fee, created_at_time for ledger dedup,
  ledger errors in plain words.
- Tests cross-check request ids, envelopes, certificate lookups, Candid bytes and principals against @dfinity/agent,
  candid, principal and identity-secp256k1 2.4.x. Live: a signed transfer from the unfunded test-vector account was
  accepted by icp-api.io and answered InsufficientFunds.
- No injected provider: ICRC-94 (extension discovery) is still a working-group DRAFT; Plug's window.ic.plug is
  proprietary. README lists what the provider would use once ICRC-94 is final.
- core: bg.icp.* messages in English and 11 languages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…stnet

Chainflip is a Substrate solo chain (ss58 2112 "cF…", FLIP 18) that the existing sr25519 account signs for, and
lp.chainflip.io finds 1Mask's injectedWeb3 provider (it lists Object.keys(window.injectedWeb3)). Read live on
2026-10-06: genesis 0x8b8c140b… (mainnet, chainflip-node 20216) and 0x7a5d4db8… (Perseverance, 20302), both
transactionVersion 13, 6-second blocks.

- networks: Chainflip (mainnet-rpc.chainflip.io, rpc.chainflip.io) and Chainflip Perseverance
  (archive.perseverance.chainflip.io, perseverance.chainflip.xyz), keys flip / flip-testnet, scan.chainflip.io
  /extrinsics/ links.
- balances: the runtime has no Balances pallet, so FLIP is read from Flip.Account (balance, bond included, which
  is what pays fees); getFlipAccount() splits it into bond, redeemable (balance - bond) and a pending redemption.
- buildTransfer refuses with substrate/no-transfers: FLIP only enters by funding from Ethereum and leaves by
  Funding.redeem.
- decode: plain words for Funding.redeem / rebalance and the permanent bind_redeem_address /
  bind_executor_address (danger), LiquidityProvider, Swapping deposit channels, LendingPools (Boost, lending) and
  AccountRoles.as_sub_account, with cross-chain addresses in each chain's own format. LP order calls stay
  Pallet.call(args) with a caution about the 1 FLIP order escrow.
- signing: AuthorizeCall / WeightReclaim are empty and add nothing; signing bytes and the signed extrinsic match
  @polkadot/types 17 byte for byte, and a vault-signed register_lp_account was validated read-only by both
  networks (TaggedTransactionQueue → Payment).
- fixed: two-byte SS58 prefixes (polkadot-api 0.21 reads 2112 as 20488) and a malformed sr25519 signature that
  made finalize throw instead of substrate/bad-signature.
- messages: bg.chainflip.* in English and the 11 languages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ain, Provenance, THORChain and Initia

One package, four key families (cosmos 118, provenance 505, thorchain 931, initia 60 ethsecp256k1), each its
own createCosmosModule({ family }) answering only its networks (cosmos:<chain-id>). Hand-written protobuf and
Amino JSON (checked byte for byte against cosmjs-types / @cosmjs/amino), SIGN_MODE_DIRECT, REST with failover,
simulate-based gas, per-chain fee models (Osmosis txfees base fee, Initia dynamicfee, Provenance flat fees,
THORChain fixed native fee with /types.MsgSend), sync broadcast and polling. decode explains bank, IBC,
staking, distribution, CosmWasm execute and authz/feegrant grants (danger), ADR-36; anything else is blind.

1Mask: a Keplr-compatible provider at window.clipwallet.cosmos (never window.keplr) with its background
dispatcher (signer ownership per chain prefix) and tests; matrix dapp page for osmo-test-5 with cosmjs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- inpage/n87.ts installs the new families' providers under the wallet's own identity: Keplr-compatible API at
  window[globalKey].cosmos (Osmosis, dYdX, ZIGChain, Provenance, THORChain, Initia; never window.keplr), TRON
  TIP-1193 announced with TIP-6963, Stacks SIP-030 on window.wbip_providers (WBIP-004), and a Fuel connector
  announced with the FuelConnector event. `providers.{cosmos,tron,stacks,fuel}` turn each off.
- router: the Cosmos, TRON, Stacks and Fuel dispatchers; methods.ts allowlists them. Families without a verified
  injected standard (XRPL, Antelope, MultiversX, ICP, Bitcoin Cash) stay send and receive only.
- Hosts: Keplr enable, TIP-1193 accounts, SIP-030 connect and FuelConnector connect are connect approvals;
  cosmos_sendTx / cosmos_verifyArbitrary are answered by chains-cosmos read() without an approval.
- 1mask content test: "cosmos" is a real family now; the invalid family is "dogecoin".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n, multiversx, icp, stacks, fuel

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cr requests

Bitcoin Cash mainnet, chipnet (default test network) and testnet4 at m/44'/145'/0'/0/i (Electron Cash, Paytaca),
CashAddr spelled per network (bitcoincash:/bchtest:, receiveAddress). Ids are bip122 + the first own block
(mainnet 478559 as in the ChainAgnostic test case, chipnet 115252, testnet4 genesis), so none collides with Bitcoin.

- Public Fulcrum servers over WebSocket (Electrum Cash 1.4), several per network with fallback.
- Hand-written CashAddr (P2PKH, P2SH20/32, token-aware), transactions with CashTokens prefixes and the BCH signing
  serialization (SIGHASH_ALL|FORKID, spent token prefix); bytes and sighashes checked against libauth and every
  signed transaction run through libauth's BCH 2023 VM.
- Sends: largest coins first, never a coin that carries CashTokens, dust 546, relay-fee rate, change back to the
  same address. Balances: BCH confirmed + unconfirmed, fungible CashTokens from listunspent.
- Requests use the community WalletConnect spec (bch_signTransaction with libauth-stringified source outputs,
  bch_signMessage in Electron Cash format); CashScript placeholders are refused in plain words.
- 1Mask: wc2-bch-bcr namespace, chain mapping and createBitcoinCashDispatcher (bch_getAddresses per network);
  there's no injected BCH standard, so the WalletConnect session layer is the integration step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…bytes

Each leading zero byte is a single "0", so such addresses are shorter than the usual 41 characters: the boot
addresses SP000000000000000000002Q6VF78 / ST000000000000000000002AMW42H were refused (found with a live read-only
decode against api.testnet.hiro.so). The checksum and canonical-spelling checks still decide.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… targets for the networks87 families

- engine/extension-kit: chains-bitcoincash (chipnet, testnet4, mainnet), lazily loaded in the extension.
- Matrix: targets cosmos (osmo-test-5), tron (Nile), stacks, fuel and chainflip (Perseverance), plus balance-only
  targets for Provenance, Initia, MultiversX, ICP and Bitcoin Cash (no injected dapp standard to test). Addresses
  are per target where the network spells them differently (vaultAddress keeps the vault's form). A Chainflip page
  (polkadot extension-dapp, as lp.chainflip.io) signs a message and registers an LP account; Spec.call checks a
  call's approval title where there is no transfer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… over WalletConnect (wc2-bch-bcr)

- router: accountsChanged events (connect, sign-in grant, notifyAccountsChanged) carry Stacks and Bitcoin Cash
  accounts spelled for the site's selected network (ST… / bchtest:…), as their dispatchers answer `accounts`; a
  Stacks/BCH connect also selects the network it connected on.
- walletconnect: the "bch" namespace (bch_getAddresses, bch_signTransaction, bch_signMessage; addressesChanged).
  A small chain-alias layer maps "bch:bitcoincash" / "bch:bchtest" to the wallet's bip122 BCH networks for the
  registry check, the connect screen, request routing (family bitcoincash) and session accounts, which are
  "bch:<CashAddr>" spelled for the chain as Cashonize builds them (src/stores/walletconnectStore.ts).
  bch_getAddresses is answered from the session; the bip122 (Bitcoin) namespace is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…72d requests, plain-words decode

@clip-wallet/chains-xrpl (family xrpl): mainnet xrpl:0, testnet xrpl:1, devnet xrpl:2 (ChainAgnostic CAIP-2),
public JSON-RPC checked with server_info. No SDK at runtime: the binary codec subset, Ripple base58 / X-addresses
and the JSON-RPC client are written on @noble/@Scure; tests encode the same JSON with ripple-binary-codec and
require identical bytes, verify signatures with ripple-keypairs and hash with xrpl.js.

- m/44'/144'/i'/0/0, secp256k1; digest = SHA-512Half(STX\0 ‖ signing fields); the vault's low-S r‖s is verified
  before it is DER-encoded into TxnSignature; submit, then tx until validated.
- xrpl:signTransaction / xrpl:signAndSubmitTransaction (XLS-72d params); autofill (Sequence, Fee, LastLedgerSequence)
  runs once in decode and is cached per request, so the signature covers what was shown. Other network, other
  account, multisig, already signed and master-key-disabled accounts are refused.
- Balances: XRP with the live reserve (spendable()), trust lines; RLUSD and Circle USDC known by issuer, look-alikes
  spam. buildTransfer (XRP, tokens, X-address tags) and buildTrustLine.
- decode: Payment (partial-payment danger, destination tag, unfunded recipient below the reserve, RequireDestTag →
  memo-required, no trust line), TrustSet, offers, AccountSet flags in words, SetRegularKey / SignerListSet /
  DisableMaster → account-takeover, AccountDelete → account-closure, NFTokens (accepted offers read from the
  ledger), escrows, AMM deposit/withdraw; anything else, or any field the codec doesn't know, is blind and
  can't be signed.
- Messages in the chains-xrpl section (English + 11 languages).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… dispatcher

XLS-72d "Browser Wallet Standard" (XRPLF/XRPL-Standards discussion 206; reference types @xrpl-wallet-standard/core)
is Wallet Standard with xrpl:signTransaction and xrpl:signAndSubmitTransaction on chains xrpl:<network_id>. The
wallet registers itself with registerWallet under the kit wallet's own name and icon, and is also at
window.clipwallet.xrpl. It has no message signing, so neither does 1Mask for the XRPL.

- inpage/xrpl.ts: ClipXrplWallet (connect, disconnect, events, both signing features; network aliases such as
  xrpl:testnet map to xrpl:1; only connected accounts and registry networks), installXrpl().
- background/xrpl.ts: createXrplDispatcher (allowlist, permission, the account and tx_json.Account must be
  connected, one network per request, approve(makeReq(...))). Not wired yet: router.ts/index.ts are the
  coordinator's (wiring notes in the file header).
- e2e matrix page dapps/xrpl.ts: discovery as @xrpl-wallet-standard/app does it, L1 connect, L3 a no-op AccountSet
  with a memo via signAndSubmitTransaction (rippled refuses an XRP payment to yourself); no L2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…llet Standard)

The XLS-72d wallet registers under the wallet's own identity and sits at window[globalKey].xrpl; the router
dispatches xrpl:signTransaction / xrpl:signAndSubmitTransaction through createXrplDispatcher. chains-xrpl joins the
catalogue and loads lazily in the extension. Matrix target xrpl (testnet): L1 connect, L3/L4 a no-op AccountSet
with a memo (rippled refuses a payment to yourself); XLS-72d has no message signing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…logue

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tten serialisation, accounts found by key

@clip-wallet/chains-antelope (family antelope): Jungle4, Vaulta, Telos (+ testnet), XPR Network (+ testnet) as
antelope:<first 32 hex of the chain id> (ChainAgnostic), public chain APIs checked with get_info. No SDK at runtime:
names, assets, PUB_K1/legacy keys, SIG_K1 strings, transactions and an ABI-driven (de)serialiser on @noble/@Scure;
tests compare bytes, ids, digests and signatures with @wharfkit/antelope (verifyDigest, recoverDigest).

- m/44'/194'/0'/0/i, one K1 key for every network; Account.address is the PUB_K1 key. accounts()/receiveAddress()
  find the names this key controls (get_accounts_by_authorizers on each server, then Hyperion get_key_accounts), or say
  in plain words that no account uses the key yet and how one gets created.
- antelope_signTransaction / antelope_signAndPushTransaction: header (TAPoS, expiry) filled once in decode and cached;
  digest = SHA-256(chain_id ‖ packed_trx ‖ 32 zero bytes); the vault's signature is verified, checked canonical and
  recovered before it becomes SIG_K1 (recid + 31); send_transaction2 with a push_transaction fallback. CPU/NET/RAM
  refusals in plain words per network (Vaulta PowerUp, Telos stake or PowerUp, XPR covered by the network).
- Balances: EOS (still Vaulta's system token) with A (core.vaulta) and Tether's USDT, TLOS, XPR; other tokens from
  Hyperion with look-alike symbols marked spam. buildTransfer via eosio.token-style transfer without an ABI call.
- decode: token transfers (any contract with the standard transfer ABI; unknown tokens caution, look-alikes danger),
  updateauth/deleteauth/linkauth → account-takeover, any other action through its ABI as "Call {action} on
  {contract}" with its fields; no ABI or unknown types → blind.
- No dapp provider: WharfKit plugins live in the dapp, Anchor Link/ESR and Scatter injection answer as Anchor or
  Scatter/TokenPocket (README). Messages in the chains-antelope section (English + 11 languages).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…umented custom-provider hook

MultiversX has no wallet-discovery standard. @multiversx/sdk-dapp 5.x's initApp merges window.multiversx?.providers
with the dapp's customProviders (deduplicated by type) and ProviderFactory.create({ type }) calls the entry's
constructor, then init(). That hook is UNDOCUMENTED as a wallet channel (sdk-dapp's README has the dapp set it; the
template dapp replaces window.multiversx), so this works only on sdk-dapp dapps that don't override it. Comments and
the chains-multiversx README say so.

- inpage/multiversx.ts: installMultiversXProvider pushes the wallet's own entry (type = global key "clipwallet", its
  name and icon; never "extension" or the DeFi Wallet) without replacing the array or other entries, and exposes the
  provider at window[globalKey].multiversx. It implements sdk-dapp's IProvider: dapp sdk-core Transactions are read
  with toPlainObject() and returned with `signature` set (guardian fields untouched); login({ token }) signs
  address + token, the message sdk-native-auth-server verifies.
- background/multiversx.ts: createMultiversXDispatcher (connect, accounts, disconnect, mvx_signTransactions,
  mvx_signMessage through approve(makeReq)), multiversxInjectedAllowlist, MULTIVERSX_CONNECT_METHODS; every signer
  must be the site's account, and a native-auth login token for another site is refused.
- shared/multiversx-methods.ts: wire method names, chain ids, nativeAuthOrigin.
- chains-multiversx: a native-auth login decodes as "Sign in to {site}", with a domain-mismatch danger when the token
  names another site.
- Matrix page dapps/multiversx.ts (devnet): sdk-dapp driven headless (initApp + ProviderFactory + native-auth login,
  verifyMessage, a self-transfer through DappProvider.signTransactions); devDependencies @multiversx/sdk-dapp 5.7.3
  and its peers. Checked in a scratch run against the real sdk-dapp: the entry was listed, the native-auth token
  validated with sdk-native-auth-server on devnet, and the signatures verified with sdk-core 15.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rt MultiversX provider

- chains-antelope (Vaulta, Telos, XPR Network + Jungle4, Telos and XPR testnets) in the catalogue, lazily loaded;
  send and receive only (no wallet-side Antelope dapp standard Clip can answer as itself).
- MultiversX: an entry on sdk-dapp's window.multiversx.providers custom-provider hook under the wallet's own name and
  icon. The hook is undocumented and only works on dapps that don't reset it; send and receive in the wallet don't
  depend on it. Router, allowlist and the connect approval (mvx:connect) wired.
- Matrix: multiversx (devnet) target with its sdk-dapp page; antelope (Jungle4) as a funding/balance target.
- extension-kit tests: 26 families (22 lazy); THORChain has no public testnet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lt does; changeset

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… model, family counts

docs/r1/networks87.md maps each of the 87 CLPR networks to its module and mainnet network id (generated from the
engine coverage test), says why Canton and Mixin can't be supported by a key wallet and what the closest honest
support is, and gives the true numbers: 85 of 87 CLPR networks, 93 mainnets by the landing page's rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eceive address (OSMO on osmo1…)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Matrix on the new families' testnets: L1 connect passes for Cosmos (osmo-test-5), TRON (Nile), Stacks, Fuel, XRP
Ledger, Chainflip (Perseverance) and MultiversX (devnet); L2 message signatures verify with each ecosystem's own
function (XLS-72d has none); L3 confirmed on Stacks and the XRP Ledger (both funded from keyless faucet APIs); the rest
wait for funds and say why. Fixes found: XRPL testnet RPC without CORS preflight (testnet.xrpl-labs.com first) and the
MultiversX page's L1 asking for a second approval (native auth off). docs/r1/dapp-matrix.md and
dapp-matrix-funding.md list results and the faucets left for the owner. MATRIX_DEBUG=1 prints a dapp page's console.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Schayan Salehi and others added 3 commits October 6, 2026 21:57
…on-path check covers every family

- chains-cosmos tests use Buffer: @types/node as a dev dependency, as the other chain packages have it (vitest 4 no
  longer brings it in).
- extension-kit's derivation-path test (every module's derivationPath() names the path the vault derives) expected
  14 families; it now checks FAMILIES.length, and all 26 match.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ADME network table and counts

- reference/networks (in the sidebar): 85 of the 87 CLPR networks and 93 mainnets, how the count works, every
  supported CLPR network with its module, network id and dapp connectivity, the families' derivation paths, why
  Canton and Mixin aren't supported, and the limits worth knowing. Built from docs/r1/networks87.md; the coverage is
  the one networks87.test.ts computes from the catalogue.
- Dapp guides: Cosmos SDK (Keplr-compatible API at window.clipwallet.cosmos), TRON (TIP-1193 + TIP-6963), XRP Ledger
  (XLS-72d), Stacks (SIP-030 + WBIP-004), Fuel (FuelConnector), Bitcoin Cash (WalletConnect wc2-bch-bcr) and
  MultiversX (best effort, through sdk-dapp's undocumented hook), with typechecked snippets; Antelope and ICP are
  send and receive only; Chainflip in the Polkadot guide, STRATO in the EVM guide, bch in the WalletConnect table.
- Chain modules, vault derivation table, vault cryptography and the family counts across the site follow the 26
  families; the docs workspace depends on the new chain packages so their README examples typecheck.
- README: 85 of 87 CLPR networks, 26 families, 93 mainnets; the standards 1Mask speaks; the network table gains the
  newer families with their dapp matrix results; the internal review covered the first 14 families.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nitia feature names

Reviewed false positives of the generic-api-key rule: Antelope PUB_K1 and secp256k1 public keys in test fixtures,
XRPL NFToken and offer ids (public ledger object ids), and Initia's chain feature names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread packages/chains-cosmos/src/rest.ts Fixed
Schayan Salehi and others added 3 commits October 6, 2026 22:38
Trailing slashes are trimmed with a scan instead of /\/+$/ (backup-client's base URL, chains-cosmos REST endpoints,
chains-hedera's mirror node, CoinGecko's base, settle-on-Hedera Connector URLs), and route's short ledger names drop
a trailing "(…)" with indexOf instead of /\s*\(.*\)\s*$/. Same results, linear on any input.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… ReDoS)

packages/route/src/url.ts withoutTrailingSlashes() replaces /\/+$/ in the mirror-node reader (which then drops a
trailing /api/v1 with endsWith), the tracker's base URL and the Connector quote URL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The comment that explained the Initia feature-name entries quoted them, so the ignore list itself matched the
generic-api-key rule. The comment no longer quotes them, and the commit that did is listed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@shayansal
shayansal changed the base branch from feat/kit-all-platforms to main October 7, 2026 08:57
@shayansal
shayansal merged commit b3ecfbb into main Oct 7, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants