@kingdomchain/wallet-client
v0.2.0
Published
Kingdom Chain browser wallet + CosmJS client for citizenship applications and recovery attestations
Maintainers
Readme
Kingdom Chain TypeScript / CosmJS client
Self-contained TypeScript package for constructing, signing, and broadcasting Kingdom Chain transactions via CosmJS. Includes a Keplr / Leap / Cosmostation browser wallet connector for non-custodial signing.
Scope (current)
- MsgSubmitApplication (citizenship application)
- MsgSubmitRecoveryAttestation (wallet recovery attestation)
- Browser wallet connector (
src/browserSigner.ts) — Keplr / Leap / Cosmostation viaexperimentalSuggestChain+OfflineDirectSigner - WalletConnect mobile signer (
src/walletConnectSigner.ts) — WalletConnect v2OfflineDirectSigneradapter - Embedded passkey wallet (
src/embeddedWallet/) — WebAuthn PRF + PBKDF2 fallback, IndexedDB vault, mandatory backup gate - Ed25519 attestation signing ported from
x/compliance/types/attestation.go - Proto codegen via
ts-proto+buf
Setup
cd clients/ts
npm install
npm run codegen # regenerate from ../../proto (requires buf + repo root)Testing
cd clients/ts
npm test # unit + property fuzz (1500 cross-lang iterations)
npm run test:mutate # Stryker mutation testing on attestation.ts + registry.tsCross-language fuzz compares TS attestationSignPayload against a compiled Go helper (payload_attestation.go) for 1000 citizenship + 500 recovery inputs.
Live E2E (Ona devnet)
Requires a running node at ~/.kingdomchain-e2e (see scripts/citizen-compliance-e2e/run.sh).
# Build CLI if needed
go build -o /tmp/kingdomchaind ./cmd/kingdomchaind
cd clients/ts
npm run e2e:submit-application
npm run e2e:submit-recoveryEnvironment overrides:
| Variable | Default |
|----------|---------|
| CHAIN_ID | kingdomchain-e2e |
| RPC_URL | http://127.0.0.1:26657 |
| REST_URL | http://127.0.0.1:1317 |
| HOME_DIR | ~/.kingdomchain-e2e |
| KINGDOMCHAIND | /tmp/kingdomchaind |
| PROVIDER_SEED_HEX | devnet provider-alpha seed from e2e script |
Browser wallet demo (Keplr / Leap)
Manual click-through demo for Isa — not automated in CI. Unit tests mock window.keplr / window.leap; the demo requires a real extension in your browser.
- Start the Ona devnet (
scripts/citizen-compliance-e2e/run.shor your existing node). - Fund the Keplr/Leap account you will connect with (
ukdronkingdomchain-e2e). - From
clients/ts:
npm run demo- Open the printed URL (default
http://localhost:5173) in a browser with Keplr or Leap installed. - Click Connect Keplr or Connect Leap, approve the chain suggestion + connection, then Submit test application.
Optional Vite env overrides (prefix VITE_):
| Variable | Default |
|----------|---------|
| VITE_CHAIN_ID | kingdomchain-e2e |
| VITE_RPC_URL | http://127.0.0.1:26657 |
| VITE_REST_URL | http://127.0.0.1:1317 |
| VITE_PROVIDER_ID | provider-alpha |
| VITE_POLICY_VERSION | policy-v1 |
| VITE_PROVIDER_SEED_HEX | devnet provider-alpha seed |
The demo signs the provider attestation off-chain (devnet seed) and broadcasts MsgSubmitApplication using your connected wallet as the on-chain tx signer.
Kingdom OS / Base44 reference wiring
Copy-paste React integration lives in clients/kingdom-os-reference/:
useKingdomWallet.js— unified hook for Keplr, Leap, Cosmostation, WalletConnect, embedded passkeyWalletStep.jsx— onboarding UI with side-by-side connect buttonsWalletConnectQrModal.jsx— QR pairing modal (VITE_WC_PROJECT_IDrequired)EmbeddedWalletPanel.jsx— create / unlock / mandatory backup gate
See clients/kingdom-os-reference/README.md for env vars and usage.
Embedded wallet API (src/embeddedWallet/)
createEmbeddedWallet({ userId, userName, displayName, rpId? })— register passkey + encrypt vault in IndexedDBunlockEmbeddedWallet()— passkey assertion → in-memory sessiongetEmbeddedOfflineSigner()— CosmJS signer; throwsEmbeddedWalletBackupRequiredErroruntil backup acknowledgedacknowledgeEmbeddedBackup()/downloadEmbeddedBackupFile()— mandatory backup gateimportEmbeddedBackup(json)— restore vault from user-held backup filehasEmbeddedWallet()/clearEmbeddedWallet()— lifecycle helpers
KDF selection: WebAuthn PRF when available, PBKDF2-passkey fallback (310k iterations — bump to 600k+ before production).
Recovery gap (phase 3): The encrypted backup file requires the original passkey to decrypt. Option D (BIP39 mnemonic export for passkey loss without iCloud/Google sync) is approved in the ADR but not implemented in phase 2 — see docs/architecture/ADR-EMBEDDED-WALLET-ONBOARDING.md § "Known gap: Option D mnemonic recovery".
WalletConnect API (src/walletConnectSigner.ts)
initWalletConnectClient({ chainId, projectId, metadata })connectWalletConnect(client, chainId)→{ uri, session, signer }(displayurias QR)restoreWalletConnectSession(client, chainId)— reconnect on page loadcreateWalletConnectOfflineSigner(client, session, chainId)disconnectWalletConnect(client, session)
Browser wallet API (src/browserSigner.ts)
isKeplrAvailable()/isLeapAvailable()buildKingdomChainInfo(chainId, rpcUrl, restUrl)—ukdr/ KDR with 6 decimals (x/supply/types/constants.go,TOKENOMICS_COSMOS_SPEC.md), bech32 prefixking, coin type 118connectKeplr(chainInfo)/connectLeap(chainInfo)— suggest chain + enable + offline signercreateBrowserSigningClient(rpcUrl, signer)—SigningStargateClient+createKingdomChainRegistry()
Encoding notes (for Base44 frontend)
- Custom protobuf registry — CosmJS
SigningStargateClientmust be constructed with aRegistrythat includes Kingdom Chain message type URLs (e.g./isatheword.kingdomchain.compliance.v1.MsgSubmitApplication) alongsidedefaultRegistryTypes. - Attestation signing is off-chain — providers sign a canonical SHA256-payload (not the tx bytes). The TS port in
src/attestation.tsmust match GoAttestationSignPayloadexactly; the E2E script cross-checks againstscripts/citizen-compliance-e2e/sign_attestation.go. - Timestamps — proto
google.protobuf.Timestampfields (issued_at,expires_at) areDatein generated TS; encoding uses@bufbuild/protobufwire format. - Uint64 fields —
provider_key_versionisbigintin generated types. - Tx signer —
MsgSubmitApplicationsigner isapplicant_wallet; the fee payer / signer must be the applicant's secp256k1 account (kingbech32 prefix, coin type 118).
