@kingdomchain/wallet-client 0.4.1 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +130 -130
- package/dist/index.d.ts +53 -18
- package/dist/index.js +125 -61
- package/dist/index.js.map +1 -1
- package/package.json +77 -77
package/README.md
CHANGED
|
@@ -1,130 +1,130 @@
|
|
|
1
|
-
# Kingdom Chain TypeScript / CosmJS client
|
|
2
|
-
|
|
3
|
-
Self-contained TypeScript package for constructing, signing, and broadcasting Kingdom Chain transactions via [CosmJS](https://github.com/cosmos/cosm-js). Includes a Keplr / Leap / Cosmostation browser wallet connector for non-custodial signing.
|
|
4
|
-
|
|
5
|
-
## Scope (current)
|
|
6
|
-
|
|
7
|
-
- **MsgSubmitApplication** (citizenship application)
|
|
8
|
-
- **MsgSubmitRecoveryAttestation** (wallet recovery attestation)
|
|
9
|
-
- **Browser wallet connector** (`src/browserSigner.ts`) — Keplr / Leap / Cosmostation via `experimentalSuggestChain` + `OfflineDirectSigner`
|
|
10
|
-
- **WalletConnect mobile signer** (`src/walletConnectSigner.ts`) — WalletConnect v2 `OfflineDirectSigner` adapter
|
|
11
|
-
- **Embedded passkey wallet** (`src/embeddedWallet/`) — WebAuthn PRF + PBKDF2 fallback, IndexedDB vault, mandatory backup gate
|
|
12
|
-
- Ed25519 attestation signing ported from `x/compliance/types/attestation.go`
|
|
13
|
-
- Proto codegen via `ts-proto` + `buf`
|
|
14
|
-
|
|
15
|
-
## Setup
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
cd clients/ts
|
|
19
|
-
npm install
|
|
20
|
-
npm run codegen # regenerate from ../../proto (requires buf + repo root)
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Testing
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
cd clients/ts
|
|
27
|
-
npm test # unit + property fuzz (1500 cross-lang iterations)
|
|
28
|
-
npm run test:mutate # Stryker mutation testing on attestation.ts + registry.ts
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
Cross-language fuzz compares TS `attestationSignPayload` against a compiled Go helper (`payload_attestation.go`) for 1000 citizenship + 500 recovery inputs.
|
|
32
|
-
|
|
33
|
-
## Live E2E (Ona devnet)
|
|
34
|
-
|
|
35
|
-
Requires a running node at `~/.kingdomchain-e2e` (see `scripts/citizen-compliance-e2e/run.sh`).
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
# Build CLI if needed
|
|
39
|
-
go build -o /tmp/kingdomchaind ./cmd/kingdomchaind
|
|
40
|
-
|
|
41
|
-
cd clients/ts
|
|
42
|
-
npm run e2e:submit-application
|
|
43
|
-
npm run e2e:submit-recovery
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
Environment overrides:
|
|
47
|
-
|
|
48
|
-
| Variable | Default |
|
|
49
|
-
|----------|---------|
|
|
50
|
-
| `CHAIN_ID` | `kingdomchain-e2e` |
|
|
51
|
-
| `RPC_URL` | `http://127.0.0.1:26657` |
|
|
52
|
-
| `REST_URL` | `http://127.0.0.1:1317` |
|
|
53
|
-
| `HOME_DIR` | `~/.kingdomchain-e2e` |
|
|
54
|
-
| `KINGDOMCHAIND` | `/tmp/kingdomchaind` |
|
|
55
|
-
| `PROVIDER_SEED_HEX` | devnet provider-alpha seed from e2e script |
|
|
56
|
-
|
|
57
|
-
## Browser wallet demo (Keplr / Leap)
|
|
58
|
-
|
|
59
|
-
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.
|
|
60
|
-
|
|
61
|
-
1. Start the Ona devnet (`scripts/citizen-compliance-e2e/run.sh` or your existing node).
|
|
62
|
-
2. Fund the Keplr/Leap account you will connect with (`ukdr` on `kingdomchain-e2e`).
|
|
63
|
-
3. From `clients/ts`:
|
|
64
|
-
|
|
65
|
-
```bash
|
|
66
|
-
npm run demo
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
4. Open the printed URL (default `http://localhost:5173`) in a browser with Keplr or Leap installed.
|
|
70
|
-
5. Click **Connect Keplr** or **Connect Leap**, approve the chain suggestion + connection, then **Submit test application**.
|
|
71
|
-
|
|
72
|
-
Optional Vite env overrides (prefix `VITE_`):
|
|
73
|
-
|
|
74
|
-
| Variable | Default |
|
|
75
|
-
|----------|---------|
|
|
76
|
-
| `VITE_CHAIN_ID` | `kingdomchain-e2e` |
|
|
77
|
-
| `VITE_RPC_URL` | `http://127.0.0.1:26657` |
|
|
78
|
-
| `VITE_REST_URL` | `http://127.0.0.1:1317` |
|
|
79
|
-
| `VITE_PROVIDER_ID` | `provider-alpha` |
|
|
80
|
-
| `VITE_POLICY_VERSION` | `policy-v1` |
|
|
81
|
-
| `VITE_PROVIDER_SEED_HEX` | devnet provider-alpha seed |
|
|
82
|
-
|
|
83
|
-
The demo signs the provider attestation off-chain (devnet seed) and broadcasts `MsgSubmitApplication` using your connected wallet as the on-chain tx signer.
|
|
84
|
-
|
|
85
|
-
## Kingdom OS / Base44 reference wiring
|
|
86
|
-
|
|
87
|
-
Copy-paste React integration lives in `clients/kingdom-os-reference/`:
|
|
88
|
-
|
|
89
|
-
- `useKingdomWallet.js` — unified hook for Keplr, Leap, Cosmostation, WalletConnect, embedded passkey
|
|
90
|
-
- `WalletStep.jsx` — onboarding UI with side-by-side connect buttons
|
|
91
|
-
- `WalletConnectQrModal.jsx` — QR pairing modal (`VITE_WC_PROJECT_ID` required)
|
|
92
|
-
- `EmbeddedWalletPanel.jsx` — create / unlock / mandatory backup gate
|
|
93
|
-
|
|
94
|
-
See `clients/kingdom-os-reference/README.md` for env vars and usage.
|
|
95
|
-
|
|
96
|
-
### Embedded wallet API (`src/embeddedWallet/`)
|
|
97
|
-
|
|
98
|
-
- `createEmbeddedWallet({ userId, userName, displayName, rpId? })` — register passkey + encrypt vault in IndexedDB
|
|
99
|
-
- `unlockEmbeddedWallet()` — passkey assertion → in-memory session
|
|
100
|
-
- `getEmbeddedOfflineSigner()` — CosmJS signer; throws `EmbeddedWalletBackupRequiredError` until backup acknowledged
|
|
101
|
-
- `acknowledgeEmbeddedBackup()` / `downloadEmbeddedBackupFile()` — mandatory backup gate
|
|
102
|
-
- `importEmbeddedBackup(json)` — restore vault from user-held backup file
|
|
103
|
-
- `hasEmbeddedWallet()` / `clearEmbeddedWallet()` — lifecycle helpers
|
|
104
|
-
|
|
105
|
-
KDF selection: WebAuthn PRF when available, PBKDF2-passkey fallback (310k iterations — bump to 600k+ before production).
|
|
106
|
-
|
|
107
|
-
**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".
|
|
108
|
-
|
|
109
|
-
### WalletConnect API (`src/walletConnectSigner.ts`)
|
|
110
|
-
|
|
111
|
-
- `initWalletConnectClient({ chainId, projectId, metadata })`
|
|
112
|
-
- `connectWalletConnect(client, chainId)` → `{ uri, session, signer }` (display `uri` as QR)
|
|
113
|
-
- `restoreWalletConnectSession(client, chainId)` — reconnect on page load
|
|
114
|
-
- `createWalletConnectOfflineSigner(client, session, chainId)`
|
|
115
|
-
- `disconnectWalletConnect(client, session)`
|
|
116
|
-
|
|
117
|
-
### Browser wallet API (`src/browserSigner.ts`)
|
|
118
|
-
|
|
119
|
-
- `isKeplrAvailable()` / `isLeapAvailable()`
|
|
120
|
-
- `buildKingdomChainInfo(chainId, rpcUrl, restUrl)` — `ukdr` / KDR with **6 decimals** (`x/supply/types/constants.go`, `TOKENOMICS_COSMOS_SPEC.md`), bech32 prefix `king`, coin type 118
|
|
121
|
-
- `connectKeplr(chainInfo)` / `connectLeap(chainInfo)` — suggest chain + enable + offline signer
|
|
122
|
-
- `createBrowserSigningClient(rpcUrl, signer)` — `SigningStargateClient` + `createKingdomChainRegistry()`
|
|
123
|
-
|
|
124
|
-
## Encoding notes (for Base44 frontend)
|
|
125
|
-
|
|
126
|
-
1. **Custom protobuf registry** — CosmJS `SigningStargateClient` must be constructed with a `Registry` that includes Kingdom Chain message type URLs (e.g. `/isatheword.kingdomchain.compliance.v1.MsgSubmitApplication`) alongside `defaultRegistryTypes`.
|
|
127
|
-
2. **Attestation signing is off-chain** — providers sign a canonical SHA256-payload (not the tx bytes). The TS port in `src/attestation.ts` must match Go `AttestationSignPayload` exactly; the E2E script cross-checks against `scripts/citizen-compliance-e2e/sign_attestation.go`.
|
|
128
|
-
3. **Timestamps** — proto `google.protobuf.Timestamp` fields (`issued_at`, `expires_at`) are `Date` in generated TS; encoding uses `@bufbuild/protobuf` wire format.
|
|
129
|
-
4. **Uint64 fields** — `provider_key_version` is `bigint` in generated types.
|
|
130
|
-
5. **Tx signer** — `MsgSubmitApplication` signer is `applicant_wallet`; the fee payer / signer must be the applicant's secp256k1 account (`king` bech32 prefix, coin type 118).
|
|
1
|
+
# Kingdom Chain TypeScript / CosmJS client
|
|
2
|
+
|
|
3
|
+
Self-contained TypeScript package for constructing, signing, and broadcasting Kingdom Chain transactions via [CosmJS](https://github.com/cosmos/cosm-js). Includes a Keplr / Leap / Cosmostation browser wallet connector for non-custodial signing.
|
|
4
|
+
|
|
5
|
+
## Scope (current)
|
|
6
|
+
|
|
7
|
+
- **MsgSubmitApplication** (citizenship application)
|
|
8
|
+
- **MsgSubmitRecoveryAttestation** (wallet recovery attestation)
|
|
9
|
+
- **Browser wallet connector** (`src/browserSigner.ts`) — Keplr / Leap / Cosmostation via `experimentalSuggestChain` + `OfflineDirectSigner`
|
|
10
|
+
- **WalletConnect mobile signer** (`src/walletConnectSigner.ts`) — WalletConnect v2 `OfflineDirectSigner` adapter
|
|
11
|
+
- **Embedded passkey wallet** (`src/embeddedWallet/`) — WebAuthn PRF + PBKDF2 fallback, IndexedDB vault, mandatory backup gate
|
|
12
|
+
- Ed25519 attestation signing ported from `x/compliance/types/attestation.go`
|
|
13
|
+
- Proto codegen via `ts-proto` + `buf`
|
|
14
|
+
|
|
15
|
+
## Setup
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
cd clients/ts
|
|
19
|
+
npm install
|
|
20
|
+
npm run codegen # regenerate from ../../proto (requires buf + repo root)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Testing
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
cd clients/ts
|
|
27
|
+
npm test # unit + property fuzz (1500 cross-lang iterations)
|
|
28
|
+
npm run test:mutate # Stryker mutation testing on attestation.ts + registry.ts
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Cross-language fuzz compares TS `attestationSignPayload` against a compiled Go helper (`payload_attestation.go`) for 1000 citizenship + 500 recovery inputs.
|
|
32
|
+
|
|
33
|
+
## Live E2E (Ona devnet)
|
|
34
|
+
|
|
35
|
+
Requires a running node at `~/.kingdomchain-e2e` (see `scripts/citizen-compliance-e2e/run.sh`).
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Build CLI if needed
|
|
39
|
+
go build -o /tmp/kingdomchaind ./cmd/kingdomchaind
|
|
40
|
+
|
|
41
|
+
cd clients/ts
|
|
42
|
+
npm run e2e:submit-application
|
|
43
|
+
npm run e2e:submit-recovery
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Environment overrides:
|
|
47
|
+
|
|
48
|
+
| Variable | Default |
|
|
49
|
+
|----------|---------|
|
|
50
|
+
| `CHAIN_ID` | `kingdomchain-e2e` |
|
|
51
|
+
| `RPC_URL` | `http://127.0.0.1:26657` |
|
|
52
|
+
| `REST_URL` | `http://127.0.0.1:1317` |
|
|
53
|
+
| `HOME_DIR` | `~/.kingdomchain-e2e` |
|
|
54
|
+
| `KINGDOMCHAIND` | `/tmp/kingdomchaind` |
|
|
55
|
+
| `PROVIDER_SEED_HEX` | devnet provider-alpha seed from e2e script |
|
|
56
|
+
|
|
57
|
+
## Browser wallet demo (Keplr / Leap)
|
|
58
|
+
|
|
59
|
+
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.
|
|
60
|
+
|
|
61
|
+
1. Start the Ona devnet (`scripts/citizen-compliance-e2e/run.sh` or your existing node).
|
|
62
|
+
2. Fund the Keplr/Leap account you will connect with (`ukdr` on `kingdomchain-e2e`).
|
|
63
|
+
3. From `clients/ts`:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
npm run demo
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
4. Open the printed URL (default `http://localhost:5173`) in a browser with Keplr or Leap installed.
|
|
70
|
+
5. Click **Connect Keplr** or **Connect Leap**, approve the chain suggestion + connection, then **Submit test application**.
|
|
71
|
+
|
|
72
|
+
Optional Vite env overrides (prefix `VITE_`):
|
|
73
|
+
|
|
74
|
+
| Variable | Default |
|
|
75
|
+
|----------|---------|
|
|
76
|
+
| `VITE_CHAIN_ID` | `kingdomchain-e2e` |
|
|
77
|
+
| `VITE_RPC_URL` | `http://127.0.0.1:26657` |
|
|
78
|
+
| `VITE_REST_URL` | `http://127.0.0.1:1317` |
|
|
79
|
+
| `VITE_PROVIDER_ID` | `provider-alpha` |
|
|
80
|
+
| `VITE_POLICY_VERSION` | `policy-v1` |
|
|
81
|
+
| `VITE_PROVIDER_SEED_HEX` | devnet provider-alpha seed |
|
|
82
|
+
|
|
83
|
+
The demo signs the provider attestation off-chain (devnet seed) and broadcasts `MsgSubmitApplication` using your connected wallet as the on-chain tx signer.
|
|
84
|
+
|
|
85
|
+
## Kingdom OS / Base44 reference wiring
|
|
86
|
+
|
|
87
|
+
Copy-paste React integration lives in `clients/kingdom-os-reference/`:
|
|
88
|
+
|
|
89
|
+
- `useKingdomWallet.js` — unified hook for Keplr, Leap, Cosmostation, WalletConnect, embedded passkey
|
|
90
|
+
- `WalletStep.jsx` — onboarding UI with side-by-side connect buttons
|
|
91
|
+
- `WalletConnectQrModal.jsx` — QR pairing modal (`VITE_WC_PROJECT_ID` required)
|
|
92
|
+
- `EmbeddedWalletPanel.jsx` — create / unlock / mandatory backup gate
|
|
93
|
+
|
|
94
|
+
See `clients/kingdom-os-reference/README.md` for env vars and usage.
|
|
95
|
+
|
|
96
|
+
### Embedded wallet API (`src/embeddedWallet/`)
|
|
97
|
+
|
|
98
|
+
- `createEmbeddedWallet({ userId, userName, displayName, rpId? })` — register passkey + encrypt vault in IndexedDB
|
|
99
|
+
- `unlockEmbeddedWallet()` — passkey assertion → in-memory session
|
|
100
|
+
- `getEmbeddedOfflineSigner()` — CosmJS signer; throws `EmbeddedWalletBackupRequiredError` until backup acknowledged
|
|
101
|
+
- `acknowledgeEmbeddedBackup()` / `downloadEmbeddedBackupFile()` — mandatory backup gate
|
|
102
|
+
- `importEmbeddedBackup(json)` — restore vault from user-held backup file
|
|
103
|
+
- `hasEmbeddedWallet()` / `clearEmbeddedWallet()` — lifecycle helpers
|
|
104
|
+
|
|
105
|
+
KDF selection: WebAuthn PRF when available, PBKDF2-passkey fallback (310k iterations — bump to 600k+ before production).
|
|
106
|
+
|
|
107
|
+
**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".
|
|
108
|
+
|
|
109
|
+
### WalletConnect API (`src/walletConnectSigner.ts`)
|
|
110
|
+
|
|
111
|
+
- `initWalletConnectClient({ chainId, projectId, metadata })`
|
|
112
|
+
- `connectWalletConnect(client, chainId)` → `{ uri, session, signer }` (display `uri` as QR)
|
|
113
|
+
- `restoreWalletConnectSession(client, chainId)` — reconnect on page load
|
|
114
|
+
- `createWalletConnectOfflineSigner(client, session, chainId)`
|
|
115
|
+
- `disconnectWalletConnect(client, session)`
|
|
116
|
+
|
|
117
|
+
### Browser wallet API (`src/browserSigner.ts`)
|
|
118
|
+
|
|
119
|
+
- `isKeplrAvailable()` / `isLeapAvailable()`
|
|
120
|
+
- `buildKingdomChainInfo(chainId, rpcUrl, restUrl)` — `ukdr` / KDR with **6 decimals** (`x/supply/types/constants.go`, `TOKENOMICS_COSMOS_SPEC.md`), bech32 prefix `king`, coin type 118
|
|
121
|
+
- `connectKeplr(chainInfo)` / `connectLeap(chainInfo)` — suggest chain + enable + offline signer
|
|
122
|
+
- `createBrowserSigningClient(rpcUrl, signer)` — `SigningStargateClient` + `createKingdomChainRegistry()`
|
|
123
|
+
|
|
124
|
+
## Encoding notes (for Base44 frontend)
|
|
125
|
+
|
|
126
|
+
1. **Custom protobuf registry** — CosmJS `SigningStargateClient` must be constructed with a `Registry` that includes Kingdom Chain message type URLs (e.g. `/isatheword.kingdomchain.compliance.v1.MsgSubmitApplication`) alongside `defaultRegistryTypes`.
|
|
127
|
+
2. **Attestation signing is off-chain** — providers sign a canonical SHA256-payload (not the tx bytes). The TS port in `src/attestation.ts` must match Go `AttestationSignPayload` exactly; the E2E script cross-checks against `scripts/citizen-compliance-e2e/sign_attestation.go`.
|
|
128
|
+
3. **Timestamps** — proto `google.protobuf.Timestamp` fields (`issued_at`, `expires_at`) are `Date` in generated TS; encoding uses `@bufbuild/protobuf` wire format.
|
|
129
|
+
4. **Uint64 fields** — `provider_key_version` is `bigint` in generated types.
|
|
130
|
+
5. **Tx signer** — `MsgSubmitApplication` signer is `applicant_wallet`; the fee payer / signer must be the applicant's secp256k1 account (`king` bech32 prefix, coin type 118).
|
package/dist/index.d.ts
CHANGED
|
@@ -301,6 +301,11 @@ declare class EmbeddedWalletBackupRequiredError extends Error {
|
|
|
301
301
|
declare class EmbeddedWalletVaultError extends Error {
|
|
302
302
|
constructor(message: string, cause?: unknown);
|
|
303
303
|
}
|
|
304
|
+
/** Thrown when AES-GCM decryption fails (wrong KEK or tampered ciphertext). */
|
|
305
|
+
declare class EmbeddedWalletDecryptError extends EmbeddedWalletVaultError {
|
|
306
|
+
readonly code: "decrypt_failed";
|
|
307
|
+
constructor(cause?: unknown);
|
|
308
|
+
}
|
|
304
309
|
type PasscodeStrengthLabel = "weak" | "fair" | "good" | "strong";
|
|
305
310
|
type PasscodeBlockReason = "denylist" | "too_weak" | "numeric_short";
|
|
306
311
|
/** Thrown when too many failed passcode unlock attempts trigger a timed lockout. */
|
|
@@ -402,14 +407,21 @@ declare function decodeCredentialId(encoded: string): Uint8Array;
|
|
|
402
407
|
declare function embeddedPlaintextToSigner(plaintext: EmbeddedWalletPlaintext, prefix?: string): Promise<DirectSecp256k1Wallet>;
|
|
403
408
|
declare function defaultEmbeddedHdPath(): string;
|
|
404
409
|
|
|
410
|
+
/** Legacy unscoped vault key used before per-account scoping shipped. */
|
|
411
|
+
declare const VAULT_LEGACY_KEY = "primary";
|
|
412
|
+
interface VaultStorageOptions {
|
|
413
|
+
/** When set, vault is stored under this account-scoped key instead of {@link VAULT_LEGACY_KEY}. */
|
|
414
|
+
scopeId?: string;
|
|
415
|
+
}
|
|
405
416
|
interface PasscodeLockoutRecord {
|
|
406
417
|
failedAttempts: number;
|
|
407
418
|
lockoutTier: number;
|
|
408
419
|
lockedUntil: string | null;
|
|
409
420
|
}
|
|
410
|
-
declare function
|
|
411
|
-
declare function
|
|
412
|
-
declare function
|
|
421
|
+
declare function resolveVaultStorageKey(scopeId?: string): string;
|
|
422
|
+
declare function saveVaultToIndexedDb(vault: EmbeddedWalletVaultV1, options?: VaultStorageOptions): Promise<void>;
|
|
423
|
+
declare function loadVaultFromIndexedDb(options?: VaultStorageOptions): Promise<EmbeddedWalletVaultV1 | null>;
|
|
424
|
+
declare function clearVaultFromIndexedDb(options?: VaultStorageOptions): Promise<void>;
|
|
413
425
|
declare function loadPasscodeLockoutRecord(publicAddress: string): Promise<PasscodeLockoutRecord | null>;
|
|
414
426
|
declare function savePasscodeLockoutRecord(publicAddress: string, record: PasscodeLockoutRecord): Promise<void>;
|
|
415
427
|
declare function clearPasscodeLockoutRecord(publicAddress: string): Promise<void>;
|
|
@@ -420,6 +432,8 @@ declare const PASSCODE_LOCKOUT_FAILURE_THRESHOLD = 5;
|
|
|
420
432
|
declare const PASSCODE_LOCKOUT_INITIAL_MS = 30000;
|
|
421
433
|
/** Maximum lockout duration (15 minutes). */
|
|
422
434
|
declare const PASSCODE_LOCKOUT_MAX_MS = 900000;
|
|
435
|
+
/** Pure lockout duration for a tier (exported for property tests). */
|
|
436
|
+
declare function computePasscodeLockoutDurationMs(tier: number): number;
|
|
423
437
|
/** Throws when the vault is temporarily locked after too many failed unlock attempts. */
|
|
424
438
|
declare function assertPasscodeUnlockAllowed(publicAddress: string): Promise<void>;
|
|
425
439
|
/** Record a failed passcode unlock attempt; triggers lockout at threshold. */
|
|
@@ -429,8 +443,6 @@ declare function recordPasscodeUnlockSuccess(publicAddress: string): Promise<voi
|
|
|
429
443
|
declare function getPasscodeLockoutState(publicAddress: string): Promise<PasscodeLockoutRecord & {
|
|
430
444
|
retryAfterMs: number;
|
|
431
445
|
}>;
|
|
432
|
-
/** @internal Test helper — reset lockout without clearing vault. */
|
|
433
|
-
declare function clearPasscodeLockoutForTests(publicAddress: string): Promise<void>;
|
|
434
446
|
|
|
435
447
|
interface PasscodeStrengthResult {
|
|
436
448
|
score: 0 | 1 | 2 | 3 | 4;
|
|
@@ -453,8 +465,8 @@ declare const EMBEDDED_WALLET_PASSCODE_MAX_LENGTH = 128;
|
|
|
453
465
|
* Uses native Web Crypto — no WASM bundle required.
|
|
454
466
|
*/
|
|
455
467
|
declare const EMBEDDED_WALLET_PIN_PBKDF2_ITERATIONS = 600000;
|
|
456
|
-
/**
|
|
457
|
-
declare const EMBEDDED_WALLET_PASSKEY_PBKDF2_ITERATIONS =
|
|
468
|
+
/** Passkey PBKDF2 fallback iteration count (matches PIN path; OWASP 2023 guidance). */
|
|
469
|
+
declare const EMBEDDED_WALLET_PASSKEY_PBKDF2_ITERATIONS = 600000;
|
|
458
470
|
declare function normalizePasscode(passcode: string): string;
|
|
459
471
|
/** Validate citizen-chosen passcode before KDF. */
|
|
460
472
|
declare function assertValidPasscode(passcode: string): void;
|
|
@@ -479,16 +491,20 @@ declare function recoveryMnemonicAddress(mnemonic: string, keyType: EmbeddedWall
|
|
|
479
491
|
/** Build the recovery phrase for an unlocked plaintext payload. */
|
|
480
492
|
declare function recoveryMnemonicFromPlaintext(plaintext: EmbeddedWalletPlaintext): string;
|
|
481
493
|
|
|
482
|
-
interface
|
|
494
|
+
interface EmbeddedWalletScopeOptions {
|
|
495
|
+
/** Supabase user id or other account key — scopes IndexedDB vault storage per account. */
|
|
496
|
+
scopeId?: string;
|
|
497
|
+
}
|
|
498
|
+
interface CreateEmbeddedWalletOptions extends EmbeddedWalletScopeOptions {
|
|
483
499
|
passcode: string;
|
|
484
500
|
}
|
|
485
|
-
interface UnlockEmbeddedWalletOptions {
|
|
501
|
+
interface UnlockEmbeddedWalletOptions extends EmbeddedWalletScopeOptions {
|
|
486
502
|
passcode?: string;
|
|
487
503
|
}
|
|
488
|
-
interface RevealEmbeddedRecoveryPhraseOptions {
|
|
504
|
+
interface RevealEmbeddedRecoveryPhraseOptions extends EmbeddedWalletScopeOptions {
|
|
489
505
|
passcode?: string;
|
|
490
506
|
}
|
|
491
|
-
interface RecoverEmbeddedWalletOptions {
|
|
507
|
+
interface RecoverEmbeddedWalletOptions extends EmbeddedWalletScopeOptions {
|
|
492
508
|
passcode: string;
|
|
493
509
|
mnemonic: string;
|
|
494
510
|
/** When omitted, inferred from expectedAddress or defaults to hd-derived. */
|
|
@@ -499,13 +515,25 @@ interface RecoverEmbeddedWalletOptions {
|
|
|
499
515
|
/** When true, replaces an existing vault on this device (e.g. after device loss). */
|
|
500
516
|
replaceExisting?: boolean;
|
|
501
517
|
}
|
|
502
|
-
interface EnableEmbeddedPasskeyUnlockOptions {
|
|
518
|
+
interface EnableEmbeddedPasskeyUnlockOptions extends EmbeddedWalletScopeOptions {
|
|
503
519
|
passcode: string;
|
|
504
520
|
userId: Uint8Array;
|
|
505
521
|
userName: string;
|
|
506
522
|
displayName: string;
|
|
507
523
|
rpId?: string;
|
|
508
524
|
}
|
|
525
|
+
interface MigrateLegacyEmbeddedWalletOptions extends EmbeddedWalletScopeOptions {
|
|
526
|
+
scopeId: string;
|
|
527
|
+
passcode?: string;
|
|
528
|
+
}
|
|
529
|
+
interface ImportEmbeddedBackupOptions extends EmbeddedWalletScopeOptions {
|
|
530
|
+
/** When true, replaces an existing vault on this device (e.g. intentional restore). */
|
|
531
|
+
replaceExisting?: boolean;
|
|
532
|
+
}
|
|
533
|
+
interface ClearEmbeddedWalletOptions extends EmbeddedWalletScopeOptions {
|
|
534
|
+
}
|
|
535
|
+
interface AcknowledgeEmbeddedBackupOptions extends EmbeddedWalletScopeOptions {
|
|
536
|
+
}
|
|
509
537
|
interface EmbeddedWalletSession {
|
|
510
538
|
address: string;
|
|
511
539
|
vault: EmbeddedWalletVaultV1;
|
|
@@ -513,8 +541,15 @@ interface EmbeddedWalletSession {
|
|
|
513
541
|
}
|
|
514
542
|
declare function vaultUsesPasskeyUnlock(vault: EmbeddedWalletVaultV1): boolean;
|
|
515
543
|
declare function vaultUsesPasscodeUnlock(vault: EmbeddedWalletVaultV1): boolean;
|
|
516
|
-
/** Returns true if an encrypted vault exists
|
|
517
|
-
declare function hasEmbeddedWallet(): Promise<boolean>;
|
|
544
|
+
/** Returns true if an encrypted vault exists under the given scope (not the legacy key). */
|
|
545
|
+
declare function hasEmbeddedWallet(options?: EmbeddedWalletScopeOptions): Promise<boolean>;
|
|
546
|
+
/** Returns true if an unscoped legacy vault still exists under the "primary" key. */
|
|
547
|
+
declare function hasLegacyEmbeddedWallet(): Promise<boolean>;
|
|
548
|
+
/**
|
|
549
|
+
* Verify ownership of a legacy "primary" vault, copy it to a scoped key, and remove the legacy entry.
|
|
550
|
+
* Does not run automatically — callers must confirm with the user first.
|
|
551
|
+
*/
|
|
552
|
+
declare function migrateLegacyEmbeddedWallet(options: MigrateLegacyEmbeddedWalletOptions): Promise<EmbeddedWalletSession>;
|
|
518
553
|
/** Create passcode-protected encrypted vault; does not unlock signer until backup is acknowledged. */
|
|
519
554
|
declare function createEmbeddedWallet(options: CreateEmbeddedWalletOptions): Promise<{
|
|
520
555
|
address: string;
|
|
@@ -551,11 +586,11 @@ declare function getEmbeddedWalletSession(): EmbeddedWalletSession | null;
|
|
|
551
586
|
/** Offline signer for CosmJS; enforces backup gate before signing. */
|
|
552
587
|
declare function getEmbeddedOfflineSigner(): OfflineDirectSigner;
|
|
553
588
|
/** Mark backup downloaded/acknowledged and persist. Returns backup file payload. */
|
|
554
|
-
declare function acknowledgeEmbeddedBackup(): Promise<EmbeddedWalletBackupFileV1>;
|
|
589
|
+
declare function acknowledgeEmbeddedBackup(options?: AcknowledgeEmbeddedBackupOptions): Promise<EmbeddedWalletBackupFileV1>;
|
|
555
590
|
declare function downloadEmbeddedBackupFile(backup: EmbeddedWalletBackupFileV1, filename?: string): void;
|
|
556
591
|
/** Restore vault from user-held backup file (requires passcode or passkey to decrypt). */
|
|
557
|
-
declare function importEmbeddedBackup(json: string): Promise<EmbeddedWalletVaultV1>;
|
|
558
|
-
declare function clearEmbeddedWallet(): Promise<void>;
|
|
592
|
+
declare function importEmbeddedBackup(json: string, options?: ImportEmbeddedBackupOptions): Promise<EmbeddedWalletVaultV1>;
|
|
593
|
+
declare function clearEmbeddedWallet(options?: ClearEmbeddedWalletOptions): Promise<void>;
|
|
559
594
|
|
|
560
595
|
/**
|
|
561
596
|
* Kingdom Chain on-chain denom and display metadata.
|
|
@@ -599,4 +634,4 @@ declare function signCitizenshipAttestation(params: SubmitApplicationParams): Pr
|
|
|
599
634
|
input: AttestationPayloadInput;
|
|
600
635
|
}>;
|
|
601
636
|
|
|
602
|
-
export { ATTESTATION_TYPE_CITIZENSHIP_APPLICATION, ATTESTATION_TYPE_RECOVERY, ApplicationStatus, type AttestationPayloadInput, BECH32_PREFIX, type BrowserWalletApi, CHAIN_COIN_TYPE, type ChainCurrency, type ChainInfo, type CosmostationWindowApi, type CreateEmbeddedWalletOptions, DEFAULT_CHAIN_ID, DEFAULT_REST_URL, DEFAULT_RPC_URL, EMBEDDED_WALLET_KDF_PBKDF2, EMBEDDED_WALLET_KDF_PIN, EMBEDDED_WALLET_KDF_PRF, EMBEDDED_WALLET_KEY_DIRECT_ENTROPY, EMBEDDED_WALLET_KEY_HD_DERIVED, EMBEDDED_WALLET_PASSCODE_MAX_LENGTH, EMBEDDED_WALLET_PASSCODE_MIN_LENGTH, EMBEDDED_WALLET_PASSKEY_PBKDF2_ITERATIONS, EMBEDDED_WALLET_PIN_PBKDF2_ITERATIONS, EMBEDDED_WALLET_RECOVERY_PHRASE_DIRECT_ENTROPY_WARNING, EMBEDDED_WALLET_RECOVERY_PHRASE_GENERAL_WARNING, EMBEDDED_WALLET_VAULT_VERSION, type EmbeddedWalletBackupFileV1, EmbeddedWalletBackupRequiredError, type EmbeddedWalletKdf, type EmbeddedWalletKeyType, EmbeddedWalletLockoutError, type EmbeddedWalletPlaintext, type EmbeddedWalletRecoveryPhraseReveal, type EmbeddedWalletRecoveryPhraseWarning, type EmbeddedWalletSession, EmbeddedWalletVaultError, type EmbeddedWalletVaultV1, EmbeddedWalletWeakPasscodeError, type EnableEmbeddedPasskeyUnlockOptions, type EncryptWalletOptions, InvalidChainConfigError, MsgSubmitApplication, MsgSubmitRecoveryAttestation, PASSCODE_LOCKOUT_FAILURE_THRESHOLD, PASSCODE_LOCKOUT_INITIAL_MS, PASSCODE_LOCKOUT_MAX_MS, type PasscodeBlockReason, type PasscodeLockoutRecord, type PasscodeStrengthLabel, type PasscodeStrengthResult, type PasskeyAssertionResult, type PasskeyRegistrationResult, type RecoverEmbeddedWalletOptions, RecoveryAttestationStatus, type RevealEmbeddedRecoveryPhraseOptions, RpcConnectionError, type SubmitApplicationParams, UKDR_DECIMALS, UKDR_DISPLAY_DENOM, UKDR_MINIMAL_DENOM, type UnlockEmbeddedWalletOptions, WALLETCONNECT_COSMOS_METHODS, WALLETCONNECT_COSMOS_NAMESPACE, WEBAUTHN_RP_NAME, WalletAccountError, type WalletConnectChainConfig, type WalletConnectConnectResult, type WalletConnectMetadata, WalletConnectNotInitializedError, WalletConnectSessionError, WalletConnectSigningError, WalletConnectionError, WalletConnectionRejectedError, WalletNotInstalledError, type WebAuthnPrfCapabilities, WebAuthnUnavailableError, WebAuthnUserCancelledError, acknowledgeEmbeddedBackup, addressFromHdMnemonic, addressFromPrivateKey, assertPasscodeAllowedForCreation, assertPasscodeUnlockAllowed, assertPasskey, assertValidPasscode, assertValidRecoveryMnemonic, assertVaultPermitsTransaction, attestationSignPayload, buildKingdomChainInfo, buildRequiredCosmosNamespaces, buildSubmitApplicationMsg, clearEmbeddedWallet,
|
|
637
|
+
export { ATTESTATION_TYPE_CITIZENSHIP_APPLICATION, ATTESTATION_TYPE_RECOVERY, type AcknowledgeEmbeddedBackupOptions, ApplicationStatus, type AttestationPayloadInput, BECH32_PREFIX, type BrowserWalletApi, CHAIN_COIN_TYPE, type ChainCurrency, type ChainInfo, type ClearEmbeddedWalletOptions, type CosmostationWindowApi, type CreateEmbeddedWalletOptions, DEFAULT_CHAIN_ID, DEFAULT_REST_URL, DEFAULT_RPC_URL, EMBEDDED_WALLET_KDF_PBKDF2, EMBEDDED_WALLET_KDF_PIN, EMBEDDED_WALLET_KDF_PRF, EMBEDDED_WALLET_KEY_DIRECT_ENTROPY, EMBEDDED_WALLET_KEY_HD_DERIVED, EMBEDDED_WALLET_PASSCODE_MAX_LENGTH, EMBEDDED_WALLET_PASSCODE_MIN_LENGTH, EMBEDDED_WALLET_PASSKEY_PBKDF2_ITERATIONS, EMBEDDED_WALLET_PIN_PBKDF2_ITERATIONS, EMBEDDED_WALLET_RECOVERY_PHRASE_DIRECT_ENTROPY_WARNING, EMBEDDED_WALLET_RECOVERY_PHRASE_GENERAL_WARNING, EMBEDDED_WALLET_VAULT_VERSION, type EmbeddedWalletBackupFileV1, EmbeddedWalletBackupRequiredError, EmbeddedWalletDecryptError, type EmbeddedWalletKdf, type EmbeddedWalletKeyType, EmbeddedWalletLockoutError, type EmbeddedWalletPlaintext, type EmbeddedWalletRecoveryPhraseReveal, type EmbeddedWalletRecoveryPhraseWarning, type EmbeddedWalletScopeOptions, type EmbeddedWalletSession, EmbeddedWalletVaultError, type EmbeddedWalletVaultV1, EmbeddedWalletWeakPasscodeError, type EnableEmbeddedPasskeyUnlockOptions, type EncryptWalletOptions, type ImportEmbeddedBackupOptions, InvalidChainConfigError, type MigrateLegacyEmbeddedWalletOptions, MsgSubmitApplication, MsgSubmitRecoveryAttestation, PASSCODE_LOCKOUT_FAILURE_THRESHOLD, PASSCODE_LOCKOUT_INITIAL_MS, PASSCODE_LOCKOUT_MAX_MS, type PasscodeBlockReason, type PasscodeLockoutRecord, type PasscodeStrengthLabel, type PasscodeStrengthResult, type PasskeyAssertionResult, type PasskeyRegistrationResult, type RecoverEmbeddedWalletOptions, RecoveryAttestationStatus, type RevealEmbeddedRecoveryPhraseOptions, RpcConnectionError, type SubmitApplicationParams, UKDR_DECIMALS, UKDR_DISPLAY_DENOM, UKDR_MINIMAL_DENOM, type UnlockEmbeddedWalletOptions, VAULT_LEGACY_KEY, type VaultStorageOptions, WALLETCONNECT_COSMOS_METHODS, WALLETCONNECT_COSMOS_NAMESPACE, WEBAUTHN_RP_NAME, WalletAccountError, type WalletConnectChainConfig, type WalletConnectConnectResult, type WalletConnectMetadata, WalletConnectNotInitializedError, WalletConnectSessionError, WalletConnectSigningError, WalletConnectionError, WalletConnectionRejectedError, WalletNotInstalledError, type WebAuthnPrfCapabilities, WebAuthnUnavailableError, WebAuthnUserCancelledError, acknowledgeEmbeddedBackup, addressFromHdMnemonic, addressFromPrivateKey, assertPasscodeAllowedForCreation, assertPasscodeUnlockAllowed, assertPasskey, assertValidPasscode, assertValidRecoveryMnemonic, assertVaultPermitsTransaction, attestationSignPayload, buildKingdomChainInfo, buildRequiredCosmosNamespaces, buildSubmitApplicationMsg, clearEmbeddedWallet, clearPasscodeLockoutRecord, clearVaultFromIndexedDb, computePasscodeLockoutDurationMs, connectCosmostation, connectKeplr, connectLeap, connectWalletConnect, createBrowserSigningClient, createEmbeddedWallet, createHdDerivedPlaintext, createKingdomChainRegistry, createPasskeyMaterialFromAssertion, createPbkdf2Salt, createWalletConnectOfflineSigner, decodeCredentialId, decodeDirectEntropyMnemonic, decryptWalletPayload, defaultEmbeddedHdPath, deriveKekFromPasscode, deriveKekFromPbkdf2, deriveKekFromPrf, derivePrivateKeyFromHdMnemonic, detectRecoveryMnemonicKeyType, detectWebAuthnPrfCapabilities, disconnectWalletConnect, downloadEmbeddedBackupFile, embeddedPlaintextToSigner, enableEmbeddedPasskeyUnlock, encodeCredentialId, encodeDirectEntropyMnemonic, encryptWalletPayload, evaluatePasscodeStrength, exportEncryptedBackup, getCosmostationKeplrApi, getEmbeddedOfflineSigner, getEmbeddedWalletSession, getPasscodeLockoutState, hasEmbeddedWallet, hasLegacyEmbeddedWallet, hasMixedCharacterClasses, importEmbeddedBackup, initWalletConnectClient, isCosmostationAvailable, isKeplrAvailable, isLeapAvailable, loadPasscodeLockoutRecord, loadVaultFromIndexedDb, lockEmbeddedWallet, markVaultBackupAcknowledged, migrateLegacyEmbeddedWallet, normalizePasscode, normalizeRecoveryMnemonic, parseEncryptedBackup, parseWalletConnectAccount, plaintextFromRecoveryMnemonic, providerSeedFromHex, publicKeyFromPrivateSeed, readPrfOutput, recordPasscodeUnlockFailure, recordPasscodeUnlockSuccess, recoverEmbeddedWalletFromMnemonic, recoveryMnemonicAddress, recoveryMnemonicFromPlaintext, registerPasskey, resolvePlaintextKeyType, resolveVaultStorageKey, restoreWalletConnectSession, revealEmbeddedRecoveryPhrase, savePasscodeLockoutRecord, saveVaultToIndexedDb, selectEmbeddedWalletKdf, serializeBackupFile, signAttestationPayload, signCitizenshipAttestation, suggestAndConnect, toWalletConnectCosmosChainId, unlockEmbeddedWallet, validateChainConfig, vaultUsesPasscodeUnlock, vaultUsesPasskeyUnlock };
|