@kingdomchain/wallet-client 0.1.0 → 0.4.1
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 +36 -2
- package/dist/index.d.ts +384 -2
- package/dist/index.js +1336 -3
- package/dist/index.js.map +1 -1
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
# Kingdom Chain TypeScript / CosmJS client
|
|
2
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 browser wallet connector for non-custodial signing.
|
|
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
4
|
|
|
5
5
|
## Scope (current)
|
|
6
6
|
|
|
7
7
|
- **MsgSubmitApplication** (citizenship application)
|
|
8
8
|
- **MsgSubmitRecoveryAttestation** (wallet recovery attestation)
|
|
9
|
-
- **Browser wallet connector** (`src/browserSigner.ts`) — Keplr / Leap via `experimentalSuggestChain` + `OfflineDirectSigner`
|
|
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
|
|
10
12
|
- Ed25519 attestation signing ported from `x/compliance/types/attestation.go`
|
|
11
13
|
- Proto codegen via `ts-proto` + `buf`
|
|
12
14
|
|
|
@@ -80,6 +82,38 @@ Optional Vite env overrides (prefix `VITE_`):
|
|
|
80
82
|
|
|
81
83
|
The demo signs the provider attestation off-chain (devnet seed) and broadcasts `MsgSubmitApplication` using your connected wallet as the on-chain tx signer.
|
|
82
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
|
+
|
|
83
117
|
### Browser wallet API (`src/browserSigner.ts`)
|
|
84
118
|
|
|
85
119
|
- `isKeplrAvailable()` / `isLeapAvailable()`
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { Registry, OfflineDirectSigner, EncodeObject } from '@cosmjs/proto-signing';
|
|
1
|
+
import { Registry, OfflineDirectSigner, DirectSecp256k1Wallet, EncodeObject } from '@cosmjs/proto-signing';
|
|
2
2
|
import { SigningStargateClient } from '@cosmjs/stargate';
|
|
3
|
+
import SignClient from '@walletconnect/sign-client';
|
|
4
|
+
import { SessionTypes, ProposalTypes } from '@walletconnect/types';
|
|
3
5
|
import { BinaryWriter, BinaryReader } from '@bufbuild/protobuf/wire';
|
|
4
6
|
|
|
5
7
|
/** Must match x/compliance/types/keys.go AttestationTypeCitizenshipApplication */
|
|
@@ -156,25 +158,405 @@ declare class RpcConnectionError extends Error {
|
|
|
156
158
|
readonly rpcUrl: string;
|
|
157
159
|
constructor(rpcUrl: string, cause?: unknown);
|
|
158
160
|
}
|
|
161
|
+
/** Cosmostation exposes a Keplr-compatible provider at providers.keplr. */
|
|
162
|
+
interface CosmostationWindowApi {
|
|
163
|
+
providers?: {
|
|
164
|
+
keplr?: BrowserWalletApi;
|
|
165
|
+
};
|
|
166
|
+
}
|
|
159
167
|
declare global {
|
|
160
168
|
interface Window {
|
|
161
169
|
keplr?: BrowserWalletApi;
|
|
162
170
|
leap?: BrowserWalletApi;
|
|
171
|
+
cosmostation?: CosmostationWindowApi;
|
|
163
172
|
}
|
|
164
173
|
}
|
|
165
174
|
/** Validate chain endpoint inputs before passing to Keplr/Leap. */
|
|
166
175
|
declare function validateChainConfig(chainId: string, rpcUrl: string, restUrl: string): void;
|
|
167
176
|
declare function isKeplrAvailable(): boolean;
|
|
168
177
|
declare function isLeapAvailable(): boolean;
|
|
178
|
+
/** Keplr-compatible API injected by the Cosmostation extension. */
|
|
179
|
+
declare function getCosmostationKeplrApi(): BrowserWalletApi | undefined;
|
|
180
|
+
declare function isCosmostationAvailable(): boolean;
|
|
169
181
|
/** Build ChainInfo for Keplr/Leap experimentalSuggestChain. */
|
|
170
182
|
declare function buildKingdomChainInfo(chainId: string, rpcUrl: string, restUrl: string, chainName?: string): ChainInfo;
|
|
171
183
|
/** Suggest chain, request access, return CosmJS OfflineDirectSigner. */
|
|
172
184
|
declare function suggestAndConnect(walletApi: BrowserWalletApi, chainInfo: ChainInfo, walletName?: string): Promise<OfflineDirectSigner>;
|
|
173
185
|
declare function connectKeplr(chainInfo: ChainInfo): Promise<OfflineDirectSigner>;
|
|
174
186
|
declare function connectLeap(chainInfo: ChainInfo): Promise<OfflineDirectSigner>;
|
|
187
|
+
declare function connectCosmostation(chainInfo: ChainInfo): Promise<OfflineDirectSigner>;
|
|
175
188
|
/** SigningStargateClient wired with Kingdom Chain custom message registry. */
|
|
176
189
|
declare function createBrowserSigningClient(rpcUrl: string, signer: OfflineDirectSigner): Promise<SigningStargateClient>;
|
|
177
190
|
|
|
191
|
+
declare const WALLETCONNECT_COSMOS_NAMESPACE = "cosmos";
|
|
192
|
+
declare const WALLETCONNECT_COSMOS_METHODS: readonly ["cosmos_getAccounts", "cosmos_signDirect", "cosmos_signAmino"];
|
|
193
|
+
interface WalletConnectMetadata {
|
|
194
|
+
name: string;
|
|
195
|
+
description: string;
|
|
196
|
+
url: string;
|
|
197
|
+
icons: string[];
|
|
198
|
+
}
|
|
199
|
+
interface WalletConnectChainConfig {
|
|
200
|
+
chainId: string;
|
|
201
|
+
projectId: string;
|
|
202
|
+
metadata: WalletConnectMetadata;
|
|
203
|
+
relayUrl?: string;
|
|
204
|
+
}
|
|
205
|
+
interface WalletConnectConnectResult {
|
|
206
|
+
uri: string;
|
|
207
|
+
session: SessionTypes.Struct;
|
|
208
|
+
signer: OfflineDirectSigner;
|
|
209
|
+
}
|
|
210
|
+
declare class WalletConnectNotInitializedError extends Error {
|
|
211
|
+
constructor();
|
|
212
|
+
}
|
|
213
|
+
declare class WalletConnectSessionError extends Error {
|
|
214
|
+
constructor(message: string, cause?: unknown);
|
|
215
|
+
}
|
|
216
|
+
declare class WalletConnectSigningError extends Error {
|
|
217
|
+
constructor(message: string, cause?: unknown);
|
|
218
|
+
}
|
|
219
|
+
/** WalletConnect chain id: `cosmos:{chainId}`. */
|
|
220
|
+
declare function toWalletConnectCosmosChainId(chainId: string): string;
|
|
221
|
+
declare function parseWalletConnectAccount(account: string): {
|
|
222
|
+
namespace: string;
|
|
223
|
+
chainId: string;
|
|
224
|
+
address: string;
|
|
225
|
+
};
|
|
226
|
+
declare function buildRequiredCosmosNamespaces(chainId: string): ProposalTypes.RequiredNamespaces;
|
|
227
|
+
declare function initWalletConnectClient(config: WalletConnectChainConfig): Promise<SignClient>;
|
|
228
|
+
declare function createWalletConnectOfflineSigner(client: SignClient, session: SessionTypes.Struct, chainId: string): OfflineDirectSigner;
|
|
229
|
+
/** Pair with a mobile wallet; returns WC URI (for QR) and approval promise. */
|
|
230
|
+
declare function connectWalletConnect(client: SignClient, chainId: string, options?: {
|
|
231
|
+
pairingTopic?: string;
|
|
232
|
+
}): Promise<WalletConnectConnectResult>;
|
|
233
|
+
declare function disconnectWalletConnect(client: SignClient, session: SessionTypes.Struct, reason?: string): Promise<void>;
|
|
234
|
+
declare function restoreWalletConnectSession(client: SignClient, chainId: string): Promise<{
|
|
235
|
+
session: SessionTypes.Struct;
|
|
236
|
+
signer: OfflineDirectSigner;
|
|
237
|
+
} | null>;
|
|
238
|
+
|
|
239
|
+
/** Embedded wallet vault format version. */
|
|
240
|
+
declare const EMBEDDED_WALLET_VAULT_VERSION = 1;
|
|
241
|
+
declare const EMBEDDED_WALLET_KDF_PRF: "webauthn-prf";
|
|
242
|
+
declare const EMBEDDED_WALLET_KDF_PBKDF2: "pbkdf2-passkey";
|
|
243
|
+
declare const EMBEDDED_WALLET_KDF_PIN: "pbkdf2-pin";
|
|
244
|
+
type EmbeddedWalletKdf = typeof EMBEDDED_WALLET_KDF_PRF | typeof EMBEDDED_WALLET_KDF_PBKDF2 | typeof EMBEDDED_WALLET_KDF_PIN;
|
|
245
|
+
/** How the wallet key relates to its recovery phrase. */
|
|
246
|
+
declare const EMBEDDED_WALLET_KEY_HD_DERIVED: "hd-derived";
|
|
247
|
+
declare const EMBEDDED_WALLET_KEY_DIRECT_ENTROPY: "direct-entropy";
|
|
248
|
+
type EmbeddedWalletKeyType = typeof EMBEDDED_WALLET_KEY_HD_DERIVED | typeof EMBEDDED_WALLET_KEY_DIRECT_ENTROPY;
|
|
249
|
+
/** Plaintext wallet payload — never persisted unencrypted. */
|
|
250
|
+
interface EmbeddedWalletPlaintext {
|
|
251
|
+
privateKey: Uint8Array;
|
|
252
|
+
hdPath: string;
|
|
253
|
+
createdAt: string;
|
|
254
|
+
/** Omitted in pre-phase-3 vaults; treated as direct-entropy when absent. */
|
|
255
|
+
keyType?: EmbeddedWalletKeyType;
|
|
256
|
+
/** Stored for hd-derived wallets so the phrase can be revealed later. */
|
|
257
|
+
mnemonic?: string;
|
|
258
|
+
}
|
|
259
|
+
/** Warnings shown before revealing a recovery phrase. */
|
|
260
|
+
interface EmbeddedWalletRecoveryPhraseWarning {
|
|
261
|
+
id: "general" | "direct-entropy-portability";
|
|
262
|
+
title: string;
|
|
263
|
+
body: string;
|
|
264
|
+
}
|
|
265
|
+
declare const EMBEDDED_WALLET_RECOVERY_PHRASE_GENERAL_WARNING: EmbeddedWalletRecoveryPhraseWarning;
|
|
266
|
+
declare const EMBEDDED_WALLET_RECOVERY_PHRASE_DIRECT_ENTROPY_WARNING: EmbeddedWalletRecoveryPhraseWarning;
|
|
267
|
+
interface EmbeddedWalletRecoveryPhraseReveal {
|
|
268
|
+
mnemonic: string;
|
|
269
|
+
keyType: EmbeddedWalletKeyType;
|
|
270
|
+
address: string;
|
|
271
|
+
warnings: EmbeddedWalletRecoveryPhraseWarning[];
|
|
272
|
+
}
|
|
273
|
+
/** Encrypted vault stored in IndexedDB and exported backup files. */
|
|
274
|
+
interface EmbeddedWalletVaultV1 {
|
|
275
|
+
version: typeof EMBEDDED_WALLET_VAULT_VERSION;
|
|
276
|
+
kdf: EmbeddedWalletKdf;
|
|
277
|
+
credentialId: string;
|
|
278
|
+
publicAddress: string;
|
|
279
|
+
iv: string;
|
|
280
|
+
ciphertext: string;
|
|
281
|
+
/** PBKDF2 salt (base64). Empty when kdf=webauthn-prf. */
|
|
282
|
+
kdfSalt: string;
|
|
283
|
+
/** PBKDF2 iterations. Zero when kdf=webauthn-prf. */
|
|
284
|
+
kdfIterations: number;
|
|
285
|
+
/** PRF eval salt (base64). Empty when kdf=pbkdf2-passkey. */
|
|
286
|
+
prfSalt: string;
|
|
287
|
+
/** Hard gate: must be true before any transaction is permitted. */
|
|
288
|
+
backupAcknowledged: boolean;
|
|
289
|
+
backupAcknowledgedAt?: string;
|
|
290
|
+
createdAt: string;
|
|
291
|
+
}
|
|
292
|
+
interface EmbeddedWalletBackupFileV1 {
|
|
293
|
+
format: "kingdom-os-embedded-wallet-backup";
|
|
294
|
+
version: typeof EMBEDDED_WALLET_VAULT_VERSION;
|
|
295
|
+
vault: EmbeddedWalletVaultV1;
|
|
296
|
+
exportedAt: string;
|
|
297
|
+
}
|
|
298
|
+
declare class EmbeddedWalletBackupRequiredError extends Error {
|
|
299
|
+
constructor();
|
|
300
|
+
}
|
|
301
|
+
declare class EmbeddedWalletVaultError extends Error {
|
|
302
|
+
constructor(message: string, cause?: unknown);
|
|
303
|
+
}
|
|
304
|
+
type PasscodeStrengthLabel = "weak" | "fair" | "good" | "strong";
|
|
305
|
+
type PasscodeBlockReason = "denylist" | "too_weak" | "numeric_short";
|
|
306
|
+
/** Thrown when too many failed passcode unlock attempts trigger a timed lockout. */
|
|
307
|
+
declare class EmbeddedWalletLockoutError extends Error {
|
|
308
|
+
readonly retryAfterMs: number;
|
|
309
|
+
constructor(retryAfterMs: number);
|
|
310
|
+
}
|
|
311
|
+
/** Thrown when a passcode is too weak or on the common-password denylist. */
|
|
312
|
+
declare class EmbeddedWalletWeakPasscodeError extends Error {
|
|
313
|
+
readonly reason: PasscodeBlockReason;
|
|
314
|
+
constructor(reason: PasscodeBlockReason);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
interface EncryptWalletOptions {
|
|
318
|
+
kdf: EmbeddedWalletKdf;
|
|
319
|
+
credentialId: Uint8Array;
|
|
320
|
+
publicAddress: string;
|
|
321
|
+
kek: Uint8Array;
|
|
322
|
+
/** Required when kdf=pbkdf2-passkey or kdf=pbkdf2-pin */
|
|
323
|
+
kdfSalt?: Uint8Array;
|
|
324
|
+
/** Required when kdf=webauthn-prf */
|
|
325
|
+
prfSalt?: Uint8Array;
|
|
326
|
+
/** Override PBKDF2 iterations (defaults vary by kdf type). */
|
|
327
|
+
kdfIterations?: number;
|
|
328
|
+
backupAcknowledged?: boolean;
|
|
329
|
+
}
|
|
330
|
+
declare function deriveKekFromPrf(prfOutput: Uint8Array): Promise<Uint8Array>;
|
|
331
|
+
/** PBKDF2-SHA256 fallback when WebAuthn PRF is unavailable (Safari cross-device QR, etc.). */
|
|
332
|
+
declare function deriveKekFromPbkdf2(passkeyMaterial: Uint8Array, salt: Uint8Array, iterations?: number): Promise<Uint8Array>;
|
|
333
|
+
declare function createPbkdf2Salt(): Uint8Array;
|
|
334
|
+
declare function createPasskeyMaterialFromAssertion(authenticatorData: Uint8Array, clientDataJSON: Uint8Array): Uint8Array;
|
|
335
|
+
declare function encryptWalletPayload(payload: EmbeddedWalletPlaintext, options: EncryptWalletOptions): Promise<EmbeddedWalletVaultV1>;
|
|
336
|
+
declare function decryptWalletPayload(vault: EmbeddedWalletVaultV1, kek: Uint8Array): Promise<EmbeddedWalletPlaintext>;
|
|
337
|
+
declare function markVaultBackupAcknowledged(vault: EmbeddedWalletVaultV1): EmbeddedWalletVaultV1;
|
|
338
|
+
declare function assertVaultPermitsTransaction(vault: EmbeddedWalletVaultV1): void;
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* WebAuthn PRF capability detection for embedded wallet KEK derivation.
|
|
342
|
+
*
|
|
343
|
+
* Safari does not expose PRF during cross-device QR-code WebAuthn flows — only
|
|
344
|
+
* direct iCloud-synced passkeys. Callers must fall back to PBKDF2 in that case.
|
|
345
|
+
*/
|
|
346
|
+
interface WebAuthnPrfCapabilities {
|
|
347
|
+
/** Browser exposes PublicKeyCredential. */
|
|
348
|
+
webAuthnAvailable: boolean;
|
|
349
|
+
/** PRF extension likely usable on this device/browser combo. */
|
|
350
|
+
prfLikelySupported: boolean;
|
|
351
|
+
/** Human-readable reason when prfLikelySupported is false. */
|
|
352
|
+
prfFallbackReason?: string;
|
|
353
|
+
}
|
|
354
|
+
/** Best-effort PRF support probe — PBKDF2 fallback remains mandatory. */
|
|
355
|
+
declare function detectWebAuthnPrfCapabilities(): WebAuthnPrfCapabilities;
|
|
356
|
+
/** Extract 32-byte PRF output from assertion clientExtensionResults. */
|
|
357
|
+
declare function readPrfOutput(clientExtensionResults: AuthenticationExtensionsClientOutputs | undefined): Uint8Array | null;
|
|
358
|
+
declare function selectEmbeddedWalletKdf(caps: WebAuthnPrfCapabilities, prfOutput: Uint8Array | null): "webauthn-prf" | "pbkdf2-passkey";
|
|
359
|
+
|
|
360
|
+
declare function exportEncryptedBackup(vault: EmbeddedWalletVaultV1): EmbeddedWalletBackupFileV1;
|
|
361
|
+
declare function parseEncryptedBackup(json: string): EmbeddedWalletBackupFileV1;
|
|
362
|
+
declare function serializeBackupFile(backup: EmbeddedWalletBackupFileV1): string;
|
|
363
|
+
|
|
364
|
+
declare const WEBAUTHN_RP_NAME = "Kingdom OS";
|
|
365
|
+
interface PasskeyRegistrationResult {
|
|
366
|
+
credentialId: Uint8Array;
|
|
367
|
+
authenticatorData: Uint8Array;
|
|
368
|
+
clientDataJSON: Uint8Array;
|
|
369
|
+
prfOutput: Uint8Array | null;
|
|
370
|
+
prfSalt: Uint8Array;
|
|
371
|
+
}
|
|
372
|
+
interface PasskeyAssertionResult {
|
|
373
|
+
credentialId: Uint8Array;
|
|
374
|
+
authenticatorData: Uint8Array;
|
|
375
|
+
clientDataJSON: Uint8Array;
|
|
376
|
+
prfOutput: Uint8Array | null;
|
|
377
|
+
}
|
|
378
|
+
declare class WebAuthnUnavailableError extends Error {
|
|
379
|
+
constructor(message?: string);
|
|
380
|
+
}
|
|
381
|
+
declare class WebAuthnUserCancelledError extends Error {
|
|
382
|
+
constructor(message?: string);
|
|
383
|
+
}
|
|
384
|
+
/** Register a platform passkey; attempts PRF extension when supported. */
|
|
385
|
+
declare function registerPasskey(options: {
|
|
386
|
+
userId: Uint8Array;
|
|
387
|
+
userName: string;
|
|
388
|
+
displayName: string;
|
|
389
|
+
rpId?: string;
|
|
390
|
+
prfSalt?: Uint8Array;
|
|
391
|
+
}): Promise<PasskeyRegistrationResult>;
|
|
392
|
+
/** Assert an existing passkey; re-derives PRF output when extension succeeds. */
|
|
393
|
+
declare function assertPasskey(options: {
|
|
394
|
+
credentialId: Uint8Array;
|
|
395
|
+
rpId?: string;
|
|
396
|
+
prfSalt?: Uint8Array;
|
|
397
|
+
}): Promise<PasskeyAssertionResult>;
|
|
398
|
+
declare function encodeCredentialId(id: Uint8Array): string;
|
|
399
|
+
declare function decodeCredentialId(encoded: string): Uint8Array;
|
|
400
|
+
|
|
401
|
+
/** Build a CosmJS offline signer from decrypted vault plaintext. */
|
|
402
|
+
declare function embeddedPlaintextToSigner(plaintext: EmbeddedWalletPlaintext, prefix?: string): Promise<DirectSecp256k1Wallet>;
|
|
403
|
+
declare function defaultEmbeddedHdPath(): string;
|
|
404
|
+
|
|
405
|
+
interface PasscodeLockoutRecord {
|
|
406
|
+
failedAttempts: number;
|
|
407
|
+
lockoutTier: number;
|
|
408
|
+
lockedUntil: string | null;
|
|
409
|
+
}
|
|
410
|
+
declare function saveVaultToIndexedDb(vault: EmbeddedWalletVaultV1): Promise<void>;
|
|
411
|
+
declare function loadVaultFromIndexedDb(): Promise<EmbeddedWalletVaultV1 | null>;
|
|
412
|
+
declare function clearVaultFromIndexedDb(): Promise<void>;
|
|
413
|
+
declare function loadPasscodeLockoutRecord(publicAddress: string): Promise<PasscodeLockoutRecord | null>;
|
|
414
|
+
declare function savePasscodeLockoutRecord(publicAddress: string, record: PasscodeLockoutRecord): Promise<void>;
|
|
415
|
+
declare function clearPasscodeLockoutRecord(publicAddress: string): Promise<void>;
|
|
416
|
+
|
|
417
|
+
/** Consecutive wrong passcodes before lockout triggers. */
|
|
418
|
+
declare const PASSCODE_LOCKOUT_FAILURE_THRESHOLD = 5;
|
|
419
|
+
/** First lockout duration (milliseconds). */
|
|
420
|
+
declare const PASSCODE_LOCKOUT_INITIAL_MS = 30000;
|
|
421
|
+
/** Maximum lockout duration (15 minutes). */
|
|
422
|
+
declare const PASSCODE_LOCKOUT_MAX_MS = 900000;
|
|
423
|
+
/** Throws when the vault is temporarily locked after too many failed unlock attempts. */
|
|
424
|
+
declare function assertPasscodeUnlockAllowed(publicAddress: string): Promise<void>;
|
|
425
|
+
/** Record a failed passcode unlock attempt; triggers lockout at threshold. */
|
|
426
|
+
declare function recordPasscodeUnlockFailure(publicAddress: string): Promise<void>;
|
|
427
|
+
/** Clear lockout state after a successful passcode unlock. */
|
|
428
|
+
declare function recordPasscodeUnlockSuccess(publicAddress: string): Promise<void>;
|
|
429
|
+
declare function getPasscodeLockoutState(publicAddress: string): Promise<PasscodeLockoutRecord & {
|
|
430
|
+
retryAfterMs: number;
|
|
431
|
+
}>;
|
|
432
|
+
/** @internal Test helper — reset lockout without clearing vault. */
|
|
433
|
+
declare function clearPasscodeLockoutForTests(publicAddress: string): Promise<void>;
|
|
434
|
+
|
|
435
|
+
interface PasscodeStrengthResult {
|
|
436
|
+
score: 0 | 1 | 2 | 3 | 4;
|
|
437
|
+
label: PasscodeStrengthLabel;
|
|
438
|
+
blocked: boolean;
|
|
439
|
+
blockReason?: "denylist" | "too_weak" | "numeric_short";
|
|
440
|
+
}
|
|
441
|
+
declare function hasMixedCharacterClasses(passcode: string): boolean;
|
|
442
|
+
/** Score passcode strength for creation UI (denylist + zxcvbn). */
|
|
443
|
+
declare function evaluatePasscodeStrength(passcode: string): PasscodeStrengthResult;
|
|
444
|
+
/** Hard reject weak or common passcodes at wallet creation / recovery. */
|
|
445
|
+
declare function assertPasscodeAllowedForCreation(passcode: string): void;
|
|
446
|
+
|
|
447
|
+
/** Minimum passcode length — alphanumeric passcode, not a 4–6 digit PIN. */
|
|
448
|
+
declare const EMBEDDED_WALLET_PASSCODE_MIN_LENGTH = 8;
|
|
449
|
+
/** Maximum passcode length (DoS guard for PBKDF2 input). */
|
|
450
|
+
declare const EMBEDDED_WALLET_PASSCODE_MAX_LENGTH = 128;
|
|
451
|
+
/**
|
|
452
|
+
* OWASP-recommended PBKDF2-SHA256 iteration count (2023 guidance).
|
|
453
|
+
* Uses native Web Crypto — no WASM bundle required.
|
|
454
|
+
*/
|
|
455
|
+
declare const EMBEDDED_WALLET_PIN_PBKDF2_ITERATIONS = 600000;
|
|
456
|
+
/** Legacy passkey PBKDF2 fallback iteration count (pre-PIN vaults). */
|
|
457
|
+
declare const EMBEDDED_WALLET_PASSKEY_PBKDF2_ITERATIONS = 310000;
|
|
458
|
+
declare function normalizePasscode(passcode: string): string;
|
|
459
|
+
/** Validate citizen-chosen passcode before KDF. */
|
|
460
|
+
declare function assertValidPasscode(passcode: string): void;
|
|
461
|
+
declare function deriveKekFromPasscode(passcode: string, salt: Uint8Array, iterations?: number): Promise<Uint8Array>;
|
|
462
|
+
|
|
463
|
+
/** Normalize user input: trim, lowercase, collapse whitespace. */
|
|
464
|
+
declare function normalizeRecoveryMnemonic(mnemonic: string): string;
|
|
465
|
+
declare function assertValidRecoveryMnemonic(mnemonic: string): void;
|
|
466
|
+
declare function resolvePlaintextKeyType(plaintext: EmbeddedWalletPlaintext): EmbeddedWalletKeyType;
|
|
467
|
+
/** Encode a legacy raw 32-byte key as a 24-word BIP-39 mnemonic (entropy encoding, no HD). */
|
|
468
|
+
declare function encodeDirectEntropyMnemonic(privateKey: Uint8Array): string;
|
|
469
|
+
/** Decode a direct-entropy mnemonic back to the original 32-byte key. */
|
|
470
|
+
declare function decodeDirectEntropyMnemonic(mnemonic: string): Uint8Array;
|
|
471
|
+
declare function derivePrivateKeyFromHdMnemonic(mnemonic: string, hdPath?: string): Promise<Uint8Array>;
|
|
472
|
+
declare function addressFromPrivateKey(privateKey: Uint8Array, prefix?: string): Promise<string>;
|
|
473
|
+
declare function addressFromHdMnemonic(mnemonic: string, hdPath?: string, prefix?: string): Promise<string>;
|
|
474
|
+
declare function createHdDerivedPlaintext(createdAt: string, hdPath?: string): Promise<EmbeddedWalletPlaintext>;
|
|
475
|
+
declare function plaintextFromRecoveryMnemonic(mnemonic: string, keyType: EmbeddedWalletKeyType, createdAt: string, hdPath?: string): Promise<EmbeddedWalletPlaintext>;
|
|
476
|
+
/** Infer key type by matching an expected on-chain address, or default to hd-derived. */
|
|
477
|
+
declare function detectRecoveryMnemonicKeyType(mnemonic: string, expectedAddress: string, hdPath?: string, prefix?: string): Promise<EmbeddedWalletKeyType>;
|
|
478
|
+
declare function recoveryMnemonicAddress(mnemonic: string, keyType: EmbeddedWalletKeyType, hdPath?: string, prefix?: string): Promise<string>;
|
|
479
|
+
/** Build the recovery phrase for an unlocked plaintext payload. */
|
|
480
|
+
declare function recoveryMnemonicFromPlaintext(plaintext: EmbeddedWalletPlaintext): string;
|
|
481
|
+
|
|
482
|
+
interface CreateEmbeddedWalletOptions {
|
|
483
|
+
passcode: string;
|
|
484
|
+
}
|
|
485
|
+
interface UnlockEmbeddedWalletOptions {
|
|
486
|
+
passcode?: string;
|
|
487
|
+
}
|
|
488
|
+
interface RevealEmbeddedRecoveryPhraseOptions {
|
|
489
|
+
passcode?: string;
|
|
490
|
+
}
|
|
491
|
+
interface RecoverEmbeddedWalletOptions {
|
|
492
|
+
passcode: string;
|
|
493
|
+
mnemonic: string;
|
|
494
|
+
/** When omitted, inferred from expectedAddress or defaults to hd-derived. */
|
|
495
|
+
keyType?: EmbeddedWalletKeyType;
|
|
496
|
+
/** Used to auto-detect legacy direct-entropy vs standard HD phrases. */
|
|
497
|
+
expectedAddress?: string;
|
|
498
|
+
hdPath?: string;
|
|
499
|
+
/** When true, replaces an existing vault on this device (e.g. after device loss). */
|
|
500
|
+
replaceExisting?: boolean;
|
|
501
|
+
}
|
|
502
|
+
interface EnableEmbeddedPasskeyUnlockOptions {
|
|
503
|
+
passcode: string;
|
|
504
|
+
userId: Uint8Array;
|
|
505
|
+
userName: string;
|
|
506
|
+
displayName: string;
|
|
507
|
+
rpId?: string;
|
|
508
|
+
}
|
|
509
|
+
interface EmbeddedWalletSession {
|
|
510
|
+
address: string;
|
|
511
|
+
vault: EmbeddedWalletVaultV1;
|
|
512
|
+
signer: OfflineDirectSigner;
|
|
513
|
+
}
|
|
514
|
+
declare function vaultUsesPasskeyUnlock(vault: EmbeddedWalletVaultV1): boolean;
|
|
515
|
+
declare function vaultUsesPasscodeUnlock(vault: EmbeddedWalletVaultV1): boolean;
|
|
516
|
+
/** Returns true if an encrypted vault exists in IndexedDB. */
|
|
517
|
+
declare function hasEmbeddedWallet(): Promise<boolean>;
|
|
518
|
+
/** Create passcode-protected encrypted vault; does not unlock signer until backup is acknowledged. */
|
|
519
|
+
declare function createEmbeddedWallet(options: CreateEmbeddedWalletOptions): Promise<{
|
|
520
|
+
address: string;
|
|
521
|
+
vault: EmbeddedWalletVaultV1;
|
|
522
|
+
}>;
|
|
523
|
+
/**
|
|
524
|
+
* Re-authenticate and return the recovery phrase plus UI warnings.
|
|
525
|
+
* Call only after showing {@link EMBEDDED_WALLET_RECOVERY_PHRASE_GENERAL_WARNING} (and the
|
|
526
|
+
* direct-entropy portability warning when applicable).
|
|
527
|
+
*/
|
|
528
|
+
declare function revealEmbeddedRecoveryPhrase(options?: RevealEmbeddedRecoveryPhraseOptions): Promise<EmbeddedWalletRecoveryPhraseReveal>;
|
|
529
|
+
/**
|
|
530
|
+
* Restore an embedded wallet on a new device from a recovery phrase.
|
|
531
|
+
* Sets a new passcode and stores an encrypted vault in IndexedDB.
|
|
532
|
+
*/
|
|
533
|
+
declare function recoverEmbeddedWalletFromMnemonic(options: RecoverEmbeddedWalletOptions): Promise<{
|
|
534
|
+
address: string;
|
|
535
|
+
vault: EmbeddedWalletVaultV1;
|
|
536
|
+
keyType: EmbeddedWalletKeyType;
|
|
537
|
+
}>;
|
|
538
|
+
/**
|
|
539
|
+
* Opt-in upgrade: re-wrap an existing passcode vault with passkey unlock.
|
|
540
|
+
* Does not change the underlying private key or address.
|
|
541
|
+
*/
|
|
542
|
+
declare function enableEmbeddedPasskeyUnlock(options: EnableEmbeddedPasskeyUnlockOptions): Promise<{
|
|
543
|
+
address: string;
|
|
544
|
+
vault: EmbeddedWalletVaultV1;
|
|
545
|
+
}>;
|
|
546
|
+
/** Unlock existing vault with passcode (default) or passkey (opt-in upgrade path). */
|
|
547
|
+
declare function unlockEmbeddedWallet(options?: UnlockEmbeddedWalletOptions): Promise<EmbeddedWalletSession>;
|
|
548
|
+
/** Clear in-memory signer. */
|
|
549
|
+
declare function lockEmbeddedWallet(): void;
|
|
550
|
+
declare function getEmbeddedWalletSession(): EmbeddedWalletSession | null;
|
|
551
|
+
/** Offline signer for CosmJS; enforces backup gate before signing. */
|
|
552
|
+
declare function getEmbeddedOfflineSigner(): OfflineDirectSigner;
|
|
553
|
+
/** Mark backup downloaded/acknowledged and persist. Returns backup file payload. */
|
|
554
|
+
declare function acknowledgeEmbeddedBackup(): Promise<EmbeddedWalletBackupFileV1>;
|
|
555
|
+
declare function downloadEmbeddedBackupFile(backup: EmbeddedWalletBackupFileV1, filename?: string): void;
|
|
556
|
+
/** 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>;
|
|
559
|
+
|
|
178
560
|
/**
|
|
179
561
|
* Kingdom Chain on-chain denom and display metadata.
|
|
180
562
|
*
|
|
@@ -217,4 +599,4 @@ declare function signCitizenshipAttestation(params: SubmitApplicationParams): Pr
|
|
|
217
599
|
input: AttestationPayloadInput;
|
|
218
600
|
}>;
|
|
219
601
|
|
|
220
|
-
export { ATTESTATION_TYPE_CITIZENSHIP_APPLICATION, ATTESTATION_TYPE_RECOVERY, ApplicationStatus, type AttestationPayloadInput, BECH32_PREFIX, type BrowserWalletApi, CHAIN_COIN_TYPE, type ChainCurrency, type ChainInfo, DEFAULT_CHAIN_ID, DEFAULT_REST_URL, DEFAULT_RPC_URL, InvalidChainConfigError, MsgSubmitApplication, MsgSubmitRecoveryAttestation, RecoveryAttestationStatus, RpcConnectionError, type SubmitApplicationParams, UKDR_DECIMALS, UKDR_DISPLAY_DENOM, UKDR_MINIMAL_DENOM, WalletAccountError, WalletConnectionError, WalletConnectionRejectedError, WalletNotInstalledError, attestationSignPayload, buildKingdomChainInfo, buildSubmitApplicationMsg, connectKeplr, connectLeap, createBrowserSigningClient, createKingdomChainRegistry, isKeplrAvailable, isLeapAvailable, providerSeedFromHex, publicKeyFromPrivateSeed, signAttestationPayload, signCitizenshipAttestation, suggestAndConnect, validateChainConfig };
|
|
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, clearPasscodeLockoutForTests, clearPasscodeLockoutRecord, clearVaultFromIndexedDb, 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, hasMixedCharacterClasses, importEmbeddedBackup, initWalletConnectClient, isCosmostationAvailable, isKeplrAvailable, isLeapAvailable, loadPasscodeLockoutRecord, loadVaultFromIndexedDb, lockEmbeddedWallet, markVaultBackupAcknowledged, normalizePasscode, normalizeRecoveryMnemonic, parseEncryptedBackup, parseWalletConnectAccount, plaintextFromRecoveryMnemonic, providerSeedFromHex, publicKeyFromPrivateSeed, readPrfOutput, recordPasscodeUnlockFailure, recordPasscodeUnlockSuccess, recoverEmbeddedWalletFromMnemonic, recoveryMnemonicAddress, recoveryMnemonicFromPlaintext, registerPasskey, resolvePlaintextKeyType, restoreWalletConnectSession, revealEmbeddedRecoveryPhrase, savePasscodeLockoutRecord, saveVaultToIndexedDb, selectEmbeddedWalletKdf, serializeBackupFile, signAttestationPayload, signCitizenshipAttestation, suggestAndConnect, toWalletConnectCosmosChainId, unlockEmbeddedWallet, validateChainConfig, vaultUsesPasscodeUnlock, vaultUsesPasskeyUnlock };
|