@anywalletkit/extension-kit 0.1.2 → 0.1.4
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 +12 -3
- package/dist/index.cjs +194 -67
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +65 -24
- package/dist/index.d.ts +65 -24
- package/dist/index.js +194 -67
- package/dist/index.js.map +1 -1
- package/package.json +10 -7
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/vault.ts","../src/codec.ts","../src/session.ts","../src/relay.ts","../src/chrome.ts","../src/keyring.ts","../src/networks.ts","../src/storage.ts","../src/permissions.ts","../src/approvals.ts","../src/router.ts","../src/siwe.ts","../src/signing.ts","../src/gate.ts","../src/swap.ts","../src/swaps.ts","../src/earn.ts","../src/tonconnect.ts","../src/phishing.ts","../src/webauthn.ts","../src/poison.ts"],"sourcesContent":["export * from './errors.js'\nexport * from './vault.js'\nexport * from './session.js'\nexport * from './relay.js'\nexport * from './chrome.js'\nexport * from './keyring.js'\nexport * from './networks.js'\nexport * from './storage.js'\nexport * from './permissions.js'\nexport * from './approvals.js'\nexport * from './router.js'\nexport * from './signing.js'\nexport * from './gate.js'\nexport * from './swap.js'\nexport * from './swaps.js'\nexport * from './earn.js'\nexport * from './tonconnect.js'\nexport * from './phishing.js'\nexport * from './webauthn.js'\nexport * from './siwe.js'\nexport * from './poison.js'\n","/** A vault or session rule was broken. Messages are safe to show the user and never contain secrets. */\nexport class VaultError extends Error {\n readonly code: VaultErrorCode\n constructor(message: string, code: VaultErrorCode) {\n super(message)\n this.name = 'VaultError'\n this.code = code\n }\n}\n\nexport type VaultErrorCode =\n /** The password did not open the vault (or the envelope was tampered with — AES-GCM cannot tell the two apart). */\n | 'wrong-password'\n /** `create` was called while a vault already exists — an existing wallet is never overwritten. */\n | 'exists'\n /** `unlock` / `getSecret` on a storage area that holds no vault. */\n | 'missing'\n /** The stored envelope has a version or shape this build does not read. */\n | 'unsupported-envelope'\n /** The session is locked: the unlocked key is gone (auto-lock, browser exit, explicit lock). */\n | 'locked'\n /** Bad input (empty or too-short password, bad key length, bad id). */\n | 'invalid-input'\n /** The stored envelope's KDF parameters are below the floor this build accepts (edited on disk). */\n | 'weak-kdf'\n","/**\n * The vault: every secret (seed phrase, imported private key, TON words) at rest\n * in `chrome.storage.local`, encrypted with WebCrypto plus one audited pure-JS\n * primitive (`@noble/hashes` scrypt) — no WASM, no third-party crypto in the\n * key path beyond that.\n *\n * Two layers of keys, so that unlocking does not keep the password around and\n * other unlock paths (passkeys) do not re-encrypt the secrets:\n *\n * ```text\n * password ──scrypt (N=2^17, r=8, p=1)──▶ KEK ──AES-256-GCM──▶ wraps the DEK (envelope v2)\n * passkey PRF ──HKDF-SHA256 (salt = credential id)──▶ KEK ──AES-256-GCM──▶ wraps the DEK, one box per passkey\n * DEK (32 random bytes) ──AES-256-GCM, AAD = secret id──▶ each secret\n * ```\n *\n * What the session holds while unlocked is the DEK (see {@link Session}); the\n * password and the PRF output never leave {@link Vault.create} / {@link Vault.unlock} /\n * {@link Vault.unlockWithPasskey}. Every ciphertext carries its own 96-bit IV; the\n * AAD binds a secret to its id (so two entries cannot be swapped inside the\n * envelope) and binds the DEK box to the exact KDF parameters (so an envelope whose\n * salt or cost was edited on disk fails to open instead of deriving a weaker key).\n * Wrong password and tampering are indistinguishable (GCM tag failure) and both\n * surface as `wrong-password`.\n *\n * Envelope versions: v1 = PBKDF2-SHA256 (≥ 600 000 iterations), still opened and\n * re-sealed as v2 on the next successful unlock (MetaMask's `updateVault` pattern);\n * v2 = scrypt (OWASP parameters, memory-hard: an attacker who copied the Chrome\n * profile cannot run the search on GPUs the way PBKDF2 allows) + optional passkey\n * boxes. Anything else is refused (`unsupported-envelope`) instead of guessed.\n * Passwords: at least {@link VAULT_MIN_PASSWORD_LENGTH} characters, enforced here\n * and not only in a UI.\n */\nimport { zeroize } from '@anywalletkit/core'\nimport { scryptAsync } from '@noble/hashes/scrypt.js'\nimport { fromBase64, toArrayBuffer, toBase64 } from './codec.js'\nimport { VaultError } from './errors.js'\n\n/** PBKDF2-SHA256 iterations (v1 envelopes): OWASP 2023 floor for SHA-256; anything lower is refused. */\nexport const VAULT_MIN_ITERATIONS = 600_000\nexport const VAULT_DEFAULT_ITERATIONS = 600_000\n/** scrypt for v2 envelopes: OWASP's recommended cost (128 MiB, ~1 s in a service worker). */\nexport const VAULT_SCRYPT = { N: 1 << 17, r: 8, p: 1 } as const\n/** The weakest scrypt an envelope may carry and still open (16 MiB). Tests use this; `create` uses {@link VAULT_SCRYPT}. */\nexport const VAULT_MIN_SCRYPT = { N: 1 << 14, r: 8, p: 1 } as const\n/** Shortest password `create` / `changePassword` accept. `unlock` takes whatever opens the vault. */\nexport const VAULT_MIN_PASSWORD_LENGTH = 8\nconst SALT_BYTES = 32\nconst IV_BYTES = 12\nconst DEK_BYTES = 32\n/** PRF outputs are 32 bytes (WebAuthn `prf` extension, `first`). */\nconst PRF_BYTES = 32\n\nexport interface SealedBox {\n /** 96-bit AES-GCM nonce, base64. */\n iv: string\n /** ciphertext ‖ 128-bit tag, base64. */\n data: string\n}\n\nexport interface VaultEnvelopeV1 {\n v: 1\n kdf: { name: 'PBKDF2-SHA256'; iterations: number; salt: string }\n /** The DEK, sealed under the password-derived key. AAD = version + kdf. */\n dek: SealedBox\n /** One box per key source (keyring source id), sealed under the DEK. AAD `forgewallet-vault/secret/<id>`. */\n secrets: Record<string, SealedBox>\n createdAt: number\n}\n\nexport interface VaultPasskey {\n /** WebAuthn credential id, base64url. */\n id: string\n label: string\n createdAt: number\n /** The DEK sealed under HKDF(PRF output, salt = credential id). AAD = `forgewallet-vault/2/passkey/<id>`. */\n dek: SealedBox\n /** The credential's public key (SPKI, base64) when the authenticator gave one — lets the worker verify assertions (passkey-per-signature). */\n publicKey?: string\n /** COSE algorithm of `publicKey` (-7 = ES256). */\n alg?: number\n}\n\nexport interface VaultEnvelopeV2 {\n v: 2\n kdf: { name: 'scrypt'; N: number; r: number; p: number; salt: string }\n dek: SealedBox\n secrets: Record<string, SealedBox>\n passkeys: VaultPasskey[]\n createdAt: number\n /** When a v1 envelope was re-sealed as v2. */\n upgradedAt?: number\n}\n\nexport type VaultEnvelope = VaultEnvelopeV1 | VaultEnvelopeV2\n\n/** Where the envelope lives. `chromeLocalVaultStorage()` for the extension, `memoryVaultStorage()` for tests. */\nexport interface VaultStorage {\n get(): Promise<VaultEnvelope | null>\n set(envelope: VaultEnvelope): Promise<void>\n clear(): Promise<void>\n}\n\nexport interface VaultOptions {\n storage: VaultStorage\n /** KDF for NEW envelopes and re-seals. Default scrypt (v2); `'pbkdf2'` writes v1 (tests, or a build that must stay FIPS-only). */\n kdf?: 'scrypt' | 'pbkdf2'\n /** PBKDF2 iterations for v1 envelopes (default and minimum {@link VAULT_DEFAULT_ITERATIONS}). */\n iterations?: number\n /** scrypt cost for v2 envelopes (default {@link VAULT_SCRYPT}; not below {@link VAULT_MIN_SCRYPT}). */\n scrypt?: { N: number; r: number; p: number }\n /** Progress of the scrypt derivation, 0..1 — the unlock screen's bar. */\n onProgress?: (fraction: number) => void\n /** Defaults to `globalThis.crypto`; injectable for tests. */\n crypto?: Crypto\n}\n\nexport interface VaultKdfInfo {\n version: 1 | 2\n name: 'PBKDF2-SHA256' | 'scrypt'\n /** Human line for the UI, e.g. \"scrypt N=2^17 r=8 p=1\". */\n summary: string\n}\n\n// AAD / HKDF labels are part of the sealed format: existing vaults open only with these exact strings.\nconst aadDekV1 = (kdf: VaultEnvelopeV1['kdf']) => `forgewallet-vault/1/dek/${kdf.name}/${kdf.iterations}/${kdf.salt}`\nconst aadDekV2 = (kdf: VaultEnvelopeV2['kdf']) => `forgewallet-vault/2/dek/scrypt/${kdf.N}/${kdf.r}/${kdf.p}/${kdf.salt}`\nconst aadPasskey = (id: string) => `forgewallet-vault/2/passkey/${id}`\nconst aadSecret = (id: string) => `forgewallet-vault/secret/${id}`\nconst HKDF_INFO = 'forgewallet-vault/2/passkey'\n\nexport class Vault {\n private readonly _storage: VaultStorage\n private readonly _kdf: 'scrypt' | 'pbkdf2'\n private readonly _iterations: number\n private readonly _scrypt: { N: number; r: number; p: number }\n private readonly _onProgress: ((fraction: number) => void) | undefined\n private readonly _crypto: Crypto\n\n constructor(options: VaultOptions) {\n this._storage = options.storage\n this._kdf = options.kdf ?? 'scrypt'\n this._iterations = options.iterations ?? VAULT_DEFAULT_ITERATIONS\n this._scrypt = options.scrypt ?? VAULT_SCRYPT\n this._onProgress = options.onProgress\n this._crypto = options.crypto ?? globalThis.crypto\n if (!Number.isInteger(this._iterations) || this._iterations < VAULT_MIN_ITERATIONS) {\n throw new VaultError(`PBKDF2 iterations must be an integer ≥ ${VAULT_MIN_ITERATIONS}`, 'invalid-input')\n }\n if (!isStrongScrypt(this._scrypt)) throw new VaultError(`scrypt cost must be at least N=${VAULT_MIN_SCRYPT.N} r=${VAULT_MIN_SCRYPT.r} p=${VAULT_MIN_SCRYPT.p} (N a power of two)`, 'invalid-input')\n }\n\n async exists(): Promise<boolean> {\n return (await this._storage.get()) !== null\n }\n\n /** What protects the DEK right now (UI). `null` without a vault. */\n async kdfInfo(): Promise<VaultKdfInfo | null> {\n const e = await this._storage.get()\n if (!e) return null\n if (isEnvelopeV1(e)) return { version: 1, name: 'PBKDF2-SHA256', summary: `PBKDF2-SHA256 ${e.kdf.iterations.toLocaleString('en-US')} iterations` }\n if (isEnvelopeV2(e)) return { version: 2, name: 'scrypt', summary: `scrypt N=2^${Math.log2(e.kdf.N)} r=${e.kdf.r} p=${e.kdf.p}` }\n return null\n }\n\n /**\n * Create an empty vault protected by `password`. Returns the DEK — hand it to the\n * session, then `setSecret` the first seed. Refuses when a vault exists.\n */\n async create(password: string): Promise<Uint8Array> {\n requirePassword(password, VAULT_MIN_PASSWORD_LENGTH)\n if (await this.exists()) throw new VaultError('A vault already exists; unlock it or reset explicitly.', 'exists')\n const dek = this._random(DEK_BYTES)\n await this._storage.set(await this._sealEnvelope(password, dek, {}, [], Date.now()))\n return dek\n }\n\n /**\n * Derive the KEK from `password`, unseal and return the DEK. `wrong-password` on\n * failure. A v1 (PBKDF2) envelope that opens is re-sealed as v2 (scrypt) on the\n * way out, secrets untouched.\n */\n async unlock(password: string): Promise<Uint8Array> {\n requirePassword(password)\n const envelope = await this._load()\n if (isEnvelopeV1(envelope)) {\n if (envelope.kdf.iterations < VAULT_MIN_ITERATIONS) throw new VaultError(`The vault's KDF (${envelope.kdf.iterations} iterations) is below the floor this build accepts.`, 'weak-kdf')\n const kek = await this._derivePbkdf2(password, fromBase64(envelope.kdf.salt), envelope.kdf.iterations)\n const dek = await this._open(kek, envelope.dek, aadDekV1(envelope.kdf), 'wrong-password')\n if (this._kdf === 'scrypt') {\n // Upgrade in place: same secrets, same createdAt, scrypt-wrapped DEK.\n const next = await this._sealEnvelope(password, dek, envelope.secrets, [], envelope.createdAt)\n await this._storage.set(isEnvelopeV2(next) ? { ...next, upgradedAt: Date.now() } : next)\n }\n return dek\n }\n if (!isStrongScrypt(envelope.kdf)) throw new VaultError(`The vault's scrypt cost (N=${envelope.kdf.N} r=${envelope.kdf.r} p=${envelope.kdf.p}) is below the floor this build accepts.`, 'weak-kdf')\n const kek = await this._deriveScrypt(password, fromBase64(envelope.kdf.salt), envelope.kdf)\n return this._open(kek, envelope.dek, aadDekV2(envelope.kdf), 'wrong-password')\n }\n\n /** Re-wrap the DEK under a new password (fresh salt, current KDF). Secrets and passkeys are untouched. */\n async changePassword(oldPassword: string, newPassword: string): Promise<void> {\n requirePassword(newPassword, VAULT_MIN_PASSWORD_LENGTH)\n const dek = await this.unlock(oldPassword)\n try {\n const envelope = await this._load()\n const passkeys = isEnvelopeV2(envelope) ? envelope.passkeys : []\n const next = await this._sealEnvelope(newPassword, dek, envelope.secrets, passkeys, envelope.createdAt)\n await this._storage.set(isEnvelopeV2(envelope) && envelope.upgradedAt !== undefined && isEnvelopeV2(next) ? { ...next, upgradedAt: envelope.upgradedAt } : next)\n } finally {\n zeroize(dek)\n }\n }\n\n // ---- passkeys (v2) ----\n\n /** Public view of the registered passkeys (ids, labels; whether each can verify assertions). */\n async listPasskeys(): Promise<Array<{ id: string; label: string; createdAt: number; canVerify: boolean }>> {\n const e = await this._storage.get()\n if (!e || !isEnvelopeV2(e)) return []\n return e.passkeys.map((p) => ({ id: p.id, label: p.label, createdAt: p.createdAt, canVerify: typeof p.publicKey === 'string' && p.alg === -7 }))\n }\n\n /** The SPKI public key (base64) of one passkey, for assertion verification; `null` when unknown. */\n async passkeyPublicKey(id: string): Promise<{ publicKey: string; alg: number } | null> {\n const e = await this._storage.get()\n if (!e || !isEnvelopeV2(e)) return null\n const p = e.passkeys.find((k) => k.id === id)\n return p?.publicKey && p.alg !== undefined ? { publicKey: p.publicKey, alg: p.alg } : null\n }\n\n /**\n * Register a passkey as a second unlock path: the DEK (from the unlocked session)\n * is sealed under HKDF-SHA256(`prf`, salt = credential id). The password stays\n * the recovery path; `prf` is zeroized here. A v1 envelope must be unlocked (and\n * thereby upgraded) first.\n */\n async addPasskey(dek: Uint8Array, passkey: { id: string; prf: Uint8Array; label: string; publicKey?: string | undefined; alg?: number | undefined }): Promise<void> {\n try {\n requireId(passkey.id)\n if (passkey.prf.length !== PRF_BYTES) throw new VaultError(`A PRF output is ${PRF_BYTES} bytes.`, 'invalid-input')\n const envelope = await this._load()\n if (!isEnvelopeV2(envelope)) throw new VaultError('Unlock with the password once so the vault is upgraded before adding a passkey.', 'unsupported-envelope')\n if (envelope.passkeys.some((p) => p.id === passkey.id)) throw new VaultError('This passkey is already registered.', 'exists')\n // Prove the DEK is the vault's before sealing it under a new key.\n await this._requireDek(dek, envelope)\n const key = await this._derivePasskeyKek(passkey.prf, passkey.id)\n const entry: VaultPasskey = { id: passkey.id, label: passkey.label.slice(0, 64), createdAt: Date.now(), dek: await this._seal(key, dek, aadPasskey(passkey.id)) }\n if (passkey.publicKey && passkey.alg !== undefined) { entry.publicKey = passkey.publicKey; entry.alg = passkey.alg }\n await this._storage.set({ ...envelope, passkeys: [...envelope.passkeys, entry] })\n } finally {\n zeroize(passkey.prf)\n }\n }\n\n /** Unseal the DEK with a passkey's PRF output. `wrong-password` when the box does not open, `missing` when the id is unknown. */\n async unlockWithPasskey(id: string, prf: Uint8Array): Promise<Uint8Array> {\n try {\n requireId(id)\n if (prf.length !== PRF_BYTES) throw new VaultError(`A PRF output is ${PRF_BYTES} bytes.`, 'invalid-input')\n const envelope = await this._load()\n if (!isEnvelopeV2(envelope)) throw new VaultError('This vault has no passkeys; unlock with the password.', 'missing')\n const entry = envelope.passkeys.find((p) => p.id === id)\n if (!entry) throw new VaultError('No such passkey on this vault.', 'missing')\n const key = await this._derivePasskeyKek(prf, id)\n return await this._open(key, entry.dek, aadPasskey(id), 'wrong-password')\n } finally {\n zeroize(prf)\n }\n }\n\n async removePasskey(id: string): Promise<void> {\n requireId(id)\n const envelope = await this._load()\n if (!isEnvelopeV2(envelope)) return\n await this._storage.set({ ...envelope, passkeys: envelope.passkeys.filter((p) => p.id !== id) })\n }\n\n // ---- secrets ----\n\n async listSecretIds(): Promise<string[]> {\n const envelope = await this._storage.get()\n return envelope ? Object.keys(envelope.secrets) : []\n }\n\n /** Seal `secret` under the DEK as `sourceId` (overwrites an entry with the same id). */\n async setSecret(dek: Uint8Array, sourceId: string, secret: Uint8Array): Promise<void> {\n requireId(sourceId)\n const envelope = await this._load()\n const key = await this._importDek(dek)\n const box = await this._seal(key, secret, aadSecret(sourceId))\n await this._storage.set({ ...envelope, secrets: { ...envelope.secrets, [sourceId]: box } })\n }\n\n /** Unseal one secret. `null` when the id is unknown; the caller zeroizes the result after use. */\n async getSecret(dek: Uint8Array, sourceId: string): Promise<Uint8Array | null> {\n requireId(sourceId)\n const envelope = await this._load()\n const box = envelope.secrets[sourceId]\n if (!box) return null\n const key = await this._importDek(dek)\n return this._open(key, box, aadSecret(sourceId), 'locked')\n }\n\n async deleteSecret(sourceId: string): Promise<void> {\n requireId(sourceId)\n const envelope = await this._load()\n if (!(sourceId in envelope.secrets)) return\n const secrets = { ...envelope.secrets }\n delete secrets[sourceId]\n await this._storage.set({ ...envelope, secrets })\n }\n\n /** Remove the whole vault. The explicit destructive flow only (back up → wipe → create). */\n async destroy(): Promise<void> {\n await this._storage.clear()\n }\n\n // ---- crypto ----\n\n private _random(n: number): Uint8Array {\n return this._crypto.getRandomValues(new Uint8Array(n))\n }\n\n /** A fresh envelope (v2 by default, v1 with `kdf: 'pbkdf2'`) wrapping `dek` under `password`. */\n private async _sealEnvelope(password: string, dek: Uint8Array, secrets: Record<string, SealedBox>, passkeys: VaultPasskey[], createdAt: number): Promise<VaultEnvelope> {\n const salt = this._random(SALT_BYTES)\n if (this._kdf === 'pbkdf2') {\n const kdf: VaultEnvelopeV1['kdf'] = { name: 'PBKDF2-SHA256', iterations: this._iterations, salt: toBase64(salt) }\n const kek = await this._derivePbkdf2(password, salt, this._iterations)\n return { v: 1, kdf, dek: await this._seal(kek, dek, aadDekV1(kdf)), secrets, createdAt }\n }\n const kdf: VaultEnvelopeV2['kdf'] = { name: 'scrypt', ...this._scrypt, salt: toBase64(salt) }\n const kek = await this._deriveScrypt(password, salt, kdf)\n return { v: 2, kdf, dek: await this._seal(kek, dek, aadDekV2(kdf)), secrets, passkeys, createdAt }\n }\n\n /** The caller's DEK must open this envelope's secrets — it is the key the password protects, not any 32 bytes. */\n private async _requireDek(dek: Uint8Array, envelope: VaultEnvelope): Promise<void> {\n const ids = Object.keys(envelope.secrets)\n const key = await this._importDek(dek)\n if (ids.length === 0) return\n const probe = await this._open(key, envelope.secrets[ids[0]!]!, aadSecret(ids[0]!), 'locked')\n zeroize(probe)\n }\n\n private async _derivePbkdf2(password: string, salt: Uint8Array, iterations: number): Promise<CryptoKey> {\n const subtle = this._crypto.subtle\n const material = await subtle.importKey('raw', toArrayBuffer(new TextEncoder().encode(password.normalize('NFKC'))), 'PBKDF2', false, ['deriveKey'])\n return subtle.deriveKey({ name: 'PBKDF2', hash: 'SHA-256', salt: toArrayBuffer(salt), iterations }, material, { name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt'])\n }\n\n private async _deriveScrypt(password: string, salt: Uint8Array, cost: { N: number; r: number; p: number }): Promise<CryptoKey> {\n const pw = new TextEncoder().encode(password.normalize('NFKC'))\n let raw: Uint8Array\n try {\n raw = await scryptAsync(pw, salt, { N: cost.N, r: cost.r, p: cost.p, dkLen: 32, maxmem: 2 * 128 * cost.N * cost.r + 1024 * 1024, ...(this._onProgress ? { onProgress: this._onProgress } : {}) })\n } finally {\n zeroize(pw)\n }\n try {\n return await this._crypto.subtle.importKey('raw', toArrayBuffer(raw), { name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt'])\n } finally {\n zeroize(raw)\n }\n }\n\n /** HKDF-SHA256(ikm = PRF output, salt = credential id bytes, info) → AES-256-GCM key. */\n private async _derivePasskeyKek(prf: Uint8Array, credentialId: string): Promise<CryptoKey> {\n const subtle = this._crypto.subtle\n const ikm = await subtle.importKey('raw', toArrayBuffer(prf), 'HKDF', false, ['deriveKey'])\n return subtle.deriveKey({ name: 'HKDF', hash: 'SHA-256', salt: toArrayBuffer(fromBase64Url(credentialId)), info: toArrayBuffer(new TextEncoder().encode(HKDF_INFO)) }, ikm, { name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt'])\n }\n\n private async _importDek(dek: Uint8Array): Promise<CryptoKey> {\n if (dek.length !== DEK_BYTES) throw new VaultError('Vault key must be 32 bytes.', 'invalid-input')\n return this._crypto.subtle.importKey('raw', toArrayBuffer(dek), { name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt'])\n }\n\n private async _seal(key: CryptoKey, plaintext: Uint8Array, aad: string): Promise<SealedBox> {\n const iv = this._random(IV_BYTES)\n const ct = await this._crypto.subtle.encrypt({ name: 'AES-GCM', iv: toArrayBuffer(iv), additionalData: toArrayBuffer(new TextEncoder().encode(aad)) }, key, toArrayBuffer(plaintext))\n return { iv: toBase64(iv), data: toBase64(new Uint8Array(ct)) }\n }\n\n private async _open(key: CryptoKey, box: SealedBox, aad: string, onFail: 'wrong-password' | 'locked'): Promise<Uint8Array> {\n try {\n const pt = await this._crypto.subtle.decrypt(\n { name: 'AES-GCM', iv: toArrayBuffer(fromBase64(box.iv)), additionalData: toArrayBuffer(new TextEncoder().encode(aad)) },\n key,\n toArrayBuffer(fromBase64(box.data)),\n )\n return new Uint8Array(pt)\n } catch {\n throw new VaultError(onFail === 'wrong-password' ? 'Wrong password.' : 'The vault key does not open this entry; lock and unlock again.', onFail)\n }\n }\n\n private async _load(): Promise<VaultEnvelope> {\n const envelope = await this._storage.get()\n if (!envelope) throw new VaultError('No vault in this storage area.', 'missing')\n if (!isEnvelopeV1(envelope) && !isEnvelopeV2(envelope)) throw new VaultError('Unsupported vault envelope.', 'unsupported-envelope')\n return envelope\n }\n}\n\nexport function isEnvelopeV1(x: unknown): x is VaultEnvelopeV1 {\n if (typeof x !== 'object' || x === null) return false\n const e = x as Record<string, unknown>\n const kdf = e.kdf as Record<string, unknown> | undefined\n return (\n e.v === 1 &&\n typeof kdf === 'object' && kdf !== null && kdf.name === 'PBKDF2-SHA256' && Number.isInteger(kdf.iterations) && typeof kdf.salt === 'string' &&\n isBox(e.dek) &&\n typeof e.secrets === 'object' && e.secrets !== null && Object.values(e.secrets as object).every(isBox)\n )\n}\n\nexport function isEnvelopeV2(x: unknown): x is VaultEnvelopeV2 {\n if (typeof x !== 'object' || x === null) return false\n const e = x as Record<string, unknown>\n const kdf = e.kdf as Record<string, unknown> | undefined\n return (\n e.v === 2 &&\n typeof kdf === 'object' && kdf !== null && kdf.name === 'scrypt' && Number.isInteger(kdf.N) && Number.isInteger(kdf.r) && Number.isInteger(kdf.p) && typeof kdf.salt === 'string' &&\n isBox(e.dek) &&\n typeof e.secrets === 'object' && e.secrets !== null && Object.values(e.secrets as object).every(isBox) &&\n Array.isArray(e.passkeys) && e.passkeys.every((p) => typeof p === 'object' && p !== null && typeof (p as VaultPasskey).id === 'string' && typeof (p as VaultPasskey).label === 'string' && isBox((p as VaultPasskey).dek))\n )\n}\n\nfunction isBox(x: unknown): x is SealedBox {\n return typeof x === 'object' && x !== null && typeof (x as SealedBox).iv === 'string' && typeof (x as SealedBox).data === 'string'\n}\n\nfunction isStrongScrypt(c: { N: number; r: number; p: number }): boolean {\n return Number.isInteger(c.N) && c.N >= VAULT_MIN_SCRYPT.N && (c.N & (c.N - 1)) === 0 && Number.isInteger(c.r) && c.r >= VAULT_MIN_SCRYPT.r && Number.isInteger(c.p) && c.p >= VAULT_MIN_SCRYPT.p\n}\n\nfunction requirePassword(password: string, minLength = 1): void {\n if (typeof password !== 'string' || password.length === 0) throw new VaultError('Password must not be empty.', 'invalid-input')\n if ([...password].length < minLength) throw new VaultError(`Password must be at least ${minLength} characters.`, 'invalid-input')\n}\n\nfunction requireId(id: string): void {\n if (typeof id !== 'string' || id.length === 0 || id.length > 128) throw new VaultError('Bad source id.', 'invalid-input')\n}\n\n/** base64url (WebAuthn ids) → bytes; plain base64 is accepted too. */\nexport function fromBase64Url(text: string): Uint8Array {\n const b64 = text.replace(/-/g, '+').replace(/_/g, '/')\n return fromBase64(b64 + '='.repeat((4 - (b64.length % 4)) % 4))\n}\n\nexport function toBase64Url(bytes: Uint8Array): string {\n return toBase64(bytes).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n}\n\n/** Envelope in memory — tests and the smoke. */\nexport function memoryVaultStorage(initial: VaultEnvelope | null = null): VaultStorage & { envelope: VaultEnvelope | null } {\n const s = {\n envelope: initial,\n async get() { return s.envelope ? structuredClone(s.envelope) : null },\n async set(envelope: VaultEnvelope) { s.envelope = structuredClone(envelope) },\n async clear() { s.envelope = null },\n }\n return s\n}\n","// base64 for the JSON envelopes — `btoa`/`atob` exist in every extension context (service worker included).\n\nexport function toBase64(bytes: Uint8Array): string {\n let s = ''\n for (let i = 0; i < bytes.length; i += 0x8000) s += String.fromCharCode(...bytes.subarray(i, i + 0x8000))\n return btoa(s)\n}\n\nexport function fromBase64(text: string): Uint8Array {\n const s = atob(text)\n const out = new Uint8Array(s.length)\n for (let i = 0; i < s.length; i++) out[i] = s.charCodeAt(i)\n return out\n}\n\nexport const utf8 = {\n encode: (text: string): Uint8Array => new TextEncoder().encode(text),\n decode: (bytes: Uint8Array): string => new TextDecoder().decode(bytes),\n}\n\n/** Copy into a fresh ArrayBuffer — WebCrypto rejects views over shared / offset buffers in some engines. */\nexport function toArrayBuffer(bytes: Uint8Array): ArrayBuffer {\n const copy = new Uint8Array(bytes.byteLength)\n copy.set(bytes)\n return copy.buffer\n}\n","/**\n * The unlocked state. An MV3 service worker dies after ~30 s idle, so the\n * unlocked vault key cannot live in a JS variable: it lives in\n * `chrome.storage.session` (memory-only, cleared when the browser exits, readable\n * by extension contexts only) together with its expiry, and a `chrome.alarms`\n * alarm locks it when the auto-lock timer (default 15 min since the last\n * activity) runs out.\n *\n * The session never sees a password or a seed — only the DEK the vault returned.\n * The popup never receives the DEK either: it asks the service worker to\n * perform operations by id.\n */\nimport { zeroize } from '@anywalletkit/core'\nimport { fromBase64, toBase64 } from './codec.js'\nimport { VaultError } from './errors.js'\n\n/** Structural `chrome.storage.session` (or any `StorageArea`); `memorySessionStorage()` for tests. */\nexport interface SessionStorage {\n get(key: string): Promise<unknown>\n set(key: string, value: unknown): Promise<void>\n remove(key: string): Promise<void>\n}\n\n/** Structural `chrome.alarms`: one named alarm, fired once at `when` (ms since epoch). */\nexport interface SessionAlarms {\n schedule(name: string, when: number): Promise<void> | void\n clear(name: string): Promise<void> | void\n /** Register the lock callback; the chrome adapter wires `chrome.alarms.onAlarm`. */\n onFire(handler: (name: string) => void): void\n}\n\nexport interface SessionOptions {\n storage: SessionStorage\n alarms: SessionAlarms\n /** Lock this long after the last `touch` / `unlock`. Default 15 min; 0 disables the timer (lock only on browser exit or explicit lock). */\n autoLockMs?: number\n /** Storage key and alarm name prefix. */\n name?: string\n /** Clock, injectable for tests. */\n now?: () => number\n}\n\ninterface SessionRecord {\n key: string\n expiresAt: number\n}\n\nexport const SESSION_DEFAULT_AUTOLOCK_MS = 15 * 60_000\n\nexport class Session {\n private readonly _storage: SessionStorage\n private readonly _alarms: SessionAlarms\n private _autoLockMs: number\n private readonly _key: string\n private readonly _alarm: string\n private readonly _now: () => number\n private readonly _onLock = new Set<() => void>()\n\n constructor(options: SessionOptions) {\n this._storage = options.storage\n this._alarms = options.alarms\n this._autoLockMs = options.autoLockMs ?? SESSION_DEFAULT_AUTOLOCK_MS\n const name = options.name ?? 'anywalletkit-session'\n this._key = name\n this._alarm = `${name}/autolock`\n this._now = options.now ?? Date.now\n this._alarms.onFire((fired) => { if (fired === this._alarm) void this.lock() })\n }\n\n /** Store the DEK and arm the auto-lock. The caller's copy is zeroized. */\n async unlock(dek: Uint8Array): Promise<void> {\n if (dek.length !== 32) throw new VaultError('Vault key must be 32 bytes.', 'invalid-input')\n const expiresAt = this._expiry()\n await this._storage.set(this._key, { key: toBase64(dek), expiresAt } satisfies SessionRecord)\n zeroize(dek)\n await this._arm(expiresAt)\n }\n\n /** Forget the DEK and cancel the alarm. Safe to call when already locked. */\n async lock(): Promise<void> {\n const was = await this._storage.get(this._key)\n await this._storage.remove(this._key)\n await this._alarms.clear(this._alarm)\n if (was !== undefined && was !== null) for (const cb of this._onLock) cb()\n }\n\n async isUnlocked(): Promise<boolean> {\n return (await this._read()) !== null\n }\n\n /**\n * The DEK for one operation (zeroize it after). `locked` when there is none or the\n * timer ran out while the worker was asleep — the record is then removed as well, so\n * a missed alarm cannot keep the key alive.\n */\n async getKey(): Promise<Uint8Array> {\n const record = await this._read()\n if (!record) throw new VaultError('Wallet is locked.', 'locked')\n return fromBase64(record.key)\n }\n\n /** User activity: push the auto-lock out again. No-op when locked. */\n async touch(): Promise<void> {\n const record = await this._read()\n if (!record) return\n const expiresAt = this._expiry()\n await this._storage.set(this._key, { ...record, expiresAt } satisfies SessionRecord)\n await this._arm(expiresAt)\n }\n\n get autoLockMs(): number {\n return this._autoLockMs\n }\n\n /** Change the timer (options page); re-arms from now when unlocked. 0 disables. */\n async setAutoLockMs(ms: number): Promise<void> {\n if (!Number.isFinite(ms) || ms < 0) throw new VaultError('Auto-lock must be a non-negative number of milliseconds.', 'invalid-input')\n this._autoLockMs = ms\n await this.touch()\n }\n\n onLock(callback: () => void): () => void {\n this._onLock.add(callback)\n return () => this._onLock.delete(callback)\n }\n\n private _expiry(): number {\n return this._autoLockMs > 0 ? this._now() + this._autoLockMs : Number.POSITIVE_INFINITY\n }\n\n private async _arm(expiresAt: number): Promise<void> {\n if (Number.isFinite(expiresAt)) await this._alarms.schedule(this._alarm, expiresAt)\n else await this._alarms.clear(this._alarm)\n }\n\n private async _read(): Promise<SessionRecord | null> {\n const raw = (await this._storage.get(this._key)) as Partial<SessionRecord> | undefined | null\n if (!raw || typeof raw.key !== 'string' || typeof raw.expiresAt !== 'number') return null\n if (raw.expiresAt <= this._now()) { await this.lock(); return null }\n return raw as SessionRecord\n }\n}\n\n/** In-memory `chrome.storage.session` stand-in. */\nexport function memorySessionStorage(): SessionStorage & { data: Map<string, unknown> } {\n const data = new Map<string, unknown>()\n return {\n data,\n async get(key) { return data.get(key) },\n async set(key, value) { data.set(key, structuredClone(value)) },\n async remove(key) { data.delete(key) },\n }\n}\n\n/** In-memory alarms: `fire(name)` from the test, `pending` to inspect. */\nexport function memoryAlarms(): SessionAlarms & { pending: Map<string, number>; fire(name: string): void } {\n const pending = new Map<string, number>()\n const handlers = new Set<(name: string) => void>()\n return {\n pending,\n schedule(name, when) { pending.set(name, when) },\n clear(name) { pending.delete(name) },\n onFire(handler) { handlers.add(handler) },\n fire(name) { pending.delete(name); for (const h of handlers) h(name) },\n }\n}\n","/**\n * Message shapes on the two hops between a dApp and the wallet:\n *\n * ```text\n * page (injected provider, MAIN world)\n * │ window.postMessage — PageRequest ⇄ PageResponse / PageEvent\n * content script (isolated world) — stamps `location.origin`, owns the port\n * │ chrome.runtime.connect(PORT_NAME) — RelayRequest ⇄ RelayResponse / RelayEvent\n * service worker — trusts `port.sender` (set by the browser), never the page\n * ```\n *\n * The page can forge anything it posts, so a page message carries no origin and\n * no identity: the content script adds the origin, and the service worker\n * cross-checks it against `port.sender.origin` ({@link checkSenderOrigin}) — a\n * mismatch is dropped, not answered. Request ids are opaque strings minted by\n * the page side ({@link newRequestId}); the content script does not reuse them\n * across ports.\n */\n\n/** `chrome.runtime.connect({ name })` for content-script ports. */\nexport const PORT_NAME = 'anywalletkit/relay/1'\n/** `window.postMessage` discriminators (both directions). */\nexport const PAGE_TARGET = { toContent: 'anywalletkit/content', toPage: 'anywalletkit/page' } as const\n\n/** CAIP-2 namespace of the provider that spoke. */\nexport type RelayChain = 'eip155' | 'solana' | 'ton' | 'tron' | 'bip122' | 'near'\n\nexport interface RelayError {\n /** EIP-1193 / EIP-1474 numbering for EVM; the same numbers are reused for the other providers. */\n code: number\n message: string\n data?: unknown\n}\n\nexport const RELAY_ERRORS = {\n userRejected: 4001,\n unauthorized: 4100,\n unsupportedMethod: 4200,\n disconnected: 4900,\n chainDisconnected: 4901,\n /** EIP-3326/3085: the chain is not in the wallet (`wallet_switchEthereumChain` → suggest `wallet_addEthereumChain`). */\n chainNotAdded: 4902,\n internal: -32603,\n invalidRequest: -32600,\n invalidParams: -32602,\n /** EIP-1474: a request of the same kind from this origin is already waiting (MetaMask's \"already pending\"). */\n resourceUnavailable: -32002,\n /** EIP-1474: this origin has too many requests waiting. */\n limitExceeded: -32005,\n} as const\n\n// ---- hop 1: page ⇄ content script ----\n\nexport interface PageRequest {\n target: typeof PAGE_TARGET.toContent\n id: string\n chain: RelayChain\n method: string\n params?: unknown\n}\n\nexport interface PageResponse {\n target: typeof PAGE_TARGET.toPage\n id: string\n result?: unknown\n error?: RelayError\n}\n\nexport interface PageEvent {\n target: typeof PAGE_TARGET.toPage\n chain: RelayChain\n event: string\n data?: unknown\n}\n\n// ---- hop 2: content script ⇄ service worker ----\n\nexport interface RelayRequest {\n kind: 'request'\n id: string\n /** `location.origin` of the page, stamped by the content script. */\n origin: string\n chain: RelayChain\n method: string\n params?: unknown\n}\n\nexport interface RelayResponse {\n kind: 'response'\n id: string\n result?: unknown\n error?: RelayError\n}\n\nexport interface RelayEvent {\n kind: 'event'\n chain: RelayChain\n event: string\n data?: unknown\n}\n\nexport type RelayToWorker = RelayRequest\nexport type RelayToContent = RelayResponse | RelayEvent\n\n// ---- guards ----\n\nconst CHAINS: ReadonlySet<string> = new Set<RelayChain>(['eip155', 'solana', 'ton', 'tron', 'bip122', 'near'])\n\nconst isRecord = (x: unknown): x is Record<string, unknown> => typeof x === 'object' && x !== null\nconst isId = (x: unknown): x is string => typeof x === 'string' && x.length > 0 && x.length <= 64\n\nexport function isPageRequest(x: unknown): x is PageRequest {\n return isRecord(x) && x.target === PAGE_TARGET.toContent && isId(x.id) && CHAINS.has(x.chain as string) && typeof x.method === 'string'\n}\n\nexport function isPageResponse(x: unknown): x is PageResponse {\n return isRecord(x) && x.target === PAGE_TARGET.toPage && isId(x.id)\n}\n\nexport function isPageEvent(x: unknown): x is PageEvent {\n return isRecord(x) && x.target === PAGE_TARGET.toPage && !('id' in x) && CHAINS.has(x.chain as string) && typeof x.event === 'string'\n}\n\nexport function isRelayRequest(x: unknown): x is RelayRequest {\n return isRecord(x) && x.kind === 'request' && isId(x.id) && typeof x.origin === 'string' && CHAINS.has(x.chain as string) && typeof x.method === 'string'\n}\n\nexport function isRelayToContent(x: unknown): x is RelayToContent {\n return isRecord(x) && ((x.kind === 'response' && isId(x.id)) || (x.kind === 'event' && typeof x.event === 'string'))\n}\n\nexport function newRequestId(): string {\n return crypto.randomUUID()\n}\n\n/** The content script's stamp: {@link PageRequest} + the page origin. */\nexport function stampOrigin(request: PageRequest, origin: string): RelayRequest {\n const { id, chain, method } = request\n return 'params' in request ? { kind: 'request', id, origin, chain, method, params: request.params } : { kind: 'request', id, origin, chain, method }\n}\n\n/** What `port.sender` looks like (structural `chrome.runtime.MessageSender`). */\nexport interface PortSender {\n origin?: string | undefined\n url?: string | undefined\n tab?: { id?: number | undefined } | undefined\n frameId?: number | undefined\n}\n\n/**\n * The service worker's check before it believes a stamped origin: it must equal the\n * origin the browser recorded for the port. Returns the trusted origin or `null`.\n */\nexport function checkSenderOrigin(sender: PortSender | undefined, stamped: string): string | null {\n const fromSender = sender?.origin ?? (sender?.url ? safeOrigin(sender.url) : undefined)\n if (!fromSender || fromSender === 'null') return null\n return fromSender === stamped ? fromSender : null\n}\n\nfunction safeOrigin(url: string): string | undefined {\n try { return new URL(url).origin } catch { return undefined }\n}\n\nexport const relayError = (code: number, message: string, data?: unknown): RelayError => (data === undefined ? { code, message } : { code, message, data })\n","/**\n * Adapters over the `chrome.*` APIs, typed structurally so this package needs no\n * `@types/chrome` and tests can pass fakes. Promise forms (MV3) only.\n */\nimport type { SessionAlarms, SessionStorage } from './session.js'\nimport type { VaultEnvelope, VaultStorage } from './vault.js'\n\nexport interface StorageAreaLike {\n get(keys: string | string[]): Promise<Record<string, unknown>>\n set(items: Record<string, unknown>): Promise<void>\n remove(keys: string | string[]): Promise<void>\n /** `chrome.storage.session` only. */\n setAccessLevel?(options: { accessLevel: 'TRUSTED_CONTEXTS' | 'TRUSTED_AND_UNTRUSTED_CONTEXTS' }): Promise<void>\n}\n\nexport interface AlarmsLike {\n create(name: string, info: { when: number }): Promise<void> | void\n clear(name: string): Promise<boolean> | boolean | void\n onAlarm: { addListener(callback: (alarm: { name: string }) => void): void }\n}\n\n/** Stable storage key: existing vaults live under it — never rename. */\nexport const VAULT_STORAGE_KEY = 'forgewallet.vault.v1'\n\n/** The encrypted envelope in `chrome.storage.local` (survives browser restarts; ciphertext only). */\nexport function chromeLocalVaultStorage(area: StorageAreaLike, key = VAULT_STORAGE_KEY): VaultStorage {\n return {\n async get() { const r = await area.get(key); return (r[key] as VaultEnvelope | undefined) ?? null },\n async set(envelope) { await area.set({ [key]: envelope }) },\n async clear() { await area.remove(key) },\n }\n}\n\n/**\n * `chrome.storage.session`: memory-only, gone when the browser exits. Access is\n * pinned to trusted contexts (the default; made explicit so a content script can\n * never read the unlocked key even if a later change opens the area to them).\n */\nexport function chromeSessionStorage(area: StorageAreaLike): SessionStorage {\n const ready = area.setAccessLevel ? area.setAccessLevel({ accessLevel: 'TRUSTED_CONTEXTS' }) : Promise.resolve()\n return {\n async get(key) { await ready; return (await area.get(key))[key] },\n async set(key, value) { await ready; await area.set({ [key]: value }) },\n async remove(key) { await ready; await area.remove(key) },\n }\n}\n\n/** `chrome.alarms` as one-shot named alarms. Chrome rounds alarms to ≥ 30 s in packed extensions. */\nexport function chromeAlarms(alarms: AlarmsLike): SessionAlarms {\n return {\n async schedule(name, when) { await alarms.create(name, { when }) },\n async clear(name) { await alarms.clear(name) },\n onFire(handler) { alarms.onAlarm.addListener((alarm) => handler(alarm.name)) },\n }\n}\n","/**\n * `@anywalletkit/keyring` adapters for the extension. The keyring stores public\n * metadata (names, addresses, flags) through `KeyringStorage` and one secret per\n * key source through `SecretStorage`:\n *\n * - {@link chromeKeyringStorage}: the metadata as plain JSON in `chrome.storage.local`;\n * - {@link vaultSecretStorage}: every secret sealed in the {@link Vault} under the\n * DEK the {@link Session} holds. Each call fetches the DEK, uses it once and\n * zeroizes it; a locked session surfaces as `VaultError('locked')`, which the\n * service worker turns into \"unlock first\" for the UI.\n *\n * The keyring's secret strings (JSON with the mnemonic) are immutable JS values\n * and cannot be zeroized; the keyring reads one per operation and drops it, so\n * their lifetime is one call. The byte buffers this module owns are zeroized.\n */\nimport { zeroize } from '@anywalletkit/core'\nimport type { KeyringState, KeyringStorage, SecretStorage } from '@anywalletkit/keyring'\nimport type { StorageAreaLike } from './chrome.js'\nimport { utf8 } from './codec.js'\nimport type { Session } from './session.js'\nimport type { Vault } from './vault.js'\n\n/** Stable storage key: existing keyrings live under it — never rename. */\nexport const KEYRING_STORAGE_KEY = 'forgewallet.keyring.v1'\n\n/** Keyring metadata (no secrets) in `chrome.storage.local`. */\nexport function chromeKeyringStorage(area: StorageAreaLike, key = KEYRING_STORAGE_KEY): KeyringStorage {\n return {\n async load() { const r = await area.get(key); return (r[key] as KeyringState | undefined) ?? null },\n async save(state) { await area.set({ [key]: state }) },\n }\n}\n\n/** Keyring secrets sealed in the vault; readable only while the session is unlocked. */\nexport function vaultSecretStorage(vault: Vault, session: Session): SecretStorage {\n const withKey = async <T>(fn: (dek: Uint8Array) => Promise<T>): Promise<T> => {\n const dek = await session.getKey()\n try { return await fn(dek) } finally { zeroize(dek) }\n }\n return {\n async get(sourceId) {\n return withKey(async (dek) => {\n const bytes = await vault.getSecret(dek, sourceId)\n if (!bytes) return null\n try { return utf8.decode(bytes) } finally { zeroize(bytes) }\n })\n },\n async set(sourceId, secret) {\n const bytes = utf8.encode(secret)\n try { await withKey((dek) => vault.setSecret(dek, sourceId, bytes)) } finally { zeroize(bytes) }\n },\n async delete(sourceId) {\n await vault.deleteSecret(sourceId)\n },\n }\n}\n","/**\n * Default EVM networks for an extension built on this kit: the chains Vaulty's in-app\n * browser can read and sign on, with the same public RPC failover lists\n * (`mobile/lib/swap2.ts`), no API keys. A wallet build may prepend its own\n * endpoints; `wallet_addEthereumChain` may add a chain the asset catalog\n * (`@anywalletkit/swap2-assets`) knows — an unknown chain id is refused, so a\n * site cannot point the wallet at a look-alike network.\n */\nimport { ccChain } from '@anywalletkit/swap2-assets'\nimport { RELAY_ERRORS, relayError, type RelayError } from './relay.js'\nimport type { JsonStorage } from './storage.js'\n\nexport interface EvmNetwork {\n /** CAIP-2, `eip155:<chainId>`. */\n caip2: string\n chainId: number\n name: string\n /** Native currency symbol, 18 decimals on every chain here (on Arc that is the 18-decimal native view of USDC). */\n symbol: string\n /** Tried in order; the client fails over. */\n rpcs: string[]\n explorer?: string\n /** Set when a SITE supplied the RPC list (wallet_addEthereumChain): every sheet on this network says so and simulations are not trusted. */\n custom?: { origin: string; addedAt: number }\n}\n\nexport const DEFAULT_CHAIN = 'eip155:1'\n\nconst net = (chainId: number, name: string, symbol: string, rpcs: string[], explorer?: string): EvmNetwork =>\n explorer === undefined ? { caip2: `eip155:${chainId}`, chainId, name, symbol, rpcs } : { caip2: `eip155:${chainId}`, chainId, name, symbol, rpcs, explorer }\n\nexport const DEFAULT_NETWORKS: readonly EvmNetwork[] = Object.freeze([\n net(1, 'Ethereum', 'ETH', ['https://ethereum-rpc.publicnode.com', 'https://eth.drpc.org'], 'https://etherscan.io'),\n net(8453, 'Base', 'ETH', ['https://base-rpc.publicnode.com', 'https://mainnet.base.org', 'https://base.drpc.org'], 'https://basescan.org'),\n net(56, 'BNB Chain', 'BNB', ['https://bsc-rpc.publicnode.com', 'https://bsc-dataseed.bnbchain.org', 'https://bsc.drpc.org'], 'https://bscscan.com'),\n net(42161, 'Arbitrum', 'ETH', ['https://arbitrum-one-rpc.publicnode.com', 'https://arb1.arbitrum.io/rpc', 'https://arbitrum.drpc.org'], 'https://arbiscan.io'),\n net(10, 'Optimism', 'ETH', ['https://optimism-rpc.publicnode.com', 'https://mainnet.optimism.io', 'https://optimism.drpc.org'], 'https://optimistic.etherscan.io'),\n net(137, 'Polygon', 'POL', ['https://polygon-bor-rpc.publicnode.com', 'https://polygon.drpc.org'], 'https://polygonscan.com'),\n net(43114, 'Avalanche', 'AVAX', ['https://avalanche-c-chain-rpc.publicnode.com', 'https://api.avax.network/ext/bc/C/rpc', 'https://avalanche.drpc.org'], 'https://snowtrace.io'),\n net(999, 'HyperEVM', 'HYPE', ['https://rpc.hyperliquid.xyz/evm', 'https://hyperliquid.drpc.org', 'https://hyperliquid-json-rpc.stakely.io']),\n net(4663, 'Robinhood Chain', 'ETH', ['https://rpc.mainnet.chain.robinhood.com', 'https://robinhood.drpc.org'], 'https://robinhoodchain.blockscout.com'),\n net(324, 'zkSync Era', 'ETH', ['https://mainnet.era.zksync.io', 'https://zksync.drpc.org'], 'https://era.zksync.network'),\n net(42220, 'Celo', 'CELO', ['https://forno.celo.org', 'https://celo.drpc.org'], 'https://celoscan.io'),\n net(4326, 'MegaETH', 'ETH', ['https://mainnet.megaeth.com/rpc']),\n net(130, 'Unichain', 'ETH', ['https://mainnet.unichain.org', 'https://unichain-rpc.publicnode.com'], 'https://uniscan.xyz'),\n net(143, 'Monad', 'MON', ['https://rpc.monad.xyz']),\n net(9745, 'Plasma', 'XPL', ['https://rpc.plasma.to']),\n net(59144, 'Linea', 'ETH', ['https://rpc.linea.build', 'https://linea-rpc.publicnode.com'], 'https://lineascan.build'),\n net(100, 'Gnosis', 'xDAI', ['https://rpc.gnosischain.com', 'https://gnosis-rpc.publicnode.com'], 'https://gnosisscan.io'),\n net(146, 'Sonic', 'S', ['https://rpc.soniclabs.com', 'https://sonic-rpc.publicnode.com'], 'https://sonicscan.org'),\n net(480, 'World Chain', 'ETH', ['https://worldchain-mainnet.g.alchemy.com/public', 'https://worldchain-mainnet.gateway.tenderly.co'], 'https://worldscan.org'),\n net(1329, 'Sei', 'SEI', ['https://evm-rpc.sei-apis.com'], 'https://seitrace.com'),\n net(57073, 'Ink', 'ETH', ['https://rpc-gel.inkonchain.com'], 'https://explorer.inkonchain.com'),\n net(98866, 'Plume', 'PLUME', ['https://rpc.plume.org'], 'https://explorer.plume.org'),\n net(196, 'X Layer', 'OKB', ['https://rpc.xlayer.tech', 'https://xlayerrpc.okx.com'], 'https://www.okx.com/web3/explorer/xlayer'),\n net(534352, 'Scroll', 'ETH', ['https://rpc.scroll.io', 'https://scroll-rpc.publicnode.com'], 'https://scrollscan.com'),\n net(80094, 'Berachain', 'BERA', ['https://rpc.berachain.com', 'https://berachain-rpc.publicnode.com'], 'https://berascan.com'),\n // Arc (Circle's L1): the gas token is USDC. eth_getBalance / msg.value / gas are accounted in 18-decimal units (the\n // `symbol` here names that native view); the ERC-20 interface at 0x3600…0000 reads the SAME balance in 6 decimals\n // and is what the catalog, LI.FI and CCTP address (see swap2-assets). Balances must show one view, not both.\n net(5042, 'Arc', 'USDC', ['https://rpc.mainnet.arc.io'], 'https://explorer.arc.io'),\n net(5000, 'Mantle', 'MNT', ['https://rpc.mantle.xyz', 'https://mantle-rpc.publicnode.com'], 'https://mantlescan.xyz'),\n net(747474, 'Katana', 'ETH', ['https://rpc.katana.network'], 'https://explorer.katanarpc.com'),\n net(2818, 'Morph', 'ETH', ['https://rpc.morphl2.io', 'https://rpc-quicknode.morphl2.io'], 'https://explorer.morphl2.io'),\n net(14, 'Flare', 'FLR', ['https://flare-api.flare.network/ext/C/rpc', 'https://flare.rpc.thirdweb.com'], 'https://flare-explorer.flare.network'),\n])\n\nexport const chainHex = (caip2: string): string => `0x${Number(caip2.split(':')[1]).toString(16)}`\n\n/** `0x1` / `1` → `eip155:1`; `null` for anything that is not a positive integer chain id. */\nexport function caip2FromChainId(value: unknown): string | null {\n let n: number\n if (typeof value === 'string') {\n const s = value.trim()\n if (/^0x[0-9a-f]+$/i.test(s)) n = Number.parseInt(s, 16)\n else if (/^[0-9]+$/.test(s)) n = Number.parseInt(s, 10)\n else return null\n } else if (typeof value === 'number') n = value\n else return null\n return Number.isSafeInteger(n) && n > 0 ? `eip155:${n}` : null\n}\n\n/** Whether the asset catalog knows this chain — the gate for `wallet_addEthereumChain`. */\nexport function isCatalogChain(caip2: string): boolean {\n return ccChain(caip2) !== undefined\n}\n\n/**\n * Shipped networks plus the ones the user accepted from sites, persisted. Lookup\n * by CAIP-2; a custom entry for a shipped chain is ignored (the build's RPC list\n * wins — a site must not be able to replace Ethereum's endpoints).\n */\nexport class NetworksTable {\n private _custom: EvmNetwork[] | null = null\n private _loading: Promise<EvmNetwork[]> | null = null\n /** add/remove run one after another (scan F22, as PermissionStore). */\n private _queue: Promise<unknown> = Promise.resolve()\n\n constructor(private readonly storage: JsonStorage<EvmNetwork[]>, private readonly defaults: readonly EvmNetwork[] = DEFAULT_NETWORKS) {}\n\n async list(): Promise<EvmNetwork[]> {\n return [...this.defaults, ...(await this.custom())]\n }\n\n async get(caip2: string): Promise<EvmNetwork | null> {\n return this.defaults.find((n) => n.caip2 === caip2) ?? (await this.custom()).find((n) => n.caip2 === caip2) ?? null\n }\n\n add(network: EvmNetwork): Promise<void> {\n return this.serialize(async () => {\n if (this.defaults.some((n) => n.caip2 === network.caip2)) return\n const custom = (await this.custom()).filter((n) => n.caip2 !== network.caip2)\n custom.push(network)\n await this.write(custom)\n })\n }\n\n remove(caip2: string): Promise<void> {\n return this.serialize(async () => {\n const current = await this.custom()\n if (!current.some((n) => n.caip2 === caip2)) return\n await this.write(current.filter((n) => n.caip2 !== caip2))\n })\n }\n\n private serialize<T>(fn: () => Promise<T>): Promise<T> {\n const run = this._queue.then(fn, fn)\n this._queue = run.then(() => undefined, () => undefined)\n return run\n }\n\n /** Cache first (readers see it at once), rolled back when storage refuses. */\n private async write(custom: EvmNetwork[]): Promise<void> {\n const prev = await this.custom()\n this._custom = custom\n try {\n await this.storage.set(custom)\n } catch (e) {\n if (this._custom === custom) this._custom = prev\n throw e\n }\n }\n\n private async custom(): Promise<EvmNetwork[]> {\n if (this._custom) return this._custom\n this._loading ??= this.storage.get().then(\n (s) => (this._custom ??= s ?? []),\n (e: unknown) => { this._loading = null; throw e },\n )\n return this._loading\n }\n}\n\n/**\n * EIP-3085 `wallet_addEthereumChain` parameter → {@link EvmNetwork}, or the error\n * to answer with. https RPC urls only; the chain id must be in the catalog.\n */\nexport function parseAddChainParams(params: unknown, known: (caip2: string) => boolean = isCatalogChain): EvmNetwork | RelayError {\n const p = (Array.isArray(params) ? params[0] : params) as Record<string, unknown> | undefined\n if (!p || typeof p !== 'object') return relayError(RELAY_ERRORS.invalidParams, 'wallet_addEthereumChain expects one object parameter.')\n const caip2 = caip2FromChainId(p.chainId)\n if (!caip2) return relayError(RELAY_ERRORS.invalidParams, 'chainId must be a 0x-prefixed hex string.')\n if (!known(caip2)) return relayError(RELAY_ERRORS.chainNotAdded, `Chain ${String(p.chainId)} is not in this wallet's catalog.`)\n const rpcs = Array.isArray(p.rpcUrls) ? p.rpcUrls.filter((u): u is string => typeof u === 'string' && /^https:\\/\\/[^\\s/?#]+/i.test(u)) : []\n if (rpcs.length === 0) return relayError(RELAY_ERRORS.invalidParams, 'rpcUrls must contain at least one https URL.')\n const name = typeof p.chainName === 'string' && p.chainName.trim() ? p.chainName.trim().slice(0, 64) : caip2\n const currency = p.nativeCurrency as { symbol?: unknown; decimals?: unknown } | undefined\n if (currency && currency.decimals !== undefined && currency.decimals !== 18) return relayError(RELAY_ERRORS.invalidParams, 'nativeCurrency.decimals must be 18.')\n const symbol = typeof currency?.symbol === 'string' && /^[A-Za-z0-9]{1,12}$/.test(currency.symbol) ? currency.symbol : 'ETH'\n const explorers = Array.isArray(p.blockExplorerUrls) ? p.blockExplorerUrls.filter((u): u is string => typeof u === 'string' && /^https:\\/\\//i.test(u)) : []\n const network: EvmNetwork = { caip2, chainId: Number(caip2.split(':')[1]), name, symbol, rpcs }\n return explorers[0] ? { ...network, explorer: explorers[0] } : network\n}\n\n// ---- non-EVM chains: the CAIP-2 ids the asset catalog / swap2 engine use, and public endpoints only (Vaulty's lists minus its proxies) ----\n\n/** Solana mainnet as the catalog names it (`solana:mainnet`); the wallet package also accepts the genesis-hash form. */\nexport const SOLANA_CHAIN = 'solana:mainnet'\nexport const SOLANA_RPCS: readonly string[] = Object.freeze(['https://solana-rpc.publicnode.com', 'https://api.mainnet-beta.solana.com'])\nexport const TON_CHAIN = 'ton:-239'\nexport const TON_ENDPOINTS: readonly string[] = Object.freeze(['https://ton.access.orbs.network/1/mainnet/toncenter-api-v2/jsonRPC', 'https://toncenter.com/api/v2/jsonRPC'])\nexport const TRON_CHAIN = 'tron:728126428'\nexport const TRON_PROVIDERS: readonly string[] = Object.freeze(['https://api.trongrid.io'])\nexport const BTC_CHAIN = 'bitcoin:mainnet'\nexport const BTC_ESPLORA: readonly string[] = Object.freeze(['https://mempool.space/api', 'https://blockstream.info/api'])\nexport const NEAR_CHAIN = 'near:mainnet'\nexport const NEAR_PROVIDERS: readonly string[] = Object.freeze(['https://free.rpc.fastnear.com', 'https://rpc.mainnet.near.org'])\n/** Zcash transparent (t1…) accounts over Blockchair's public API, as `@anywalletkit/wallet-zcash` reads and broadcasts them. */\nexport const ZCASH_CHAIN = 'zcash:mainnet'\nexport const ZCASH_BLOCKCHAIR = 'https://api.blockchair.com/zcash'\n\nexport interface ChainDescriptor {\n caip2: string\n key: 'solana' | 'ton' | 'tron' | 'btc' | 'near' | 'zcash'\n name: string\n symbol: string\n decimals: number\n explorerTx: string\n explorerAddress: string\n}\n\nexport const NON_EVM_CHAINS: readonly ChainDescriptor[] = Object.freeze([\n { caip2: SOLANA_CHAIN, key: 'solana', name: 'Solana', symbol: 'SOL', decimals: 9, explorerTx: 'https://solscan.io/tx/', explorerAddress: 'https://solscan.io/account/' },\n { caip2: TON_CHAIN, key: 'ton', name: 'TON', symbol: 'GRAM', decimals: 9, explorerTx: 'https://tonviewer.com/transaction/', explorerAddress: 'https://tonviewer.com/' },\n { caip2: TRON_CHAIN, key: 'tron', name: 'Tron', symbol: 'TRX', decimals: 6, explorerTx: 'https://tronscan.org/#/transaction/', explorerAddress: 'https://tronscan.org/#/address/' },\n { caip2: BTC_CHAIN, key: 'btc', name: 'Bitcoin', symbol: 'BTC', decimals: 8, explorerTx: 'https://mempool.space/tx/', explorerAddress: 'https://mempool.space/address/' },\n { caip2: NEAR_CHAIN, key: 'near', name: 'NEAR', symbol: 'NEAR', decimals: 24, explorerTx: 'https://nearblocks.io/txns/', explorerAddress: 'https://nearblocks.io/address/' },\n { caip2: ZCASH_CHAIN, key: 'zcash', name: 'Zcash', symbol: 'ZEC', decimals: 8, explorerTx: 'https://blockchair.com/zcash/transaction/', explorerAddress: 'https://blockchair.com/zcash/address/' },\n])\n\nexport const nonEvmChain = (caip2: string): ChainDescriptor | undefined => NON_EVM_CHAINS.find((c) => c.caip2 === caip2)\n","import type { StorageAreaLike } from './chrome.js'\n\n/** One JSON value under one key — the shape every small store here needs. */\nexport interface JsonStorage<T> {\n get(): Promise<T | null>\n set(value: T): Promise<void>\n}\n\nexport function chromeJsonStorage<T>(area: StorageAreaLike, key: string): JsonStorage<T> {\n return {\n async get() { return ((await area.get(key))[key] as T | undefined) ?? null },\n async set(value) { await area.set({ [key]: value }) },\n }\n}\n\nexport function memoryJsonStorage<T>(initial: T | null = null): JsonStorage<T> & { value: T | null } {\n const s = {\n value: initial,\n async get() { return s.value === null ? null : structuredClone(s.value) },\n async set(value: T) { s.value = structuredClone(value) },\n }\n return s\n}\n","/**\n * Per-origin permissions: which accounts a site may see and which chain it is\n * on. Nothing here is secret (`chrome.storage.local`, plain JSON); the origin\n * key is the one the browser recorded for the port, never the page's claim.\n */\nimport type { JsonStorage } from './storage.js'\n\nexport interface OriginPermission {\n origin: string\n /** EVM addresses exposed to this origin (checksummed as the keyring stores them). Empty when only another chain is connected. */\n accounts: string[]\n /** CAIP-2 chain the origin currently sees (`eth_chainId`). */\n chain: string\n /** Solana addresses exposed to this origin (Wallet Standard `standard:connect`). */\n solanaAccounts?: string[]\n /** TON addresses exposed to this origin (TON Connect). */\n tonAccounts?: string[]\n /** Tron (TIP-1193), Bitcoin (sats-connect) and NEAR (wallet-selector) addresses. */\n tronAccounts?: string[]\n btcAccounts?: string[]\n nearAccounts?: string[]\n connectedAt: number\n}\n\nexport type PermissionsState = Record<string, OriginPermission>\n\nexport type ChainAccountsKey = 'solanaAccounts' | 'tonAccounts' | 'tronAccounts' | 'btcAccounts' | 'nearAccounts'\nexport const CHAIN_ACCOUNT_KEYS: readonly ChainAccountsKey[] = ['solanaAccounts', 'tonAccounts', 'tronAccounts', 'btcAccounts', 'nearAccounts']\n\nexport class PermissionStore {\n private _state: PermissionsState | null = null\n private _loading: Promise<PermissionsState> | null = null\n /** Every mutation runs here, one after another (scan F22): a read-modify-write never starts from a snapshot another one is about to replace. */\n private _queue: Promise<unknown> = Promise.resolve()\n private readonly _listeners = new Set<(origin: string, permission: OriginPermission | null) => void>()\n\n constructor(private readonly storage: JsonStorage<PermissionsState>) {}\n\n private async state(): Promise<PermissionsState> {\n if (this._state) return this._state\n // One load; a load that resolves after a write must not replace the newer cache.\n this._loading ??= this.storage.get().then(\n (s) => (this._state ??= s ?? {}),\n (e: unknown) => { this._loading = null; throw e },\n )\n return this._loading\n }\n\n /**\n * Run `fn` after every earlier mutation settled. Public mutators wrap their WHOLE read-modify-write\n * in this; `write` itself is unlocked (setAccountsEverywhere calls it in a loop — a lock there too\n * would deadlock). Nothing awaited inside may wait on the user: routers await the approval sheet\n * first and only then call the store.\n */\n private serialize<T>(fn: () => Promise<T>): Promise<T> {\n const run = this._queue.then(fn, fn)\n this._queue = run.then(() => undefined, () => undefined)\n return run\n }\n\n async get(origin: string): Promise<OriginPermission | null> {\n return (await this.state())[origin] ?? null\n }\n\n async list(): Promise<OriginPermission[]> {\n return Object.values(await this.state())\n }\n\n connect(origin: string, accounts: string[], chain: string): Promise<OriginPermission> {\n return this.serialize(async () => {\n if (accounts.length === 0) throw new Error('Connect at least one account.')\n const current = await this.get(origin)\n const permission: OriginPermission = { ...(current ?? {}), origin, accounts: [...accounts], chain, connectedAt: current?.connectedAt ?? Date.now() }\n await this.write(origin, permission)\n return permission\n })\n }\n\n /** Connect another chain's accounts to the same origin (one \"connected sites\" list). */\n connectChain(origin: string, key: ChainAccountsKey, accounts: string[], defaultChain: string): Promise<OriginPermission> {\n return this.serialize(async () => {\n if (accounts.length === 0) throw new Error('Connect at least one account.')\n const current = await this.get(origin)\n const permission: OriginPermission = { origin, accounts: current?.accounts ?? [], chain: current?.chain ?? defaultChain, ...(current ?? {}), [key]: [...accounts], connectedAt: current?.connectedAt ?? Date.now() }\n await this.write(origin, permission)\n return permission\n })\n }\n\n /** Drop one chain's accounts; the origin stays connected while any chain remains. A no-op (no write) when there is nothing to drop. */\n disconnectChain(origin: string, key: 'accounts' | ChainAccountsKey): Promise<void> {\n return this.serialize(async () => {\n const current = await this.get(origin)\n if (!current) return\n if (key === 'accounts' ? current.accounts.length === 0 : current[key] === undefined) return\n const next: OriginPermission = { ...current, [key]: key === 'accounts' ? [] : undefined }\n if (key !== 'accounts') delete next[key]\n const anything = next.accounts.length > 0 || CHAIN_ACCOUNT_KEYS.some((k) => (next[k]?.length ?? 0) > 0)\n await this.write(origin, anything ? next : null)\n })\n }\n\n setChain(origin: string, chain: string): Promise<OriginPermission | null> {\n return this.serialize(async () => {\n const current = await this.get(origin)\n if (!current) return null\n const next = { ...current, chain }\n await this.write(origin, next)\n return next\n })\n }\n\n /**\n * The active EVM account changed: every origin holding an EVM grant now sees `accounts` (MetaMask behaviour).\n * An origin connected only on another chain (`accounts: []` — Solana/TON/Tron/BTC/NEAR providers, a WalletConnect\n * session without eip155) is skipped: it never passed an EVM connect and must not learn the EVM address (scan F6/F8).\n * Lock never writes `[]` here, so the skip cannot strip a real EVM grant.\n */\n setAccountsEverywhere(accounts: string[]): Promise<OriginPermission[]> {\n return this.serialize(async () => {\n const changed: OriginPermission[] = []\n for (const p of await this.list()) {\n if (p.accounts.length === 0 || sameList(p.accounts, accounts)) continue\n const next = { ...p, accounts: [...accounts] }\n await this.write(p.origin, next)\n changed.push(next)\n }\n return changed\n })\n }\n\n disconnect(origin: string): Promise<void> {\n return this.serialize(async () => {\n if (!(await this.get(origin))) return\n await this.write(origin, null)\n })\n }\n\n onChange(listener: (origin: string, permission: OriginPermission | null) => void): () => void {\n this._listeners.add(listener)\n return () => this._listeners.delete(listener)\n }\n\n /** Unlocked: callers hold the queue. The cache changes before the await (readers see it at once) and is rolled back when storage refuses. */\n private async write(origin: string, permission: OriginPermission | null): Promise<void> {\n const prev = await this.state()\n const state = { ...prev }\n if (permission) state[origin] = permission\n else delete state[origin]\n this._state = state\n try {\n await this.storage.set(state)\n } catch (e) {\n if (this._state === state) this._state = prev\n throw e\n }\n for (const l of this._listeners) l(origin, permission)\n }\n}\n\nconst sameList = (a: string[], b: string[]) => a.length === b.length && a.every((x, i) => x === b[i])\n","/**\n * The approval queue — Vaulty's `txGate` (mobile/lib/txGate.ts) for an\n * extension. A dApp request that needs the user waits here; ONE approval window\n * is open at a time (`chrome.windows.create({ type: 'popup' })`), the next\n * request opens when the current one is answered. The window losing focus\n * changes nothing: the request stays pending. Closing the window, or declining,\n * rejects with {@link ReviewDeclined} — EIP-1193 4001, \"nothing was signed\".\n *\n * The queue lives in the service worker's memory: an open approval window keeps\n * the worker alive, and if the worker is nevertheless restarted the pending\n * promises die with it — the page gets no answer and retries, which is the\n * failure mode MetaMask has too.\n *\n * Two limits keep a page from burying one real request under decoys (SDK-142 M3):\n * at most `maxPendingPerOrigin` requests wait per origin (-32005), and a second\n * `connect` while one is pending is refused outright (-32002).\n *\n * An origin can carry a transport note (`via`, set by the WalletConnect bridge):\n * the sheet then says the request came over WalletConnect, what the dApp claims\n * to be and what WalletConnect Verify says about that claim — the claim itself is\n * never used as the permission key.\n */\nimport { RELAY_ERRORS } from './relay.js'\n\nexport class ReviewDeclined extends Error {\n readonly code = RELAY_ERRORS.userRejected\n constructor(message = 'You declined — nothing was signed.') {\n super(message)\n this.name = 'ReviewDeclined'\n }\n}\n\nexport type ApprovalKind = 'connect' | 'switch-chain' | 'add-chain' | 'sign-message' | 'sign-typed-data' | 'send-transaction' | 'solana-send' | 'swap' | 'earn' | 'chain-send' | 'tron-sign' | 'btc-sign' | 'near-sign' | 'near-signin' | 'wc-session'\n\n/** How a request reached the wallet when it did not come through a content script. */\nexport interface OriginVia {\n transport: 'walletconnect'\n /** What the dApp declared about itself (self-reported, unverified unless `verify` says so). */\n url: string\n name: string\n /** WalletConnect Verify: VALID = the relay saw the request come from `url`'s origin; INVALID = it came from somewhere else; UNKNOWN = not attested. */\n verify: 'VALID' | 'INVALID' | 'UNKNOWN'\n scam?: boolean\n}\n\n/** The queue refused to enqueue (per-origin limits); carries an EIP-1474 code the page understands. */\nexport class QueueLimitError extends Error {\n constructor(readonly code: number, message: string) {\n super(message)\n this.name = 'QueueLimitError'\n }\n}\n\nexport const APPROVALS_MAX_PENDING_PER_ORIGIN = 3\n\nexport interface ApprovalRequest<P = unknown> {\n id: string\n origin: string\n chain: string\n kind: ApprovalKind\n /** What the window shows; shape per kind, public data only. */\n payload: P\n createdAt: number\n /** Phishing / lookalike / punycode notes about the origin, from the queue's `annotate` hook. */\n originWarnings?: string[]\n /** Set when the origin is a transport pseudo-origin (`wc:<topic>`): what the sheet should say about where this came from. */\n via?: OriginVia\n}\n\nexport interface ApprovalQueueOptions {\n /** Called for every request's origin; the lines are shown on the sheet (e.g. the shipped phishing list's verdict). */\n annotate?: (origin: string) => string[]\n /** Requests one origin may have waiting (current + queued). Default {@link APPROVALS_MAX_PENDING_PER_ORIGIN}. */\n maxPendingPerOrigin?: number\n}\n\n/** The window side: open for one request, close when it is answered. `memoryApprovalWindow()` for tests. */\nexport interface ApprovalWindow {\n open(request: ApprovalRequest): Promise<void>\n close(requestId: string): Promise<void>\n /** The user closed the window themself (chrome.windows.onRemoved): the queue declines the request. */\n onClosed(handler: (requestId: string) => void): void\n}\n\ninterface Pending<T = unknown> {\n request: ApprovalRequest\n resolve: (value: T) => void\n reject: (error: Error) => void\n}\n\nexport class ApprovalQueue {\n private _current: Pending | null = null\n private readonly _waiting: Pending[] = []\n private readonly _listeners = new Set<() => void>()\n private readonly _via = new Map<string, OriginVia>()\n\n constructor(private readonly window: ApprovalWindow, private readonly newId: () => string = () => crypto.randomUUID(), private readonly options: ApprovalQueueOptions = {}) {\n window.onClosed((id) => { if (this._current?.request.id === id) this.decline(id) })\n }\n\n /** Enqueue and wait for the user's answer. Refuses (never queues) past the per-origin limits. */\n request<T = unknown>(input: Omit<ApprovalRequest, 'id' | 'createdAt' | 'originWarnings' | 'via'>): Promise<T> {\n const sameOrigin = [...(this._current ? [this._current] : []), ...this._waiting].filter((p) => p.request.origin === input.origin)\n if (input.kind === 'connect' && sameOrigin.some((p) => p.request.kind === 'connect')) {\n return Promise.reject(new QueueLimitError(RELAY_ERRORS.resourceUnavailable, 'A connect request from this site is already waiting for your answer.'))\n }\n const max = this.options.maxPendingPerOrigin ?? APPROVALS_MAX_PENDING_PER_ORIGIN\n if (sameOrigin.length >= max) {\n return Promise.reject(new QueueLimitError(RELAY_ERRORS.limitExceeded, `This site already has ${max} requests waiting for you; answer or close them first.`))\n }\n return new Promise<T>((resolve, reject) => {\n const warnings = this.options.annotate?.(input.origin) ?? []\n const via = this._via.get(input.origin)\n const pending: Pending = { request: { ...input, id: this.newId(), createdAt: Date.now(), ...(warnings.length ? { originWarnings: warnings } : {}), ...(via ? { via } : {}) }, resolve: resolve as (v: unknown) => void, reject }\n this._waiting.push(pending)\n void this.next()\n })\n }\n\n /** Attach (or clear) the transport note every later request from `origin` carries. */\n setVia(origin: string, via: OriginVia | null): void {\n if (via) this._via.set(origin, via)\n else this._via.delete(origin)\n }\n\n /** The transport note later requests from `origin` carry (WalletConnect Verify's verdict for `wc:<topic>`), if any. */\n viaFor(origin: string): OriginVia | undefined {\n return this._via.get(origin)\n }\n\n /** Requests waiting for `origin` (current + queued). */\n pendingFor(origin: string): number {\n return [...(this._current ? [this._current] : []), ...this._waiting].filter((p) => p.request.origin === origin).length\n }\n\n /** The request currently shown (the window asks for it by id on load). */\n get current(): ApprovalRequest | null {\n return this._current?.request ?? null\n }\n\n get queued(): number {\n return this._waiting.length\n }\n\n resolve(requestId: string, value: unknown): boolean {\n return this.settle(requestId, (p) => p.resolve(value))\n }\n\n decline(requestId: string, error: Error = new ReviewDeclined()): boolean {\n return this.settle(requestId, (p) => p.reject(error))\n }\n\n /** Lock, disconnect, shutdown: everything pending is declined. */\n declineAll(error: Error = new ReviewDeclined('The wallet was locked.')): void {\n const all = [...(this._current ? [this._current] : []), ...this._waiting.splice(0)]\n for (const p of all) p.reject(error)\n if (this._current) void this.window.close(this._current.request.id)\n this._current = null\n this.emit()\n }\n\n onChange(listener: () => void): () => void {\n this._listeners.add(listener)\n return () => this._listeners.delete(listener)\n }\n\n private settle(requestId: string, fn: (p: Pending) => void): boolean {\n if (this._current?.request.id === requestId) {\n const p = this._current\n this._current = null\n fn(p)\n void this.window.close(requestId).catch(() => undefined)\n this.emit()\n void this.next()\n return true\n }\n const i = this._waiting.findIndex((p) => p.request.id === requestId)\n if (i < 0) return false\n fn(this._waiting.splice(i, 1)[0]!)\n this.emit()\n return true\n }\n\n private async next(): Promise<void> {\n if (this._current || this._waiting.length === 0) return\n const p = this._waiting.shift()!\n this._current = p\n this.emit()\n try {\n await this.window.open(p.request)\n } catch (e) {\n if (this._current === p) {\n this._current = null\n p.reject(e instanceof Error ? e : new Error(String(e)))\n this.emit()\n void this.next()\n }\n }\n }\n\n private emit(): void {\n for (const l of this._listeners) l()\n }\n}\n\n/** In-memory window: tests answer through the queue; `opened` records every request shown. */\nexport function memoryApprovalWindow(): ApprovalWindow & { opened: ApprovalRequest[]; openIds: Set<string>; userClose(id: string): void } {\n let handler: (id: string) => void = () => undefined\n const w = {\n opened: [] as ApprovalRequest[],\n openIds: new Set<string>(),\n async open(request: ApprovalRequest) { w.opened.push(request); w.openIds.add(request.id) },\n async close(id: string) { w.openIds.delete(id) },\n onClosed(h: (id: string) => void) { handler = h },\n userClose(id: string) { w.openIds.delete(id); handler(id) },\n }\n return w\n}\n","/**\n * The request router: what a dApp may ask and what happens to each request.\n * Policy ported from Vaulty's in-app browser (`mobile/lib/browser.ts`):\n *\n * - the origin is the browser's (checked by the service worker before this runs);\n * - accounts are exposed only to origins the user connected (`eth_requestAccounts`\n * → approval window); `eth_accounts` is `[]` otherwise;\n * - chain switching and adding go through the approval window; a chain can be\n * added only if the asset catalog knows it, with https RPCs;\n * - read-only JSON-RPC is answered from the wallet's own clients (the networks\n * table's failover list), never from a URL the page names;\n * - `eth_sign` (blind hash signing) is never offered; the other signing methods\n * go to the `sign` hook (the review flow) when the wallet provides one;\n * - everything else is refused with 4200.\n *\n * Errors leave as {@link RouterError} (EIP-1193 codes) or {@link ReviewDeclined}\n * (4001); the service worker turns both into a `RelayResponse.error`.\n */\nimport { ApprovalQueue, ReviewDeclined } from './approvals.js'\nimport { DEFAULT_CHAIN, NetworksTable, caip2FromChainId, chainHex, parseAddChainParams, type EvmNetwork } from './networks.js'\nimport { PermissionStore, type OriginPermission } from './permissions.js'\nimport { RELAY_ERRORS, type RelayChain, type RelayError } from './relay.js'\n\nexport class RouterError extends Error {\n readonly code: number\n readonly data: unknown\n constructor(code: number, message: string, data?: unknown) {\n super(message)\n this.name = 'RouterError'\n this.code = code\n this.data = data\n }\n static from(e: RelayError): RouterError {\n return new RouterError(e.code, e.message, e.data)\n }\n}\n\n/** Any error → the `RelayError` for the page. Unknown errors keep their message but never their stack. */\nexport function toRelayError(e: unknown): RelayError {\n if (e instanceof RouterError) return e.data === undefined ? { code: e.code, message: e.message } : { code: e.code, message: e.message, data: e.data }\n if (e instanceof ReviewDeclined) return { code: e.code, message: e.message }\n const code = typeof (e as { code?: unknown })?.code === 'number' ? (e as { code: number }).code : RELAY_ERRORS.internal\n return { code, message: e instanceof Error ? e.message : String(e) }\n}\n\n/** Read-only methods answered from our RPC without asking the user. */\nexport const READ_METHODS: ReadonlySet<string> = new Set([\n 'eth_blockNumber', 'eth_call', 'eth_estimateGas', 'eth_feeHistory', 'eth_gasPrice', 'eth_getBalance',\n 'eth_getBlockByHash', 'eth_getBlockByNumber', 'eth_getCode', 'eth_getLogs', 'eth_getStorageAt',\n 'eth_getTransactionByHash', 'eth_getTransactionCount', 'eth_getTransactionReceipt', 'eth_maxPriorityFeePerGas',\n])\n\n/** Methods that produce a signature — the review flow's business (step 4), never answered here. */\nexport const SIGNING_METHODS: ReadonlySet<string> = new Set(['personal_sign', 'eth_signTypedData_v4', 'eth_signTypedData_v3', 'eth_signTypedData', 'eth_sendTransaction'])\n\nexport interface ConnectApproval {\n /** Addresses the wallet can expose, active account first (empty while locked — the window unlocks first and reloads). */\n accounts: string[]\n}\nexport interface SwitchChainApproval {\n from: EvmNetwork | null\n to: EvmNetwork\n}\nexport interface AddChainApproval {\n network: EvmNetwork\n}\n\nexport interface RouterDeps {\n permissions: PermissionStore\n networks: NetworksTable\n approvals: ApprovalQueue\n /** EVM addresses the wallet exposes, active account first. Empty when locked or without a wallet. */\n accounts(): Promise<string[]>\n /** Read-only JSON-RPC over the network's own RPC list. */\n rpc(network: EvmNetwork, method: string, params: unknown[]): Promise<unknown>\n /** Push an EIP-1193 event to every page of `origin`. */\n emit(origin: string, event: string, data: unknown): void\n /** The review flow for signing methods. Absent → 4200. */\n sign?(input: { origin: string; network: EvmNetwork; method: string; params: unknown[]; accounts: string[] }): Promise<unknown>\n defaultChain?: string\n}\n\nexport class RequestRouter {\n constructor(private readonly deps: RouterDeps) {}\n\n /** The chain an origin currently sees (its permission's, else the default). */\n async chainFor(origin: string): Promise<EvmNetwork> {\n const permission = await this.deps.permissions.get(origin)\n const wanted = permission?.chain ?? this.deps.defaultChain ?? DEFAULT_CHAIN\n return (await this.deps.networks.get(wanted)) ?? (await this.deps.networks.get(DEFAULT_CHAIN))!\n }\n\n async handle(origin: string, chain: RelayChain, method: string, rawParams: unknown): Promise<unknown> {\n if (chain !== 'eip155') throw new RouterError(RELAY_ERRORS.unsupportedMethod, `${chain} providers are not available yet.`)\n const params = Array.isArray(rawParams) ? rawParams : rawParams === undefined ? [] : [rawParams]\n const network = await this.chainFor(origin)\n const permission = await this.deps.permissions.get(origin)\n\n switch (method) {\n case 'eth_chainId':\n return chainHex(network.caip2)\n case 'net_version':\n return String(network.chainId)\n case 'eth_accounts':\n return this.visibleAccounts(permission)\n case 'eth_requestAccounts':\n return this.connect(origin, network)\n case 'wallet_getPermissions':\n // An origin connected only on another chain holds no EVM permission (scan F6/F8).\n return permission && permission.accounts.length > 0 ? [permissionDescriptor(origin, permission.accounts)] : []\n case 'wallet_requestPermissions': {\n const accounts = await this.connect(origin, network)\n return [permissionDescriptor(origin, accounts)]\n }\n case 'wallet_revokePermissions':\n await this.disconnect(origin)\n return null\n case 'wallet_switchEthereumChain': {\n const target = caip2FromChainId((params[0] as { chainId?: unknown } | undefined)?.chainId)\n if (!target) throw new RouterError(RELAY_ERRORS.invalidParams, 'wallet_switchEthereumChain expects [{ chainId }].')\n const to = await this.deps.networks.get(target)\n if (!to) throw new RouterError(RELAY_ERRORS.chainNotAdded, `Chain ${chainHex(target)} is not in this wallet; add it with wallet_addEthereumChain.`)\n await this.switchChain(origin, network, to)\n return null\n }\n case 'wallet_addEthereumChain': {\n const parsed = parseAddChainParams(params)\n if ('code' in parsed) throw RouterError.from(parsed)\n const existing = await this.deps.networks.get(parsed.caip2)\n if (existing) { await this.switchChain(origin, network, existing); return null }\n await this.deps.approvals.request({ origin, chain: network.caip2, kind: 'add-chain', payload: { network: parsed } satisfies AddChainApproval })\n // EIP-3085: the endpoint must answer for the chain it is being added as (a look-alike RPC for a real chain id is the phishing shape).\n let answered: unknown\n try { answered = await this.deps.rpc(parsed, 'eth_chainId', []) } catch (e) { throw new RouterError(RELAY_ERRORS.invalidParams, `The RPC for ${parsed.name} did not answer eth_chainId (${e instanceof Error ? e.message : String(e)}); the network was not added.`) }\n const got = caip2FromChainId(answered)\n if (got !== parsed.caip2) throw new RouterError(RELAY_ERRORS.invalidParams, `The RPC for ${parsed.name} answers chain ${String(answered)}, not ${chainHex(parsed.caip2)}; the network was not added.`)\n await this.deps.networks.add({ ...parsed, custom: { origin, addedAt: Date.now() } })\n if (permission) await this.switchChain(origin, network, parsed, true)\n return null\n }\n case 'eth_sign':\n case 'eth_signTransaction':\n throw new RouterError(RELAY_ERRORS.unsupportedMethod, `${method} (blind signing) is never offered by this wallet.`)\n }\n\n if (READ_METHODS.has(method)) return this.deps.rpc(network, method, params)\n\n if (SIGNING_METHODS.has(method)) {\n if (!this.deps.sign) throw new RouterError(RELAY_ERRORS.unsupportedMethod, `${method} is not available yet.`)\n if (!permission) throw new RouterError(RELAY_ERRORS.unauthorized, 'Connect the wallet first (eth_requestAccounts).')\n return this.deps.sign({ origin, network, method, params, accounts: permission.accounts })\n }\n\n throw new RouterError(RELAY_ERRORS.unsupportedMethod, `This wallet does not support ${method}.`)\n }\n\n /** What a connected origin sees right now: its permitted accounts that the wallet can expose (none while locked). */\n private async visibleAccounts(permission: OriginPermission | null): Promise<string[]> {\n if (!permission) return []\n const available = await this.deps.accounts()\n return permission.accounts.filter((a) => available.includes(a))\n }\n\n /**\n * Connected and unlocked → the accounts; otherwise the approval window (which\n * unlocks first when needed) picks them. Emits `connect` + `accountsChanged`.\n */\n private async connect(origin: string, network: EvmNetwork): Promise<string[]> {\n const existing = await this.visibleAccounts(await this.deps.permissions.get(origin))\n if (existing.length) return existing\n const chosen = await this.deps.approvals.request<unknown>({ origin, chain: network.caip2, kind: 'connect', payload: { accounts: await this.deps.accounts() } satisfies ConnectApproval })\n const available = await this.deps.accounts()\n const accounts = Array.isArray(chosen) ? chosen.filter((a): a is string => typeof a === 'string' && available.includes(a)) : []\n if (accounts.length === 0) throw new ReviewDeclined('No account was selected.')\n await this.deps.permissions.connect(origin, accounts, network.caip2)\n this.deps.emit(origin, 'connect', { chainId: chainHex(network.caip2) })\n this.deps.emit(origin, 'accountsChanged', accounts)\n return accounts\n }\n\n async disconnect(origin: string): Promise<void> {\n if (!(await this.deps.permissions.get(origin))) return\n await this.deps.permissions.disconnect(origin)\n this.deps.emit(origin, 'accountsChanged', [])\n this.deps.emit(origin, 'disconnect', { code: RELAY_ERRORS.disconnected, message: 'The wallet disconnected this site.' })\n }\n\n private async switchChain(origin: string, from: EvmNetwork, to: EvmNetwork, approved = false): Promise<void> {\n if (from.caip2 === to.caip2) return\n const permission = await this.deps.permissions.get(origin)\n if (!permission) throw new RouterError(RELAY_ERRORS.unauthorized, 'Connect the wallet first (eth_requestAccounts).')\n if (!approved) await this.deps.approvals.request({ origin, chain: from.caip2, kind: 'switch-chain', payload: { from, to } satisfies SwitchChainApproval })\n await this.deps.permissions.setChain(origin, to.caip2)\n this.deps.emit(origin, 'chainChanged', chainHex(to.caip2))\n }\n}\n\nconst permissionDescriptor = (origin: string, accounts: string[]) => ({\n id: crypto.randomUUID(),\n parentCapability: 'eth_accounts',\n invoker: origin,\n caveats: [{ type: 'restrictReturnedAccounts', value: [...accounts] }],\n date: Date.now(),\n})\n","/**\n * Sign-In with Ethereum (EIP-4361) messages, parsed so the sheet can say what a\n * `personal_sign` really is and check the fields a phishing site would lie\n * about: the domain (scheme + host) must be the site asking, the address must\n * be the signing account, the chain must be the site's, the message must not be\n * expired or not-yet-valid, and the nonce must look like one (replay).\n *\n * Everything here is a WARNING: the sheet turns problems into warn checks and\n * the user can still sign. Whenever the first line is an EIP-4361 header the\n * text is treated as a sign-in (scan F9) — a message whose remaining fields do\n * not parse is reported as malformed instead of silently becoming a plain\n * message without the cross-site check.\n */\nimport type { OriginVia } from './approvals.js'\n\nexport interface SiweMessage {\n /** As written in the header: `host[:port]`, optionally prefixed by `scheme://`. */\n domain: string\n address: string\n statement?: string\n uri: string\n version: string\n chainId: number\n nonce: string\n issuedAt: string\n expirationTime?: string\n notBefore?: string\n requestId?: string\n resources: string[]\n}\n\nexport interface SiweInfo {\n message: SiweMessage\n /** Human lines, each a reason the sheet should warn; empty = the sign-in is consistent with the request. */\n problems: string[]\n /** The header said \"sign-in\" but the rest did not parse as EIP-4361 (`message` then holds what could be read). */\n malformed?: boolean\n}\n\nexport interface SiweContext {\n /** The page that asked, as the browser recorded it (`https://…`), or a transport pseudo-origin (`wc:<topic>`). */\n origin: string\n /** The signing address. */\n account: string\n /** The site's chain. */\n chainId: number\n now?: number\n /** Transport note for pseudo-origins (WalletConnect): the dApp's claimed URL and what Verify said about it. */\n via?: OriginVia\n}\n\n/** First line of an EIP-4361 message; the \"Ethereum account\" literal is what makes it one. */\nconst HEADER_LINE = /^(?<domain>[^\\n]+?) wants you to sign in with your Ethereum account:(?:\\n|$)/\nconst ADDRESS_LINE = /^0x[0-9a-fA-F]{40}$/\nconst FIELD = /^([A-Za-z ]+): (.*)$/\n\ninterface Parsed { message: SiweMessage; missing: string[] }\n\n/** Tolerant parse: `null` only when the first line is not an EIP-4361 header. */\nfunction parseLoose(text: string): Parsed | null {\n const head = HEADER_LINE.exec(text)\n if (!head?.groups) return null\n const lines = text.slice(head[0].length).split('\\n')\n const missing: string[] = []\n const addressLine = lines.shift() ?? ''\n const address = ADDRESS_LINE.test(addressLine) ? addressLine : ''\n if (!address) missing.push('address')\n // Between the address and the `URI:` line: blank lines and at most one statement line.\n // Covers `addr\\n\\nstatement\\n\\nURI`, `addr\\n\\n\\nURI` (no statement, the ABNF form) and `addr\\n\\nURI` (older libraries).\n const uriAt = lines.findIndex((l) => l.startsWith('URI: '))\n const between = (uriAt < 0 ? lines : lines.slice(0, uriAt)).filter((l) => l !== '')\n let statement: string | undefined\n if (uriAt >= 0) {\n if (between.length === 1 && !FIELD.test(between[0]!)) statement = between[0]\n else if (between.length > 0) missing.push('statement layout')\n }\n const fields: Record<string, string> = {}\n const resources: string[] = []\n for (const line of uriAt < 0 ? [] : lines.slice(uriAt)) {\n if (line.startsWith('- ')) { resources.push(line.slice(2)); continue }\n const m = FIELD.exec(line)\n if (m && !(m[1]! in fields)) fields[m[1]!] = m[2]!\n }\n const chainId = Number(fields['Chain ID'])\n if (!fields.URI) missing.push('URI')\n if (!fields.Version) missing.push('Version')\n if (fields['Chain ID'] === undefined || !Number.isInteger(chainId)) missing.push('Chain ID')\n if (!fields.Nonce) missing.push('Nonce')\n if (!fields['Issued At']) missing.push('Issued At')\n const message: SiweMessage = { domain: head.groups.domain!, address, uri: fields.URI ?? '', version: fields.Version ?? '', chainId: Number.isInteger(chainId) ? chainId : NaN, nonce: fields.Nonce ?? '', issuedAt: fields['Issued At'] ?? '', resources }\n if (statement) message.statement = statement\n if (fields['Expiration Time']) message.expirationTime = fields['Expiration Time']\n if (fields['Not Before']) message.notBefore = fields['Not Before']\n if (fields['Request ID']) message.requestId = fields['Request ID']\n return { message, missing }\n}\n\n/** `null` when the text is not a well-formed EIP-4361 message (see {@link describeSiwe} for the tolerant form the sheet uses). */\nexport function parseSiwe(text: string): SiweMessage | null {\n const p = parseLoose(text)\n return p && p.missing.length === 0 ? p.message : null\n}\n\ninterface Where { scheme: string; host: string }\n\n/** `scheme://host[:port]` or bare `host[:port]` (scheme defaults to https, as EIP-4361 says). */\nfunction whereOf(s: string): Where | null {\n try {\n if (!s.includes('://')) {\n // A URL parser, never fetched — and written as the one dynamic `https://` prefix the extension's host gate knows.\n const host = new URL(`https://${s}`).host.toLowerCase()\n return host ? { scheme: 'https', host } : null\n }\n const u = new URL(s)\n return u.host ? { scheme: u.protocol.replace(/:$/, '').toLowerCase(), host: u.host.toLowerCase() } : null\n } catch { return null }\n}\n\n/** A browser origin with a host the wallet can vouch for: http(s) only — `wc:<topic>` and other pseudo-origins have none. */\nfunction originWhere(origin: string): Where | null {\n try {\n const u = new URL(origin)\n return (u.protocol === 'https:' || u.protocol === 'http:') && u.host ? { scheme: u.protocol.slice(0, -1), host: u.host.toLowerCase() } : null\n } catch { return null }\n}\n\n/** Loopback / `*.localhost` (dev servers): plain http is normal there, so no scheme warnings. Takes `host[:port]`. */\nexport function isLocalHost(host: string): boolean {\n const h = host.toLowerCase().replace(/:\\d+$/, '')\n return h === 'localhost' || h === '127.0.0.1' || h === '[::1]' || h.endsWith('.localhost')\n}\n\n/** The checks; `origin` is the page that asked (as the browser recorded it), `account` the signing address, `chainId` the site's chain. */\nexport function siweProblems(m: SiweMessage, ctx: SiweContext): string[] {\n const out: string[] = []\n const domain = whereOf(m.domain)\n let site = originWhere(ctx.origin)\n if (!site) {\n // No browser-recorded host (WalletConnect `wc:<topic>`): only a Verify-attested claim naming the same host counts (scan F10).\n const claimed = ctx.via?.verify === 'VALID' && !ctx.via.scam ? whereOf(ctx.via.url) : null\n if (claimed && domain && claimed.host === domain.host) site = claimed\n else out.push(`The wallet cannot verify which site is asking; this sign-in for ${m.domain} may be replayed there.`)\n }\n if (site) {\n // Scheme as well as host (scan F20/F21): an http:// twin of the site must not collect sign-ins valid for the https one.\n const local = isLocalHost(site.host)\n if (site.scheme === 'http' && !local) out.push(`This sign-in is requested by an insecure page (${site.scheme}://${site.host}); anyone on the network can read or change it and replay the signature on the https site.`)\n if (!domain || domain.host !== site.host) out.push(`The sign-in names ${m.domain} but the request comes from ${site.host} — a sign-in meant for another site would be replayable there.`)\n else if (!local && domain.scheme !== site.scheme) out.push(`The sign-in is for ${domain.scheme}://${domain.host} but the request comes from ${site.scheme}://${site.host}.`)\n const uri = m.uri ? whereOf(m.uri) : null\n if (uri && uri.host !== site.host) out.push(`The URI ${m.uri} is not on ${site.host}.`)\n else if (uri && !local && (uri.scheme === 'http' || uri.scheme === 'https') && uri.scheme !== site.scheme) out.push(`The URI ${m.uri} uses ${uri.scheme}:// but the request comes from ${site.scheme}://${site.host}.`)\n }\n if (m.address && m.address.toLowerCase() !== ctx.account.toLowerCase()) out.push(`The sign-in is for ${m.address}, not the account that would sign (${ctx.account}).`)\n if (Number.isInteger(m.chainId) && m.chainId !== ctx.chainId) out.push(`The sign-in is for chain ${m.chainId}; this site is on chain ${ctx.chainId}.`)\n if (m.version && m.version !== '1') out.push(`Unknown SIWE version ${m.version}.`)\n if (m.nonce && (m.nonce.length < 8 || !/^[A-Za-z0-9]+$/.test(m.nonce))) out.push('The nonce is too short to protect against replay.')\n const now = ctx.now ?? Date.now()\n const exp = m.expirationTime ? Date.parse(m.expirationTime) : NaN\n if (m.expirationTime && (Number.isNaN(exp) || exp <= now)) out.push('The sign-in has already expired.')\n const nbf = m.notBefore ? Date.parse(m.notBefore) : NaN\n if (m.notBefore && (Number.isNaN(nbf) || nbf > now)) out.push('The sign-in is not valid yet (Not Before is in the future).')\n if (m.issuedAt) {\n const iat = Date.parse(m.issuedAt)\n if (Number.isNaN(iat)) out.push('Issued At is not a date.')\n else if (iat > now + 5 * 60_000) out.push('Issued At is in the future.')\n }\n return out\n}\n\n/** `null` only when the text does not start with an EIP-4361 header; a header with unreadable fields comes back with a \"malformed sign-in message\" problem. */\nexport function describeSiwe(text: string, ctx: SiweContext): SiweInfo | null {\n const p = parseLoose(text)\n if (!p) return null\n const problems = siweProblems(p.message, ctx)\n if (p.missing.length === 0) return { message: p.message, problems }\n return { message: p.message, problems: [`This is a malformed sign-in message (EIP-4361): ${p.missing.join(', ')} missing or unreadable — check the site before signing.`, ...problems], malformed: true }\n}\n","/**\n * Signing requests from dApps (and from the wallet's own Send): classification,\n * transaction preparation, the review stop, the signature.\n *\n * Classification is Vaulty's `signingRequest` (mobile/lib/browser.ts): the\n * address a page names must be one the user connected; typed data bound to\n * another chain than the one the site is on is refused (4901); a transaction\n * must have a `to` (no deployments) and a `chainId`, when given, equal to the\n * site's chain; `eth_sign` never reaches here (the router refuses it).\n *\n * Preparation fills nonce, gas and fees from the wallet's own RPC (never the\n * page's): EIP-1559 cap = 2 × base fee + tip with the tip floored at 0.1 gwei\n * (Vaulty's `evmFees`), legacy `gasPrice` where a chain has no base fee, gas =\n * the page's limit or `eth_estimateGas` × 1.2.\n *\n * The review payload ({@link SignApproval}) carries what the window shows: the\n * classified request, the prepared fields, the fee, and the preview the wallet\n * attached (tx-preview-evm: decode, simulation, balance changes, checks). Only\n * after the user approves does {@link SignDeps.signerFor} open the key; the\n * handle is disposed (zeroized) in `finally`, the raw transaction goes out via\n * `eth_sendRawTransaction` on the wallet's RPC.\n */\nimport { ApprovalQueue, type OriginVia } from './approvals.js'\nimport type { EvmNetwork } from './networks.js'\nimport { RELAY_ERRORS, type RelayError } from './relay.js'\nimport { RouterError, type RouterDeps } from './router.js'\nimport { describeSiwe, type SiweInfo } from './siwe.js'\n\nexport type SignRequestInfo =\n | { kind: 'sign-message'; method: 'personal_sign'; account: string; /** Decoded text when printable, else the hex. */ text: string; /** What is actually signed (hex or utf-8 string). */ raw: string; /** Parsed Sign-In with Ethereum (EIP-4361) with the checks against the asking origin, when the text is one. */ siwe?: SiweInfo }\n | { kind: 'sign-typed-data'; method: string; account: string; /** Pretty-printed JSON. */ text: string; typedData: TypedData }\n | { kind: 'send-transaction'; method: 'eth_sendTransaction'; account: string; tx: { to: string; value: string; data: string | null; gas: string | null } }\n\nexport interface TypedData {\n domain: Record<string, unknown>\n types: Record<string, Array<{ name: string; type: string }>>\n message: Record<string, unknown>\n primaryType?: string\n}\n\nexport interface PreparedTx {\n chainId: number\n nonce: number\n gasLimit: string\n /** EIP-1559 fields, or `gasPrice` on legacy-fee chains. All 0x hex. */\n maxFeePerGas?: string\n maxPriorityFeePerGas?: string\n gasPrice?: string\n /** gasLimit × max fee, base units. */\n maxFee: string\n}\n\n/** The approval window's payload for the three signing kinds. */\nexport interface SignApproval {\n request: SignRequestInfo\n network: EvmNetwork\n prepared?: PreparedTx\n /** What the wallet attached (tx-preview-evm `TxPreview`, typed-data description…). */\n preview: unknown\n}\n\nexport interface EvmSigner {\n signMessage(message: string | Uint8Array): Promise<string>\n signTypedData(typed: TypedData): Promise<string>\n /** Fully specified tx (chainId, nonce, gas, fees) → signed raw transaction. */\n signTransaction(tx: { chainId: number; nonce: number; to: string; value: bigint; data: string; gasLimit: bigint; maxFeePerGas?: bigint; maxPriorityFeePerGas?: bigint; gasPrice?: bigint }): Promise<string>\n}\n\nexport interface SignDeps {\n approvals: ApprovalQueue\n rpc(network: EvmNetwork, method: string, params: unknown[]): Promise<unknown>\n /** Opens the key for `address`; `dispose()` zeroizes it. */\n signerFor(address: string, network: EvmNetwork): Promise<{ signer: EvmSigner; dispose(): void }>\n /** Review data for the window (errors inside are the wallet's to swallow → `null`). */\n preview?(input: { network: EvmNetwork; request: SignRequestInfo; accounts: string[] }): Promise<unknown>\n /** Tip floor per chain id in wei (default 0.1 gwei everywhere). */\n tipFloor?: (chainId: number) => bigint\n}\n\nconst ADDRESS = /^0x[0-9a-fA-F]{40}$/\nconst HEX = /^0x([0-9a-fA-F]{2})*$/\nconst lc = (s: string) => s.toLowerCase()\n\n/** Vaulty's `messageText`: hex that decodes to printable text is shown decoded; binary payloads stay hex. */\nexport function messageText(value: unknown): string {\n if (typeof value !== 'string') return ''\n if (!HEX.test(value)) return value\n try {\n const bytes = Uint8Array.from(value.slice(2).match(/../g) ?? [], (b) => Number.parseInt(b, 16))\n const s = new TextDecoder('utf-8', { fatal: true }).decode(bytes)\n return /^[\\x09\\x0a\\x0d\\x20-\\x7e -]*$/.test(s) ? s : value\n } catch {\n return value\n }\n}\n\n/**\n * The message as the signer will sign it: hex decoded when it is valid UTF-8, whatever\n * its printability (scan 2026-10-23 F7 — the SIWE checks must read the bytes that get\n * signed, not the hex fallback `messageText` shows for unprintable text).\n */\nexport function decodedMessage(value: unknown): string | null {\n if (typeof value !== 'string') return null\n if (!HEX.test(value)) return value\n try {\n return new TextDecoder('utf-8', { fatal: true }).decode(Uint8Array.from(value.slice(2).match(/../g) ?? [], (b) => Number.parseInt(b, 16)))\n } catch {\n return null\n }\n}\n\n/** Control characters other than tab / newline / carriage return — never part of an honest EIP-4361 message. */\nconst HIDDEN_CONTROL = /[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f-\\x9f]/\n\nconst err = (code: number, message: string): RelayError => ({ code, message })\n\n/** Signing method + params → what the window reviews, or the error to answer with. */\nexport function classifySignRequest(input: { network: EvmNetwork; method: string; params: unknown[]; accounts: string[]; /** The asking page (browser-recorded) — needed for the SIWE domain check. */ origin?: string; /** Transport note for pseudo-origins (WalletConnect Verify), for the SIWE check. */ via?: OriginVia; now?: number }): SignRequestInfo | RelayError {\n const { method, params } = input\n const owned = new Set(input.accounts.map(lc))\n const ours = (a: unknown): a is string => typeof a === 'string' && ADDRESS.test(a) && owned.has(lc(a))\n const checksum = (a: string) => input.accounts.find((x) => lc(x) === lc(a)) ?? a\n\n if (method === 'personal_sign') {\n // [message, address] per spec; some dApps send [address, message].\n let [msg, addr] = params\n if (ours(msg) && !ours(addr)) [msg, addr] = [addr, msg]\n if (!ours(addr)) return err(RELAY_ERRORS.unauthorized, 'personal_sign for an address this wallet does not hold.')\n if (typeof msg !== 'string') return err(RELAY_ERRORS.invalidParams, 'personal_sign expects a message string.')\n const text = messageText(msg)\n const signed = decodedMessage(msg) ?? text\n const siwe = input.origin ? describeSiwe(signed, { origin: input.origin, account: checksum(addr), chainId: input.network.chainId, ...(input.via ? { via: input.via } : {}), ...(input.now !== undefined ? { now: input.now } : {}) }) : null\n // A sign-in message with hidden control characters would show as an opaque hex blob while\n // a lenient verifier still accepts it: refuse it outright.\n if (siwe && HIDDEN_CONTROL.test(signed)) return err(RELAY_ERRORS.invalidParams, 'This sign-in message contains hidden control characters — refused.')\n return { kind: 'sign-message', method, account: checksum(addr), text, raw: msg, ...(siwe ? { siwe } : {}) }\n }\n\n if (method === 'eth_signTypedData_v4' || method === 'eth_signTypedData_v3' || method === 'eth_signTypedData') {\n const [addr, data] = params\n if (!ours(addr)) return err(RELAY_ERRORS.unauthorized, 'signTypedData for an address this wallet does not hold.')\n let parsed: TypedData\n try {\n parsed = (typeof data === 'string' ? JSON.parse(data) : data) as TypedData\n } catch {\n return err(RELAY_ERRORS.invalidParams, 'Typed data is not valid JSON.')\n }\n if (!parsed || typeof parsed !== 'object' || typeof parsed.domain !== 'object' || typeof parsed.types !== 'object' || typeof parsed.message !== 'object') {\n return err(RELAY_ERRORS.invalidParams, 'Typed data needs domain, types and message.')\n }\n const cid = parsed.domain.chainId\n if (cid !== undefined && cid !== null && Number(cid) !== input.network.chainId) {\n // A domain bound to another chain than the one the site is on is the classic cross-chain replay / phishing shape.\n return err(RELAY_ERRORS.chainDisconnected, `Typed data is for chain ${String(cid)}; this site is on ${input.network.name} (${input.network.chainId}).`)\n }\n return { kind: 'sign-typed-data', method, account: checksum(addr), text: JSON.stringify(parsed, bigintSafe, 2), typedData: parsed }\n }\n\n if (method === 'eth_sendTransaction') {\n const tx = (params[0] ?? {}) as { from?: unknown; to?: unknown; value?: unknown; data?: unknown; gas?: unknown; gasLimit?: unknown; chainId?: unknown; type?: unknown; authorizationList?: unknown }\n if (!ours(tx.from)) return err(RELAY_ERRORS.unauthorized, 'Transaction from an address this wallet does not hold.')\n // EIP-7702: a delegation hands the whole account to a contract; >80 % of early delegations went to sweepers. Sites never get one from this wallet.\n if ((Array.isArray(tx.authorizationList) && tx.authorizationList.length > 0) || tx.type === '0x4' || tx.type === 4) return err(RELAY_ERRORS.unsupportedMethod, 'EIP-7702 delegations (authorizationList / type 4) are never signed for a site by this wallet.')\n if (typeof tx.to !== 'string' || !ADDRESS.test(tx.to)) return err(RELAY_ERRORS.invalidParams, 'Contract deployment is not supported (a transaction needs a valid `to`).')\n if (tx.chainId !== undefined && tx.chainId !== null && Number(tx.chainId) !== input.network.chainId) return err(RELAY_ERRORS.chainDisconnected, 'Transaction chainId differs from the selected chain.')\n let value: string\n try {\n value = BigInt((tx.value as string | number | bigint | undefined) ?? 0).toString()\n } catch {\n return err(RELAY_ERRORS.invalidParams, 'Bad transaction value.')\n }\n const data = typeof tx.data === 'string' && tx.data !== '0x' ? tx.data : null\n if (data !== null && !HEX.test(data)) return err(RELAY_ERRORS.invalidParams, 'Transaction data is not hex.')\n const gasRaw = tx.gas ?? tx.gasLimit\n const gas = typeof gasRaw === 'string' && /^0x[0-9a-fA-F]+$/.test(gasRaw) ? gasRaw : null\n return { kind: 'send-transaction', method, account: checksum(tx.from), tx: { to: tx.to, value, data, gas } }\n }\n\n return err(RELAY_ERRORS.unsupportedMethod, `This wallet does not support ${method}.`)\n}\n\nconst bigintSafe = (_k: string, v: unknown) => (typeof v === 'bigint' ? v.toString() : v)\nconst hex = (n: bigint) => `0x${n.toString(16)}`\nconst big = (v: unknown): bigint => BigInt(v as string)\nconst MIN_TIP_WEI = 100_000_000n // 0.1 gwei\n\n/** Nonce, gas, fees from the wallet's RPC. */\nexport async function prepareTransaction(deps: Pick<SignDeps, 'rpc' | 'tipFloor'>, network: EvmNetwork, from: string, tx: { to: string; value: string; data: string | null; gas: string | null }): Promise<PreparedTx> {\n const call = { from, to: tx.to, value: hex(BigInt(tx.value)), ...(tx.data ? { data: tx.data } : {}) }\n const [nonceHex, block, gasHex] = await Promise.all([\n deps.rpc(network, 'eth_getTransactionCount', [from, 'pending']),\n deps.rpc(network, 'eth_getBlockByNumber', ['latest', false]) as Promise<{ baseFeePerGas?: string | null } | null>,\n tx.gas ? Promise.resolve(tx.gas) : deps.rpc(network, 'eth_estimateGas', [call]),\n ])\n const estimated = big(gasHex)\n const gasLimit = tx.gas ? estimated : (estimated * 120n + 99n) / 100n\n const base = block?.baseFeePerGas != null ? big(block.baseFeePerGas) : null\n if (base === null) {\n const gasPrice = big(await deps.rpc(network, 'eth_gasPrice', []))\n return { chainId: network.chainId, nonce: Number(big(nonceHex)), gasLimit: hex(gasLimit), gasPrice: hex(gasPrice), maxFee: (gasLimit * gasPrice).toString() }\n }\n const floor = deps.tipFloor?.(network.chainId) ?? MIN_TIP_WEI\n const nodeTip = await (deps.rpc(network, 'eth_maxPriorityFeePerGas', []) as Promise<string>).then(big).catch(() => 0n)\n const tip = nodeTip > floor ? nodeTip : floor\n const maxFeePerGas = base * 2n + tip\n return { chainId: network.chainId, nonce: Number(big(nonceHex)), gasLimit: hex(gasLimit), maxFeePerGas: hex(maxFeePerGas), maxPriorityFeePerGas: hex(tip), maxFee: (gasLimit * maxFeePerGas).toString() }\n}\n\n/** The router's `sign` hook: classify → prepare → review → sign (→ broadcast). */\nexport function createSignHandler(deps: SignDeps): NonNullable<RouterDeps['sign']> {\n return async ({ origin, network, method, params, accounts }) => {\n const via = deps.approvals.viaFor(origin)\n const info = classifySignRequest({ network, method, params, accounts, origin, ...(via ? { via } : {}) })\n if ('code' in info) throw RouterError.from(info)\n\n const prepared = info.kind === 'send-transaction' ? await prepareTransaction(deps, network, info.account, info.tx) : undefined\n const preview = deps.preview ? await deps.preview({ network, request: info, accounts }).catch(() => null) : null\n const payload: SignApproval = { request: info, network, ...(prepared ? { prepared } : {}), preview }\n await deps.approvals.request({ origin, chain: network.caip2, kind: info.kind, payload })\n\n const handle = await deps.signerFor(info.account, network)\n try {\n switch (info.kind) {\n case 'sign-message':\n return await handle.signer.signMessage(HEX.test(info.raw) ? Uint8Array.from(info.raw.slice(2).match(/../g) ?? [], (b) => Number.parseInt(b, 16)) : info.raw)\n case 'sign-typed-data':\n return await handle.signer.signTypedData(info.typedData)\n case 'send-transaction': {\n const p = prepared!\n const raw = await handle.signer.signTransaction({\n chainId: p.chainId, nonce: p.nonce, to: info.tx.to, value: BigInt(info.tx.value), data: info.tx.data ?? '0x', gasLimit: BigInt(p.gasLimit),\n ...(p.gasPrice !== undefined ? { gasPrice: BigInt(p.gasPrice) } : { maxFeePerGas: BigInt(p.maxFeePerGas!), maxPriorityFeePerGas: BigInt(p.maxPriorityFeePerGas!) }),\n })\n return await deps.rpc(network, 'eth_sendRawTransaction', [raw])\n }\n }\n } finally {\n handle.dispose()\n }\n }\n}\n","/**\n * Pre-approvals — the second half of Vaulty's `txGate` (mobile/lib/txGate.ts).\n * A flow that reviewed a WHOLE plan in one sheet (a swap: approvals + source\n * leg) registers one matcher per operation it is about to perform; the\n * reviewed account then lets exactly those operations through without a second\n * window, each once, within `ttlMs`. Anything else still stops at the review.\n */\nexport type GatedOp =\n | { kind: 'evm-tx'; caip2: string; to: string; data?: string; value: bigint }\n | { kind: 'evm-typed-data'; caip2: string }\n | { kind: 'solana-transfer'; to: string; amount: bigint; token?: string }\n | { kind: 'solana-tx'; to: string; value: bigint }\n | { kind: 'solana-serialized'; serializedTx: string }\n /** A module-built Solana transaction message (instructions), reviewed as a plan. */\n | { kind: 'solana-message' }\n /** TON / Tron / Bitcoin / NEAR send or token transfer (amount in base units; token = jetton master / TRC-20 / NEP-141 id). */\n | { kind: 'chain-tx'; chain: string; to: string; amount: bigint; token?: string | undefined; memo?: string | undefined }\n\nexport type GateMatcher = (op: GatedOp) => boolean\n\nexport class ReviewGate {\n private approved: { match: GateMatcher; until: number }[] = []\n\n constructor(private readonly now: () => number = Date.now) {}\n\n /** Each matcher passes ONE operation, within `ttlMs` (default 10 min). */\n preApprove(matchers: GateMatcher[], ttlMs = 10 * 60_000): void {\n const until = this.now() + ttlMs\n this.approved.push(...matchers.map((match) => ({ match, until })))\n }\n\n /** True (and the matcher is spent) when a pre-approval covers `op`. */\n consume(op: GatedOp): boolean {\n const now = this.now()\n this.approved = this.approved.filter((a) => a.until > now)\n const i = this.approved.findIndex((a) => a.match(op))\n if (i < 0) return false\n this.approved.splice(i, 1)\n return true\n }\n\n get pending(): number {\n return this.approved.length\n }\n\n clear(): void {\n this.approved = []\n }\n}\n\nconst lc = (s: string) => s.toLowerCase()\n\n/** Matcher for an exact EVM call: same chain, `to`, calldata and value. */\nexport function evmCallMatcher(expected: { caip2: string; to: string; data?: string | undefined; value: bigint }): GateMatcher {\n const data = expected.data && expected.data !== '0x' ? lc(expected.data) : undefined\n return (op) =>\n op.kind === 'evm-tx' &&\n op.caip2 === expected.caip2 &&\n lc(op.to) === lc(expected.to) &&\n (op.data && op.data !== '0x' ? lc(op.data) : undefined) === data &&\n op.value === expected.value\n}\n\n/** Matcher for a non-EVM send: same chain, recipient, amount, token and memo. */\nexport function chainTxMatcher(expected: { chain: string; to: string; amount: bigint; token?: string | undefined; memo?: string | undefined }): GateMatcher {\n return (op) => op.kind === 'chain-tx' && op.chain === expected.chain && op.to === expected.to && op.amount === expected.amount && (op.token ?? '') === (expected.token ?? '') && (op.memo ?? '') === (expected.memo ?? '')\n}\n","/**\n * Swaps for the extension, the DIRECT path of Vaulty mobile's `lib/swap2.ts`:\n * the providers run in the service worker and talk to their APIs themselves.\n *\n * - {@link quoteRoutes}: dry quotes from every provider that can serve the\n * pair, delivered progressively (`onUpdate` fires as each venue answers), with\n * BEST / FASTEST tags and every refusal named.\n * TODO: replace with `CrossChainRouter.getQuotes` (net-USD ranking,\n * RouteSet). Until then this fan-out over the public `CrossChainProvider`\n * interface ranks by output amount.\n * - {@link reviewSwapPlan}: the engine's `reviewExecution` hook — one sheet for\n * the whole plan (approvals + source leg) BEFORE anything is signed; on\n * approval exactly those operations are pre-approved in the {@link ReviewGate}\n * so the reviewed account lets them through once; a decline aborts with\n * nothing sent (`ReviewDeclined`, 4001).\n */\nimport type { CrossChainProvider, Quote, QuoteParams, Swap2ExecutionPlan } from '@anywalletkit/protocol-swap2-core'\nimport { validQuote } from '@anywalletkit/protocol-swap2-core'\nimport { ApprovalQueue } from './approvals.js'\nimport { ReviewGate, chainTxMatcher, evmCallMatcher, type GateMatcher } from './gate.js'\n\nexport interface RouteView {\n provider: string\n destAmount: string\n minDestAmount: string\n feeUsd: number\n /** On-chain pool venues take the fee inside the output; \"$0.00\" would mislead. */\n feeNote?: string\n etaSeconds: number\n validUntilMs: number\n tags: ('best' | 'fastest')[]\n}\n\nexport interface RouteListView {\n routes: RouteView[]\n /** Providers still quoting. */\n pending: string[]\n /** Provider → why it sat out (refusal, error, timeout). */\n refusals: Record<string, string>\n /** The quotes themselves, by provider, for execution with the same numbers the user saw. */\n quotes: Record<string, Quote>\n}\n\nexport interface QuoteRoutesOptions {\n onUpdate?: (view: RouteListView) => void\n /** Per-provider wall clock (default 20 s). */\n timeoutMs?: number\n signal?: AbortSignal\n now?: () => number\n}\n\n/** Dry quotes from every enabled provider that claims the route, progressively. */\nexport async function quoteRoutes(providers: readonly CrossChainProvider[], params: QuoteParams, options: QuoteRoutesOptions = {}): Promise<RouteListView> {\n const timeoutMs = options.timeoutMs ?? 20_000\n const from = { chain: params.sourceChain, token: params.sourceToken }\n const to = { chain: params.destChain, token: params.destToken }\n const refusals: Record<string, string> = {}\n const quotes: Record<string, Quote> = {}\n const candidates: CrossChainProvider[] = []\n for (const p of providers) {\n let enabled = false\n try { enabled = p.enabled() } catch { /* fail closed */ }\n if (!enabled) continue\n if (params.sourceChain === params.destChain && !p.supportsSameChain) { refusals[p.name] = 'does not do same-chain swaps'; continue }\n let serves = false\n try { serves = p.supportsRoute(from, to) } catch (e) { refusals[p.name] = e instanceof Error ? e.message : String(e); continue }\n if (!serves) { refusals[p.name] = 'does not serve this pair'; continue }\n candidates.push(p)\n }\n const pending = new Set(candidates.map((p) => p.name))\n const view = (): RouteListView => ({ routes: rank(Object.values(quotes)), pending: [...pending], refusals: { ...refusals }, quotes: { ...quotes } })\n const emit = () => options.onUpdate?.(view())\n emit()\n await Promise.all(\n candidates.map(async (p) => {\n const ctrl = new AbortController()\n const timer = setTimeout(() => ctrl.abort(new Error(`no answer within ${Math.round(timeoutMs / 1000)} s`)), timeoutMs)\n const onAbort = () => ctrl.abort(options.signal?.reason)\n options.signal?.addEventListener('abort', onAbort, { once: true })\n let refusal: string | undefined\n try {\n // Race the signal too: a provider that ignores it must not hold the list open forever.\n const aborted = new Promise<never>((_, reject) => ctrl.signal.addEventListener('abort', () => reject(ctrl.signal.reason instanceof Error ? ctrl.signal.reason : new Error(String(ctrl.signal.reason ?? 'cancelled'))), { once: true }))\n const q = await Promise.race([p.getQuote({ ...params, dry: true, onRefusal: (r) => { refusal = r } }, ctrl.signal), aborted])\n if (q && validQuote(q, { ...params, dry: true }, p.name)) quotes[p.name] = q\n else refusals[p.name] = refusal ?? (q ? 'returned an invalid quote' : 'no route for this pair right now')\n } catch (e) {\n refusals[p.name] = ctrl.signal.aborted ? String(ctrl.signal.reason instanceof Error ? ctrl.signal.reason.message : ctrl.signal.reason ?? 'cancelled') : e instanceof Error ? e.message : String(e)\n } finally {\n clearTimeout(timer)\n options.signal?.removeEventListener('abort', onAbort)\n pending.delete(p.name)\n emit()\n }\n }),\n )\n return view()\n}\n\n/** Highest output first (same destination token for every quote); FASTEST = lowest ETA among them. */\nexport function rank(quotes: Quote[]): RouteView[] {\n const sorted = [...quotes].sort((a, b) => (BigInt(b.destAmount) > BigInt(a.destAmount) ? 1 : BigInt(b.destAmount) < BigInt(a.destAmount) ? -1 : a.feeUsd - b.feeUsd || a.etaSeconds - b.etaSeconds))\n const fastest = sorted.length ? sorted.reduce((f, q) => (q.etaSeconds < f.etaSeconds ? q : f)) : null\n return sorted.map((q, i) => {\n const poolFee = q.providerData?.poolFee\n const feeNote = typeof poolFee === 'string' && poolFee && q.feeUsd === 0 ? (poolFee === 'pools' ? 'pool fees in price' : `pool ${poolFee} in price`) : undefined\n const tags: RouteView['tags'] = []\n if (i === 0) tags.push('best')\n if (fastest && q.provider === fastest.provider) tags.push('fastest')\n return { provider: q.provider, destAmount: q.destAmount, minDestAmount: q.minDestAmount, feeUsd: q.feeUsd, etaSeconds: q.etaSeconds, validUntilMs: q.validUntilMs, tags, ...(feeNote ? { feeNote } : {}) }\n })\n}\n\n/** Vaulty's execution floor: 50 bps under the quoted minimum rides normal drift while the user reviews, still refuses a real reprice. */\nexport const FLOOR_TOLERANCE_BPS = 50n\nexport function executionFloor(minDestAmount: bigint): bigint {\n const floor = (minDestAmount * (10_000n - FLOOR_TOLERANCE_BPS)) / 10_000n\n return floor > 0n ? floor : minDestAmount\n}\n\n// ---- the review stop ----\n\nexport interface SwapReviewMeta {\n /** Who runs the flow (the wallet's origin). */\n origin: string\n providerLabel: string\n fromSymbol: string\n fromDecimals: number\n toSymbol: string\n toDecimals: number\n fromChainName: string\n toChainName: string\n /** All of the user's addresses — recipient own/foreign. */\n own: string[]\n}\n\n/** What the swap sheet renders. Amounts are base-unit strings. */\nexport interface SwapApproval {\n provider: string\n providerLabel: string\n fromChain: string\n toChain: string\n fromChainName: string\n toChainName: string\n send: { symbol: string; decimals: number; amount: string }\n receive: { symbol: string; decimals: number; amount: string; min: string }\n recipient: { address: string; isOwn: boolean }\n refundAddress: string\n feeUsd: number\n etaSeconds: number\n validUntilMs: number\n approvals: { token: string; spender: string; amount: string }[]\n source:\n | { kind: 'call'; to: string; data?: string; value: string; deposit?: string }\n | { kind: 'token-transfer'; token: string; recipient: string; amount: string; memo?: string }\n | { kind: 'serialized' }\n | { kind: 'typed-order' }\n checks: { status: 'ok' | 'warn' | 'unknown'; label: string }[]\n}\n\nconst APPROVE_SELECTOR = '0x095ea7b3'\nconst TRANSFER_SELECTOR = '0xa9059cbb'\nconst pad = (hexNoPrefix: string) => hexNoPrefix.toLowerCase().padStart(64, '0')\nexport const encodeApproveCalldata = (spender: string, amount: bigint): string => `${APPROVE_SELECTOR}${pad(spender.slice(2))}${pad(amount.toString(16))}`\nconst lc = (s: string) => s.toLowerCase()\n\n/** A plain native send or ERC-20 transfer pays a provider deposit address (1Click-style). */\nfunction depositOf(s: { to: string; data?: string }, approvals: number): string | undefined {\n if (approvals > 0) return undefined\n if (!s.data || s.data === '0x') return s.to\n if (!s.data.startsWith(TRANSFER_SELECTOR) || s.data.length < 10 + 64) return undefined\n return `0x${s.data.slice(10 + 24, 10 + 64)}`\n}\n\nexport function swapApprovalPayload(plan: Swap2ExecutionPlan, meta: SwapReviewMeta): SwapApproval {\n const isOwn = meta.own.some((a) => lc(a) === lc(plan.recipient))\n const checks: SwapApproval['checks'] = [{ status: 'ok', label: `Built by the ${meta.providerLabel} module` }]\n const s = plan.source\n let source: SwapApproval['source']\n if (s.kind === 'call') {\n const deposit = depositOf(s, plan.approvals.length)\n source = { kind: 'call', to: s.to, ...(s.data ? { data: s.data } : {}), value: s.value.toString(), ...(deposit ? { deposit } : {}) }\n checks.push(deposit ? { status: 'ok', label: `Deposit address from the ${meta.providerLabel} quote` } : { status: 'ok', label: `Calls the ${meta.providerLabel} contract` })\n } else if (s.kind === 'token-transfer') {\n source = { kind: 'token-transfer', token: s.token, recipient: s.recipient, amount: s.amount.toString(), ...(s.memo ? { memo: s.memo } : {}) }\n checks.push({ status: 'ok', label: `Deposit address from the ${meta.providerLabel} quote` })\n } else if (s.kind === 'serialized') {\n source = { kind: 'serialized' }\n checks.push({ status: 'ok', label: 'Balance changes are proven before signing (SDK guard)' })\n } else {\n source = { kind: 'typed-order' }\n checks.push({ status: 'ok', label: 'Signed order — no transaction is sent from your wallet' })\n }\n for (const a of plan.approvals) checks.push(a.amount > plan.sourceAmount ? { status: 'warn', label: 'Approval is larger than this swap needs' } : { status: 'ok', label: 'Approval is exactly the amount needed' })\n if (plan.approvals.length > 1) checks.push({ status: 'ok', label: `${plan.approvals.length} approvals (reset to 0 first)` })\n checks.push(isOwn ? { status: 'ok', label: 'Funds arrive at your address' } : { status: 'warn', label: `Funds arrive at ${plan.recipient.slice(0, 6)}…${plan.recipient.slice(-4)}, not your address` })\n return {\n provider: plan.provider, providerLabel: meta.providerLabel, fromChain: plan.fromChain, toChain: plan.destChain, fromChainName: meta.fromChainName, toChainName: meta.toChainName,\n send: { symbol: meta.fromSymbol, decimals: meta.fromDecimals, amount: plan.sourceAmount.toString() },\n receive: { symbol: meta.toSymbol, decimals: meta.toDecimals, amount: plan.destAmount.toString(), min: plan.minDestAmount.toString() },\n recipient: { address: plan.recipient, isOwn }, refundAddress: plan.refundAddress, feeUsd: plan.feeUsd, etaSeconds: plan.etaSeconds, validUntilMs: plan.validUntilMs,\n approvals: plan.approvals.map((a) => ({ token: a.token, spender: a.spender, amount: a.amount.toString() })),\n source, checks,\n }\n}\n\n/** Matchers for exactly the operations the plan will perform, in the engine's order. */\nexport function planMatchers(plan: Swap2ExecutionPlan): GateMatcher[] {\n const m: GateMatcher[] = plan.approvals.map((a) => evmCallMatcher({ caip2: plan.fromChain, to: a.token, data: encodeApproveCalldata(a.spender, a.amount), value: 0n }))\n const s = plan.source\n if (s.kind === 'call') {\n if (plan.fromChain.startsWith('eip155:')) m.push(evmCallMatcher({ caip2: plan.fromChain, to: s.to, data: s.data, value: s.value }))\n else if (plan.fromChain.startsWith('solana:')) m.push((op) => op.kind === 'solana-tx' && op.to === s.to && op.value === s.value)\n else m.push(chainTxMatcher({ chain: plan.fromChain, to: s.to, amount: s.value, memo: s.memo }))\n } else if (s.kind === 'token-transfer') {\n if (plan.fromChain.startsWith('eip155:')) m.push(evmCallMatcher({ caip2: plan.fromChain, to: s.token, data: `${TRANSFER_SELECTOR}${pad(s.recipient.slice(2))}${pad(s.amount.toString(16))}`, value: 0n }))\n else if (plan.fromChain.startsWith('solana:')) m.push((op) => op.kind === 'solana-transfer' && op.to === s.recipient && op.amount === s.amount && (op.token ?? '') === s.token)\n else m.push(chainTxMatcher({ chain: plan.fromChain, to: s.recipient, amount: s.amount, token: s.token, memo: s.memo }))\n } else if (s.kind === 'serialized') {\n m.push((op) => op.kind === 'solana-serialized' && op.serializedTx === s.serializedTx)\n } else {\n m.push((op) => op.kind === 'evm-typed-data' && op.caip2 === plan.fromChain)\n }\n return m\n}\n\n/** The engine's `reviewExecution`: one sheet for the plan; approve → pre-approve exactly its operations; decline → nothing sent. */\nexport function reviewSwapPlan(approvals: ApprovalQueue, gate: ReviewGate, meta: SwapReviewMeta): (plan: Swap2ExecutionPlan) => Promise<void> {\n return async (plan) => {\n const payload = swapApprovalPayload(plan, meta)\n await approvals.request({ origin: meta.origin, chain: plan.fromChain, kind: 'swap', payload })\n gate.clear()\n gate.preApprove(planMatchers(plan), Math.max(60_000, plan.validUntilMs - Date.now() + 5 * 60_000))\n }\n}\n","/**\n * Pending swaps across service-worker restarts: records in `chrome.storage.local`,\n * a `chrome.alarms` tick every minute while anything is active, resumable by\n * the swap2 id (`awk1.<provider>.<intent>[.<sourceTxHash>]`), the provider's\n * `trackIntent` as the only source of truth.\n *\n * States (the provider's `IntentState` plus the wallet's own `claiming`):\n * pending ──deposit seen──▶ pending (depositReceived)\n * pending ──attested (CCTP)──▶ action-required ──user claims──▶ claiming ──mint seen──▶ completed\n * pending ──▶ completed | failed | refunded | refund-pending | partial | cancelled | expired\n * A tracker error leaves the record as it was (with `lastError`); a record older\n * than `giveUpAfterMs` with no progress becomes `expired` so the alarm stops.\n */\nimport { SWAP2_ID_PREFIX, type IntentStatus } from '@anywalletkit/protocol-swap2-core'\nimport type { JsonStorage } from './storage.js'\n\nexport type SwapRecordStatus = IntentStatus['state'] | 'claiming'\n\nexport interface SwapRecord {\n /** swap2 id — `awk1.<provider>.<intentId>[.<sourceTxHash>]`. */\n id: string\n provider: string\n fromChain: string\n toChain: string\n fromToken: string\n toToken: string\n /** Base units. */\n amountIn: string\n destAmount: string\n recipient: string\n sourceTxHash: string | null\n destTxHash: string | null\n status: SwapRecordStatus\n depositReceived?: boolean\n /** Two-phase routes: where and whether the claim can be built now. */\n claim?: { chain: string; ready: boolean }\n createdAt: number\n updatedAt: number\n /** Last tracker problem (RPC/API), kept until the next successful check. */\n lastError?: string\n checks: number\n}\n\nexport const ACTIVE_STATUSES: ReadonlySet<SwapRecordStatus> = new Set<SwapRecordStatus>(['pending', 'action-required', 'refund-pending', 'partial', 'claiming'])\n\nexport function parseSwapId(id: string): { provider: string; intentId: string; sourceTxHash?: string } | null {\n if (!id.startsWith(`${SWAP2_ID_PREFIX}.`)) return null\n const parts = id.slice(SWAP2_ID_PREFIX.length + 1).split('.')\n if (parts.length < 2 || parts.length > 3 || !parts[0] || !parts[1]) return null\n const provider = decodeURIComponent(parts[0])\n const intentId = decodeURIComponent(parts[1])\n const sourceTxHash = parts[2] ? decodeURIComponent(parts[2]) : undefined\n return sourceTxHash ? { provider, intentId, sourceTxHash } : { provider, intentId }\n}\n\nexport class SwapsStore {\n private _records: SwapRecord[] | null = null\n private readonly _listeners = new Set<() => void>()\n\n constructor(private readonly storage: JsonStorage<SwapRecord[]>) {}\n\n async list(): Promise<SwapRecord[]> {\n this._records ??= (await this.storage.get()) ?? []\n return [...this._records].sort((a, b) => b.createdAt - a.createdAt)\n }\n\n async get(id: string): Promise<SwapRecord | null> {\n return (await this.list()).find((r) => r.id === id) ?? null\n }\n\n async active(): Promise<SwapRecord[]> {\n return (await this.list()).filter((r) => ACTIVE_STATUSES.has(r.status))\n }\n\n async add(record: SwapRecord): Promise<void> {\n const all = (await this.list()).filter((r) => r.id !== record.id)\n await this.write([...all, record])\n }\n\n async update(id: string, patch: Partial<SwapRecord>): Promise<SwapRecord | null> {\n const all = await this.list()\n const i = all.findIndex((r) => r.id === id)\n if (i < 0) return null\n const next = { ...all[i]!, ...patch, updatedAt: patch.updatedAt ?? Date.now() }\n all[i] = next\n await this.write(all)\n return next\n }\n\n async remove(id: string): Promise<void> {\n await this.write((await this.list()).filter((r) => r.id !== id))\n }\n\n onChange(listener: () => void): () => void {\n this._listeners.add(listener)\n return () => this._listeners.delete(listener)\n }\n\n private async write(records: SwapRecord[]): Promise<void> {\n await this.storage.set(records)\n this._records = records\n for (const l of this._listeners) l()\n }\n}\n\nexport interface SwapTrackerDeps {\n store: SwapsStore\n /** The provider's view of the swap (`CrossChainRouter.trackIntent`). */\n status(record: SwapRecord): Promise<IntentStatus>\n /** Start / stop the periodic alarm (`chrome.alarms.create(name, { periodInMinutes: 1 })`). */\n alarm: { start(): Promise<void> | void; stop(): Promise<void> | void }\n now?: () => number\n /** No progress for this long → `expired` (default 48 h). */\n giveUpAfterMs?: number\n}\n\nexport class SwapTracker {\n private readonly now: () => number\n private ticking: Promise<void> | null = null\n\n constructor(private readonly deps: SwapTrackerDeps) {\n this.now = deps.now ?? Date.now\n }\n\n /** Record a just-executed swap and make sure the alarm runs. */\n async track(input: Omit<SwapRecord, 'createdAt' | 'updatedAt' | 'checks' | 'status' | 'destTxHash'> & { status?: SwapRecordStatus }): Promise<SwapRecord> {\n const t = this.now()\n const record: SwapRecord = { ...input, status: input.status ?? 'pending', destTxHash: null, createdAt: t, updatedAt: t, checks: 0 }\n await this.deps.store.add(record)\n await this.deps.alarm.start()\n return record\n }\n\n /** After the user's claim transaction went out: keep polling until the provider sees the mint. */\n async claimed(id: string, destTxHash: string): Promise<void> {\n await this.deps.store.update(id, { status: 'claiming', destTxHash, claim: undefined as never })\n await this.deps.alarm.start()\n }\n\n /** One alarm tick: check every active record once; stop the alarm when nothing is active. Concurrent ticks coalesce. */\n tick(): Promise<void> {\n this.ticking ??= this.run().finally(() => { this.ticking = null })\n return this.ticking\n }\n\n private async run(): Promise<void> {\n const active = await this.deps.store.active()\n if (active.length === 0) { await this.deps.alarm.stop(); return }\n const giveUp = this.deps.giveUpAfterMs ?? 48 * 60 * 60_000\n for (const record of active) {\n const patch: Partial<SwapRecord> = { checks: record.checks + 1, updatedAt: this.now() }\n try {\n const s = await this.deps.status(record)\n patch.lastError = undefined as never\n if (s.depositReceived !== undefined) patch.depositReceived = s.depositReceived\n if (s.destTxHash) patch.destTxHash = s.destTxHash\n if (s.claim) patch.claim = s.claim\n // Our own claim is out: the provider still says action-required until it sees the mint; keep \"claiming\".\n patch.status = record.status === 'claiming' && (s.state === 'action-required' || s.state === 'pending') ? 'claiming' : s.state\n } catch (e) {\n patch.lastError = e instanceof Error ? e.message : String(e)\n if (this.now() - record.createdAt > giveUp) patch.status = 'expired'\n }\n await this.deps.store.update(record.id, patch)\n }\n if ((await this.deps.store.active()).length === 0) await this.deps.alarm.stop()\n }\n}\n","/**\n * Earn plan review — the Earn modules' counterpart of the swap sheet. A module\n * that exposes its plan (Aave / Morpho `planSupply` & co: ERC-20 approvals\n * first, then the call) gets ONE sheet for the whole plan; on approval exactly\n * those calls are pre-approved in the {@link ReviewGate} so the module's own\n * `supply()` / `withdraw()` / … passes through the reviewed account without a\n * second window. Modules without a plan API (Mellow, Lido, SSV, Jito) are\n * reviewed per transaction by the reviewed account itself — still every send.\n */\nimport { ApprovalQueue } from './approvals.js'\nimport { ReviewGate, evmCallMatcher, type GateMatcher } from './gate.js'\nimport type { EvmNetwork } from './networks.js'\n\nexport interface EarnTx {\n to: string\n data?: string | undefined\n /** Base units, decimal string. */\n value: string\n}\n\nexport interface EarnPlan {\n approvals: EarnTx[]\n tx: EarnTx\n}\n\nexport interface EarnReviewMeta {\n origin: string\n /** 'Aave v3', 'Morpho', … */\n module: string\n /** 'Supply', 'Withdraw', 'Borrow', 'Repay', 'Stake', … */\n action: string\n network: EvmNetwork\n /** Human lines the sheet shows (asset, amount, APY, market/vault, health factor…). */\n facts: { k: string; v: string }[]\n /** What the module says about the plan (its own refusals never reach here — they throw before). */\n checks?: { status: 'ok' | 'warn' | 'unknown'; label: string }[]\n /** tx-preview-evm result for approvals + call, attached by the wallet (JSON-safe) or null. */\n preview?: unknown\n}\n\nexport interface EarnApproval {\n module: string\n action: string\n network: EvmNetwork\n facts: { k: string; v: string }[]\n approvals: EarnTx[]\n tx: EarnTx\n checks: { status: 'ok' | 'warn' | 'unknown'; label: string }[]\n preview: unknown\n}\n\nconst APPROVE_SELECTOR = '0x095ea7b3'\n\nexport function earnPlanMatchers(network: EvmNetwork, plan: EarnPlan): GateMatcher[] {\n return [...plan.approvals, plan.tx].map((t) => evmCallMatcher({ caip2: network.caip2, to: t.to, data: t.data, value: BigInt(t.value) }))\n}\n\nexport function earnApprovalPayload(plan: EarnPlan, meta: EarnReviewMeta): EarnApproval {\n const checks = [{ status: 'ok' as const, label: `Built by the ${meta.module} module` }, ...(meta.checks ?? [])]\n for (const a of plan.approvals) {\n if (!a.data?.startsWith(APPROVE_SELECTOR)) checks.push({ status: 'warn', label: `Unexpected pre-call to ${a.to.slice(0, 8)}…` })\n }\n if (plan.approvals.length > 1) checks.push({ status: 'ok', label: `${plan.approvals.length} approvals (reset to 0 first)` })\n return { module: meta.module, action: meta.action, network: meta.network, facts: meta.facts, approvals: plan.approvals, tx: plan.tx, checks, preview: meta.preview ?? null }\n}\n\n/** One sheet for the plan; approve → pre-approve exactly its calls; decline → ReviewDeclined, nothing sent. */\nexport async function reviewEarnPlan(approvals: ApprovalQueue, gate: ReviewGate, meta: EarnReviewMeta, plan: EarnPlan): Promise<void> {\n await approvals.request({ origin: meta.origin, chain: meta.network.caip2, kind: 'earn', payload: earnApprovalPayload(plan, meta) })\n gate.preApprove(earnPlanMatchers(meta.network, plan), 10 * 60_000)\n}\n","/**\n * TON Connect protocol v2 — the parts that are pure data: request parsing,\n * the bytes `ton_proof` and `signData` sign, error codes. The wallet side (keys,\n * sheet, broadcast) lives in the extension; nothing here touches a key.\n *\n * ton_proof (docs.ton.org/develop/dapps/ton-connect/sign):\n * message = sha256(0xffff ‖ \"ton-connect\" ‖ sha256(\n * \"ton-proof-item-v2/\" ‖ workchain:int32BE ‖ address_hash:32 ‖\n * domain_len:uint32LE ‖ domain ‖ timestamp:uint64LE ‖ payload))\n * signature = ed25519(message)\n * signData (text | binary; `cell` payloads are refused here):\n * message = sha256(0xffff ‖ \"ton-connect/sign-data/\" ‖ workchain:int32BE ‖ address_hash:32 ‖\n * domain_len:uint32BE ‖ domain ‖ timestamp:uint64BE ‖ payload_prefix(\"txt\"|\"bin\") ‖ payload_len:uint32BE ‖ payload)\n */\nimport { sha256 } from '@noble/hashes/sha2.js'\n\nexport const TONCONNECT_ERRORS = { unknown: 0, badRequest: 1, manifestNotFound: 2, manifestContent: 3, unknownApp: 100, userDeclined: 300, methodNotSupported: 400 } as const\n\nexport class TonConnectError extends Error {\n constructor(readonly code: number, message: string) { super(message); this.name = 'TonConnectError' }\n}\n\nexport interface TonConnectRequest {\n manifestUrl: string\n /** `ton_addr` always; `ton_proof` with the dApp's payload when asked. */\n proofPayload?: string\n}\n\nexport function parseConnectRequest(message: unknown): TonConnectRequest {\n const m = message as { manifestUrl?: unknown; items?: unknown } | undefined\n if (!m || typeof m.manifestUrl !== 'string' || !/^https:\\/\\//.test(m.manifestUrl)) throw new TonConnectError(TONCONNECT_ERRORS.badRequest, 'ConnectRequest needs an https manifestUrl.')\n const items = Array.isArray(m.items) ? (m.items as Array<{ name?: unknown; payload?: unknown }>) : []\n if (!items.some((i) => i?.name === 'ton_addr')) throw new TonConnectError(TONCONNECT_ERRORS.badRequest, 'ConnectRequest must ask for ton_addr.')\n const proof = items.find((i) => i?.name === 'ton_proof')\n if (proof && typeof proof.payload !== 'string') throw new TonConnectError(TONCONNECT_ERRORS.badRequest, 'ton_proof needs a string payload.')\n for (const i of items) if (i?.name !== 'ton_addr' && i?.name !== 'ton_proof') throw new TonConnectError(TONCONNECT_ERRORS.badRequest, `Unknown connect item ${String(i?.name)}.`)\n return { manifestUrl: m.manifestUrl, ...(proof ? { proofPayload: proof.payload as string } : {}) }\n}\n\nexport interface TonConnectMessage {\n /** Destination, as given (friendly or raw). */\n address: string\n /** Nanotons, decimal string. */\n amount: string\n /** base64 BoC body. */\n payload?: string\n /** base64 BoC state init. */\n stateInit?: string\n}\n\nexport interface TonConnectSendTransaction {\n validUntil?: number\n network?: string\n from?: string\n messages: TonConnectMessage[]\n}\n\nexport const TONCONNECT_MAX_MESSAGES = 4\n\n/** `sendTransaction` params[0] (a JSON string per the spec, or an object). */\nexport function parseSendTransaction(param: unknown, options: { maxMessages?: number; network?: string } = {}): TonConnectSendTransaction {\n let o: Record<string, unknown>\n try { o = (typeof param === 'string' ? JSON.parse(param) : param) as Record<string, unknown> } catch { throw new TonConnectError(TONCONNECT_ERRORS.badRequest, 'sendTransaction params[0] is not valid JSON.') }\n if (!o || typeof o !== 'object') throw new TonConnectError(TONCONNECT_ERRORS.badRequest, 'sendTransaction needs a request object.')\n const network = options.network ?? '-239'\n if (o.network !== undefined && String(o.network) !== network) throw new TonConnectError(TONCONNECT_ERRORS.badRequest, `This wallet is on network ${network}; the request names ${String(o.network)}.`)\n const raw = Array.isArray(o.messages) ? (o.messages as Array<Record<string, unknown>>) : []\n if (raw.length === 0) throw new TonConnectError(TONCONNECT_ERRORS.badRequest, 'sendTransaction has no messages.')\n if (raw.length > (options.maxMessages ?? TONCONNECT_MAX_MESSAGES)) throw new TonConnectError(TONCONNECT_ERRORS.badRequest, `At most ${options.maxMessages ?? TONCONNECT_MAX_MESSAGES} messages per transaction.`)\n const messages: TonConnectMessage[] = raw.map((m, i) => {\n if (typeof m.address !== 'string' || !m.address) throw new TonConnectError(TONCONNECT_ERRORS.badRequest, `Message ${i + 1} has no address.`)\n if (typeof m.amount !== 'string' || !/^[0-9]+$/.test(m.amount)) throw new TonConnectError(TONCONNECT_ERRORS.badRequest, `Message ${i + 1} amount must be a decimal string of nanotons.`)\n if (m.payload !== undefined && typeof m.payload !== 'string') throw new TonConnectError(TONCONNECT_ERRORS.badRequest, `Message ${i + 1} payload must be a base64 BoC.`)\n if (m.stateInit !== undefined && typeof m.stateInit !== 'string') throw new TonConnectError(TONCONNECT_ERRORS.badRequest, `Message ${i + 1} stateInit must be a base64 BoC.`)\n return { address: m.address, amount: m.amount, ...(m.payload ? { payload: m.payload } : {}), ...(m.stateInit ? { stateInit: m.stateInit } : {}) }\n })\n const validUntil = typeof o.valid_until === 'number' ? o.valid_until : typeof o.validUntil === 'number' ? o.validUntil : undefined\n if (validUntil !== undefined && validUntil * 1000 < Date.now()) throw new TonConnectError(TONCONNECT_ERRORS.badRequest, 'The request has expired (valid_until is in the past).')\n return { messages, ...(validUntil !== undefined ? { validUntil } : {}), ...(o.network !== undefined ? { network: String(o.network) } : {}), ...(typeof o.from === 'string' ? { from: o.from } : {}) }\n}\n\nexport type TonSignDataPayload = { type: 'text'; text: string } | { type: 'binary'; bytes: string }\n\n/** `signData` params[0]: text or binary only — `cell` payloads need schema-aware rendering and are refused by name. */\nexport function parseSignData(param: unknown): TonSignDataPayload {\n let o: Record<string, unknown>\n try { o = (typeof param === 'string' ? JSON.parse(param) : param) as Record<string, unknown> } catch { throw new TonConnectError(TONCONNECT_ERRORS.badRequest, 'signData params[0] is not valid JSON.') }\n if (o?.type === 'text' && typeof o.text === 'string') return { type: 'text', text: o.text }\n if (o?.type === 'binary' && typeof o.bytes === 'string') return { type: 'binary', bytes: o.bytes }\n if (o?.type === 'cell') throw new TonConnectError(TONCONNECT_ERRORS.methodNotSupported, 'signData with a cell payload is not supported by this wallet.')\n throw new TonConnectError(TONCONNECT_ERRORS.badRequest, 'signData payload must be { type: \"text\", text } or { type: \"binary\", bytes }.')\n}\n\nexport interface TonAddressParts { workchain: number; hash: Uint8Array }\n\nconst utf8 = (s: string) => new TextEncoder().encode(s)\nconst int32BE = (n: number) => { const b = new Uint8Array(4); new DataView(b.buffer).setInt32(0, n, false); return b }\nconst uint32LE = (n: number) => { const b = new Uint8Array(4); new DataView(b.buffer).setUint32(0, n, true); return b }\nconst uint32BE = (n: number) => { const b = new Uint8Array(4); new DataView(b.buffer).setUint32(0, n, false); return b }\nconst uint64LE = (n: number) => { const b = new Uint8Array(8); new DataView(b.buffer).setBigUint64(0, BigInt(n), true); return b }\nconst uint64BE = (n: number) => { const b = new Uint8Array(8); new DataView(b.buffer).setBigUint64(0, BigInt(n), false); return b }\nconst concat = (...parts: Uint8Array[]) => { const out = new Uint8Array(parts.reduce((n, p) => n + p.length, 0)); let o = 0; for (const p of parts) { out.set(p, o); o += p.length } return out }\n\n/** The bytes a wallet signs for `ton_proof` (already hashed — sign them raw with ed25519). */\nexport function tonProofMessage(input: { address: TonAddressParts; domain: string; timestamp: number; payload: string }): Uint8Array {\n if (input.address.hash.length !== 32) throw new TonConnectError(TONCONNECT_ERRORS.unknown, 'address hash must be 32 bytes')\n const domain = utf8(input.domain)\n const inner = concat(utf8('ton-proof-item-v2/'), int32BE(input.address.workchain), input.address.hash, uint32LE(domain.length), domain, uint64LE(input.timestamp), utf8(input.payload))\n return sha256(concat(new Uint8Array([0xff, 0xff]), utf8('ton-connect'), sha256(inner)))\n}\n\n/** The bytes a wallet signs for `signData` (text / binary). */\nexport function tonSignDataMessage(input: { address: TonAddressParts; domain: string; timestamp: number; payload: TonSignDataPayload }): Uint8Array {\n if (input.address.hash.length !== 32) throw new TonConnectError(TONCONNECT_ERRORS.unknown, 'address hash must be 32 bytes')\n const domain = utf8(input.domain)\n const payload = input.payload.type === 'text' ? utf8(input.payload.text) : Uint8Array.from(atob(input.payload.bytes), (c) => c.charCodeAt(0))\n const prefix = utf8(input.payload.type === 'text' ? 'txt' : 'bin')\n return sha256(concat(new Uint8Array([0xff, 0xff]), utf8('ton-connect/sign-data/'), int32BE(input.address.workchain), input.address.hash, uint32BE(domain.length), domain, uint64BE(input.timestamp), prefix, uint32BE(payload.length), payload))\n}\n\n/** `0:abcd…` → parts; friendly addresses are the wallet package's job (it hands us the raw form). */\nexport function parseRawAddress(raw: string): TonAddressParts {\n const m = /^(-?\\d+):([0-9a-fA-F]{64})$/.exec(raw)\n if (!m) throw new TonConnectError(TONCONNECT_ERRORS.unknown, `not a raw TON address: ${raw}`)\n return { workchain: Number(m[1]), hash: Uint8Array.from(m[2]!.match(/../g)!, (h) => Number.parseInt(h, 16)) }\n}\n\n/** The dApp's domain for proofs, from the page origin (host only, as the spec's `domain.value`). */\nexport function proofDomain(origin: string): string {\n try { return new URL(origin).host } catch { throw new TonConnectError(TONCONNECT_ERRORS.badRequest, `bad origin ${origin}`) }\n}\n\n/** Our relay errors → TON Connect error codes. */\nexport function tonConnectErrorCode(e: unknown): number {\n if (e instanceof TonConnectError) return e.code\n const code = (e as { code?: unknown })?.code\n if (code === 4001) return TONCONNECT_ERRORS.userDeclined\n if (code === 4100) return TONCONNECT_ERRORS.unknownApp\n if (code === 4200) return TONCONNECT_ERRORS.methodNotSupported\n if (code === -32602) return TONCONNECT_ERRORS.badRequest\n return TONCONNECT_ERRORS.unknown\n}\n","/**\n * Phishing / impersonation checks on a page's host, against a SHIPPED list\n * (never fetched at runtime — decision 10). The list format is MetaMask's\n * eth-phishing-detect `config.json`: `blacklist` / `whitelist` (hosts; a listed\n * domain covers its subdomains), `fuzzylist` + `tolerance` (well-known hosts a\n * lookalike is measured against by Levenshtein distance). On top: punycode\n * (`xn--`) labels are flagged, because mixed-script lookalikes are the common\n * impersonation shape.\n */\nexport interface PhishingList {\n version?: number\n tolerance?: number\n blacklist: readonly string[]\n whitelist?: readonly string[]\n fuzzylist?: readonly string[]\n /** The wallet's own additions to the fuzzylist (the big dApps our users visit): same semantics. */\n extraFuzzylist?: readonly string[]\n}\n\nexport interface HostCheck {\n host: string\n /** On the blocklist (or a subdomain of a listed domain): refuse to inject / connect. */\n blocked: boolean\n /** Human lines for the approval window; empty when nothing is odd. */\n warnings: string[]\n}\n\nexport class PhishingDetector {\n private readonly black: Set<string>\n private readonly white: Set<string>\n private readonly fuzzy: string[]\n private readonly tolerance: number\n\n constructor(list: PhishingList) {\n this.black = new Set(list.blacklist.map(normalizeHost))\n this.white = new Set((list.whitelist ?? []).map(normalizeHost))\n this.fuzzy = [...new Set([...(list.fuzzylist ?? []), ...(list.extraFuzzylist ?? [])].map(normalizeHost))]\n this.tolerance = list.tolerance ?? 1\n }\n\n get size(): number {\n return this.black.size\n }\n\n check(hostOrOrigin: string): HostCheck {\n const host = hostOf(hostOrOrigin)\n const warnings: string[] = []\n if (!host) return { host, blocked: false, warnings }\n if (matchesList(host, this.white)) return { host, blocked: false, warnings }\n if (matchesList(host, this.black)) return { host, blocked: true, warnings: ['This site is on the shipped phishing list.'] }\n if (host.split('.').some((l) => l.startsWith('xn--'))) warnings.push('The address uses punycode (xn--): it may imitate another site with look-alike characters.')\n const look = this.lookalike(host)\n if (look) warnings.push(`The address looks like ${look} but is not that site.`)\n else {\n const brand = this.brandInLabel(host)\n if (brand) warnings.push(`The address contains the name of ${brand.known} (“${brand.label}”) but is not that site.`)\n }\n return { host, blocked: false, warnings }\n }\n\n /**\n * `metamask.io-login.com`, `app-uniswap.com`, `uniswap.org.evil.net`: a known site's name used as (part of) a label\n * of a host that is not that site. Names shorter than 5 characters are skipped (too many honest matches).\n */\n brandInLabel(host: string): { known: string; label: string } | null {\n const labels = host.split('.')\n for (const known of this.fuzzy) {\n if (host === known || host.endsWith(`.${known}`)) return null\n const name = stripForFuzzy(known).split('.').pop() ?? ''\n if (name.length < 5) continue\n const hit = labels.find((l) => l.includes(name))\n if (hit) return { known, label: hit }\n }\n return null\n }\n\n /** eth-phishing-detect's fuzzy check: the host (minus the TLD and a www.) within `tolerance` edits of a known one. */\n lookalike(host: string): string | null {\n const probe = stripForFuzzy(host)\n const probeName = probe.split('.').pop() ?? probe\n for (const known of this.fuzzy) {\n if (host === known || host.endsWith(`.${known}`)) return null // the real site or one of its subdomains\n const stripped = stripForFuzzy(known)\n if (levenshtein(probe, stripped) <= this.tolerance) return known // same name on another TLD counts as a lookalike\n // `uniswep.org` vs the listed `app.uniswap.org`: compare the registrable labels too (names ≥ 5 chars)\n const name = stripped.split('.').pop() ?? stripped\n if (name.length >= 5 && name !== probeName && levenshtein(probeName, name) <= this.tolerance) return known\n }\n return null\n }\n}\n\nexport const normalizeHost = (h: string): string => h.trim().toLowerCase().replace(/\\.$/, '')\n\nexport function hostOf(hostOrOrigin: string): string {\n try { return normalizeHost(new URL(hostOrOrigin.includes('://') ? hostOrOrigin : `https://${hostOrOrigin}`).hostname) } catch { return normalizeHost(hostOrOrigin) }\n}\n\n/** `a.b.c` matches a list containing `a.b.c`, `b.c` (parent) — never `c` alone unless listed. */\nfunction matchesList(host: string, list: Set<string>): boolean {\n const parts = host.split('.')\n for (let i = 0; i < parts.length - 1; i++) if (list.has(parts.slice(i).join('.'))) return true\n return list.has(host)\n}\n\nfunction stripForFuzzy(host: string): string {\n const parts = host.replace(/^www\\./, '').split('.')\n if (parts.length > 1) parts.pop() // TLD\n return parts.join('.')\n}\n\nexport function levenshtein(a: string, b: string): number {\n if (a === b) return 0\n const m = a.length, n = b.length\n if (m === 0) return n\n if (n === 0) return m\n let prev = Array.from({ length: n + 1 }, (_, j) => j)\n for (let i = 1; i <= m; i++) {\n const cur = [i]\n for (let j = 1; j <= n; j++) cur[j] = Math.min(prev[j]! + 1, cur[j - 1]! + 1, prev[j - 1]! + (a[i - 1] === b[j - 1] ? 0 : 1))\n prev = cur\n }\n return prev[n]!\n}\n","/**\n * WebAuthn assertion verification for \"passkey on every signature\": the approval\n * page asks the authenticator to sign a challenge the service worker derived from\n * the request, and the worker checks the assertion against the public key the\n * vault stored at registration. The ceremony itself (`navigator.credentials`) runs\n * in an extension page; this module is pure WebCrypto so it is testable and the\n * worker never trusts the page's word that the user touched the authenticator.\n *\n * ES256 (COSE -7, P-256 + SHA-256) only — the only algorithm registration asks\n * for. The signature is DER (WebAuthn) and converted to the raw r‖s WebCrypto\n * wants.\n */\nimport { fromBase64, toArrayBuffer } from './codec.js'\nimport { fromBase64Url } from './vault.js'\n\nexport interface AssertionInput {\n /** `PublicKeyCredential.rawId`, base64url. */\n credentialId: string\n /** `AuthenticatorAssertionResponse.authenticatorData`, base64url. */\n authenticatorData: string\n /** `AuthenticatorAssertionResponse.clientDataJSON`, base64url. */\n clientDataJSON: string\n /** `AuthenticatorAssertionResponse.signature` (DER), base64url. */\n signature: string\n}\n\nexport interface AssertionExpectations {\n /** SPKI public key of the credential, base64 (what `getPublicKey()` returned at registration). */\n publicKey: string\n /** COSE alg of the key; only -7 is accepted. */\n alg: number\n /** The challenge the worker handed the page (raw bytes; the page sent it base64url in clientDataJSON). */\n challenge: Uint8Array\n /** `chrome-extension://<id>` */\n origin: string\n /** The RP id the credential was created for (the extension id); its SHA-256 must be the first 32 bytes of authenticatorData. */\n rpId: string\n /** Require the UV flag (user verification: biometric / PIN) — on for signing. */\n requireUserVerification?: boolean\n crypto?: Crypto\n}\n\nexport type AssertionVerdict = { ok: true; counter: number } | { ok: false; reason: string }\n\nconst FLAG_UP = 0x01\nconst FLAG_UV = 0x04\n\n/** Verify one assertion. Never throws on bad input — a verdict with the reason, so the worker can refuse in-band. */\nexport async function verifyAssertion(input: AssertionInput, expect: AssertionExpectations): Promise<AssertionVerdict> {\n const c = expect.crypto ?? globalThis.crypto\n try {\n if (expect.alg !== -7) return { ok: false, reason: `unsupported algorithm ${expect.alg} (ES256 only)` }\n const authData = fromBase64Url(input.authenticatorData)\n const clientData = fromBase64Url(input.clientDataJSON)\n const signature = fromBase64Url(input.signature)\n if (authData.length < 37) return { ok: false, reason: 'authenticatorData too short' }\n // 1. client data: type, challenge, origin\n let client: { type?: unknown; challenge?: unknown; origin?: unknown; crossOrigin?: unknown }\n try { client = JSON.parse(new TextDecoder().decode(clientData)) as typeof client } catch { return { ok: false, reason: 'clientDataJSON is not JSON' } }\n if (client.type !== 'webauthn.get') return { ok: false, reason: `clientData.type is ${String(client.type)}` }\n if (client.origin !== expect.origin) return { ok: false, reason: `assertion origin ${String(client.origin)} is not ${expect.origin}` }\n if (client.crossOrigin === true) return { ok: false, reason: 'cross-origin assertion' }\n if (typeof client.challenge !== 'string' || !equal(fromBase64Url(client.challenge), expect.challenge)) return { ok: false, reason: 'challenge does not match this request' }\n // 2. authenticator data: rpIdHash, flags, counter\n const rpIdHash = new Uint8Array(await c.subtle.digest('SHA-256', toArrayBuffer(new TextEncoder().encode(expect.rpId))))\n if (!equal(authData.subarray(0, 32), rpIdHash)) return { ok: false, reason: 'rpIdHash does not match this extension' }\n const flags = authData[32]!\n if (!(flags & FLAG_UP)) return { ok: false, reason: 'user presence flag not set' }\n if (expect.requireUserVerification !== false && !(flags & FLAG_UV)) return { ok: false, reason: 'user verification flag not set' }\n const counter = ((authData[33]! << 24) | (authData[34]! << 16) | (authData[35]! << 8) | authData[36]!) >>> 0\n // 3. signature over authenticatorData ‖ SHA-256(clientDataJSON)\n const clientHash = new Uint8Array(await c.subtle.digest('SHA-256', toArrayBuffer(clientData)))\n const signed = new Uint8Array(authData.length + clientHash.length)\n signed.set(authData, 0)\n signed.set(clientHash, authData.length)\n const raw = derToRaw(signature)\n if (!raw) return { ok: false, reason: 'signature is not a DER ECDSA signature' }\n const key = await c.subtle.importKey('spki', toArrayBuffer(fromBase64(expect.publicKey)), { name: 'ECDSA', namedCurve: 'P-256' }, false, ['verify'])\n const ok = await c.subtle.verify({ name: 'ECDSA', hash: 'SHA-256' }, key, toArrayBuffer(raw), toArrayBuffer(signed))\n return ok ? { ok: true, counter } : { ok: false, reason: 'signature does not verify against the registered passkey' }\n } catch (e) {\n return { ok: false, reason: e instanceof Error ? e.message : String(e) }\n }\n}\n\n/** DER `SEQUENCE { INTEGER r, INTEGER s }` → 64-byte r‖s; `null` when malformed. */\nexport function derToRaw(der: Uint8Array): Uint8Array | null {\n if (der[0] !== 0x30) return null\n let i = 2\n if (der[1]! & 0x80) i = 2 + (der[1]! & 0x7f)\n const int = (): Uint8Array | null => {\n if (der[i] !== 0x02) return null\n const len = der[i + 1]!\n const start = i + 2\n i = start + len\n let v = der.subarray(start, start + len)\n while (v.length > 32 && v[0] === 0) v = v.subarray(1)\n if (v.length > 32) return null\n const out = new Uint8Array(32)\n out.set(v, 32 - v.length)\n return out\n }\n const r = int()\n if (!r) return null\n const s = int()\n if (!s) return null\n const raw = new Uint8Array(64)\n raw.set(r, 0)\n raw.set(s, 32)\n return raw\n}\n\n/** Raw r‖s → DER (tests build assertions with WebCrypto, which signs raw). */\nexport function rawToDer(raw: Uint8Array): Uint8Array {\n const enc = (v: Uint8Array): number[] => {\n let i = 0\n while (i < v.length - 1 && v[i] === 0) i++\n let body = Array.from(v.subarray(i))\n if (body[0]! & 0x80) body = [0, ...body]\n return [0x02, body.length, ...body]\n }\n const r = enc(raw.subarray(0, 32))\n const s = enc(raw.subarray(32, 64))\n return Uint8Array.from([0x30, r.length + s.length, ...r, ...s])\n}\n\n/**\n * The challenge for one approval request: SHA-256 over the request id, kind,\n * origin and payload, so an assertion made for one sheet cannot answer another.\n */\nexport async function approvalChallenge(request: { id: string; kind: string; origin: string; payload: unknown }, c: Crypto = globalThis.crypto): Promise<Uint8Array> {\n const text = JSON.stringify([request.id, request.kind, request.origin, request.payload])\n return new Uint8Array(await c.subtle.digest('SHA-256', toArrayBuffer(new TextEncoder().encode(text))))\n}\n\nfunction equal(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false\n let d = 0\n for (let i = 0; i < a.length; i++) d |= a[i]! ^ b[i]!\n return d === 0\n}\n","/**\n * Address poisoning: an attacker sends dust from an address whose first and\n * last characters match one the user actually paid, hoping the next copy-paste\n * picks the wrong one. The wallet has no transaction history, so it keeps its\n * own book of recipients the user confirmed (per chain) and warns when a new\n * recipient looks like one of them without being it. \"Fresh address\" (no\n * activity on chain) is the other half of the signal; the EVM preview computes it.\n */\nimport type { JsonStorage } from './storage.js'\n\nexport type RecipientsState = Record<string, string[]>\n\n/** How many characters at each end must match (after any `0x`). */\nexport const LOOKALIKE_PREFIX = 4\nexport const LOOKALIKE_SUFFIX = 4\n\nconst norm = (a: string) => a.trim().toLowerCase().replace(/^0x/, '')\n\n/** A known recipient that `address` imitates (same start and end, different address), or `null`. */\nexport function lookalikeOf(address: string, known: readonly string[]): string | null {\n const a = norm(address)\n if (a.length < LOOKALIKE_PREFIX + LOOKALIKE_SUFFIX + 1) return null\n for (const k of known) {\n const b = norm(k)\n if (b === a || b.length !== a.length) continue\n if (a.startsWith(b.slice(0, LOOKALIKE_PREFIX)) && a.endsWith(b.slice(-LOOKALIKE_SUFFIX))) return k\n }\n return null\n}\n\n/** Recipients the user confirmed on each chain (`eip155`, `solana`, …), newest last, capped. */\nexport class RecipientBook {\n private _state: RecipientsState | null = null\n\n constructor(private readonly storage: JsonStorage<RecipientsState>, private readonly cap = 500) {}\n\n private async state(): Promise<RecipientsState> {\n this._state ??= (await this.storage.get()) ?? {}\n return this._state\n }\n\n async list(namespace: string): Promise<string[]> {\n return [...((await this.state())[namespace] ?? [])]\n }\n\n async remember(namespace: string, address: string): Promise<void> {\n const s = { ...(await this.state()) }\n const list = (s[namespace] ?? []).filter((a) => norm(a) !== norm(address))\n list.push(address)\n s[namespace] = list.slice(-this.cap)\n await this.storage.set(s)\n this._state = s\n }\n\n /** `known` → the address is one the user paid before; `lookalike` → it imitates one. */\n async check(namespace: string, address: string): Promise<{ known: boolean; lookalike: string | null }> {\n const list = await this.list(namespace)\n const known = list.some((a) => norm(a) === norm(address))\n return { known, lookalike: known ? null : lookalikeOf(address, list) }\n }\n}\n"],"mappings":"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","names":["kek","kdf","import_core","import_core","lc","lc","import_protocol_swap2_core","APPROVE_SELECTOR","utf8"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/vault.ts","../src/codec.ts","../src/session.ts","../src/relay.ts","../src/chrome.ts","../src/keyring.ts","../src/networks.ts","../src/storage.ts","../src/permissions.ts","../src/approvals.ts","../src/router.ts","../src/siwe.ts","../src/signing.ts","../src/gate.ts","../src/swap.ts","../src/swaps.ts","../src/earn.ts","../src/tonconnect.ts","../src/phishing.ts","../src/webauthn.ts","../src/poison.ts"],"sourcesContent":["export * from './errors.js'\nexport * from './vault.js'\nexport * from './session.js'\nexport * from './relay.js'\nexport * from './chrome.js'\nexport * from './keyring.js'\nexport * from './networks.js'\nexport * from './storage.js'\nexport * from './permissions.js'\nexport * from './approvals.js'\nexport * from './router.js'\nexport * from './signing.js'\nexport * from './gate.js'\nexport * from './swap.js'\nexport * from './swaps.js'\nexport * from './earn.js'\nexport * from './tonconnect.js'\nexport * from './phishing.js'\nexport * from './webauthn.js'\nexport * from './siwe.js'\nexport * from './poison.js'\n","/** A vault or session rule was broken. Messages are safe to show the user and never contain secrets. */\nexport class VaultError extends Error {\n readonly code: VaultErrorCode\n constructor(message: string, code: VaultErrorCode) {\n super(message)\n this.name = 'VaultError'\n this.code = code\n }\n}\n\nexport type VaultErrorCode =\n /** The password did not open the vault (or the envelope was tampered with — AES-GCM cannot tell the two apart). */\n | 'wrong-password'\n /** `create` was called while a vault already exists — an existing wallet is never overwritten. */\n | 'exists'\n /** `unlock` / `getSecret` on a storage area that holds no vault. */\n | 'missing'\n /** The stored envelope has a version or shape this build does not read. */\n | 'unsupported-envelope'\n /** The session is locked: the unlocked key is gone (auto-lock, browser exit, explicit lock). */\n | 'locked'\n /** Bad input (empty or too-short password, bad key length, bad id). */\n | 'invalid-input'\n /** The stored envelope's KDF parameters are below the floor this build accepts (edited on disk). */\n | 'weak-kdf'\n","/**\n * The vault: every secret (seed phrase, imported private key, TON words) at rest\n * in `chrome.storage.local`, encrypted with WebCrypto plus one audited pure-JS\n * primitive (`@noble/hashes` scrypt) — no WASM, no third-party crypto in the\n * key path beyond that.\n *\n * Two layers of keys, so that unlocking does not keep the password around and\n * other unlock paths (passkeys) do not re-encrypt the secrets:\n *\n * ```text\n * password ──scrypt (N=2^17, r=8, p=1)──▶ KEK ──AES-256-GCM──▶ wraps the DEK (envelope v2)\n * passkey PRF ──HKDF-SHA256 (salt = credential id)──▶ KEK ──AES-256-GCM──▶ wraps the DEK, one box per passkey\n * DEK (32 random bytes) ──AES-256-GCM, AAD = secret id──▶ each secret\n * ```\n *\n * What the session holds while unlocked is the DEK (see {@link Session}); the\n * password and the PRF output never leave {@link Vault.create} / {@link Vault.unlock} /\n * {@link Vault.unlockWithPasskey}. Every ciphertext carries its own 96-bit IV; the\n * AAD binds a secret to its id (so two entries cannot be swapped inside the\n * envelope) and binds the DEK box to the exact KDF parameters (so an envelope whose\n * salt or cost was edited on disk fails to open instead of deriving a weaker key).\n * Wrong password and tampering are indistinguishable (GCM tag failure) and both\n * surface as `wrong-password`.\n *\n * Envelope versions: v1 = PBKDF2-SHA256 (≥ 600 000 iterations), still opened and\n * re-sealed as v2 on the next successful unlock (MetaMask's `updateVault` pattern);\n * v2 = scrypt (OWASP parameters, memory-hard: an attacker who copied the Chrome\n * profile cannot run the search on GPUs the way PBKDF2 allows) + optional passkey\n * boxes. Anything else is refused (`unsupported-envelope`) instead of guessed.\n * Passwords: at least {@link VAULT_MIN_PASSWORD_LENGTH} characters, enforced here\n * and not only in a UI.\n */\nimport { zeroize } from '@anywalletkit/core'\nimport { scryptAsync } from '@noble/hashes/scrypt.js'\nimport { fromBase64, toArrayBuffer, toBase64 } from './codec.js'\nimport { VaultError } from './errors.js'\n\n/** PBKDF2-SHA256 iterations (v1 envelopes): OWASP 2023 floor for SHA-256; anything lower is refused. */\nexport const VAULT_MIN_ITERATIONS = 600_000\nexport const VAULT_DEFAULT_ITERATIONS = 600_000\n/** scrypt for v2 envelopes: OWASP's recommended cost (128 MiB, ~1 s in a service worker). */\nexport const VAULT_SCRYPT = { N: 1 << 17, r: 8, p: 1 } as const\n/** The weakest scrypt an envelope may carry and still open (16 MiB). Tests use this; `create` uses {@link VAULT_SCRYPT}. */\nexport const VAULT_MIN_SCRYPT = { N: 1 << 14, r: 8, p: 1 } as const\n/** Shortest password `create` / `changePassword` accept. `unlock` takes whatever opens the vault. */\nexport const VAULT_MIN_PASSWORD_LENGTH = 8\n/**\n * Upper bounds on what an envelope (and the options) may carry, checked before any KDF runs: an\n * envelope edited on disk must not make unlock hang (PBKDF2 iterations) or exhaust the worker's\n * memory (scrypt N × r), and its size stays within what `chrome.storage.local` holds.\n */\nexport const VAULT_LIMITS = Object.freeze({\n /** scrypt cost: 2^20 × 16 = 2 GiB is the most any envelope may ask for. */\n scrypt: Object.freeze({ N: 1 << 20, r: 16, p: 4 }),\n /** PBKDF2-SHA256 iterations (v1 envelopes). */\n iterations: 5_000_000,\n /** Sealed secrets in one vault. */\n secrets: 1_000,\n /** Registered passkeys. */\n passkeys: 32,\n /** Plaintext bytes of one secret (`setSecret`). */\n secretBytes: 16 * 1024,\n /** base64 characters of one sealed box (iv or data). */\n boxChars: 32 * 1024,\n /** JSON characters of the whole envelope. */\n envelopeChars: 4 * 1024 * 1024,\n})\nconst SALT_BYTES = 32\nconst IV_BYTES = 12\nconst DEK_BYTES = 32\n/** PRF outputs are 32 bytes (WebAuthn `prf` extension, `first`). */\nconst PRF_BYTES = 32\n\nexport interface SealedBox {\n /** 96-bit AES-GCM nonce, base64. */\n iv: string\n /** ciphertext ‖ 128-bit tag, base64. */\n data: string\n}\n\nexport interface VaultEnvelopeV1 {\n v: 1\n kdf: { name: 'PBKDF2-SHA256'; iterations: number; salt: string }\n /** The DEK, sealed under the password-derived key. AAD = version + kdf. */\n dek: SealedBox\n /** One box per key source (keyring source id), sealed under the DEK. AAD `forgewallet-vault/secret/<id>`. */\n secrets: Record<string, SealedBox>\n createdAt: number\n}\n\nexport interface VaultPasskey {\n /** WebAuthn credential id, base64url. */\n id: string\n label: string\n createdAt: number\n /** The DEK sealed under HKDF(PRF output, salt = credential id). AAD = `forgewallet-vault/2/passkey/<id>`. */\n dek: SealedBox\n /** The credential's public key (SPKI, base64) when the authenticator gave one — lets the worker verify assertions (passkey-per-signature). */\n publicKey?: string\n /** COSE algorithm of `publicKey` (-7 = ES256). */\n alg?: number\n}\n\nexport interface VaultEnvelopeV2 {\n v: 2\n kdf: { name: 'scrypt'; N: number; r: number; p: number; salt: string }\n dek: SealedBox\n secrets: Record<string, SealedBox>\n passkeys: VaultPasskey[]\n createdAt: number\n /** When a v1 envelope was re-sealed as v2. */\n upgradedAt?: number\n}\n\nexport type VaultEnvelope = VaultEnvelopeV1 | VaultEnvelopeV2\n\n/** Where the envelope lives. `chromeLocalVaultStorage()` for the extension, `memoryVaultStorage()` for tests. */\nexport interface VaultStorage {\n get(): Promise<VaultEnvelope | null>\n set(envelope: VaultEnvelope): Promise<void>\n clear(): Promise<void>\n}\n\nexport interface VaultOptions {\n storage: VaultStorage\n /** KDF for NEW envelopes and re-seals. Default scrypt (v2); `'pbkdf2'` writes v1 (tests, or a build that must stay FIPS-only). */\n kdf?: 'scrypt' | 'pbkdf2'\n /** PBKDF2 iterations for v1 envelopes (default and minimum {@link VAULT_DEFAULT_ITERATIONS}). */\n iterations?: number\n /** scrypt cost for v2 envelopes (default {@link VAULT_SCRYPT}; not below {@link VAULT_MIN_SCRYPT}). */\n scrypt?: { N: number; r: number; p: number }\n /** Progress of the scrypt derivation, 0..1 — the unlock screen's bar. */\n onProgress?: (fraction: number) => void\n /** Defaults to `globalThis.crypto`; injectable for tests. */\n crypto?: Crypto\n}\n\nexport interface VaultKdfInfo {\n version: 1 | 2\n name: 'PBKDF2-SHA256' | 'scrypt'\n /** Human line for the UI, e.g. \"scrypt N=2^17 r=8 p=1\". */\n summary: string\n}\n\n// AAD / HKDF labels are part of the sealed format: existing vaults open only with these exact strings.\nconst aadDekV1 = (kdf: VaultEnvelopeV1['kdf']) => `forgewallet-vault/1/dek/${kdf.name}/${kdf.iterations}/${kdf.salt}`\nconst aadDekV2 = (kdf: VaultEnvelopeV2['kdf']) => `forgewallet-vault/2/dek/scrypt/${kdf.N}/${kdf.r}/${kdf.p}/${kdf.salt}`\nconst aadPasskey = (id: string) => `forgewallet-vault/2/passkey/${id}`\nconst aadSecret = (id: string) => `forgewallet-vault/secret/${id}`\nconst HKDF_INFO = 'forgewallet-vault/2/passkey'\n\n/**\n * One `Vault` per storage area: writes to the envelope are serialized inside the instance, so two\n * instances over the same area could still overwrite each other.\n */\nexport class Vault {\n private readonly _storage: VaultStorage\n /** Every read-modify-write of the envelope runs here, one after another (a parallel write would drop the other's change). */\n private _queue: Promise<unknown> = Promise.resolve()\n private readonly _kdf: 'scrypt' | 'pbkdf2'\n private readonly _iterations: number\n private readonly _scrypt: { N: number; r: number; p: number }\n private readonly _onProgress: ((fraction: number) => void) | undefined\n private readonly _crypto: Crypto\n\n constructor(options: VaultOptions) {\n this._storage = options.storage\n this._kdf = options.kdf ?? 'scrypt'\n this._iterations = options.iterations ?? VAULT_DEFAULT_ITERATIONS\n this._scrypt = options.scrypt ?? VAULT_SCRYPT\n this._onProgress = options.onProgress\n this._crypto = options.crypto ?? globalThis.crypto\n if (!Number.isInteger(this._iterations) || this._iterations < VAULT_MIN_ITERATIONS || this._iterations > VAULT_LIMITS.iterations) {\n throw new VaultError(`PBKDF2 iterations must be an integer from ${VAULT_MIN_ITERATIONS} to ${VAULT_LIMITS.iterations}`, 'invalid-input')\n }\n if (!isStrongScrypt(this._scrypt)) throw new VaultError(`scrypt cost must be at least N=${VAULT_MIN_SCRYPT.N} r=${VAULT_MIN_SCRYPT.r} p=${VAULT_MIN_SCRYPT.p} (N a power of two)`, 'invalid-input')\n if (!isBoundedScrypt(this._scrypt)) throw new VaultError(`scrypt cost must be at most N=${VAULT_LIMITS.scrypt.N} r=${VAULT_LIMITS.scrypt.r} p=${VAULT_LIMITS.scrypt.p}`, 'invalid-input')\n }\n\n async exists(): Promise<boolean> {\n return (await this._storage.get()) !== null\n }\n\n /** What protects the DEK right now (UI). `null` without a vault. */\n async kdfInfo(): Promise<VaultKdfInfo | null> {\n const e = await this._storage.get()\n if (!e) return null\n if (isEnvelopeV1(e)) return { version: 1, name: 'PBKDF2-SHA256', summary: `PBKDF2-SHA256 ${e.kdf.iterations.toLocaleString('en-US')} iterations` }\n if (isEnvelopeV2(e)) return { version: 2, name: 'scrypt', summary: `scrypt N=2^${Math.log2(e.kdf.N)} r=${e.kdf.r} p=${e.kdf.p}` }\n return null\n }\n\n /**\n * Create an empty vault protected by `password`. Returns the DEK — hand it to the\n * session, then `setSecret` the first seed. Refuses when a vault exists.\n */\n async create(password: string): Promise<Uint8Array> {\n requirePassword(password, VAULT_MIN_PASSWORD_LENGTH)\n return this._exclusive(async () => {\n if (await this.exists()) throw new VaultError('A vault already exists; unlock it or reset explicitly.', 'exists')\n const dek = this._random(DEK_BYTES)\n await this._write(await this._sealEnvelope(password, dek, {}, [], Date.now()))\n return dek\n })\n }\n\n /**\n * Derive the KEK from `password`, unseal and return the DEK. `wrong-password` on\n * failure. A v1 (PBKDF2) envelope that opens is re-sealed as v2 (scrypt) on the\n * way out, secrets untouched.\n */\n async unlock(password: string): Promise<Uint8Array> {\n requirePassword(password)\n return this._exclusive(() => this._unlock(password))\n }\n\n private async _unlock(password: string): Promise<Uint8Array> {\n const envelope = await this._load()\n if (isEnvelopeV1(envelope)) {\n if (envelope.kdf.iterations < VAULT_MIN_ITERATIONS) throw new VaultError(`The vault's KDF (${envelope.kdf.iterations} iterations) is below the floor this build accepts.`, 'weak-kdf')\n const kek = await this._derivePbkdf2(password, fromBase64(envelope.kdf.salt), envelope.kdf.iterations)\n const dek = await this._open(kek, envelope.dek, aadDekV1(envelope.kdf), 'wrong-password')\n if (this._kdf === 'scrypt') {\n // Upgrade in place: same secrets, same createdAt, scrypt-wrapped DEK.\n const next = await this._sealEnvelope(password, dek, envelope.secrets, [], envelope.createdAt)\n await this._write(isEnvelopeV2(next) ? { ...next, upgradedAt: Date.now() } : next)\n }\n return dek\n }\n if (!isStrongScrypt(envelope.kdf)) throw new VaultError(`The vault's scrypt cost (N=${envelope.kdf.N} r=${envelope.kdf.r} p=${envelope.kdf.p}) is below the floor this build accepts.`, 'weak-kdf')\n const kek = await this._deriveScrypt(password, fromBase64(envelope.kdf.salt), envelope.kdf)\n return this._open(kek, envelope.dek, aadDekV2(envelope.kdf), 'wrong-password')\n }\n\n /** Re-wrap the DEK under a new password (fresh salt, current KDF). Secrets and passkeys are untouched. */\n async changePassword(oldPassword: string, newPassword: string): Promise<void> {\n requirePassword(newPassword, VAULT_MIN_PASSWORD_LENGTH)\n requirePassword(oldPassword)\n return this._exclusive(async () => {\n const dek = await this._unlock(oldPassword)\n try {\n const envelope = await this._load()\n const passkeys = isEnvelopeV2(envelope) ? envelope.passkeys : []\n const next = await this._sealEnvelope(newPassword, dek, envelope.secrets, passkeys, envelope.createdAt)\n await this._write(isEnvelopeV2(envelope) && envelope.upgradedAt !== undefined && isEnvelopeV2(next) ? { ...next, upgradedAt: envelope.upgradedAt } : next)\n } finally {\n zeroize(dek)\n }\n })\n }\n\n // ---- passkeys (v2) ----\n\n /** Public view of the registered passkeys (ids, labels; whether each can verify assertions). */\n async listPasskeys(): Promise<Array<{ id: string; label: string; createdAt: number; canVerify: boolean }>> {\n const e = await this._storage.get()\n if (!e || !isEnvelopeV2(e)) return []\n return e.passkeys.map((p) => ({ id: p.id, label: p.label, createdAt: p.createdAt, canVerify: typeof p.publicKey === 'string' && p.alg === -7 }))\n }\n\n /** The SPKI public key (base64) of one passkey, for assertion verification; `null` when unknown. */\n async passkeyPublicKey(id: string): Promise<{ publicKey: string; alg: number } | null> {\n const e = await this._storage.get()\n if (!e || !isEnvelopeV2(e)) return null\n const p = e.passkeys.find((k) => k.id === id)\n return p?.publicKey && p.alg !== undefined ? { publicKey: p.publicKey, alg: p.alg } : null\n }\n\n /**\n * Register a passkey as a second unlock path: the DEK (from the unlocked session)\n * is sealed under HKDF-SHA256(`prf`, salt = credential id). The password stays\n * the recovery path; `prf` is zeroized here. A v1 envelope must be unlocked (and\n * thereby upgraded) first, and the vault must hold a secret (it proves the DEK).\n */\n async addPasskey(dek: Uint8Array, passkey: { id: string; prf: Uint8Array; label: string; publicKey?: string | undefined; alg?: number | undefined }): Promise<void> {\n try {\n requireId(passkey.id)\n if (passkey.prf.length !== PRF_BYTES) throw new VaultError(`A PRF output is ${PRF_BYTES} bytes.`, 'invalid-input')\n await this._exclusive(() => this._addPasskey(dek, passkey))\n } finally {\n zeroize(passkey.prf)\n }\n }\n\n private async _addPasskey(dek: Uint8Array, passkey: { id: string; prf: Uint8Array; label: string; publicKey?: string | undefined; alg?: number | undefined }): Promise<void> {\n const envelope = await this._load()\n if (!isEnvelopeV2(envelope)) throw new VaultError('Unlock with the password once so the vault is upgraded before adding a passkey.', 'unsupported-envelope')\n if (envelope.passkeys.some((p) => p.id === passkey.id)) throw new VaultError('This passkey is already registered.', 'exists')\n // Prove the DEK is the vault's before sealing it under a new key.\n await this._requireDek(dek, envelope)\n const key = await this._derivePasskeyKek(passkey.prf, passkey.id)\n const entry: VaultPasskey = { id: passkey.id, label: passkey.label.slice(0, 64), createdAt: Date.now(), dek: await this._seal(key, dek, aadPasskey(passkey.id)) }\n if (passkey.publicKey && passkey.alg !== undefined) { entry.publicKey = passkey.publicKey; entry.alg = passkey.alg }\n await this._write({ ...envelope, passkeys: [...envelope.passkeys, entry] })\n }\n\n /** Unseal the DEK with a passkey's PRF output. `wrong-password` when the box does not open, `missing` when the id is unknown. */\n async unlockWithPasskey(id: string, prf: Uint8Array): Promise<Uint8Array> {\n try {\n requireId(id)\n if (prf.length !== PRF_BYTES) throw new VaultError(`A PRF output is ${PRF_BYTES} bytes.`, 'invalid-input')\n const envelope = await this._load()\n if (!isEnvelopeV2(envelope)) throw new VaultError('This vault has no passkeys; unlock with the password.', 'missing')\n const entry = envelope.passkeys.find((p) => p.id === id)\n if (!entry) throw new VaultError('No such passkey on this vault.', 'missing')\n const key = await this._derivePasskeyKek(prf, id)\n return await this._open(key, entry.dek, aadPasskey(id), 'wrong-password')\n } finally {\n zeroize(prf)\n }\n }\n\n async removePasskey(id: string): Promise<void> {\n requireId(id)\n return this._exclusive(async () => {\n const envelope = await this._load()\n if (!isEnvelopeV2(envelope)) return\n await this._write({ ...envelope, passkeys: envelope.passkeys.filter((p) => p.id !== id) })\n })\n }\n\n // ---- secrets ----\n\n async listSecretIds(): Promise<string[]> {\n const envelope = await this._storage.get()\n return envelope ? Object.keys(envelope.secrets) : []\n }\n\n /** Seal `secret` under the DEK as `sourceId` (overwrites an entry with the same id). */\n async setSecret(dek: Uint8Array, sourceId: string, secret: Uint8Array): Promise<void> {\n requireId(sourceId)\n if (secret.length > VAULT_LIMITS.secretBytes) throw new VaultError(`A secret is at most ${VAULT_LIMITS.secretBytes} bytes.`, 'invalid-input')\n const key = await this._importDek(dek)\n return this._exclusive(async () => {\n const envelope = await this._load()\n if (!(sourceId in envelope.secrets) && Object.keys(envelope.secrets).length >= VAULT_LIMITS.secrets) {\n throw new VaultError(`A vault holds at most ${VAULT_LIMITS.secrets} secrets.`, 'invalid-input')\n }\n const box = await this._seal(key, secret, aadSecret(sourceId))\n await this._write({ ...envelope, secrets: { ...envelope.secrets, [sourceId]: box } })\n })\n }\n\n /** Unseal one secret. `null` when the id is unknown; the caller zeroizes the result after use. */\n async getSecret(dek: Uint8Array, sourceId: string): Promise<Uint8Array | null> {\n requireId(sourceId)\n const envelope = await this._load()\n const box = envelope.secrets[sourceId]\n if (!box) return null\n const key = await this._importDek(dek)\n return this._open(key, box, aadSecret(sourceId), 'locked')\n }\n\n async deleteSecret(sourceId: string): Promise<void> {\n requireId(sourceId)\n return this._exclusive(async () => {\n const envelope = await this._load()\n if (!(sourceId in envelope.secrets)) return\n const secrets = { ...envelope.secrets }\n delete secrets[sourceId]\n await this._write({ ...envelope, secrets })\n })\n }\n\n /** Remove the whole vault. The explicit destructive flow only (back up → wipe → create). */\n async destroy(): Promise<void> {\n return this._exclusive(() => this._storage.clear())\n }\n\n // ---- serialized writes ----\n\n private _exclusive<T>(fn: () => Promise<T>): Promise<T> {\n const run = this._queue.then(fn)\n this._queue = run.catch(() => undefined)\n return run\n }\n\n /** Store an envelope this build will open again (bounds checked before it is written). */\n private async _write(envelope: VaultEnvelope): Promise<void> {\n const problem = envelopeProblem(envelope)\n if (problem) throw new VaultError(`The vault would exceed its limits (${problem}); nothing was written.`, 'invalid-input')\n await this._storage.set(envelope)\n }\n\n // ---- crypto ----\n\n private _random(n: number): Uint8Array {\n return this._crypto.getRandomValues(new Uint8Array(n))\n }\n\n /** A fresh envelope (v2 by default, v1 with `kdf: 'pbkdf2'`) wrapping `dek` under `password`. */\n private async _sealEnvelope(password: string, dek: Uint8Array, secrets: Record<string, SealedBox>, passkeys: VaultPasskey[], createdAt: number): Promise<VaultEnvelope> {\n const salt = this._random(SALT_BYTES)\n if (this._kdf === 'pbkdf2') {\n const kdf: VaultEnvelopeV1['kdf'] = { name: 'PBKDF2-SHA256', iterations: this._iterations, salt: toBase64(salt) }\n const kek = await this._derivePbkdf2(password, salt, this._iterations)\n return { v: 1, kdf, dek: await this._seal(kek, dek, aadDekV1(kdf)), secrets, createdAt }\n }\n const kdf: VaultEnvelopeV2['kdf'] = { name: 'scrypt', ...this._scrypt, salt: toBase64(salt) }\n const kek = await this._deriveScrypt(password, salt, kdf)\n return { v: 2, kdf, dek: await this._seal(kek, dek, aadDekV2(kdf)), secrets, passkeys, createdAt }\n }\n\n /**\n * The caller's DEK must open this envelope's secrets — it is the key the password protects, not\n * any 32 bytes. An empty vault has nothing to prove it with, so it is refused rather than trusted.\n */\n private async _requireDek(dek: Uint8Array, envelope: VaultEnvelope): Promise<void> {\n const ids = Object.keys(envelope.secrets)\n const key = await this._importDek(dek)\n if (ids.length === 0) throw new VaultError('Add a secret to the vault before a passkey: an empty vault cannot prove the key is its own.', 'invalid-input')\n const probe = await this._open(key, envelope.secrets[ids[0]!]!, aadSecret(ids[0]!), 'locked')\n zeroize(probe)\n }\n\n private async _derivePbkdf2(password: string, salt: Uint8Array, iterations: number): Promise<CryptoKey> {\n const subtle = this._crypto.subtle\n const material = await subtle.importKey('raw', toArrayBuffer(new TextEncoder().encode(password.normalize('NFKC'))), 'PBKDF2', false, ['deriveKey'])\n return subtle.deriveKey({ name: 'PBKDF2', hash: 'SHA-256', salt: toArrayBuffer(salt), iterations }, material, { name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt'])\n }\n\n private async _deriveScrypt(password: string, salt: Uint8Array, cost: { N: number; r: number; p: number }): Promise<CryptoKey> {\n const pw = new TextEncoder().encode(password.normalize('NFKC'))\n let raw: Uint8Array\n try {\n raw = await scryptAsync(pw, salt, { N: cost.N, r: cost.r, p: cost.p, dkLen: 32, maxmem: 2 * 128 * cost.N * cost.r + 1024 * 1024, ...(this._onProgress ? { onProgress: this._onProgress } : {}) })\n } finally {\n zeroize(pw)\n }\n try {\n return await this._crypto.subtle.importKey('raw', toArrayBuffer(raw), { name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt'])\n } finally {\n zeroize(raw)\n }\n }\n\n /** HKDF-SHA256(ikm = PRF output, salt = credential id bytes, info) → AES-256-GCM key. */\n private async _derivePasskeyKek(prf: Uint8Array, credentialId: string): Promise<CryptoKey> {\n const subtle = this._crypto.subtle\n const ikm = await subtle.importKey('raw', toArrayBuffer(prf), 'HKDF', false, ['deriveKey'])\n return subtle.deriveKey({ name: 'HKDF', hash: 'SHA-256', salt: toArrayBuffer(fromBase64Url(credentialId)), info: toArrayBuffer(new TextEncoder().encode(HKDF_INFO)) }, ikm, { name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt'])\n }\n\n private async _importDek(dek: Uint8Array): Promise<CryptoKey> {\n if (dek.length !== DEK_BYTES) throw new VaultError('Vault key must be 32 bytes.', 'invalid-input')\n return this._crypto.subtle.importKey('raw', toArrayBuffer(dek), { name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt'])\n }\n\n private async _seal(key: CryptoKey, plaintext: Uint8Array, aad: string): Promise<SealedBox> {\n const iv = this._random(IV_BYTES)\n const ct = await this._crypto.subtle.encrypt({ name: 'AES-GCM', iv: toArrayBuffer(iv), additionalData: toArrayBuffer(new TextEncoder().encode(aad)) }, key, toArrayBuffer(plaintext))\n return { iv: toBase64(iv), data: toBase64(new Uint8Array(ct)) }\n }\n\n private async _open(key: CryptoKey, box: SealedBox, aad: string, onFail: 'wrong-password' | 'locked'): Promise<Uint8Array> {\n try {\n const pt = await this._crypto.subtle.decrypt(\n { name: 'AES-GCM', iv: toArrayBuffer(fromBase64(box.iv)), additionalData: toArrayBuffer(new TextEncoder().encode(aad)) },\n key,\n toArrayBuffer(fromBase64(box.data)),\n )\n return new Uint8Array(pt)\n } catch {\n throw new VaultError(onFail === 'wrong-password' ? 'Wrong password.' : 'The vault key does not open this entry; lock and unlock again.', onFail)\n }\n }\n\n private async _load(): Promise<VaultEnvelope> {\n const envelope = await this._storage.get()\n if (!envelope) throw new VaultError('No vault in this storage area.', 'missing')\n if (!isEnvelopeV1(envelope) && !isEnvelopeV2(envelope)) throw new VaultError('Unsupported vault envelope.', 'unsupported-envelope')\n const problem = envelopeProblem(envelope)\n if (problem) throw new VaultError(`The vault envelope is outside the limits this build opens (${problem}).`, 'unsupported-envelope')\n return envelope\n }\n}\n\nexport function isEnvelopeV1(x: unknown): x is VaultEnvelopeV1 {\n if (typeof x !== 'object' || x === null) return false\n const e = x as Record<string, unknown>\n const kdf = e.kdf as Record<string, unknown> | undefined\n return (\n e.v === 1 &&\n typeof kdf === 'object' && kdf !== null && kdf.name === 'PBKDF2-SHA256' && Number.isInteger(kdf.iterations) && typeof kdf.salt === 'string' &&\n isBox(e.dek) &&\n typeof e.secrets === 'object' && e.secrets !== null && Object.values(e.secrets as object).every(isBox)\n )\n}\n\nexport function isEnvelopeV2(x: unknown): x is VaultEnvelopeV2 {\n if (typeof x !== 'object' || x === null) return false\n const e = x as Record<string, unknown>\n const kdf = e.kdf as Record<string, unknown> | undefined\n return (\n e.v === 2 &&\n typeof kdf === 'object' && kdf !== null && kdf.name === 'scrypt' && Number.isInteger(kdf.N) && Number.isInteger(kdf.r) && Number.isInteger(kdf.p) && typeof kdf.salt === 'string' &&\n isBox(e.dek) &&\n typeof e.secrets === 'object' && e.secrets !== null && Object.values(e.secrets as object).every(isBox) &&\n Array.isArray(e.passkeys) && e.passkeys.every((p) => typeof p === 'object' && p !== null && typeof (p as VaultPasskey).id === 'string' && typeof (p as VaultPasskey).label === 'string' && isBox((p as VaultPasskey).dek))\n )\n}\n\nfunction isBox(x: unknown): x is SealedBox {\n return typeof x === 'object' && x !== null && typeof (x as SealedBox).iv === 'string' && typeof (x as SealedBox).data === 'string'\n}\n\nfunction isBoundedScrypt(c: { N: number; r: number; p: number }): boolean {\n return c.N <= VAULT_LIMITS.scrypt.N && c.r <= VAULT_LIMITS.scrypt.r && c.p <= VAULT_LIMITS.scrypt.p\n}\n\n/** Why an envelope is outside {@link VAULT_LIMITS}, or null when it is within them. */\nfunction envelopeProblem(e: VaultEnvelope): string | null {\n if (e.v === 1 && e.kdf.iterations > VAULT_LIMITS.iterations) return `PBKDF2 iterations ${e.kdf.iterations} > ${VAULT_LIMITS.iterations}`\n if (e.v === 2 && !isBoundedScrypt(e.kdf)) return `scrypt N=${e.kdf.N} r=${e.kdf.r} p=${e.kdf.p} above N=${VAULT_LIMITS.scrypt.N} r=${VAULT_LIMITS.scrypt.r} p=${VAULT_LIMITS.scrypt.p}`\n const secrets = Object.values(e.secrets)\n if (secrets.length > VAULT_LIMITS.secrets) return `${secrets.length} secrets > ${VAULT_LIMITS.secrets}`\n const passkeys = e.v === 2 ? e.passkeys : []\n if (passkeys.length > VAULT_LIMITS.passkeys) return `${passkeys.length} passkeys > ${VAULT_LIMITS.passkeys}`\n for (const box of [e.dek, ...secrets, ...passkeys.map((p) => p.dek)]) {\n if (box.iv.length > VAULT_LIMITS.boxChars || box.data.length > VAULT_LIMITS.boxChars) return `a sealed box above ${VAULT_LIMITS.boxChars} characters`\n }\n if (JSON.stringify(e).length > VAULT_LIMITS.envelopeChars) return `envelope above ${VAULT_LIMITS.envelopeChars} characters`\n return null\n}\n\nfunction isStrongScrypt(c: { N: number; r: number; p: number }): boolean {\n return Number.isInteger(c.N) && c.N >= VAULT_MIN_SCRYPT.N && (c.N & (c.N - 1)) === 0 && Number.isInteger(c.r) && c.r >= VAULT_MIN_SCRYPT.r && Number.isInteger(c.p) && c.p >= VAULT_MIN_SCRYPT.p\n}\n\nfunction requirePassword(password: string, minLength = 1): void {\n if (typeof password !== 'string' || password.length === 0) throw new VaultError('Password must not be empty.', 'invalid-input')\n if ([...password].length < minLength) throw new VaultError(`Password must be at least ${minLength} characters.`, 'invalid-input')\n}\n\nfunction requireId(id: string): void {\n if (typeof id !== 'string' || id.length === 0 || id.length > 128) throw new VaultError('Bad source id.', 'invalid-input')\n}\n\n/** base64url (WebAuthn ids) → bytes; plain base64 is accepted too. */\nexport function fromBase64Url(text: string): Uint8Array {\n const b64 = text.replace(/-/g, '+').replace(/_/g, '/')\n return fromBase64(b64 + '='.repeat((4 - (b64.length % 4)) % 4))\n}\n\nexport function toBase64Url(bytes: Uint8Array): string {\n return toBase64(bytes).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n}\n\n/** Envelope in memory — tests and the smoke. */\nexport function memoryVaultStorage(initial: VaultEnvelope | null = null): VaultStorage & { envelope: VaultEnvelope | null } {\n const s = {\n envelope: initial,\n async get() { return s.envelope ? structuredClone(s.envelope) : null },\n async set(envelope: VaultEnvelope) { s.envelope = structuredClone(envelope) },\n async clear() { s.envelope = null },\n }\n return s\n}\n","// base64 for the JSON envelopes — `btoa`/`atob` exist in every extension context (service worker included).\n\nexport function toBase64(bytes: Uint8Array): string {\n let s = ''\n for (let i = 0; i < bytes.length; i += 0x8000) s += String.fromCharCode(...bytes.subarray(i, i + 0x8000))\n return btoa(s)\n}\n\nexport function fromBase64(text: string): Uint8Array {\n const s = atob(text)\n const out = new Uint8Array(s.length)\n for (let i = 0; i < s.length; i++) out[i] = s.charCodeAt(i)\n return out\n}\n\nexport const utf8 = {\n encode: (text: string): Uint8Array => new TextEncoder().encode(text),\n decode: (bytes: Uint8Array): string => new TextDecoder().decode(bytes),\n}\n\n/** Copy into a fresh ArrayBuffer — WebCrypto rejects views over shared / offset buffers in some engines. */\nexport function toArrayBuffer(bytes: Uint8Array): ArrayBuffer {\n const copy = new Uint8Array(bytes.byteLength)\n copy.set(bytes)\n return copy.buffer\n}\n","/**\n * The unlocked state. An MV3 service worker dies after ~30 s idle, so the\n * unlocked vault key cannot live in a JS variable: it lives in\n * `chrome.storage.session` (memory-only, cleared when the browser exits, readable\n * by extension contexts only) together with its expiry, and a `chrome.alarms`\n * alarm locks it when the auto-lock timer (default 15 min since the last\n * activity) runs out.\n *\n * The session never sees a password or a seed — only the DEK the vault returned.\n * The popup never receives the DEK either: it asks the service worker to\n * perform operations by id.\n */\nimport { zeroize } from '@anywalletkit/core'\nimport { fromBase64, toBase64 } from './codec.js'\nimport { VaultError } from './errors.js'\n\n/** Structural `chrome.storage.session` (or any `StorageArea`); `memorySessionStorage()` for tests. */\nexport interface SessionStorage {\n get(key: string): Promise<unknown>\n set(key: string, value: unknown): Promise<void>\n remove(key: string): Promise<void>\n}\n\n/** Structural `chrome.alarms`: one named alarm, fired once at `when` (ms since epoch). */\nexport interface SessionAlarms {\n schedule(name: string, when: number): Promise<void> | void\n clear(name: string): Promise<void> | void\n /** Register the lock callback; the chrome adapter wires `chrome.alarms.onAlarm`. */\n onFire(handler: (name: string) => void): void\n}\n\nexport interface SessionOptions {\n storage: SessionStorage\n alarms: SessionAlarms\n /** Lock this long after the last `touch` / `unlock`. Default 15 min; 0 disables the timer (lock only on browser exit or explicit lock). */\n autoLockMs?: number\n /** Storage key and alarm name prefix. */\n name?: string\n /** Clock, injectable for tests. */\n now?: () => number\n}\n\ninterface SessionRecord {\n key: string\n expiresAt: number\n}\n\nexport const SESSION_DEFAULT_AUTOLOCK_MS = 15 * 60_000\n\nexport class Session {\n private readonly _storage: SessionStorage\n private readonly _alarms: SessionAlarms\n private _autoLockMs: number\n private readonly _key: string\n private readonly _alarm: string\n private readonly _now: () => number\n private readonly _onLock = new Set<() => void>()\n /**\n * Every operation on the stored record runs here, one after another: a `touch` that read the\n * record before a `lock` removed it would otherwise write it back and undo the lock.\n */\n private _queue: Promise<unknown> = Promise.resolve()\n /** Bumped by every lock; a `touch` writes only when no lock happened since it read the record. */\n private _epoch = 0\n\n constructor(options: SessionOptions) {\n this._storage = options.storage\n this._alarms = options.alarms\n this._autoLockMs = options.autoLockMs ?? SESSION_DEFAULT_AUTOLOCK_MS\n const name = options.name ?? 'anywalletkit-session'\n this._key = name\n this._alarm = `${name}/autolock`\n this._now = options.now ?? Date.now\n this._alarms.onFire((fired) => { if (fired === this._alarm) void this.lock() })\n }\n\n /** Store the DEK and arm the auto-lock. The caller's copy is zeroized. */\n async unlock(dek: Uint8Array): Promise<void> {\n if (dek.length !== 32) throw new VaultError('Vault key must be 32 bytes.', 'invalid-input')\n return this._serial(async () => {\n const expiresAt = this._expiry()\n await this._storage.set(this._key, { key: toBase64(dek), expiresAt } satisfies SessionRecord)\n zeroize(dek)\n await this._arm(expiresAt)\n })\n }\n\n /** Forget the DEK and cancel the alarm. Safe to call when already locked. */\n async lock(): Promise<void> {\n return this._serial(() => this._lockNow())\n }\n\n async isUnlocked(): Promise<boolean> {\n return this._serial(async () => (await this._read()) !== null)\n }\n\n /**\n * The DEK for one operation (zeroize it after). `locked` when there is none or the\n * timer ran out while the worker was asleep — the record is then removed as well, so\n * a missed alarm cannot keep the key alive.\n */\n async getKey(): Promise<Uint8Array> {\n return this._serial(async () => {\n const record = await this._read()\n if (!record) throw new VaultError('Wallet is locked.', 'locked')\n return fromBase64(record.key)\n })\n }\n\n /** User activity: push the auto-lock out again. No-op when locked. */\n async touch(): Promise<void> {\n return this._serial(async () => {\n const epoch = this._epoch\n const record = await this._read()\n if (!record || epoch !== this._epoch) return\n const expiresAt = this._expiry()\n await this._storage.set(this._key, { ...record, expiresAt } satisfies SessionRecord)\n await this._arm(expiresAt)\n })\n }\n\n get autoLockMs(): number {\n return this._autoLockMs\n }\n\n /** Change the timer (options page); re-arms from now when unlocked. 0 disables. */\n async setAutoLockMs(ms: number): Promise<void> {\n if (!Number.isFinite(ms) || ms < 0) throw new VaultError('Auto-lock must be a non-negative number of milliseconds.', 'invalid-input')\n this._autoLockMs = ms\n await this.touch()\n }\n\n onLock(callback: () => void): () => void {\n this._onLock.add(callback)\n return () => this._onLock.delete(callback)\n }\n\n private _serial<T>(fn: () => Promise<T>): Promise<T> {\n const run = this._queue.then(fn)\n this._queue = run.catch(() => undefined)\n return run\n }\n\n /** The lock itself; callers are already in the queue. */\n private async _lockNow(): Promise<void> {\n this._epoch++\n const was = await this._storage.get(this._key)\n await this._storage.remove(this._key)\n await this._alarms.clear(this._alarm)\n if (was !== undefined && was !== null) for (const cb of this._onLock) cb()\n }\n\n private _expiry(): number {\n return this._autoLockMs > 0 ? this._now() + this._autoLockMs : Number.POSITIVE_INFINITY\n }\n\n private async _arm(expiresAt: number): Promise<void> {\n if (Number.isFinite(expiresAt)) await this._alarms.schedule(this._alarm, expiresAt)\n else await this._alarms.clear(this._alarm)\n }\n\n private async _read(): Promise<SessionRecord | null> {\n const raw = (await this._storage.get(this._key)) as Partial<SessionRecord> | undefined | null\n if (!raw || typeof raw.key !== 'string' || typeof raw.expiresAt !== 'number') return null\n if (raw.expiresAt <= this._now()) { await this._lockNow(); return null }\n return raw as SessionRecord\n }\n}\n\n/** In-memory `chrome.storage.session` stand-in. */\nexport function memorySessionStorage(): SessionStorage & { data: Map<string, unknown> } {\n const data = new Map<string, unknown>()\n return {\n data,\n async get(key) { return data.get(key) },\n async set(key, value) { data.set(key, structuredClone(value)) },\n async remove(key) { data.delete(key) },\n }\n}\n\n/** In-memory alarms: `fire(name)` from the test, `pending` to inspect. */\nexport function memoryAlarms(): SessionAlarms & { pending: Map<string, number>; fire(name: string): void } {\n const pending = new Map<string, number>()\n const handlers = new Set<(name: string) => void>()\n return {\n pending,\n schedule(name, when) { pending.set(name, when) },\n clear(name) { pending.delete(name) },\n onFire(handler) { handlers.add(handler) },\n fire(name) { pending.delete(name); for (const h of handlers) h(name) },\n }\n}\n","/**\n * Message shapes on the two hops between a dApp and the wallet:\n *\n * ```text\n * page (injected provider, MAIN world)\n * │ window.postMessage — PageRequest ⇄ PageResponse / PageEvent\n * content script (isolated world) — stamps `location.origin`, owns the port\n * │ chrome.runtime.connect(PORT_NAME) — RelayRequest ⇄ RelayResponse / RelayEvent\n * service worker — trusts `port.sender` (set by the browser), never the page\n * ```\n *\n * The page can forge anything it posts, so a page message carries no origin and\n * no identity: the content script adds the origin, and the service worker\n * cross-checks it against `port.sender.origin` ({@link checkSenderOrigin}) — a\n * mismatch is dropped, not answered. Request ids are opaque strings minted by\n * the page side ({@link newRequestId}); the content script does not reuse them\n * across ports.\n */\n\n/** `chrome.runtime.connect({ name })` for content-script ports. */\nexport const PORT_NAME = 'anywalletkit/relay/1'\n/** `window.postMessage` discriminators (both directions). */\nexport const PAGE_TARGET = { toContent: 'anywalletkit/content', toPage: 'anywalletkit/page' } as const\n\n/** CAIP-2 namespace of the provider that spoke. */\nexport type RelayChain = 'eip155' | 'solana' | 'ton' | 'tron' | 'bip122' | 'near'\n\nexport interface RelayError {\n /** EIP-1193 / EIP-1474 numbering for EVM; the same numbers are reused for the other providers. */\n code: number\n message: string\n data?: unknown\n}\n\nexport const RELAY_ERRORS = {\n userRejected: 4001,\n unauthorized: 4100,\n unsupportedMethod: 4200,\n disconnected: 4900,\n chainDisconnected: 4901,\n /** EIP-3326/3085: the chain is not in the wallet (`wallet_switchEthereumChain` → suggest `wallet_addEthereumChain`). */\n chainNotAdded: 4902,\n internal: -32603,\n invalidRequest: -32600,\n invalidParams: -32602,\n /** EIP-1474: a request of the same kind from this origin is already waiting (MetaMask's \"already pending\"). */\n resourceUnavailable: -32002,\n /** EIP-1474: this origin has too many requests waiting. */\n limitExceeded: -32005,\n} as const\n\n// ---- hop 1: page ⇄ content script ----\n\nexport interface PageRequest {\n target: typeof PAGE_TARGET.toContent\n id: string\n chain: RelayChain\n method: string\n params?: unknown\n}\n\nexport interface PageResponse {\n target: typeof PAGE_TARGET.toPage\n id: string\n result?: unknown\n error?: RelayError\n}\n\nexport interface PageEvent {\n target: typeof PAGE_TARGET.toPage\n chain: RelayChain\n event: string\n data?: unknown\n}\n\n// ---- hop 2: content script ⇄ service worker ----\n\nexport interface RelayRequest {\n kind: 'request'\n id: string\n /** `location.origin` of the page, stamped by the content script. */\n origin: string\n chain: RelayChain\n method: string\n params?: unknown\n}\n\nexport interface RelayResponse {\n kind: 'response'\n id: string\n result?: unknown\n error?: RelayError\n}\n\nexport interface RelayEvent {\n kind: 'event'\n chain: RelayChain\n event: string\n data?: unknown\n}\n\nexport type RelayToWorker = RelayRequest\nexport type RelayToContent = RelayResponse | RelayEvent\n\n// ---- guards ----\n\nconst CHAINS: ReadonlySet<string> = new Set<RelayChain>(['eip155', 'solana', 'ton', 'tron', 'bip122', 'near'])\n\nconst isRecord = (x: unknown): x is Record<string, unknown> => typeof x === 'object' && x !== null\nconst isId = (x: unknown): x is string => typeof x === 'string' && x.length > 0 && x.length <= 64\n\nexport function isPageRequest(x: unknown): x is PageRequest {\n return isRecord(x) && x.target === PAGE_TARGET.toContent && isId(x.id) && CHAINS.has(x.chain as string) && typeof x.method === 'string'\n}\n\nexport function isPageResponse(x: unknown): x is PageResponse {\n return isRecord(x) && x.target === PAGE_TARGET.toPage && isId(x.id)\n}\n\nexport function isPageEvent(x: unknown): x is PageEvent {\n return isRecord(x) && x.target === PAGE_TARGET.toPage && !('id' in x) && CHAINS.has(x.chain as string) && typeof x.event === 'string'\n}\n\nexport function isRelayRequest(x: unknown): x is RelayRequest {\n return isRecord(x) && x.kind === 'request' && isId(x.id) && typeof x.origin === 'string' && CHAINS.has(x.chain as string) && typeof x.method === 'string'\n}\n\nexport function isRelayToContent(x: unknown): x is RelayToContent {\n return isRecord(x) && ((x.kind === 'response' && isId(x.id)) || (x.kind === 'event' && typeof x.event === 'string'))\n}\n\nexport function newRequestId(): string {\n return crypto.randomUUID()\n}\n\n/** The content script's stamp: {@link PageRequest} + the page origin. */\nexport function stampOrigin(request: PageRequest, origin: string): RelayRequest {\n const { id, chain, method } = request\n return 'params' in request ? { kind: 'request', id, origin, chain, method, params: request.params } : { kind: 'request', id, origin, chain, method }\n}\n\n/** What `port.sender` looks like (structural `chrome.runtime.MessageSender`). */\nexport interface PortSender {\n origin?: string | undefined\n url?: string | undefined\n tab?: { id?: number | undefined } | undefined\n frameId?: number | undefined\n}\n\n/**\n * The service worker's check before it believes a stamped origin: it must equal the\n * origin the browser recorded for the port. Returns the trusted origin or `null`.\n */\nexport function checkSenderOrigin(sender: PortSender | undefined, stamped: string): string | null {\n const fromSender = sender?.origin ?? (sender?.url ? safeOrigin(sender.url) : undefined)\n if (!fromSender || fromSender === 'null') return null\n return fromSender === stamped ? fromSender : null\n}\n\nfunction safeOrigin(url: string): string | undefined {\n try { return new URL(url).origin } catch { return undefined }\n}\n\nexport const relayError = (code: number, message: string, data?: unknown): RelayError => (data === undefined ? { code, message } : { code, message, data })\n","/**\n * Adapters over the `chrome.*` APIs, typed structurally so this package needs no\n * `@types/chrome` and tests can pass fakes. Promise forms (MV3) only.\n */\nimport type { SessionAlarms, SessionStorage } from './session.js'\nimport type { VaultEnvelope, VaultStorage } from './vault.js'\n\nexport interface StorageAreaLike {\n get(keys: string | string[]): Promise<Record<string, unknown>>\n set(items: Record<string, unknown>): Promise<void>\n remove(keys: string | string[]): Promise<void>\n /** `chrome.storage.session` only. */\n setAccessLevel?(options: { accessLevel: 'TRUSTED_CONTEXTS' | 'TRUSTED_AND_UNTRUSTED_CONTEXTS' }): Promise<void>\n}\n\nexport interface AlarmsLike {\n create(name: string, info: { when: number }): Promise<void> | void\n clear(name: string): Promise<boolean> | boolean | void\n onAlarm: { addListener(callback: (alarm: { name: string }) => void): void }\n}\n\n/** Stable storage key: existing vaults live under it — never rename. */\nexport const VAULT_STORAGE_KEY = 'forgewallet.vault.v1'\n\n/** The encrypted envelope in `chrome.storage.local` (survives browser restarts; ciphertext only). */\nexport function chromeLocalVaultStorage(area: StorageAreaLike, key = VAULT_STORAGE_KEY): VaultStorage {\n return {\n async get() { const r = await area.get(key); return (r[key] as VaultEnvelope | undefined) ?? null },\n async set(envelope) { await area.set({ [key]: envelope }) },\n async clear() { await area.remove(key) },\n }\n}\n\n/**\n * `chrome.storage.session`: memory-only, gone when the browser exits. Access is\n * pinned to trusted contexts (the default; made explicit so a content script can\n * never read the unlocked key even if a later change opens the area to them).\n */\nexport function chromeSessionStorage(area: StorageAreaLike): SessionStorage {\n const ready = area.setAccessLevel ? area.setAccessLevel({ accessLevel: 'TRUSTED_CONTEXTS' }) : Promise.resolve()\n return {\n async get(key) { await ready; return (await area.get(key))[key] },\n async set(key, value) { await ready; await area.set({ [key]: value }) },\n async remove(key) { await ready; await area.remove(key) },\n }\n}\n\n/** `chrome.alarms` as one-shot named alarms. Chrome rounds alarms to ≥ 30 s in packed extensions. */\nexport function chromeAlarms(alarms: AlarmsLike): SessionAlarms {\n return {\n async schedule(name, when) { await alarms.create(name, { when }) },\n async clear(name) { await alarms.clear(name) },\n onFire(handler) { alarms.onAlarm.addListener((alarm) => handler(alarm.name)) },\n }\n}\n","/**\n * `@anywalletkit/keyring` adapters for the extension. The keyring stores public\n * metadata (names, addresses, flags) through `KeyringStorage` and one secret per\n * key source through `SecretStorage`:\n *\n * - {@link chromeKeyringStorage}: the metadata as plain JSON in `chrome.storage.local`;\n * - {@link vaultSecretStorage}: every secret sealed in the {@link Vault} under the\n * DEK the {@link Session} holds. Each call fetches the DEK, uses it once and\n * zeroizes it; a locked session surfaces as `VaultError('locked')`, which the\n * service worker turns into \"unlock first\" for the UI.\n *\n * The keyring's secret strings (JSON with the mnemonic) are immutable JS values\n * and cannot be zeroized; the keyring reads one per operation and drops it, so\n * their lifetime is one call. The byte buffers this module owns are zeroized.\n */\nimport { zeroize } from '@anywalletkit/core'\nimport type { KeyringState, KeyringStorage, SecretStorage } from '@anywalletkit/keyring'\nimport type { StorageAreaLike } from './chrome.js'\nimport { utf8 } from './codec.js'\nimport type { Session } from './session.js'\nimport type { Vault } from './vault.js'\n\n/** Stable storage key: existing keyrings live under it — never rename. */\nexport const KEYRING_STORAGE_KEY = 'forgewallet.keyring.v1'\n\n/** Keyring metadata (no secrets) in `chrome.storage.local`. */\nexport function chromeKeyringStorage(area: StorageAreaLike, key = KEYRING_STORAGE_KEY): KeyringStorage {\n return {\n async load() { const r = await area.get(key); return (r[key] as KeyringState | undefined) ?? null },\n async save(state) { await area.set({ [key]: state }) },\n }\n}\n\n/** Keyring secrets sealed in the vault; readable only while the session is unlocked. */\nexport function vaultSecretStorage(vault: Vault, session: Session): SecretStorage {\n const withKey = async <T>(fn: (dek: Uint8Array) => Promise<T>): Promise<T> => {\n const dek = await session.getKey()\n try { return await fn(dek) } finally { zeroize(dek) }\n }\n return {\n async get(sourceId) {\n return withKey(async (dek) => {\n const bytes = await vault.getSecret(dek, sourceId)\n if (!bytes) return null\n try { return utf8.decode(bytes) } finally { zeroize(bytes) }\n })\n },\n async set(sourceId, secret) {\n const bytes = utf8.encode(secret)\n try { await withKey((dek) => vault.setSecret(dek, sourceId, bytes)) } finally { zeroize(bytes) }\n },\n async delete(sourceId) {\n await vault.deleteSecret(sourceId)\n },\n }\n}\n","/**\n * Default EVM networks for an extension built on this kit: the chains Vaulty's in-app\n * browser can read and sign on, with the same public RPC failover lists\n * (`mobile/lib/swap2.ts`), no API keys. A wallet build may prepend its own\n * endpoints; `wallet_addEthereumChain` may add a chain the asset catalog\n * (`@anywalletkit/swap2-assets`) knows — an unknown chain id is refused, so a\n * site cannot point the wallet at a look-alike network.\n */\nimport { ccChain } from '@anywalletkit/swap2-assets'\nimport { RELAY_ERRORS, relayError, type RelayError } from './relay.js'\nimport type { JsonStorage } from './storage.js'\n\nexport interface EvmNetwork {\n /** CAIP-2, `eip155:<chainId>`. */\n caip2: string\n chainId: number\n name: string\n /** Native currency symbol, 18 decimals on every chain here (on Arc that is the 18-decimal native view of USDC). */\n symbol: string\n /** Tried in order; the client fails over. */\n rpcs: string[]\n explorer?: string\n /** Set when a SITE supplied the RPC list (wallet_addEthereumChain): every sheet on this network says so and simulations are not trusted. */\n custom?: { origin: string; addedAt: number }\n}\n\nexport const DEFAULT_CHAIN = 'eip155:1'\n\nconst net = (chainId: number, name: string, symbol: string, rpcs: string[], explorer?: string): EvmNetwork =>\n explorer === undefined ? { caip2: `eip155:${chainId}`, chainId, name, symbol, rpcs } : { caip2: `eip155:${chainId}`, chainId, name, symbol, rpcs, explorer }\n\nexport const DEFAULT_NETWORKS: readonly EvmNetwork[] = Object.freeze([\n net(1, 'Ethereum', 'ETH', ['https://ethereum-rpc.publicnode.com', 'https://eth.drpc.org'], 'https://etherscan.io'),\n net(8453, 'Base', 'ETH', ['https://base-rpc.publicnode.com', 'https://mainnet.base.org', 'https://base.drpc.org'], 'https://basescan.org'),\n net(56, 'BNB Chain', 'BNB', ['https://bsc-rpc.publicnode.com', 'https://bsc-dataseed.bnbchain.org', 'https://bsc.drpc.org'], 'https://bscscan.com'),\n net(42161, 'Arbitrum', 'ETH', ['https://arbitrum-one-rpc.publicnode.com', 'https://arb1.arbitrum.io/rpc', 'https://arbitrum.drpc.org'], 'https://arbiscan.io'),\n net(10, 'Optimism', 'ETH', ['https://optimism-rpc.publicnode.com', 'https://mainnet.optimism.io', 'https://optimism.drpc.org'], 'https://optimistic.etherscan.io'),\n net(137, 'Polygon', 'POL', ['https://polygon-bor-rpc.publicnode.com', 'https://polygon.drpc.org'], 'https://polygonscan.com'),\n net(43114, 'Avalanche', 'AVAX', ['https://avalanche-c-chain-rpc.publicnode.com', 'https://api.avax.network/ext/bc/C/rpc', 'https://avalanche.drpc.org'], 'https://snowtrace.io'),\n net(999, 'HyperEVM', 'HYPE', ['https://rpc.hyperliquid.xyz/evm', 'https://hyperliquid.drpc.org', 'https://hyperliquid-json-rpc.stakely.io']),\n net(4663, 'Robinhood Chain', 'ETH', ['https://rpc.mainnet.chain.robinhood.com', 'https://robinhood.drpc.org'], 'https://robinhoodchain.blockscout.com'),\n net(324, 'zkSync Era', 'ETH', ['https://mainnet.era.zksync.io', 'https://zksync.drpc.org'], 'https://era.zksync.network'),\n net(42220, 'Celo', 'CELO', ['https://forno.celo.org', 'https://celo.drpc.org'], 'https://celoscan.io'),\n net(4326, 'MegaETH', 'ETH', ['https://mainnet.megaeth.com/rpc']),\n net(130, 'Unichain', 'ETH', ['https://mainnet.unichain.org', 'https://unichain-rpc.publicnode.com'], 'https://uniscan.xyz'),\n net(143, 'Monad', 'MON', ['https://rpc.monad.xyz']),\n net(9745, 'Plasma', 'XPL', ['https://rpc.plasma.to']),\n net(59144, 'Linea', 'ETH', ['https://rpc.linea.build', 'https://linea-rpc.publicnode.com'], 'https://lineascan.build'),\n net(100, 'Gnosis', 'xDAI', ['https://rpc.gnosischain.com', 'https://gnosis-rpc.publicnode.com'], 'https://gnosisscan.io'),\n net(146, 'Sonic', 'S', ['https://rpc.soniclabs.com', 'https://sonic-rpc.publicnode.com'], 'https://sonicscan.org'),\n net(480, 'World Chain', 'ETH', ['https://worldchain-mainnet.g.alchemy.com/public', 'https://worldchain-mainnet.gateway.tenderly.co'], 'https://worldscan.org'),\n net(1329, 'Sei', 'SEI', ['https://evm-rpc.sei-apis.com'], 'https://seitrace.com'),\n net(57073, 'Ink', 'ETH', ['https://rpc-gel.inkonchain.com'], 'https://explorer.inkonchain.com'),\n net(98866, 'Plume', 'PLUME', ['https://rpc.plume.org'], 'https://explorer.plume.org'),\n net(196, 'X Layer', 'OKB', ['https://rpc.xlayer.tech', 'https://xlayerrpc.okx.com'], 'https://www.okx.com/web3/explorer/xlayer'),\n net(534352, 'Scroll', 'ETH', ['https://rpc.scroll.io', 'https://scroll-rpc.publicnode.com'], 'https://scrollscan.com'),\n net(80094, 'Berachain', 'BERA', ['https://rpc.berachain.com', 'https://berachain-rpc.publicnode.com'], 'https://berascan.com'),\n // Arc (Circle's L1): the gas token is USDC. eth_getBalance / msg.value / gas are accounted in 18-decimal units (the\n // `symbol` here names that native view); the ERC-20 interface at 0x3600…0000 reads the SAME balance in 6 decimals\n // and is what the catalog, LI.FI and CCTP address (see swap2-assets). Balances must show one view, not both.\n net(5042, 'Arc', 'USDC', ['https://rpc.mainnet.arc.io'], 'https://explorer.arc.io'),\n net(5000, 'Mantle', 'MNT', ['https://rpc.mantle.xyz', 'https://mantle-rpc.publicnode.com'], 'https://mantlescan.xyz'),\n net(747474, 'Katana', 'ETH', ['https://rpc.katana.network'], 'https://explorer.katanarpc.com'),\n net(2818, 'Morph', 'ETH', ['https://rpc.morphl2.io', 'https://rpc-quicknode.morphl2.io'], 'https://explorer.morphl2.io'),\n net(14, 'Flare', 'FLR', ['https://flare-api.flare.network/ext/C/rpc', 'https://flare.rpc.thirdweb.com'], 'https://flare-explorer.flare.network'),\n])\n\nexport const chainHex = (caip2: string): string => `0x${Number(caip2.split(':')[1]).toString(16)}`\n\n/** `0x1` / `1` → `eip155:1`; `null` for anything that is not a positive integer chain id. */\nexport function caip2FromChainId(value: unknown): string | null {\n let n: number\n if (typeof value === 'string') {\n const s = value.trim()\n if (/^0x[0-9a-f]+$/i.test(s)) n = Number.parseInt(s, 16)\n else if (/^[0-9]+$/.test(s)) n = Number.parseInt(s, 10)\n else return null\n } else if (typeof value === 'number') n = value\n else return null\n return Number.isSafeInteger(n) && n > 0 ? `eip155:${n}` : null\n}\n\n/** Whether the asset catalog knows this chain — the gate for `wallet_addEthereumChain`. */\nexport function isCatalogChain(caip2: string): boolean {\n return ccChain(caip2) !== undefined\n}\n\n/**\n * Shipped networks plus the ones the user accepted from sites, persisted. Lookup\n * by CAIP-2; a custom entry for a shipped chain is ignored (the build's RPC list\n * wins — a site must not be able to replace Ethereum's endpoints).\n */\nexport class NetworksTable {\n private _custom: EvmNetwork[] | null = null\n private _loading: Promise<EvmNetwork[]> | null = null\n /** add/remove run one after another (scan F22, as PermissionStore). */\n private _queue: Promise<unknown> = Promise.resolve()\n\n constructor(private readonly storage: JsonStorage<EvmNetwork[]>, private readonly defaults: readonly EvmNetwork[] = DEFAULT_NETWORKS) {}\n\n async list(): Promise<EvmNetwork[]> {\n return [...this.defaults, ...(await this.custom())]\n }\n\n async get(caip2: string): Promise<EvmNetwork | null> {\n return this.defaults.find((n) => n.caip2 === caip2) ?? (await this.custom()).find((n) => n.caip2 === caip2) ?? null\n }\n\n add(network: EvmNetwork): Promise<void> {\n return this.serialize(async () => {\n if (this.defaults.some((n) => n.caip2 === network.caip2)) return\n const custom = (await this.custom()).filter((n) => n.caip2 !== network.caip2)\n custom.push(network)\n await this.write(custom)\n })\n }\n\n remove(caip2: string): Promise<void> {\n return this.serialize(async () => {\n const current = await this.custom()\n if (!current.some((n) => n.caip2 === caip2)) return\n await this.write(current.filter((n) => n.caip2 !== caip2))\n })\n }\n\n private serialize<T>(fn: () => Promise<T>): Promise<T> {\n const run = this._queue.then(fn, fn)\n this._queue = run.then(() => undefined, () => undefined)\n return run\n }\n\n /** Cache first (readers see it at once), rolled back when storage refuses. */\n private async write(custom: EvmNetwork[]): Promise<void> {\n const prev = await this.custom()\n this._custom = custom\n try {\n await this.storage.set(custom)\n } catch (e) {\n if (this._custom === custom) this._custom = prev\n throw e\n }\n }\n\n private async custom(): Promise<EvmNetwork[]> {\n if (this._custom) return this._custom\n this._loading ??= this.storage.get().then(\n (s) => (this._custom ??= s ?? []),\n (e: unknown) => { this._loading = null; throw e },\n )\n return this._loading\n }\n}\n\n/**\n * EIP-3085 `wallet_addEthereumChain` parameter → {@link EvmNetwork}, or the error\n * to answer with. https RPC urls only; the chain id must be in the catalog.\n */\nexport function parseAddChainParams(params: unknown, known: (caip2: string) => boolean = isCatalogChain): EvmNetwork | RelayError {\n const p = (Array.isArray(params) ? params[0] : params) as Record<string, unknown> | undefined\n if (!p || typeof p !== 'object') return relayError(RELAY_ERRORS.invalidParams, 'wallet_addEthereumChain expects one object parameter.')\n const caip2 = caip2FromChainId(p.chainId)\n if (!caip2) return relayError(RELAY_ERRORS.invalidParams, 'chainId must be a 0x-prefixed hex string.')\n if (!known(caip2)) return relayError(RELAY_ERRORS.chainNotAdded, `Chain ${String(p.chainId)} is not in this wallet's catalog.`)\n const rpcs = Array.isArray(p.rpcUrls) ? p.rpcUrls.filter((u): u is string => typeof u === 'string' && /^https:\\/\\/[^\\s/?#]+/i.test(u)) : []\n if (rpcs.length === 0) return relayError(RELAY_ERRORS.invalidParams, 'rpcUrls must contain at least one https URL.')\n const name = typeof p.chainName === 'string' && p.chainName.trim() ? p.chainName.trim().slice(0, 64) : caip2\n const currency = p.nativeCurrency as { symbol?: unknown; decimals?: unknown } | undefined\n if (currency && currency.decimals !== undefined && currency.decimals !== 18) return relayError(RELAY_ERRORS.invalidParams, 'nativeCurrency.decimals must be 18.')\n const symbol = typeof currency?.symbol === 'string' && /^[A-Za-z0-9]{1,12}$/.test(currency.symbol) ? currency.symbol : 'ETH'\n const explorers = Array.isArray(p.blockExplorerUrls) ? p.blockExplorerUrls.filter((u): u is string => typeof u === 'string' && /^https:\\/\\//i.test(u)) : []\n const network: EvmNetwork = { caip2, chainId: Number(caip2.split(':')[1]), name, symbol, rpcs }\n return explorers[0] ? { ...network, explorer: explorers[0] } : network\n}\n\n// ---- non-EVM chains: the CAIP-2 ids the asset catalog / swap2 engine use, and public endpoints only (Vaulty's lists minus its proxies) ----\n\n/** Solana mainnet as the catalog names it (`solana:mainnet`); the wallet package also accepts the genesis-hash form. */\nexport const SOLANA_CHAIN = 'solana:mainnet'\nexport const SOLANA_RPCS: readonly string[] = Object.freeze(['https://solana-rpc.publicnode.com', 'https://api.mainnet-beta.solana.com'])\nexport const TON_CHAIN = 'ton:-239'\nexport const TON_ENDPOINTS: readonly string[] = Object.freeze(['https://ton.access.orbs.network/1/mainnet/toncenter-api-v2/jsonRPC', 'https://toncenter.com/api/v2/jsonRPC'])\nexport const TRON_CHAIN = 'tron:728126428'\nexport const TRON_PROVIDERS: readonly string[] = Object.freeze(['https://api.trongrid.io'])\nexport const BTC_CHAIN = 'bitcoin:mainnet'\nexport const BTC_ESPLORA: readonly string[] = Object.freeze(['https://mempool.space/api', 'https://blockstream.info/api'])\nexport const NEAR_CHAIN = 'near:mainnet'\nexport const NEAR_PROVIDERS: readonly string[] = Object.freeze(['https://free.rpc.fastnear.com', 'https://rpc.mainnet.near.org'])\n/** Zcash transparent (t1…) accounts over Blockchair's public API, as `@anywalletkit/wallet-zcash` reads and broadcasts them. */\nexport const ZCASH_CHAIN = 'zcash:mainnet'\nexport const ZCASH_BLOCKCHAIR = 'https://api.blockchair.com/zcash'\n\nexport interface ChainDescriptor {\n caip2: string\n key: 'solana' | 'ton' | 'tron' | 'btc' | 'near' | 'zcash'\n name: string\n symbol: string\n decimals: number\n explorerTx: string\n explorerAddress: string\n}\n\nexport const NON_EVM_CHAINS: readonly ChainDescriptor[] = Object.freeze([\n { caip2: SOLANA_CHAIN, key: 'solana', name: 'Solana', symbol: 'SOL', decimals: 9, explorerTx: 'https://solscan.io/tx/', explorerAddress: 'https://solscan.io/account/' },\n { caip2: TON_CHAIN, key: 'ton', name: 'TON', symbol: 'GRAM', decimals: 9, explorerTx: 'https://tonviewer.com/transaction/', explorerAddress: 'https://tonviewer.com/' },\n { caip2: TRON_CHAIN, key: 'tron', name: 'Tron', symbol: 'TRX', decimals: 6, explorerTx: 'https://tronscan.org/#/transaction/', explorerAddress: 'https://tronscan.org/#/address/' },\n { caip2: BTC_CHAIN, key: 'btc', name: 'Bitcoin', symbol: 'BTC', decimals: 8, explorerTx: 'https://mempool.space/tx/', explorerAddress: 'https://mempool.space/address/' },\n { caip2: NEAR_CHAIN, key: 'near', name: 'NEAR', symbol: 'NEAR', decimals: 24, explorerTx: 'https://nearblocks.io/txns/', explorerAddress: 'https://nearblocks.io/address/' },\n { caip2: ZCASH_CHAIN, key: 'zcash', name: 'Zcash', symbol: 'ZEC', decimals: 8, explorerTx: 'https://blockchair.com/zcash/transaction/', explorerAddress: 'https://blockchair.com/zcash/address/' },\n])\n\nexport const nonEvmChain = (caip2: string): ChainDescriptor | undefined => NON_EVM_CHAINS.find((c) => c.caip2 === caip2)\n","import type { StorageAreaLike } from './chrome.js'\n\n/** One JSON value under one key — the shape every small store here needs. */\nexport interface JsonStorage<T> {\n get(): Promise<T | null>\n set(value: T): Promise<void>\n}\n\nexport function chromeJsonStorage<T>(area: StorageAreaLike, key: string): JsonStorage<T> {\n return {\n async get() { return ((await area.get(key))[key] as T | undefined) ?? null },\n async set(value) { await area.set({ [key]: value }) },\n }\n}\n\nexport function memoryJsonStorage<T>(initial: T | null = null): JsonStorage<T> & { value: T | null } {\n const s = {\n value: initial,\n async get() { return s.value === null ? null : structuredClone(s.value) },\n async set(value: T) { s.value = structuredClone(value) },\n }\n return s\n}\n","/**\n * Per-origin permissions: which accounts a site may see and which chain it is\n * on. Nothing here is secret (`chrome.storage.local`, plain JSON); the origin\n * key is the one the browser recorded for the port, never the page's claim.\n */\nimport type { JsonStorage } from './storage.js'\n\nexport interface OriginPermission {\n origin: string\n /** EVM addresses exposed to this origin (checksummed as the keyring stores them). Empty when only another chain is connected. */\n accounts: string[]\n /** CAIP-2 chain the origin currently sees (`eth_chainId`). */\n chain: string\n /** Solana addresses exposed to this origin (Wallet Standard `standard:connect`). */\n solanaAccounts?: string[]\n /** TON addresses exposed to this origin (TON Connect). */\n tonAccounts?: string[]\n /** Tron (TIP-1193), Bitcoin (sats-connect) and NEAR (wallet-selector) addresses. */\n tronAccounts?: string[]\n btcAccounts?: string[]\n nearAccounts?: string[]\n connectedAt: number\n}\n\nexport type PermissionsState = Record<string, OriginPermission>\n\nexport type ChainAccountsKey = 'solanaAccounts' | 'tonAccounts' | 'tronAccounts' | 'btcAccounts' | 'nearAccounts'\nexport const CHAIN_ACCOUNT_KEYS: readonly ChainAccountsKey[] = ['solanaAccounts', 'tonAccounts', 'tronAccounts', 'btcAccounts', 'nearAccounts']\n\nexport class PermissionStore {\n private _state: PermissionsState | null = null\n private _loading: Promise<PermissionsState> | null = null\n /** Every mutation runs here, one after another (scan F22): a read-modify-write never starts from a snapshot another one is about to replace. */\n private _queue: Promise<unknown> = Promise.resolve()\n private readonly _listeners = new Set<(origin: string, permission: OriginPermission | null) => void>()\n\n constructor(private readonly storage: JsonStorage<PermissionsState>) {}\n\n private async state(): Promise<PermissionsState> {\n if (this._state) return this._state\n // One load; a load that resolves after a write must not replace the newer cache.\n this._loading ??= this.storage.get().then(\n (s) => (this._state ??= s ?? {}),\n (e: unknown) => { this._loading = null; throw e },\n )\n return this._loading\n }\n\n /**\n * Run `fn` after every earlier mutation settled. Public mutators wrap their WHOLE read-modify-write\n * in this; `write` itself is unlocked (setAccountsEverywhere calls it in a loop — a lock there too\n * would deadlock). Nothing awaited inside may wait on the user: routers await the approval sheet\n * first and only then call the store.\n */\n private serialize<T>(fn: () => Promise<T>): Promise<T> {\n const run = this._queue.then(fn, fn)\n this._queue = run.then(() => undefined, () => undefined)\n return run\n }\n\n async get(origin: string): Promise<OriginPermission | null> {\n return (await this.state())[origin] ?? null\n }\n\n async list(): Promise<OriginPermission[]> {\n return Object.values(await this.state())\n }\n\n connect(origin: string, accounts: string[], chain: string): Promise<OriginPermission> {\n return this.serialize(async () => {\n if (accounts.length === 0) throw new Error('Connect at least one account.')\n const current = await this.get(origin)\n const permission: OriginPermission = { ...(current ?? {}), origin, accounts: [...accounts], chain, connectedAt: current?.connectedAt ?? Date.now() }\n await this.write(origin, permission)\n return permission\n })\n }\n\n /** Connect another chain's accounts to the same origin (one \"connected sites\" list). */\n connectChain(origin: string, key: ChainAccountsKey, accounts: string[], defaultChain: string): Promise<OriginPermission> {\n return this.serialize(async () => {\n if (accounts.length === 0) throw new Error('Connect at least one account.')\n const current = await this.get(origin)\n const permission: OriginPermission = { origin, accounts: current?.accounts ?? [], chain: current?.chain ?? defaultChain, ...(current ?? {}), [key]: [...accounts], connectedAt: current?.connectedAt ?? Date.now() }\n await this.write(origin, permission)\n return permission\n })\n }\n\n /** Drop one chain's accounts; the origin stays connected while any chain remains. A no-op (no write) when there is nothing to drop. */\n disconnectChain(origin: string, key: 'accounts' | ChainAccountsKey): Promise<void> {\n return this.serialize(async () => {\n const current = await this.get(origin)\n if (!current) return\n if (key === 'accounts' ? current.accounts.length === 0 : current[key] === undefined) return\n const next: OriginPermission = { ...current, [key]: key === 'accounts' ? [] : undefined }\n if (key !== 'accounts') delete next[key]\n const anything = next.accounts.length > 0 || CHAIN_ACCOUNT_KEYS.some((k) => (next[k]?.length ?? 0) > 0)\n await this.write(origin, anything ? next : null)\n })\n }\n\n setChain(origin: string, chain: string): Promise<OriginPermission | null> {\n return this.serialize(async () => {\n const current = await this.get(origin)\n if (!current) return null\n const next = { ...current, chain }\n await this.write(origin, next)\n return next\n })\n }\n\n /**\n * The active EVM account changed: every origin holding an EVM grant now sees `accounts` (MetaMask behaviour).\n * An origin connected only on another chain (`accounts: []` — Solana/TON/Tron/BTC/NEAR providers, a WalletConnect\n * session without eip155) is skipped: it never passed an EVM connect and must not learn the EVM address (scan F6/F8).\n * Lock never writes `[]` here, so the skip cannot strip a real EVM grant.\n */\n setAccountsEverywhere(accounts: string[]): Promise<OriginPermission[]> {\n return this.serialize(async () => {\n const changed: OriginPermission[] = []\n for (const p of await this.list()) {\n if (p.accounts.length === 0 || sameList(p.accounts, accounts)) continue\n const next = { ...p, accounts: [...accounts] }\n await this.write(p.origin, next)\n changed.push(next)\n }\n return changed\n })\n }\n\n disconnect(origin: string): Promise<void> {\n return this.serialize(async () => {\n if (!(await this.get(origin))) return\n await this.write(origin, null)\n })\n }\n\n onChange(listener: (origin: string, permission: OriginPermission | null) => void): () => void {\n this._listeners.add(listener)\n return () => this._listeners.delete(listener)\n }\n\n /** Unlocked: callers hold the queue. The cache changes before the await (readers see it at once) and is rolled back when storage refuses. */\n private async write(origin: string, permission: OriginPermission | null): Promise<void> {\n const prev = await this.state()\n const state = { ...prev }\n if (permission) state[origin] = permission\n else delete state[origin]\n this._state = state\n try {\n await this.storage.set(state)\n } catch (e) {\n if (this._state === state) this._state = prev\n throw e\n }\n for (const l of this._listeners) l(origin, permission)\n }\n}\n\nconst sameList = (a: string[], b: string[]) => a.length === b.length && a.every((x, i) => x === b[i])\n","/**\n * The approval queue — Vaulty's `txGate` (mobile/lib/txGate.ts) for an\n * extension. A dApp request that needs the user waits here; ONE approval window\n * is open at a time (`chrome.windows.create({ type: 'popup' })`), the next\n * request opens when the current one is answered. The window losing focus\n * changes nothing: the request stays pending. Closing the window, or declining,\n * rejects with {@link ReviewDeclined} — EIP-1193 4001, \"nothing was signed\".\n *\n * The queue lives in the service worker's memory: an open approval window keeps\n * the worker alive, and if the worker is nevertheless restarted the pending\n * promises die with it — the page gets no answer and retries, which is the\n * failure mode MetaMask has too.\n *\n * Two limits keep a page from burying one real request under decoys (SDK-142 M3):\n * at most `maxPendingPerOrigin` requests wait per origin (-32005), and a second\n * `connect` while one is pending is refused outright (-32002).\n *\n * An origin can carry a transport note (`via`, set by the WalletConnect bridge):\n * the sheet then says the request came over WalletConnect, what the dApp claims\n * to be and what WalletConnect Verify says about that claim — the claim itself is\n * never used as the permission key.\n */\nimport { RELAY_ERRORS } from './relay.js'\n\nexport class ReviewDeclined extends Error {\n readonly code = RELAY_ERRORS.userRejected\n constructor(message = 'You declined — nothing was signed.') {\n super(message)\n this.name = 'ReviewDeclined'\n }\n}\n\nexport type ApprovalKind = 'connect' | 'switch-chain' | 'add-chain' | 'sign-message' | 'sign-typed-data' | 'send-transaction' | 'solana-send' | 'swap' | 'earn' | 'chain-send' | 'tron-sign' | 'btc-sign' | 'near-sign' | 'near-signin' | 'wc-session'\n\n/** How a request reached the wallet when it did not come through a content script. */\nexport interface OriginVia {\n transport: 'walletconnect'\n /** What the dApp declared about itself (self-reported, unverified unless `verify` says so). */\n url: string\n name: string\n /** WalletConnect Verify: VALID = the relay saw the request come from `url`'s origin; INVALID = it came from somewhere else; UNKNOWN = not attested. */\n verify: 'VALID' | 'INVALID' | 'UNKNOWN'\n scam?: boolean\n}\n\n/** The queue refused to enqueue (per-origin limits); carries an EIP-1474 code the page understands. */\nexport class QueueLimitError extends Error {\n constructor(readonly code: number, message: string) {\n super(message)\n this.name = 'QueueLimitError'\n }\n}\n\nexport const APPROVALS_MAX_PENDING_PER_ORIGIN = 3\n\nexport interface ApprovalRequest<P = unknown> {\n id: string\n origin: string\n chain: string\n kind: ApprovalKind\n /** What the window shows; shape per kind, public data only. */\n payload: P\n createdAt: number\n /** Phishing / lookalike / punycode notes about the origin, from the queue's `annotate` hook. */\n originWarnings?: string[]\n /** Set when the origin is a transport pseudo-origin (`wc:<topic>`): what the sheet should say about where this came from. */\n via?: OriginVia\n}\n\nexport interface ApprovalQueueOptions {\n /** Called for every request's origin; the lines are shown on the sheet (e.g. the shipped phishing list's verdict). */\n annotate?: (origin: string) => string[]\n /** Requests one origin may have waiting (current + queued). Default {@link APPROVALS_MAX_PENDING_PER_ORIGIN}. */\n maxPendingPerOrigin?: number\n}\n\n/** The window side: open for one request, close when it is answered. `memoryApprovalWindow()` for tests. */\nexport interface ApprovalWindow {\n open(request: ApprovalRequest): Promise<void>\n close(requestId: string): Promise<void>\n /** The user closed the window themself (chrome.windows.onRemoved): the queue declines the request. */\n onClosed(handler: (requestId: string) => void): void\n}\n\ninterface Pending<T = unknown> {\n request: ApprovalRequest\n resolve: (value: T) => void\n reject: (error: Error) => void\n}\n\nexport class ApprovalQueue {\n private _current: Pending | null = null\n private readonly _waiting: Pending[] = []\n private readonly _listeners = new Set<() => void>()\n private readonly _via = new Map<string, OriginVia>()\n\n constructor(private readonly window: ApprovalWindow, private readonly newId: () => string = () => crypto.randomUUID(), private readonly options: ApprovalQueueOptions = {}) {\n window.onClosed((id) => { if (this._current?.request.id === id) this.decline(id) })\n }\n\n /** Enqueue and wait for the user's answer. Refuses (never queues) past the per-origin limits. */\n request<T = unknown>(input: Omit<ApprovalRequest, 'id' | 'createdAt' | 'originWarnings' | 'via'>): Promise<T> {\n const sameOrigin = [...(this._current ? [this._current] : []), ...this._waiting].filter((p) => p.request.origin === input.origin)\n if (input.kind === 'connect' && sameOrigin.some((p) => p.request.kind === 'connect')) {\n return Promise.reject(new QueueLimitError(RELAY_ERRORS.resourceUnavailable, 'A connect request from this site is already waiting for your answer.'))\n }\n const max = this.options.maxPendingPerOrigin ?? APPROVALS_MAX_PENDING_PER_ORIGIN\n if (sameOrigin.length >= max) {\n return Promise.reject(new QueueLimitError(RELAY_ERRORS.limitExceeded, `This site already has ${max} requests waiting for you; answer or close them first.`))\n }\n return new Promise<T>((resolve, reject) => {\n const warnings = this.options.annotate?.(input.origin) ?? []\n const via = this._via.get(input.origin)\n const pending: Pending = { request: { ...input, id: this.newId(), createdAt: Date.now(), ...(warnings.length ? { originWarnings: warnings } : {}), ...(via ? { via } : {}) }, resolve: resolve as (v: unknown) => void, reject }\n this._waiting.push(pending)\n void this.next()\n })\n }\n\n /** Attach (or clear) the transport note every later request from `origin` carries. */\n setVia(origin: string, via: OriginVia | null): void {\n if (via) this._via.set(origin, via)\n else this._via.delete(origin)\n }\n\n /** The transport note later requests from `origin` carry (WalletConnect Verify's verdict for `wc:<topic>`), if any. */\n viaFor(origin: string): OriginVia | undefined {\n return this._via.get(origin)\n }\n\n /** Requests waiting for `origin` (current + queued). */\n pendingFor(origin: string): number {\n return [...(this._current ? [this._current] : []), ...this._waiting].filter((p) => p.request.origin === origin).length\n }\n\n /** The request currently shown (the window asks for it by id on load). */\n get current(): ApprovalRequest | null {\n return this._current?.request ?? null\n }\n\n get queued(): number {\n return this._waiting.length\n }\n\n resolve(requestId: string, value: unknown): boolean {\n return this.settle(requestId, (p) => p.resolve(value))\n }\n\n decline(requestId: string, error: Error = new ReviewDeclined()): boolean {\n return this.settle(requestId, (p) => p.reject(error))\n }\n\n /** Lock, disconnect, shutdown: everything pending is declined. */\n declineAll(error: Error = new ReviewDeclined('The wallet was locked.')): void {\n const all = [...(this._current ? [this._current] : []), ...this._waiting.splice(0)]\n for (const p of all) p.reject(error)\n if (this._current) void this.window.close(this._current.request.id)\n this._current = null\n this.emit()\n }\n\n onChange(listener: () => void): () => void {\n this._listeners.add(listener)\n return () => this._listeners.delete(listener)\n }\n\n private settle(requestId: string, fn: (p: Pending) => void): boolean {\n if (this._current?.request.id === requestId) {\n const p = this._current\n this._current = null\n fn(p)\n void this.window.close(requestId).catch(() => undefined)\n this.emit()\n void this.next()\n return true\n }\n const i = this._waiting.findIndex((p) => p.request.id === requestId)\n if (i < 0) return false\n fn(this._waiting.splice(i, 1)[0]!)\n this.emit()\n return true\n }\n\n private async next(): Promise<void> {\n if (this._current || this._waiting.length === 0) return\n const p = this._waiting.shift()!\n this._current = p\n this.emit()\n try {\n await this.window.open(p.request)\n } catch (e) {\n if (this._current === p) {\n this._current = null\n p.reject(e instanceof Error ? e : new Error(String(e)))\n this.emit()\n void this.next()\n }\n }\n }\n\n private emit(): void {\n for (const l of this._listeners) l()\n }\n}\n\n/** In-memory window: tests answer through the queue; `opened` records every request shown. */\nexport function memoryApprovalWindow(): ApprovalWindow & { opened: ApprovalRequest[]; openIds: Set<string>; userClose(id: string): void } {\n let handler: (id: string) => void = () => undefined\n const w = {\n opened: [] as ApprovalRequest[],\n openIds: new Set<string>(),\n async open(request: ApprovalRequest) { w.opened.push(request); w.openIds.add(request.id) },\n async close(id: string) { w.openIds.delete(id) },\n onClosed(h: (id: string) => void) { handler = h },\n userClose(id: string) { w.openIds.delete(id); handler(id) },\n }\n return w\n}\n","/**\n * The request router: what a dApp may ask and what happens to each request.\n * Policy ported from Vaulty's in-app browser (`mobile/lib/browser.ts`):\n *\n * - the origin is the browser's (checked by the service worker before this runs);\n * - accounts are exposed only to origins the user connected (`eth_requestAccounts`\n * → approval window); `eth_accounts` is `[]` otherwise;\n * - chain switching and adding go through the approval window; a chain can be\n * added only if the asset catalog knows it, with https RPCs;\n * - read-only JSON-RPC is answered from the wallet's own clients (the networks\n * table's failover list), never from a URL the page names;\n * - `eth_sign` (blind hash signing) is never offered; the other signing methods\n * go to the `sign` hook (the review flow) when the wallet provides one;\n * - everything else is refused with 4200.\n *\n * Errors leave as {@link RouterError} (EIP-1193 codes) or {@link ReviewDeclined}\n * (4001); the service worker turns both into a `RelayResponse.error`.\n */\nimport { UserRejectedError } from '@anywalletkit/core'\nimport { ApprovalQueue, ReviewDeclined } from './approvals.js'\nimport { DEFAULT_CHAIN, NetworksTable, caip2FromChainId, chainHex, parseAddChainParams, type EvmNetwork } from './networks.js'\nimport { PermissionStore, type OriginPermission } from './permissions.js'\nimport { RELAY_ERRORS, type RelayChain, type RelayError } from './relay.js'\n\nexport class RouterError extends Error {\n readonly code: number\n readonly data: unknown\n constructor(code: number, message: string, data?: unknown) {\n super(message)\n this.name = 'RouterError'\n this.code = code\n this.data = data\n }\n static from(e: RelayError): RouterError {\n return new RouterError(e.code, e.message, e.data)\n }\n}\n\n/** Options for {@link toRelayError}. */\nexport interface RelayErrorOptions {\n /** Gets every error that is NOT passed to the page, in full — the extension's own log. */\n log?: (error: unknown) => void\n}\n\n/** EIP-1193 provider codes a wallet error may carry to the page. */\nconst PROVIDER_CODES: ReadonlySet<number> = new Set([4001, 4100, 4200, 4900, 4901, 4902])\n/** A node's JSON-RPC error: execution reverted (3) or the reserved -32768…-32000 range. */\nconst isNodeCode = (code: unknown): code is number => typeof code === 'number' && Number.isInteger(code) && (code === 3 || (code >= -32768 && code <= -32000))\nconst URL_RE = /\\b[a-z][a-z0-9+.-]*:\\/\\/[^\\s\"'<>()]+/gi\n/** A message as a page may see it: no URLs (RPC keys live in their paths and queries), one line, bounded. */\nconst pageText = (text: string): string => text.replace(URL_RE, '[url]').split('\\n')[0]!.slice(0, 300)\nconst isHexData = (v: unknown): v is string => typeof v === 'string' && /^0x[0-9a-fA-F]*$/.test(v) && v.length <= 2 + 2 * 8192\n\n/**\n * The node's own JSON-RPC error inside `e`, if there is one: viem's `RpcRequestError` (alone or\n * under a typed RPC error) carries the node's code, message (`details`) and data, while its\n * `message` adds the URL and the request body; a fetch-based transport may throw the bare\n * `{code, message, data}` object.\n */\nfunction nodeError(e: unknown): RelayError | undefined {\n for (let cur: unknown = e, depth = 0; cur && typeof cur === 'object' && depth < 8; cur = (cur as { cause?: unknown }).cause, depth++) {\n const o = cur as { name?: unknown; code?: unknown; details?: unknown; shortMessage?: unknown; message?: unknown; data?: unknown }\n if (o.name === 'RpcRequestError' && isNodeCode(o.code)) {\n const text = typeof o.details === 'string' && o.details ? o.details : typeof o.shortMessage === 'string' ? o.shortMessage : 'RPC error'\n return { code: o.code, message: pageText(text), ...(isHexData(o.data) ? { data: o.data } : {}) }\n }\n }\n if (!(e instanceof Error) && typeof e === 'object' && e !== null) {\n const o = e as { code?: unknown; message?: unknown; data?: unknown }\n if (isNodeCode(o.code) && typeof o.message === 'string') return { code: o.code, message: pageText(o.message), ...(isHexData(o.data) ? { data: o.data } : {}) }\n }\n return undefined\n}\n\n/**\n * Any error → the `RelayError` for the page. Wallet refusals keep their EIP-1193 code\n * ({@link RouterError}, {@link ReviewDeclined}, a core `UserRejectedError` → 4001), a node's own\n * JSON-RPC error keeps its code and revert data; their messages lose URLs. Everything else is\n * `-32603 Internal error` on the page and goes to `options.log` in full — transport errors name\n * the RPC URL (often with the provider key in it) and the request.\n */\nexport function toRelayError(e: unknown, options: RelayErrorOptions = {}): RelayError {\n if (e instanceof RouterError) return e.data === undefined ? { code: e.code, message: pageText(e.message) } : { code: e.code, message: pageText(e.message), data: e.data }\n if (e instanceof ReviewDeclined) return { code: e.code, message: pageText(e.message) }\n if (e instanceof UserRejectedError) return { code: RELAY_ERRORS.userRejected, message: pageText(e.message) }\n const node = nodeError(e)\n if (node) return node\n const code = (e as { code?: unknown } | null)?.code\n if (e instanceof Error && typeof code === 'number' && PROVIDER_CODES.has(code)) return { code, message: pageText(e.message) }\n options.log?.(e)\n return { code: RELAY_ERRORS.internal, message: 'Internal error' }\n}\n\n/** Read-only methods answered from our RPC without asking the user. */\nexport const READ_METHODS: ReadonlySet<string> = new Set([\n 'eth_blockNumber', 'eth_call', 'eth_estimateGas', 'eth_feeHistory', 'eth_gasPrice', 'eth_getBalance',\n 'eth_getBlockByHash', 'eth_getBlockByNumber', 'eth_getCode', 'eth_getLogs', 'eth_getStorageAt',\n 'eth_getTransactionByHash', 'eth_getTransactionCount', 'eth_getTransactionReceipt', 'eth_maxPriorityFeePerGas',\n])\n\n/** Methods that produce a signature — the review flow's business (step 4), never answered here. */\nexport const SIGNING_METHODS: ReadonlySet<string> = new Set(['personal_sign', 'eth_signTypedData_v4', 'eth_signTypedData_v3', 'eth_signTypedData', 'eth_sendTransaction'])\n\nexport interface ConnectApproval {\n /** Addresses the wallet can expose, active account first (empty while locked — the window unlocks first and reloads). */\n accounts: string[]\n}\nexport interface SwitchChainApproval {\n from: EvmNetwork | null\n to: EvmNetwork\n}\nexport interface AddChainApproval {\n network: EvmNetwork\n}\n\nexport interface RouterDeps {\n permissions: PermissionStore\n networks: NetworksTable\n approvals: ApprovalQueue\n /** EVM addresses the wallet exposes, active account first. Empty when locked or without a wallet. */\n accounts(): Promise<string[]>\n /** Read-only JSON-RPC over the network's own RPC list. */\n rpc(network: EvmNetwork, method: string, params: unknown[]): Promise<unknown>\n /** Push an EIP-1193 event to every page of `origin`. */\n emit(origin: string, event: string, data: unknown): void\n /** The review flow for signing methods. Absent → 4200. */\n sign?(input: { origin: string; network: EvmNetwork; method: string; params: unknown[]; accounts: string[] }): Promise<unknown>\n defaultChain?: string\n}\n\nexport class RequestRouter {\n constructor(private readonly deps: RouterDeps) {}\n\n /** The chain an origin currently sees (its permission's, else the default). */\n async chainFor(origin: string): Promise<EvmNetwork> {\n const permission = await this.deps.permissions.get(origin)\n const wanted = permission?.chain ?? this.deps.defaultChain ?? DEFAULT_CHAIN\n return (await this.deps.networks.get(wanted)) ?? (await this.deps.networks.get(DEFAULT_CHAIN))!\n }\n\n async handle(origin: string, chain: RelayChain, method: string, rawParams: unknown): Promise<unknown> {\n if (chain !== 'eip155') throw new RouterError(RELAY_ERRORS.unsupportedMethod, `${chain} providers are not available yet.`)\n const params = Array.isArray(rawParams) ? rawParams : rawParams === undefined ? [] : [rawParams]\n const network = await this.chainFor(origin)\n const permission = await this.deps.permissions.get(origin)\n\n switch (method) {\n case 'eth_chainId':\n return chainHex(network.caip2)\n case 'net_version':\n return String(network.chainId)\n case 'eth_accounts':\n return this.visibleAccounts(permission)\n case 'eth_requestAccounts':\n return this.connect(origin, network)\n case 'wallet_getPermissions':\n // An origin connected only on another chain holds no EVM permission (scan F6/F8).\n return permission && permission.accounts.length > 0 ? [permissionDescriptor(origin, permission.accounts)] : []\n case 'wallet_requestPermissions': {\n const accounts = await this.connect(origin, network)\n return [permissionDescriptor(origin, accounts)]\n }\n case 'wallet_revokePermissions':\n await this.disconnect(origin)\n return null\n case 'wallet_switchEthereumChain': {\n const target = caip2FromChainId((params[0] as { chainId?: unknown } | undefined)?.chainId)\n if (!target) throw new RouterError(RELAY_ERRORS.invalidParams, 'wallet_switchEthereumChain expects [{ chainId }].')\n const to = await this.deps.networks.get(target)\n if (!to) throw new RouterError(RELAY_ERRORS.chainNotAdded, `Chain ${chainHex(target)} is not in this wallet; add it with wallet_addEthereumChain.`)\n await this.switchChain(origin, network, to)\n return null\n }\n case 'wallet_addEthereumChain': {\n const parsed = parseAddChainParams(params)\n if ('code' in parsed) throw RouterError.from(parsed)\n const existing = await this.deps.networks.get(parsed.caip2)\n if (existing) { await this.switchChain(origin, network, existing); return null }\n await this.deps.approvals.request({ origin, chain: network.caip2, kind: 'add-chain', payload: { network: parsed } satisfies AddChainApproval })\n // EIP-3085: the endpoint must answer for the chain it is being added as (a look-alike RPC for a real chain id is the phishing shape).\n let answered: unknown\n try { answered = await this.deps.rpc(parsed, 'eth_chainId', []) } catch (e) { throw new RouterError(RELAY_ERRORS.invalidParams, `The RPC for ${parsed.name} did not answer eth_chainId (${e instanceof Error ? e.message : String(e)}); the network was not added.`) }\n const got = caip2FromChainId(answered)\n if (got !== parsed.caip2) throw new RouterError(RELAY_ERRORS.invalidParams, `The RPC for ${parsed.name} answers chain ${String(answered)}, not ${chainHex(parsed.caip2)}; the network was not added.`)\n await this.deps.networks.add({ ...parsed, custom: { origin, addedAt: Date.now() } })\n if (permission) await this.switchChain(origin, network, parsed, true)\n return null\n }\n case 'eth_sign':\n case 'eth_signTransaction':\n throw new RouterError(RELAY_ERRORS.unsupportedMethod, `${method} (blind signing) is never offered by this wallet.`)\n }\n\n if (READ_METHODS.has(method)) return this.deps.rpc(network, method, params)\n\n if (SIGNING_METHODS.has(method)) {\n if (!this.deps.sign) throw new RouterError(RELAY_ERRORS.unsupportedMethod, `${method} is not available yet.`)\n if (!permission) throw new RouterError(RELAY_ERRORS.unauthorized, 'Connect the wallet first (eth_requestAccounts).')\n return this.deps.sign({ origin, network, method, params, accounts: permission.accounts })\n }\n\n throw new RouterError(RELAY_ERRORS.unsupportedMethod, `This wallet does not support ${method}.`)\n }\n\n /** What a connected origin sees right now: its permitted accounts that the wallet can expose (none while locked). */\n private async visibleAccounts(permission: OriginPermission | null): Promise<string[]> {\n if (!permission) return []\n const available = await this.deps.accounts()\n return permission.accounts.filter((a) => available.includes(a))\n }\n\n /**\n * Connected and unlocked → the accounts; otherwise the approval window (which\n * unlocks first when needed) picks them. Emits `connect` + `accountsChanged`.\n */\n private async connect(origin: string, network: EvmNetwork): Promise<string[]> {\n const existing = await this.visibleAccounts(await this.deps.permissions.get(origin))\n if (existing.length) return existing\n const chosen = await this.deps.approvals.request<unknown>({ origin, chain: network.caip2, kind: 'connect', payload: { accounts: await this.deps.accounts() } satisfies ConnectApproval })\n const available = await this.deps.accounts()\n const accounts = Array.isArray(chosen) ? chosen.filter((a): a is string => typeof a === 'string' && available.includes(a)) : []\n if (accounts.length === 0) throw new ReviewDeclined('No account was selected.')\n await this.deps.permissions.connect(origin, accounts, network.caip2)\n this.deps.emit(origin, 'connect', { chainId: chainHex(network.caip2) })\n this.deps.emit(origin, 'accountsChanged', accounts)\n return accounts\n }\n\n async disconnect(origin: string): Promise<void> {\n if (!(await this.deps.permissions.get(origin))) return\n await this.deps.permissions.disconnect(origin)\n this.deps.emit(origin, 'accountsChanged', [])\n this.deps.emit(origin, 'disconnect', { code: RELAY_ERRORS.disconnected, message: 'The wallet disconnected this site.' })\n }\n\n private async switchChain(origin: string, from: EvmNetwork, to: EvmNetwork, approved = false): Promise<void> {\n if (from.caip2 === to.caip2) return\n const permission = await this.deps.permissions.get(origin)\n if (!permission) throw new RouterError(RELAY_ERRORS.unauthorized, 'Connect the wallet first (eth_requestAccounts).')\n if (!approved) await this.deps.approvals.request({ origin, chain: from.caip2, kind: 'switch-chain', payload: { from, to } satisfies SwitchChainApproval })\n await this.deps.permissions.setChain(origin, to.caip2)\n this.deps.emit(origin, 'chainChanged', chainHex(to.caip2))\n }\n}\n\nconst permissionDescriptor = (origin: string, accounts: string[]) => ({\n id: crypto.randomUUID(),\n parentCapability: 'eth_accounts',\n invoker: origin,\n caveats: [{ type: 'restrictReturnedAccounts', value: [...accounts] }],\n date: Date.now(),\n})\n","/**\n * Sign-In with Ethereum (EIP-4361) messages, parsed so the sheet can say what a\n * `personal_sign` really is and check the fields a phishing site would lie\n * about: the domain (scheme + host) must be the site asking, the address must\n * be the signing account, the chain must be the site's, the message must not be\n * expired or not-yet-valid, and the nonce must look like one (replay).\n *\n * Everything here is a WARNING: the sheet turns problems into warn checks and\n * the user can still sign. Whenever the first line is an EIP-4361 header the\n * text is treated as a sign-in (scan F9) — a message whose remaining fields do\n * not parse is reported as malformed instead of silently becoming a plain\n * message without the cross-site check.\n */\nimport type { OriginVia } from './approvals.js'\n\nexport interface SiweMessage {\n /** As written in the header: `host[:port]`, optionally prefixed by `scheme://`. */\n domain: string\n address: string\n statement?: string\n uri: string\n version: string\n chainId: number\n nonce: string\n issuedAt: string\n expirationTime?: string\n notBefore?: string\n requestId?: string\n resources: string[]\n}\n\nexport interface SiweInfo {\n message: SiweMessage\n /** Human lines, each a reason the sheet should warn; empty = the sign-in is consistent with the request. */\n problems: string[]\n /** The header said \"sign-in\" but the rest did not parse as EIP-4361 (`message` then holds what could be read). */\n malformed?: boolean\n}\n\nexport interface SiweContext {\n /** The page that asked, as the browser recorded it (`https://…`), or a transport pseudo-origin (`wc:<topic>`). */\n origin: string\n /** The signing address. */\n account: string\n /** The site's chain. */\n chainId: number\n now?: number\n /** Transport note for pseudo-origins (WalletConnect): the dApp's claimed URL and what Verify said about it. */\n via?: OriginVia\n}\n\n/** First line of an EIP-4361 message; the \"Ethereum account\" literal is what makes it one. */\nconst HEADER_LINE = /^(?<domain>[^\\n]+?) wants you to sign in with your Ethereum account:(?:\\n|$)/\nconst ADDRESS_LINE = /^0x[0-9a-fA-F]{40}$/\nconst FIELD = /^([A-Za-z ]+): (.*)$/\n\ninterface Parsed { message: SiweMessage; missing: string[] }\n\n/** Tolerant parse: `null` only when the first line is not an EIP-4361 header. */\nfunction parseLoose(text: string): Parsed | null {\n const head = HEADER_LINE.exec(text)\n if (!head?.groups) return null\n const lines = text.slice(head[0].length).split('\\n')\n const missing: string[] = []\n const addressLine = lines.shift() ?? ''\n const address = ADDRESS_LINE.test(addressLine) ? addressLine : ''\n if (!address) missing.push('address')\n // Between the address and the `URI:` line: blank lines and at most one statement line.\n // Covers `addr\\n\\nstatement\\n\\nURI`, `addr\\n\\n\\nURI` (no statement, the ABNF form) and `addr\\n\\nURI` (older libraries).\n const uriAt = lines.findIndex((l) => l.startsWith('URI: '))\n const between = (uriAt < 0 ? lines : lines.slice(0, uriAt)).filter((l) => l !== '')\n let statement: string | undefined\n if (uriAt >= 0) {\n if (between.length === 1 && !FIELD.test(between[0]!)) statement = between[0]\n else if (between.length > 0) missing.push('statement layout')\n }\n const fields: Record<string, string> = {}\n const resources: string[] = []\n for (const line of uriAt < 0 ? [] : lines.slice(uriAt)) {\n if (line.startsWith('- ')) { resources.push(line.slice(2)); continue }\n const m = FIELD.exec(line)\n if (m && !(m[1]! in fields)) fields[m[1]!] = m[2]!\n }\n const chainId = Number(fields['Chain ID'])\n if (!fields.URI) missing.push('URI')\n if (!fields.Version) missing.push('Version')\n if (fields['Chain ID'] === undefined || !Number.isInteger(chainId)) missing.push('Chain ID')\n if (!fields.Nonce) missing.push('Nonce')\n if (!fields['Issued At']) missing.push('Issued At')\n const message: SiweMessage = { domain: head.groups.domain!, address, uri: fields.URI ?? '', version: fields.Version ?? '', chainId: Number.isInteger(chainId) ? chainId : NaN, nonce: fields.Nonce ?? '', issuedAt: fields['Issued At'] ?? '', resources }\n if (statement) message.statement = statement\n if (fields['Expiration Time']) message.expirationTime = fields['Expiration Time']\n if (fields['Not Before']) message.notBefore = fields['Not Before']\n if (fields['Request ID']) message.requestId = fields['Request ID']\n return { message, missing }\n}\n\n/** `null` when the text is not a well-formed EIP-4361 message (see {@link describeSiwe} for the tolerant form the sheet uses). */\nexport function parseSiwe(text: string): SiweMessage | null {\n const p = parseLoose(text)\n return p && p.missing.length === 0 ? p.message : null\n}\n\ninterface Where { scheme: string; host: string }\n\n/** `scheme://host[:port]` or bare `host[:port]` (scheme defaults to https, as EIP-4361 says). */\nfunction whereOf(s: string): Where | null {\n try {\n if (!s.includes('://')) {\n // A URL parser, never fetched — and written as the one dynamic `https://` prefix the extension's host gate knows.\n const host = new URL(`https://${s}`).host.toLowerCase()\n return host ? { scheme: 'https', host } : null\n }\n const u = new URL(s)\n return u.host ? { scheme: u.protocol.replace(/:$/, '').toLowerCase(), host: u.host.toLowerCase() } : null\n } catch { return null }\n}\n\n/** A browser origin with a host the wallet can vouch for: http(s) only — `wc:<topic>` and other pseudo-origins have none. */\nfunction originWhere(origin: string): Where | null {\n try {\n const u = new URL(origin)\n return (u.protocol === 'https:' || u.protocol === 'http:') && u.host ? { scheme: u.protocol.slice(0, -1), host: u.host.toLowerCase() } : null\n } catch { return null }\n}\n\n/** Loopback / `*.localhost` (dev servers): plain http is normal there, so no scheme warnings. Takes `host[:port]`. */\nexport function isLocalHost(host: string): boolean {\n const h = host.toLowerCase().replace(/:\\d+$/, '')\n return h === 'localhost' || h === '127.0.0.1' || h === '[::1]' || h.endsWith('.localhost')\n}\n\n/** The checks; `origin` is the page that asked (as the browser recorded it), `account` the signing address, `chainId` the site's chain. */\nexport function siweProblems(m: SiweMessage, ctx: SiweContext): string[] {\n const out: string[] = []\n const domain = whereOf(m.domain)\n let site = originWhere(ctx.origin)\n if (!site) {\n // No browser-recorded host (WalletConnect `wc:<topic>`): only a Verify-attested claim naming the same host counts (scan F10).\n const claimed = ctx.via?.verify === 'VALID' && !ctx.via.scam ? whereOf(ctx.via.url) : null\n if (claimed && domain && claimed.host === domain.host) site = claimed\n else out.push(`The wallet cannot verify which site is asking; this sign-in for ${m.domain} may be replayed there.`)\n }\n if (site) {\n // Scheme as well as host (scan F20/F21): an http:// twin of the site must not collect sign-ins valid for the https one.\n const local = isLocalHost(site.host)\n if (site.scheme === 'http' && !local) out.push(`This sign-in is requested by an insecure page (${site.scheme}://${site.host}); anyone on the network can read or change it and replay the signature on the https site.`)\n if (!domain || domain.host !== site.host) out.push(`The sign-in names ${m.domain} but the request comes from ${site.host} — a sign-in meant for another site would be replayable there.`)\n else if (!local && domain.scheme !== site.scheme) out.push(`The sign-in is for ${domain.scheme}://${domain.host} but the request comes from ${site.scheme}://${site.host}.`)\n const uri = m.uri ? whereOf(m.uri) : null\n if (uri && uri.host !== site.host) out.push(`The URI ${m.uri} is not on ${site.host}.`)\n else if (uri && !local && (uri.scheme === 'http' || uri.scheme === 'https') && uri.scheme !== site.scheme) out.push(`The URI ${m.uri} uses ${uri.scheme}:// but the request comes from ${site.scheme}://${site.host}.`)\n }\n if (m.address && m.address.toLowerCase() !== ctx.account.toLowerCase()) out.push(`The sign-in is for ${m.address}, not the account that would sign (${ctx.account}).`)\n if (Number.isInteger(m.chainId) && m.chainId !== ctx.chainId) out.push(`The sign-in is for chain ${m.chainId}; this site is on chain ${ctx.chainId}.`)\n if (m.version && m.version !== '1') out.push(`Unknown SIWE version ${m.version}.`)\n if (m.nonce && (m.nonce.length < 8 || !/^[A-Za-z0-9]+$/.test(m.nonce))) out.push('The nonce is too short to protect against replay.')\n const now = ctx.now ?? Date.now()\n const exp = m.expirationTime ? Date.parse(m.expirationTime) : NaN\n if (m.expirationTime && (Number.isNaN(exp) || exp <= now)) out.push('The sign-in has already expired.')\n const nbf = m.notBefore ? Date.parse(m.notBefore) : NaN\n if (m.notBefore && (Number.isNaN(nbf) || nbf > now)) out.push('The sign-in is not valid yet (Not Before is in the future).')\n if (m.issuedAt) {\n const iat = Date.parse(m.issuedAt)\n if (Number.isNaN(iat)) out.push('Issued At is not a date.')\n else if (iat > now + 5 * 60_000) out.push('Issued At is in the future.')\n }\n return out\n}\n\n/** `null` only when the text does not start with an EIP-4361 header; a header with unreadable fields comes back with a \"malformed sign-in message\" problem. */\nexport function describeSiwe(text: string, ctx: SiweContext): SiweInfo | null {\n const p = parseLoose(text)\n if (!p) return null\n const problems = siweProblems(p.message, ctx)\n if (p.missing.length === 0) return { message: p.message, problems }\n return { message: p.message, problems: [`This is a malformed sign-in message (EIP-4361): ${p.missing.join(', ')} missing or unreadable — check the site before signing.`, ...problems], malformed: true }\n}\n","/**\n * Signing requests from dApps (and from the wallet's own Send): classification,\n * transaction preparation, the review stop, the signature.\n *\n * Classification is Vaulty's `signingRequest` (mobile/lib/browser.ts): the\n * address a page names must be one the user connected; typed data bound to\n * another chain than the one the site is on is refused (4901); a transaction\n * must have a `to` (no deployments) and a `chainId`, when given, equal to the\n * site's chain; `eth_sign` never reaches here (the router refuses it).\n *\n * Preparation fills nonce, gas and fees from the wallet's own RPC (never the\n * page's): EIP-1559 cap = 2 × base fee + tip with the tip floored at 0.1 gwei\n * (Vaulty's `evmFees`), legacy `gasPrice` where a chain has no base fee, gas =\n * the page's limit or `eth_estimateGas` × 1.2.\n *\n * The review payload ({@link SignApproval}) carries what the window shows: the\n * classified request, the prepared fields, the fee, and the preview the wallet\n * attached (tx-preview-evm: decode, simulation, balance changes, checks). Only\n * after the user approves does {@link SignDeps.signerFor} open the key; the\n * handle is disposed (zeroized) in `finally`, the raw transaction goes out via\n * `eth_sendRawTransaction` on the wallet's RPC.\n */\nimport { ApprovalQueue, type OriginVia } from './approvals.js'\nimport type { EvmNetwork } from './networks.js'\nimport { RELAY_ERRORS, type RelayError } from './relay.js'\nimport { RouterError, type RouterDeps } from './router.js'\nimport { describeSiwe, type SiweInfo } from './siwe.js'\n\n/** The account nonce an RPC reported, refused when it is not a safe integer (a broken or hostile RPC). */\nconst safeNonce = (n: bigint): number => {\n if (n < 0n || n > BigInt(Number.MAX_SAFE_INTEGER)) throw new Error(`The RPC returned an impossible nonce (${n}).`)\n return Number(n.toString())\n}\n\nexport type SignRequestInfo =\n | { kind: 'sign-message'; method: 'personal_sign'; account: string; /** Decoded text when printable, else the hex. */ text: string; /** What is actually signed (hex or utf-8 string). */ raw: string; /** Parsed Sign-In with Ethereum (EIP-4361) with the checks against the asking origin, when the text is one. */ siwe?: SiweInfo }\n | { kind: 'sign-typed-data'; method: string; account: string; /** Pretty-printed JSON. */ text: string; typedData: TypedData }\n | { kind: 'send-transaction'; method: 'eth_sendTransaction'; account: string; tx: { to: string; value: string; data: string | null; gas: string | null } }\n\nexport interface TypedData {\n domain: Record<string, unknown>\n types: Record<string, Array<{ name: string; type: string }>>\n message: Record<string, unknown>\n primaryType?: string\n}\n\nexport interface PreparedTx {\n chainId: number\n nonce: number\n gasLimit: string\n /** EIP-1559 fields, or `gasPrice` on legacy-fee chains. All 0x hex. */\n maxFeePerGas?: string\n maxPriorityFeePerGas?: string\n gasPrice?: string\n /** gasLimit × max fee, base units. */\n maxFee: string\n}\n\n/** The approval window's payload for the three signing kinds. */\nexport interface SignApproval {\n request: SignRequestInfo\n network: EvmNetwork\n prepared?: PreparedTx\n /** What the wallet attached (tx-preview-evm `TxPreview`, typed-data description…). */\n preview: unknown\n}\n\nexport interface EvmSigner {\n signMessage(message: string | Uint8Array): Promise<string>\n signTypedData(typed: TypedData): Promise<string>\n /** Fully specified tx (chainId, nonce, gas, fees) → signed raw transaction. */\n signTransaction(tx: { chainId: number; nonce: number; to: string; value: bigint; data: string; gasLimit: bigint; maxFeePerGas?: bigint; maxPriorityFeePerGas?: bigint; gasPrice?: bigint }): Promise<string>\n}\n\nexport interface SignDeps {\n approvals: ApprovalQueue\n rpc(network: EvmNetwork, method: string, params: unknown[]): Promise<unknown>\n /** Opens the key for `address`; `dispose()` zeroizes it. */\n signerFor(address: string, network: EvmNetwork): Promise<{ signer: EvmSigner; dispose(): void }>\n /** Review data for the window (errors inside are the wallet's to swallow → `null`). */\n preview?(input: { network: EvmNetwork; request: SignRequestInfo; accounts: string[] }): Promise<unknown>\n /** Tip floor per chain id in wei (default 0.1 gwei everywhere). */\n tipFloor?: (chainId: number) => bigint\n}\n\nconst ADDRESS = /^0x[0-9a-fA-F]{40}$/\nconst HEX = /^0x([0-9a-fA-F]{2})*$/\nconst lc = (s: string) => s.toLowerCase()\n\n/** Vaulty's `messageText`: hex that decodes to printable text is shown decoded; binary payloads stay hex. */\nexport function messageText(value: unknown): string {\n if (typeof value !== 'string') return ''\n if (!HEX.test(value)) return value\n try {\n const bytes = Uint8Array.from(value.slice(2).match(/../g) ?? [], (b) => Number.parseInt(b, 16))\n const s = new TextDecoder('utf-8', { fatal: true }).decode(bytes)\n return /^[\\x09\\x0a\\x0d\\x20-\\x7e -]*$/.test(s) ? s : value\n } catch {\n return value\n }\n}\n\n/**\n * The message as the signer will sign it: hex decoded when it is valid UTF-8, whatever\n * its printability (scan 2026-10-23 F7 — the SIWE checks must read the bytes that get\n * signed, not the hex fallback `messageText` shows for unprintable text).\n */\nexport function decodedMessage(value: unknown): string | null {\n if (typeof value !== 'string') return null\n if (!HEX.test(value)) return value\n try {\n return new TextDecoder('utf-8', { fatal: true }).decode(Uint8Array.from(value.slice(2).match(/../g) ?? [], (b) => Number.parseInt(b, 16)))\n } catch {\n return null\n }\n}\n\n/** Control characters other than tab / newline / carriage return — never part of an honest EIP-4361 message. */\nconst HIDDEN_CONTROL = /[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f-\\x9f]/\n\nconst err = (code: number, message: string): RelayError => ({ code, message })\n\n/** Signing method + params → what the window reviews, or the error to answer with. */\nexport function classifySignRequest(input: { network: EvmNetwork; method: string; params: unknown[]; accounts: string[]; /** The asking page (browser-recorded) — needed for the SIWE domain check. */ origin?: string; /** Transport note for pseudo-origins (WalletConnect Verify), for the SIWE check. */ via?: OriginVia; now?: number }): SignRequestInfo | RelayError {\n const { method, params } = input\n const owned = new Set(input.accounts.map(lc))\n const ours = (a: unknown): a is string => typeof a === 'string' && ADDRESS.test(a) && owned.has(lc(a))\n const checksum = (a: string) => input.accounts.find((x) => lc(x) === lc(a)) ?? a\n\n if (method === 'personal_sign') {\n // [message, address] per spec; some dApps send [address, message].\n let [msg, addr] = params\n if (ours(msg) && !ours(addr)) [msg, addr] = [addr, msg]\n if (!ours(addr)) return err(RELAY_ERRORS.unauthorized, 'personal_sign for an address this wallet does not hold.')\n if (typeof msg !== 'string') return err(RELAY_ERRORS.invalidParams, 'personal_sign expects a message string.')\n const text = messageText(msg)\n const signed = decodedMessage(msg) ?? text\n const siwe = input.origin ? describeSiwe(signed, { origin: input.origin, account: checksum(addr), chainId: input.network.chainId, ...(input.via ? { via: input.via } : {}), ...(input.now !== undefined ? { now: input.now } : {}) }) : null\n // A sign-in message with hidden control characters would show as an opaque hex blob while\n // a lenient verifier still accepts it: refuse it outright.\n if (siwe && HIDDEN_CONTROL.test(signed)) return err(RELAY_ERRORS.invalidParams, 'This sign-in message contains hidden control characters — refused.')\n return { kind: 'sign-message', method, account: checksum(addr), text, raw: msg, ...(siwe ? { siwe } : {}) }\n }\n\n if (method === 'eth_signTypedData_v4' || method === 'eth_signTypedData_v3' || method === 'eth_signTypedData') {\n const [addr, data] = params\n if (!ours(addr)) return err(RELAY_ERRORS.unauthorized, 'signTypedData for an address this wallet does not hold.')\n let parsed: TypedData\n try {\n parsed = (typeof data === 'string' ? JSON.parse(data) : data) as TypedData\n } catch {\n return err(RELAY_ERRORS.invalidParams, 'Typed data is not valid JSON.')\n }\n if (!parsed || typeof parsed !== 'object' || typeof parsed.domain !== 'object' || typeof parsed.types !== 'object' || typeof parsed.message !== 'object') {\n return err(RELAY_ERRORS.invalidParams, 'Typed data needs domain, types and message.')\n }\n const cid = parsed.domain.chainId\n if (cid !== undefined && cid !== null && Number(cid) !== input.network.chainId) {\n // A domain bound to another chain than the one the site is on is the classic cross-chain replay / phishing shape.\n return err(RELAY_ERRORS.chainDisconnected, `Typed data is for chain ${String(cid)}; this site is on ${input.network.name} (${input.network.chainId}).`)\n }\n return { kind: 'sign-typed-data', method, account: checksum(addr), text: JSON.stringify(parsed, bigintSafe, 2), typedData: parsed }\n }\n\n if (method === 'eth_sendTransaction') {\n const tx = (params[0] ?? {}) as { from?: unknown; to?: unknown; value?: unknown; data?: unknown; gas?: unknown; gasLimit?: unknown; chainId?: unknown; type?: unknown; authorizationList?: unknown }\n if (!ours(tx.from)) return err(RELAY_ERRORS.unauthorized, 'Transaction from an address this wallet does not hold.')\n // EIP-7702: a delegation hands the whole account to a contract; >80 % of early delegations went to sweepers. Sites never get one from this wallet.\n if ((Array.isArray(tx.authorizationList) && tx.authorizationList.length > 0) || tx.type === '0x4' || tx.type === 4) return err(RELAY_ERRORS.unsupportedMethod, 'EIP-7702 delegations (authorizationList / type 4) are never signed for a site by this wallet.')\n if (typeof tx.to !== 'string' || !ADDRESS.test(tx.to)) return err(RELAY_ERRORS.invalidParams, 'Contract deployment is not supported (a transaction needs a valid `to`).')\n if (tx.chainId !== undefined && tx.chainId !== null && Number(tx.chainId) !== input.network.chainId) return err(RELAY_ERRORS.chainDisconnected, 'Transaction chainId differs from the selected chain.')\n let value: string\n try {\n value = BigInt((tx.value as string | number | bigint | undefined) ?? 0).toString()\n } catch {\n return err(RELAY_ERRORS.invalidParams, 'Bad transaction value.')\n }\n const data = typeof tx.data === 'string' && tx.data !== '0x' ? tx.data : null\n if (data !== null && !HEX.test(data)) return err(RELAY_ERRORS.invalidParams, 'Transaction data is not hex.')\n const gasRaw = tx.gas ?? tx.gasLimit\n const gas = typeof gasRaw === 'string' && /^0x[0-9a-fA-F]+$/.test(gasRaw) ? gasRaw : null\n return { kind: 'send-transaction', method, account: checksum(tx.from), tx: { to: tx.to, value, data, gas } }\n }\n\n return err(RELAY_ERRORS.unsupportedMethod, `This wallet does not support ${method}.`)\n}\n\nconst bigintSafe = (_k: string, v: unknown) => (typeof v === 'bigint' ? v.toString() : v)\nconst hex = (n: bigint) => `0x${n.toString(16)}`\nconst big = (v: unknown): bigint => BigInt(v as string)\nconst MIN_TIP_WEI = 100_000_000n // 0.1 gwei\n\n/** Nonce, gas, fees from the wallet's RPC. */\nexport async function prepareTransaction(deps: Pick<SignDeps, 'rpc' | 'tipFloor'>, network: EvmNetwork, from: string, tx: { to: string; value: string; data: string | null; gas: string | null }): Promise<PreparedTx> {\n const call = { from, to: tx.to, value: hex(BigInt(tx.value)), ...(tx.data ? { data: tx.data } : {}) }\n const [nonceHex, block, gasHex] = await Promise.all([\n deps.rpc(network, 'eth_getTransactionCount', [from, 'pending']),\n deps.rpc(network, 'eth_getBlockByNumber', ['latest', false]) as Promise<{ baseFeePerGas?: string | null } | null>,\n tx.gas ? Promise.resolve(tx.gas) : deps.rpc(network, 'eth_estimateGas', [call]),\n ])\n const estimated = big(gasHex)\n const gasLimit = tx.gas ? estimated : (estimated * 120n + 99n) / 100n\n const base = block?.baseFeePerGas != null ? big(block.baseFeePerGas) : null\n if (base === null) {\n const gasPrice = big(await deps.rpc(network, 'eth_gasPrice', []))\n return { chainId: network.chainId, nonce: safeNonce(big(nonceHex)), gasLimit: hex(gasLimit), gasPrice: hex(gasPrice), maxFee: (gasLimit * gasPrice).toString() }\n }\n const floor = deps.tipFloor?.(network.chainId) ?? MIN_TIP_WEI\n const nodeTip = await (deps.rpc(network, 'eth_maxPriorityFeePerGas', []) as Promise<string>).then(big).catch(() => 0n)\n const tip = nodeTip > floor ? nodeTip : floor\n const maxFeePerGas = base * 2n + tip\n return { chainId: network.chainId, nonce: safeNonce(big(nonceHex)), gasLimit: hex(gasLimit), maxFeePerGas: hex(maxFeePerGas), maxPriorityFeePerGas: hex(tip), maxFee: (gasLimit * maxFeePerGas).toString() }\n}\n\n/** The router's `sign` hook: classify → prepare → review → sign (→ broadcast). */\nexport function createSignHandler(deps: SignDeps): NonNullable<RouterDeps['sign']> {\n return async ({ origin, network, method, params, accounts }) => {\n const via = deps.approvals.viaFor(origin)\n const info = classifySignRequest({ network, method, params, accounts, origin, ...(via ? { via } : {}) })\n if ('code' in info) throw RouterError.from(info)\n\n const prepared = info.kind === 'send-transaction' ? await prepareTransaction(deps, network, info.account, info.tx) : undefined\n const preview = deps.preview ? await deps.preview({ network, request: info, accounts }).catch(() => null) : null\n const payload: SignApproval = { request: info, network, ...(prepared ? { prepared } : {}), preview }\n await deps.approvals.request({ origin, chain: network.caip2, kind: info.kind, payload })\n\n const handle = await deps.signerFor(info.account, network)\n try {\n switch (info.kind) {\n case 'sign-message':\n return await handle.signer.signMessage(HEX.test(info.raw) ? Uint8Array.from(info.raw.slice(2).match(/../g) ?? [], (b) => Number.parseInt(b, 16)) : info.raw)\n case 'sign-typed-data':\n return await handle.signer.signTypedData(info.typedData)\n case 'send-transaction': {\n const p = prepared!\n const raw = await handle.signer.signTransaction({\n chainId: p.chainId, nonce: p.nonce, to: info.tx.to, value: BigInt(info.tx.value), data: info.tx.data ?? '0x', gasLimit: BigInt(p.gasLimit),\n ...(p.gasPrice !== undefined ? { gasPrice: BigInt(p.gasPrice) } : { maxFeePerGas: BigInt(p.maxFeePerGas!), maxPriorityFeePerGas: BigInt(p.maxPriorityFeePerGas!) }),\n })\n return await deps.rpc(network, 'eth_sendRawTransaction', [raw])\n }\n }\n } finally {\n handle.dispose()\n }\n }\n}\n","/**\n * Pre-approvals — the second half of Vaulty's `txGate` (mobile/lib/txGate.ts).\n * A flow that reviewed a WHOLE plan in one sheet (a swap: approvals + source\n * leg) registers one matcher per operation it is about to perform; the\n * reviewed account then lets exactly those operations through without a second\n * window, each once, within `ttlMs`. Anything else still stops at the review.\n */\nexport type GatedOp =\n | { kind: 'evm-tx'; caip2: string; to: string; data?: string; value: bigint }\n | { kind: 'evm-typed-data'; caip2: string }\n | { kind: 'solana-transfer'; to: string; amount: bigint; token?: string }\n | { kind: 'solana-tx'; to: string; value: bigint }\n | { kind: 'solana-serialized'; serializedTx: string }\n /** A module-built Solana transaction message (instructions), reviewed as a plan. */\n | { kind: 'solana-message' }\n /** TON / Tron / Bitcoin / NEAR send or token transfer (amount in base units; token = jetton master / TRC-20 / NEP-141 id). */\n | { kind: 'chain-tx'; chain: string; to: string; amount: bigint; token?: string | undefined; memo?: string | undefined }\n\nexport type GateMatcher = (op: GatedOp) => boolean\n\nexport class ReviewGate {\n private approved: { match: GateMatcher; until: number }[] = []\n\n constructor(private readonly now: () => number = Date.now) {}\n\n /** Each matcher passes ONE operation, within `ttlMs` (default 10 min). */\n preApprove(matchers: GateMatcher[], ttlMs = 10 * 60_000): void {\n const until = this.now() + ttlMs\n this.approved.push(...matchers.map((match) => ({ match, until })))\n }\n\n /** True (and the matcher is spent) when a pre-approval covers `op`. */\n consume(op: GatedOp): boolean {\n const now = this.now()\n this.approved = this.approved.filter((a) => a.until > now)\n const i = this.approved.findIndex((a) => a.match(op))\n if (i < 0) return false\n this.approved.splice(i, 1)\n return true\n }\n\n get pending(): number {\n return this.approved.length\n }\n\n clear(): void {\n this.approved = []\n }\n}\n\nconst lc = (s: string) => s.toLowerCase()\n\n/** Matcher for an exact EVM call: same chain, `to`, calldata and value. */\nexport function evmCallMatcher(expected: { caip2: string; to: string; data?: string | undefined; value: bigint }): GateMatcher {\n const data = expected.data && expected.data !== '0x' ? lc(expected.data) : undefined\n return (op) =>\n op.kind === 'evm-tx' &&\n op.caip2 === expected.caip2 &&\n lc(op.to) === lc(expected.to) &&\n (op.data && op.data !== '0x' ? lc(op.data) : undefined) === data &&\n op.value === expected.value\n}\n\n/** Matcher for a non-EVM send: same chain, recipient, amount, token and memo. */\nexport function chainTxMatcher(expected: { chain: string; to: string; amount: bigint; token?: string | undefined; memo?: string | undefined }): GateMatcher {\n return (op) => op.kind === 'chain-tx' && op.chain === expected.chain && op.to === expected.to && op.amount === expected.amount && (op.token ?? '') === (expected.token ?? '') && (op.memo ?? '') === (expected.memo ?? '')\n}\n","/**\n * Swaps for the extension, the DIRECT path of Vaulty mobile's `lib/swap2.ts`:\n * the providers run in the service worker and talk to their APIs themselves.\n *\n * - {@link quoteRoutes}: dry quotes from every provider that can serve the\n * pair, delivered progressively (`onUpdate` fires as each venue answers), with\n * BEST / FASTEST tags and every refusal named.\n * TODO: replace with `CrossChainRouter.getQuotes` (net-USD ranking,\n * RouteSet). Until then this fan-out over the public `CrossChainProvider`\n * interface ranks by output amount.\n * - {@link reviewSwapPlan}: the engine's `reviewExecution` hook — one sheet for\n * the whole plan (approvals + source leg) BEFORE anything is signed; on\n * approval exactly those operations are pre-approved in the {@link ReviewGate}\n * so the reviewed account lets them through once; a decline aborts with\n * nothing sent (`ReviewDeclined`, 4001).\n */\nimport type { CrossChainProvider, Quote, QuoteParams, Swap2ExecutionPlan } from '@anywalletkit/protocol-swap2-core'\nimport { validQuote } from '@anywalletkit/protocol-swap2-core'\nimport { ApprovalQueue } from './approvals.js'\nimport { ReviewGate, chainTxMatcher, evmCallMatcher, type GateMatcher } from './gate.js'\n\nexport interface RouteView {\n provider: string\n destAmount: string\n minDestAmount: string\n feeUsd: number\n /** On-chain pool venues take the fee inside the output; \"$0.00\" would mislead. */\n feeNote?: string\n etaSeconds: number\n validUntilMs: number\n tags: ('best' | 'fastest')[]\n}\n\nexport interface RouteListView {\n routes: RouteView[]\n /** Providers still quoting. */\n pending: string[]\n /** Provider → why it sat out (refusal, error, timeout). */\n refusals: Record<string, string>\n /** The quotes themselves, by provider, for execution with the same numbers the user saw. */\n quotes: Record<string, Quote>\n}\n\nexport interface QuoteRoutesOptions {\n onUpdate?: (view: RouteListView) => void\n /** Per-provider wall clock (default 20 s). */\n timeoutMs?: number\n signal?: AbortSignal\n now?: () => number\n}\n\n/** Dry quotes from every enabled provider that claims the route, progressively. */\nexport async function quoteRoutes(providers: readonly CrossChainProvider[], params: QuoteParams, options: QuoteRoutesOptions = {}): Promise<RouteListView> {\n const timeoutMs = options.timeoutMs ?? 20_000\n const from = { chain: params.sourceChain, token: params.sourceToken }\n const to = { chain: params.destChain, token: params.destToken }\n const refusals: Record<string, string> = {}\n const quotes: Record<string, Quote> = {}\n const candidates: CrossChainProvider[] = []\n for (const p of providers) {\n let enabled = false\n try { enabled = p.enabled() } catch { /* fail closed */ }\n if (!enabled) continue\n if (params.sourceChain === params.destChain && !p.supportsSameChain) { refusals[p.name] = 'does not do same-chain swaps'; continue }\n let serves = false\n try { serves = p.supportsRoute(from, to) } catch (e) { refusals[p.name] = e instanceof Error ? e.message : String(e); continue }\n if (!serves) { refusals[p.name] = 'does not serve this pair'; continue }\n candidates.push(p)\n }\n const pending = new Set(candidates.map((p) => p.name))\n const view = (): RouteListView => ({ routes: rank(Object.values(quotes)), pending: [...pending], refusals: { ...refusals }, quotes: { ...quotes } })\n const emit = () => options.onUpdate?.(view())\n emit()\n await Promise.all(\n candidates.map(async (p) => {\n const ctrl = new AbortController()\n const timer = setTimeout(() => ctrl.abort(new Error(`no answer within ${Math.round(timeoutMs / 1000)} s`)), timeoutMs)\n const onAbort = () => ctrl.abort(options.signal?.reason)\n options.signal?.addEventListener('abort', onAbort, { once: true })\n let refusal: string | undefined\n try {\n // Race the signal too: a provider that ignores it must not hold the list open forever.\n const aborted = new Promise<never>((_, reject) => ctrl.signal.addEventListener('abort', () => reject(ctrl.signal.reason instanceof Error ? ctrl.signal.reason : new Error(String(ctrl.signal.reason ?? 'cancelled'))), { once: true }))\n const q = await Promise.race([p.getQuote({ ...params, dry: true, onRefusal: (r) => { refusal = r } }, ctrl.signal), aborted])\n if (q && validQuote(q, { ...params, dry: true }, p.name)) quotes[p.name] = q\n else refusals[p.name] = refusal ?? (q ? 'returned an invalid quote' : 'no route for this pair right now')\n } catch (e) {\n refusals[p.name] = ctrl.signal.aborted ? String(ctrl.signal.reason instanceof Error ? ctrl.signal.reason.message : ctrl.signal.reason ?? 'cancelled') : e instanceof Error ? e.message : String(e)\n } finally {\n clearTimeout(timer)\n options.signal?.removeEventListener('abort', onAbort)\n pending.delete(p.name)\n emit()\n }\n }),\n )\n return view()\n}\n\n/** Highest output first (same destination token for every quote); FASTEST = lowest ETA among them. */\nexport function rank(quotes: Quote[]): RouteView[] {\n const sorted = [...quotes].sort((a, b) => (BigInt(b.destAmount) > BigInt(a.destAmount) ? 1 : BigInt(b.destAmount) < BigInt(a.destAmount) ? -1 : a.feeUsd - b.feeUsd || a.etaSeconds - b.etaSeconds))\n const fastest = sorted.length ? sorted.reduce((f, q) => (q.etaSeconds < f.etaSeconds ? q : f)) : null\n return sorted.map((q, i) => {\n const poolFee = q.providerData?.poolFee\n const feeNote = typeof poolFee === 'string' && poolFee && q.feeUsd === 0 ? (poolFee === 'pools' ? 'pool fees in price' : `pool ${poolFee} in price`) : undefined\n const tags: RouteView['tags'] = []\n if (i === 0) tags.push('best')\n if (fastest && q.provider === fastest.provider) tags.push('fastest')\n return { provider: q.provider, destAmount: q.destAmount, minDestAmount: q.minDestAmount, feeUsd: q.feeUsd, etaSeconds: q.etaSeconds, validUntilMs: q.validUntilMs, tags, ...(feeNote ? { feeNote } : {}) }\n })\n}\n\n/** Vaulty's execution floor: 50 bps under the quoted minimum rides normal drift while the user reviews, still refuses a real reprice. */\nexport const FLOOR_TOLERANCE_BPS = 50n\nexport function executionFloor(minDestAmount: bigint): bigint {\n const floor = (minDestAmount * (10_000n - FLOOR_TOLERANCE_BPS)) / 10_000n\n return floor > 0n ? floor : minDestAmount\n}\n\n// ---- the review stop ----\n\nexport interface SwapReviewMeta {\n /** Who runs the flow (the wallet's origin). */\n origin: string\n providerLabel: string\n fromSymbol: string\n fromDecimals: number\n toSymbol: string\n toDecimals: number\n fromChainName: string\n toChainName: string\n /** All of the user's addresses — recipient own/foreign. */\n own: string[]\n}\n\n/** What the swap sheet renders. Amounts are base-unit strings. */\nexport interface SwapApproval {\n provider: string\n providerLabel: string\n fromChain: string\n toChain: string\n fromChainName: string\n toChainName: string\n send: { symbol: string; decimals: number; amount: string }\n receive: { symbol: string; decimals: number; amount: string; min: string }\n recipient: { address: string; isOwn: boolean }\n refundAddress: string\n feeUsd: number\n etaSeconds: number\n validUntilMs: number\n approvals: { token: string; spender: string; amount: string }[]\n source:\n | { kind: 'call'; to: string; data?: string; value: string; deposit?: string }\n | { kind: 'token-transfer'; token: string; recipient: string; amount: string; memo?: string }\n | { kind: 'serialized' }\n | { kind: 'typed-order' }\n checks: { status: 'ok' | 'warn' | 'unknown'; label: string }[]\n}\n\nconst APPROVE_SELECTOR = '0x095ea7b3'\nconst TRANSFER_SELECTOR = '0xa9059cbb'\nconst pad = (hexNoPrefix: string) => hexNoPrefix.toLowerCase().padStart(64, '0')\nexport const encodeApproveCalldata = (spender: string, amount: bigint): string => `${APPROVE_SELECTOR}${pad(spender.slice(2))}${pad(amount.toString(16))}`\nconst lc = (s: string) => s.toLowerCase()\n\n/** A plain native send or ERC-20 transfer pays a provider deposit address (1Click-style). */\nfunction depositOf(s: { to: string; data?: string }, approvals: number): string | undefined {\n if (approvals > 0) return undefined\n if (!s.data || s.data === '0x') return s.to\n if (!s.data.startsWith(TRANSFER_SELECTOR) || s.data.length < 10 + 64) return undefined\n return `0x${s.data.slice(10 + 24, 10 + 64)}`\n}\n\nexport function swapApprovalPayload(plan: Swap2ExecutionPlan, meta: SwapReviewMeta): SwapApproval {\n const isOwn = meta.own.some((a) => lc(a) === lc(plan.recipient))\n const checks: SwapApproval['checks'] = [{ status: 'ok', label: `Built by the ${meta.providerLabel} module` }]\n const s = plan.source\n let source: SwapApproval['source']\n if (s.kind === 'call') {\n const deposit = depositOf(s, plan.approvals.length)\n source = { kind: 'call', to: s.to, ...(s.data ? { data: s.data } : {}), value: s.value.toString(), ...(deposit ? { deposit } : {}) }\n checks.push(deposit ? { status: 'ok', label: `Deposit address from the ${meta.providerLabel} quote` } : { status: 'ok', label: `Calls the ${meta.providerLabel} contract` })\n } else if (s.kind === 'token-transfer') {\n source = { kind: 'token-transfer', token: s.token, recipient: s.recipient, amount: s.amount.toString(), ...(s.memo ? { memo: s.memo } : {}) }\n checks.push({ status: 'ok', label: `Deposit address from the ${meta.providerLabel} quote` })\n } else if (s.kind === 'serialized') {\n source = { kind: 'serialized' }\n checks.push({ status: 'ok', label: 'Balance changes are proven before signing (SDK guard)' })\n } else {\n source = { kind: 'typed-order' }\n checks.push({ status: 'ok', label: 'Signed order — no transaction is sent from your wallet' })\n }\n for (const a of plan.approvals) checks.push(a.amount > plan.sourceAmount ? { status: 'warn', label: 'Approval is larger than this swap needs' } : { status: 'ok', label: 'Approval is exactly the amount needed' })\n if (plan.approvals.length > 1) checks.push({ status: 'ok', label: `${plan.approvals.length} approvals (reset to 0 first)` })\n checks.push(isOwn ? { status: 'ok', label: 'Funds arrive at your address' } : { status: 'warn', label: `Funds arrive at ${plan.recipient.slice(0, 6)}…${plan.recipient.slice(-4)}, not your address` })\n return {\n provider: plan.provider, providerLabel: meta.providerLabel, fromChain: plan.fromChain, toChain: plan.destChain, fromChainName: meta.fromChainName, toChainName: meta.toChainName,\n send: { symbol: meta.fromSymbol, decimals: meta.fromDecimals, amount: plan.sourceAmount.toString() },\n receive: { symbol: meta.toSymbol, decimals: meta.toDecimals, amount: plan.destAmount.toString(), min: plan.minDestAmount.toString() },\n recipient: { address: plan.recipient, isOwn }, refundAddress: plan.refundAddress, feeUsd: plan.feeUsd, etaSeconds: plan.etaSeconds, validUntilMs: plan.validUntilMs,\n approvals: plan.approvals.map((a) => ({ token: a.token, spender: a.spender, amount: a.amount.toString() })),\n source, checks,\n }\n}\n\n/** Matchers for exactly the operations the plan will perform, in the engine's order. */\nexport function planMatchers(plan: Swap2ExecutionPlan): GateMatcher[] {\n const m: GateMatcher[] = plan.approvals.map((a) => evmCallMatcher({ caip2: plan.fromChain, to: a.token, data: encodeApproveCalldata(a.spender, a.amount), value: 0n }))\n const s = plan.source\n if (s.kind === 'call') {\n if (plan.fromChain.startsWith('eip155:')) m.push(evmCallMatcher({ caip2: plan.fromChain, to: s.to, data: s.data, value: s.value }))\n else if (plan.fromChain.startsWith('solana:')) m.push((op) => op.kind === 'solana-tx' && op.to === s.to && op.value === s.value)\n else m.push(chainTxMatcher({ chain: plan.fromChain, to: s.to, amount: s.value, memo: s.memo }))\n } else if (s.kind === 'token-transfer') {\n if (plan.fromChain.startsWith('eip155:')) m.push(evmCallMatcher({ caip2: plan.fromChain, to: s.token, data: `${TRANSFER_SELECTOR}${pad(s.recipient.slice(2))}${pad(s.amount.toString(16))}`, value: 0n }))\n else if (plan.fromChain.startsWith('solana:')) m.push((op) => op.kind === 'solana-transfer' && op.to === s.recipient && op.amount === s.amount && (op.token ?? '') === s.token)\n else m.push(chainTxMatcher({ chain: plan.fromChain, to: s.recipient, amount: s.amount, token: s.token, memo: s.memo }))\n } else if (s.kind === 'serialized') {\n m.push((op) => op.kind === 'solana-serialized' && op.serializedTx === s.serializedTx)\n } else {\n m.push((op) => op.kind === 'evm-typed-data' && op.caip2 === plan.fromChain)\n }\n return m\n}\n\n/** The engine's `reviewExecution`: one sheet for the plan; approve → pre-approve exactly its operations; decline → nothing sent. */\nexport function reviewSwapPlan(approvals: ApprovalQueue, gate: ReviewGate, meta: SwapReviewMeta): (plan: Swap2ExecutionPlan) => Promise<void> {\n return async (plan) => {\n const payload = swapApprovalPayload(plan, meta)\n await approvals.request({ origin: meta.origin, chain: plan.fromChain, kind: 'swap', payload })\n gate.clear()\n gate.preApprove(planMatchers(plan), Math.max(60_000, plan.validUntilMs - Date.now() + 5 * 60_000))\n }\n}\n","/**\n * Pending swaps across service-worker restarts: records in `chrome.storage.local`,\n * a `chrome.alarms` tick every minute while anything is active, resumable by\n * the swap2 id (`awk1.<provider>.<intent>[.<sourceTxHash>]`), the provider's\n * `trackIntent` as the only source of truth.\n *\n * States (the provider's `IntentState` plus the wallet's own `claiming`):\n * pending ──deposit seen──▶ pending (depositReceived)\n * pending ──attested (CCTP)──▶ action-required ──user claims──▶ claiming ──mint seen──▶ completed\n * pending ──▶ completed | failed | refunded | refund-pending | partial | cancelled | expired\n * A tracker error leaves the record as it was (with `lastError`); a record older\n * than `giveUpAfterMs` with no progress becomes `expired` so the alarm stops.\n */\nimport { SWAP2_ID_PREFIX, type IntentStatus } from '@anywalletkit/protocol-swap2-core'\nimport type { JsonStorage } from './storage.js'\n\nexport type SwapRecordStatus = IntentStatus['state'] | 'claiming'\n\nexport interface SwapRecord {\n /** swap2 id — `awk1.<provider>.<intentId>[.<sourceTxHash>]`. */\n id: string\n provider: string\n fromChain: string\n toChain: string\n fromToken: string\n toToken: string\n /** Base units. */\n amountIn: string\n destAmount: string\n recipient: string\n sourceTxHash: string | null\n destTxHash: string | null\n status: SwapRecordStatus\n depositReceived?: boolean\n /** Two-phase routes: where and whether the claim can be built now. */\n claim?: { chain: string; ready: boolean }\n createdAt: number\n updatedAt: number\n /** Last tracker problem (RPC/API), kept until the next successful check. */\n lastError?: string\n checks: number\n}\n\nexport const ACTIVE_STATUSES: ReadonlySet<SwapRecordStatus> = new Set<SwapRecordStatus>(['pending', 'action-required', 'refund-pending', 'partial', 'claiming'])\n\nexport function parseSwapId(id: string): { provider: string; intentId: string; sourceTxHash?: string } | null {\n if (!id.startsWith(`${SWAP2_ID_PREFIX}.`)) return null\n const parts = id.slice(SWAP2_ID_PREFIX.length + 1).split('.')\n if (parts.length < 2 || parts.length > 3 || !parts[0] || !parts[1]) return null\n const provider = decodeURIComponent(parts[0])\n const intentId = decodeURIComponent(parts[1])\n const sourceTxHash = parts[2] ? decodeURIComponent(parts[2]) : undefined\n return sourceTxHash ? { provider, intentId, sourceTxHash } : { provider, intentId }\n}\n\nexport class SwapsStore {\n private _records: SwapRecord[] | null = null\n private readonly _listeners = new Set<() => void>()\n\n constructor(private readonly storage: JsonStorage<SwapRecord[]>) {}\n\n async list(): Promise<SwapRecord[]> {\n this._records ??= (await this.storage.get()) ?? []\n return [...this._records].sort((a, b) => b.createdAt - a.createdAt)\n }\n\n async get(id: string): Promise<SwapRecord | null> {\n return (await this.list()).find((r) => r.id === id) ?? null\n }\n\n async active(): Promise<SwapRecord[]> {\n return (await this.list()).filter((r) => ACTIVE_STATUSES.has(r.status))\n }\n\n async add(record: SwapRecord): Promise<void> {\n const all = (await this.list()).filter((r) => r.id !== record.id)\n await this.write([...all, record])\n }\n\n async update(id: string, patch: Partial<SwapRecord>): Promise<SwapRecord | null> {\n const all = await this.list()\n const i = all.findIndex((r) => r.id === id)\n if (i < 0) return null\n const next = { ...all[i]!, ...patch, updatedAt: patch.updatedAt ?? Date.now() }\n all[i] = next\n await this.write(all)\n return next\n }\n\n async remove(id: string): Promise<void> {\n await this.write((await this.list()).filter((r) => r.id !== id))\n }\n\n onChange(listener: () => void): () => void {\n this._listeners.add(listener)\n return () => this._listeners.delete(listener)\n }\n\n private async write(records: SwapRecord[]): Promise<void> {\n await this.storage.set(records)\n this._records = records\n for (const l of this._listeners) l()\n }\n}\n\nexport interface SwapTrackerDeps {\n store: SwapsStore\n /** The provider's view of the swap (`CrossChainRouter.trackIntent`). */\n status(record: SwapRecord): Promise<IntentStatus>\n /** Start / stop the periodic alarm (`chrome.alarms.create(name, { periodInMinutes: 1 })`). */\n alarm: { start(): Promise<void> | void; stop(): Promise<void> | void }\n now?: () => number\n /** No progress for this long → `expired` (default 48 h). */\n giveUpAfterMs?: number\n}\n\nexport class SwapTracker {\n private readonly now: () => number\n private ticking: Promise<void> | null = null\n\n constructor(private readonly deps: SwapTrackerDeps) {\n this.now = deps.now ?? Date.now\n }\n\n /** Record a just-executed swap and make sure the alarm runs. */\n async track(input: Omit<SwapRecord, 'createdAt' | 'updatedAt' | 'checks' | 'status' | 'destTxHash'> & { status?: SwapRecordStatus }): Promise<SwapRecord> {\n const t = this.now()\n const record: SwapRecord = { ...input, status: input.status ?? 'pending', destTxHash: null, createdAt: t, updatedAt: t, checks: 0 }\n await this.deps.store.add(record)\n await this.deps.alarm.start()\n return record\n }\n\n /** After the user's claim transaction went out: keep polling until the provider sees the mint. */\n async claimed(id: string, destTxHash: string): Promise<void> {\n await this.deps.store.update(id, { status: 'claiming', destTxHash, claim: undefined as never })\n await this.deps.alarm.start()\n }\n\n /** One alarm tick: check every active record once; stop the alarm when nothing is active. Concurrent ticks coalesce. */\n tick(): Promise<void> {\n this.ticking ??= this.run().finally(() => { this.ticking = null })\n return this.ticking\n }\n\n private async run(): Promise<void> {\n const active = await this.deps.store.active()\n if (active.length === 0) { await this.deps.alarm.stop(); return }\n const giveUp = this.deps.giveUpAfterMs ?? 48 * 60 * 60_000\n for (const record of active) {\n const patch: Partial<SwapRecord> = { checks: record.checks + 1, updatedAt: this.now() }\n try {\n const s = await this.deps.status(record)\n patch.lastError = undefined as never\n if (s.depositReceived !== undefined) patch.depositReceived = s.depositReceived\n if (s.destTxHash) patch.destTxHash = s.destTxHash\n if (s.claim) patch.claim = s.claim\n // Our own claim is out: the provider still says action-required until it sees the mint; keep \"claiming\".\n patch.status = record.status === 'claiming' && (s.state === 'action-required' || s.state === 'pending') ? 'claiming' : s.state\n } catch (e) {\n patch.lastError = e instanceof Error ? e.message : String(e)\n if (this.now() - record.createdAt > giveUp) patch.status = 'expired'\n }\n await this.deps.store.update(record.id, patch)\n }\n if ((await this.deps.store.active()).length === 0) await this.deps.alarm.stop()\n }\n}\n","/**\n * Earn plan review — the Earn modules' counterpart of the swap sheet. A module\n * that exposes its plan (Aave / Morpho `planSupply` & co: ERC-20 approvals\n * first, then the call) gets ONE sheet for the whole plan; on approval exactly\n * those calls are pre-approved in the {@link ReviewGate} so the module's own\n * `supply()` / `withdraw()` / … passes through the reviewed account without a\n * second window. Modules without a plan API (Mellow, Lido, SSV, Jito) are\n * reviewed per transaction by the reviewed account itself — still every send.\n */\nimport { ApprovalQueue } from './approvals.js'\nimport { ReviewGate, evmCallMatcher, type GateMatcher } from './gate.js'\nimport type { EvmNetwork } from './networks.js'\n\nexport interface EarnTx {\n to: string\n data?: string | undefined\n /** Base units, decimal string. */\n value: string\n}\n\nexport interface EarnPlan {\n approvals: EarnTx[]\n tx: EarnTx\n}\n\nexport interface EarnReviewMeta {\n origin: string\n /** 'Aave v3', 'Morpho', … */\n module: string\n /** 'Supply', 'Withdraw', 'Borrow', 'Repay', 'Stake', … */\n action: string\n network: EvmNetwork\n /** Human lines the sheet shows (asset, amount, APY, market/vault, health factor…). */\n facts: { k: string; v: string }[]\n /** What the module says about the plan (its own refusals never reach here — they throw before). */\n checks?: { status: 'ok' | 'warn' | 'unknown'; label: string }[]\n /** tx-preview-evm result for approvals + call, attached by the wallet (JSON-safe) or null. */\n preview?: unknown\n}\n\nexport interface EarnApproval {\n module: string\n action: string\n network: EvmNetwork\n facts: { k: string; v: string }[]\n approvals: EarnTx[]\n tx: EarnTx\n checks: { status: 'ok' | 'warn' | 'unknown'; label: string }[]\n preview: unknown\n}\n\nconst APPROVE_SELECTOR = '0x095ea7b3'\n\nexport function earnPlanMatchers(network: EvmNetwork, plan: EarnPlan): GateMatcher[] {\n return [...plan.approvals, plan.tx].map((t) => evmCallMatcher({ caip2: network.caip2, to: t.to, data: t.data, value: BigInt(t.value) }))\n}\n\nexport function earnApprovalPayload(plan: EarnPlan, meta: EarnReviewMeta): EarnApproval {\n const checks = [{ status: 'ok' as const, label: `Built by the ${meta.module} module` }, ...(meta.checks ?? [])]\n for (const a of plan.approvals) {\n if (!a.data?.startsWith(APPROVE_SELECTOR)) checks.push({ status: 'warn', label: `Unexpected pre-call to ${a.to.slice(0, 8)}…` })\n }\n if (plan.approvals.length > 1) checks.push({ status: 'ok', label: `${plan.approvals.length} approvals (reset to 0 first)` })\n return { module: meta.module, action: meta.action, network: meta.network, facts: meta.facts, approvals: plan.approvals, tx: plan.tx, checks, preview: meta.preview ?? null }\n}\n\n/** One sheet for the plan; approve → pre-approve exactly its calls; decline → ReviewDeclined, nothing sent. */\nexport async function reviewEarnPlan(approvals: ApprovalQueue, gate: ReviewGate, meta: EarnReviewMeta, plan: EarnPlan): Promise<void> {\n await approvals.request({ origin: meta.origin, chain: meta.network.caip2, kind: 'earn', payload: earnApprovalPayload(plan, meta) })\n gate.preApprove(earnPlanMatchers(meta.network, plan), 10 * 60_000)\n}\n","/**\n * TON Connect protocol v2 — the parts that are pure data: request parsing,\n * the bytes `ton_proof` and `signData` sign, error codes. The wallet side (keys,\n * sheet, broadcast) lives in the extension; nothing here touches a key.\n *\n * ton_proof (docs.ton.org/develop/dapps/ton-connect/sign):\n * message = sha256(0xffff ‖ \"ton-connect\" ‖ sha256(\n * \"ton-proof-item-v2/\" ‖ workchain:int32BE ‖ address_hash:32 ‖\n * domain_len:uint32LE ‖ domain ‖ timestamp:uint64LE ‖ payload))\n * signature = ed25519(message)\n * signData (text | binary; `cell` payloads are refused here):\n * message = sha256(0xffff ‖ \"ton-connect/sign-data/\" ‖ workchain:int32BE ‖ address_hash:32 ‖\n * domain_len:uint32BE ‖ domain ‖ timestamp:uint64BE ‖ payload_prefix(\"txt\"|\"bin\") ‖ payload_len:uint32BE ‖ payload)\n */\nimport { sha256 } from '@noble/hashes/sha2.js'\n\nexport const TONCONNECT_ERRORS = { unknown: 0, badRequest: 1, manifestNotFound: 2, manifestContent: 3, unknownApp: 100, userDeclined: 300, methodNotSupported: 400 } as const\n\nexport class TonConnectError extends Error {\n constructor(readonly code: number, message: string) { super(message); this.name = 'TonConnectError' }\n}\n\nexport interface TonConnectRequest {\n manifestUrl: string\n /** `ton_addr` always; `ton_proof` with the dApp's payload when asked. */\n proofPayload?: string\n}\n\nexport function parseConnectRequest(message: unknown): TonConnectRequest {\n const m = message as { manifestUrl?: unknown; items?: unknown } | undefined\n if (!m || typeof m.manifestUrl !== 'string' || !/^https:\\/\\//.test(m.manifestUrl)) throw new TonConnectError(TONCONNECT_ERRORS.badRequest, 'ConnectRequest needs an https manifestUrl.')\n const items = Array.isArray(m.items) ? (m.items as Array<{ name?: unknown; payload?: unknown }>) : []\n if (!items.some((i) => i?.name === 'ton_addr')) throw new TonConnectError(TONCONNECT_ERRORS.badRequest, 'ConnectRequest must ask for ton_addr.')\n const proof = items.find((i) => i?.name === 'ton_proof')\n if (proof && typeof proof.payload !== 'string') throw new TonConnectError(TONCONNECT_ERRORS.badRequest, 'ton_proof needs a string payload.')\n for (const i of items) if (i?.name !== 'ton_addr' && i?.name !== 'ton_proof') throw new TonConnectError(TONCONNECT_ERRORS.badRequest, `Unknown connect item ${String(i?.name)}.`)\n return { manifestUrl: m.manifestUrl, ...(proof ? { proofPayload: proof.payload as string } : {}) }\n}\n\nexport interface TonConnectMessage {\n /** Destination, as given (friendly or raw). */\n address: string\n /** Nanotons, decimal string. */\n amount: string\n /** base64 BoC body. */\n payload?: string\n /** base64 BoC state init. */\n stateInit?: string\n}\n\nexport interface TonConnectSendTransaction {\n validUntil?: number\n network?: string\n from?: string\n messages: TonConnectMessage[]\n}\n\nexport const TONCONNECT_MAX_MESSAGES = 4\n\n/** `sendTransaction` params[0] (a JSON string per the spec, or an object). */\nexport function parseSendTransaction(param: unknown, options: { maxMessages?: number; network?: string } = {}): TonConnectSendTransaction {\n let o: Record<string, unknown>\n try { o = (typeof param === 'string' ? JSON.parse(param) : param) as Record<string, unknown> } catch { throw new TonConnectError(TONCONNECT_ERRORS.badRequest, 'sendTransaction params[0] is not valid JSON.') }\n if (!o || typeof o !== 'object') throw new TonConnectError(TONCONNECT_ERRORS.badRequest, 'sendTransaction needs a request object.')\n const network = options.network ?? '-239'\n if (o.network !== undefined && String(o.network) !== network) throw new TonConnectError(TONCONNECT_ERRORS.badRequest, `This wallet is on network ${network}; the request names ${String(o.network)}.`)\n const raw = Array.isArray(o.messages) ? (o.messages as Array<Record<string, unknown>>) : []\n if (raw.length === 0) throw new TonConnectError(TONCONNECT_ERRORS.badRequest, 'sendTransaction has no messages.')\n if (raw.length > (options.maxMessages ?? TONCONNECT_MAX_MESSAGES)) throw new TonConnectError(TONCONNECT_ERRORS.badRequest, `At most ${options.maxMessages ?? TONCONNECT_MAX_MESSAGES} messages per transaction.`)\n const messages: TonConnectMessage[] = raw.map((m, i) => {\n if (typeof m.address !== 'string' || !m.address) throw new TonConnectError(TONCONNECT_ERRORS.badRequest, `Message ${i + 1} has no address.`)\n if (typeof m.amount !== 'string' || !/^[0-9]+$/.test(m.amount)) throw new TonConnectError(TONCONNECT_ERRORS.badRequest, `Message ${i + 1} amount must be a decimal string of nanotons.`)\n if (m.payload !== undefined && typeof m.payload !== 'string') throw new TonConnectError(TONCONNECT_ERRORS.badRequest, `Message ${i + 1} payload must be a base64 BoC.`)\n if (m.stateInit !== undefined && typeof m.stateInit !== 'string') throw new TonConnectError(TONCONNECT_ERRORS.badRequest, `Message ${i + 1} stateInit must be a base64 BoC.`)\n return { address: m.address, amount: m.amount, ...(m.payload ? { payload: m.payload } : {}), ...(m.stateInit ? { stateInit: m.stateInit } : {}) }\n })\n const validUntil = typeof o.valid_until === 'number' ? o.valid_until : typeof o.validUntil === 'number' ? o.validUntil : undefined\n if (validUntil !== undefined && validUntil * 1000 < Date.now()) throw new TonConnectError(TONCONNECT_ERRORS.badRequest, 'The request has expired (valid_until is in the past).')\n return { messages, ...(validUntil !== undefined ? { validUntil } : {}), ...(o.network !== undefined ? { network: String(o.network) } : {}), ...(typeof o.from === 'string' ? { from: o.from } : {}) }\n}\n\nexport type TonSignDataPayload = { type: 'text'; text: string } | { type: 'binary'; bytes: string }\n\n/** `signData` params[0]: text or binary only — `cell` payloads need schema-aware rendering and are refused by name. */\nexport function parseSignData(param: unknown): TonSignDataPayload {\n let o: Record<string, unknown>\n try { o = (typeof param === 'string' ? JSON.parse(param) : param) as Record<string, unknown> } catch { throw new TonConnectError(TONCONNECT_ERRORS.badRequest, 'signData params[0] is not valid JSON.') }\n if (o?.type === 'text' && typeof o.text === 'string') return { type: 'text', text: o.text }\n if (o?.type === 'binary' && typeof o.bytes === 'string') return { type: 'binary', bytes: o.bytes }\n if (o?.type === 'cell') throw new TonConnectError(TONCONNECT_ERRORS.methodNotSupported, 'signData with a cell payload is not supported by this wallet.')\n throw new TonConnectError(TONCONNECT_ERRORS.badRequest, 'signData payload must be { type: \"text\", text } or { type: \"binary\", bytes }.')\n}\n\nexport interface TonAddressParts { workchain: number; hash: Uint8Array }\n\nconst utf8 = (s: string) => new TextEncoder().encode(s)\nconst int32BE = (n: number) => { const b = new Uint8Array(4); new DataView(b.buffer).setInt32(0, n, false); return b }\nconst uint32LE = (n: number) => { const b = new Uint8Array(4); new DataView(b.buffer).setUint32(0, n, true); return b }\nconst uint32BE = (n: number) => { const b = new Uint8Array(4); new DataView(b.buffer).setUint32(0, n, false); return b }\nconst uint64LE = (n: number) => { const b = new Uint8Array(8); new DataView(b.buffer).setBigUint64(0, BigInt(n), true); return b }\nconst uint64BE = (n: number) => { const b = new Uint8Array(8); new DataView(b.buffer).setBigUint64(0, BigInt(n), false); return b }\nconst concat = (...parts: Uint8Array[]) => { const out = new Uint8Array(parts.reduce((n, p) => n + p.length, 0)); let o = 0; for (const p of parts) { out.set(p, o); o += p.length } return out }\n\n/** The bytes a wallet signs for `ton_proof` (already hashed — sign them raw with ed25519). */\nexport function tonProofMessage(input: { address: TonAddressParts; domain: string; timestamp: number; payload: string }): Uint8Array {\n if (input.address.hash.length !== 32) throw new TonConnectError(TONCONNECT_ERRORS.unknown, 'address hash must be 32 bytes')\n const domain = utf8(input.domain)\n const inner = concat(utf8('ton-proof-item-v2/'), int32BE(input.address.workchain), input.address.hash, uint32LE(domain.length), domain, uint64LE(input.timestamp), utf8(input.payload))\n return sha256(concat(new Uint8Array([0xff, 0xff]), utf8('ton-connect'), sha256(inner)))\n}\n\n/** The bytes a wallet signs for `signData` (text / binary). */\nexport function tonSignDataMessage(input: { address: TonAddressParts; domain: string; timestamp: number; payload: TonSignDataPayload }): Uint8Array {\n if (input.address.hash.length !== 32) throw new TonConnectError(TONCONNECT_ERRORS.unknown, 'address hash must be 32 bytes')\n const domain = utf8(input.domain)\n const payload = input.payload.type === 'text' ? utf8(input.payload.text) : Uint8Array.from(atob(input.payload.bytes), (c) => c.charCodeAt(0))\n const prefix = utf8(input.payload.type === 'text' ? 'txt' : 'bin')\n return sha256(concat(new Uint8Array([0xff, 0xff]), utf8('ton-connect/sign-data/'), int32BE(input.address.workchain), input.address.hash, uint32BE(domain.length), domain, uint64BE(input.timestamp), prefix, uint32BE(payload.length), payload))\n}\n\n/** `0:abcd…` → parts; friendly addresses are the wallet package's job (it hands us the raw form). */\nexport function parseRawAddress(raw: string): TonAddressParts {\n const m = /^(-?\\d+):([0-9a-fA-F]{64})$/.exec(raw)\n if (!m) throw new TonConnectError(TONCONNECT_ERRORS.unknown, `not a raw TON address: ${raw}`)\n return { workchain: Number(m[1]), hash: Uint8Array.from(m[2]!.match(/../g)!, (h) => Number.parseInt(h, 16)) }\n}\n\n/** The dApp's domain for proofs, from the page origin (host only, as the spec's `domain.value`). */\nexport function proofDomain(origin: string): string {\n try { return new URL(origin).host } catch { throw new TonConnectError(TONCONNECT_ERRORS.badRequest, `bad origin ${origin}`) }\n}\n\n/** Our relay errors → TON Connect error codes. */\nexport function tonConnectErrorCode(e: unknown): number {\n if (e instanceof TonConnectError) return e.code\n const code = (e as { code?: unknown })?.code\n if (code === 4001) return TONCONNECT_ERRORS.userDeclined\n if (code === 4100) return TONCONNECT_ERRORS.unknownApp\n if (code === 4200) return TONCONNECT_ERRORS.methodNotSupported\n if (code === -32602) return TONCONNECT_ERRORS.badRequest\n return TONCONNECT_ERRORS.unknown\n}\n","/**\n * Phishing / impersonation checks on a page's host, against a SHIPPED list\n * (never fetched at runtime — decision 10). The list format is MetaMask's\n * eth-phishing-detect `config.json`: `blacklist` / `whitelist` (hosts; a listed\n * domain covers its subdomains), `fuzzylist` + `tolerance` (well-known hosts a\n * lookalike is measured against by Levenshtein distance). On top: punycode\n * (`xn--`) labels are flagged, because mixed-script lookalikes are the common\n * impersonation shape.\n */\nexport interface PhishingList {\n version?: number\n tolerance?: number\n blacklist: readonly string[]\n whitelist?: readonly string[]\n fuzzylist?: readonly string[]\n /** The wallet's own additions to the fuzzylist (the big dApps our users visit): same semantics. */\n extraFuzzylist?: readonly string[]\n}\n\nexport interface HostCheck {\n host: string\n /** On the blocklist (or a subdomain of a listed domain): refuse to inject / connect. */\n blocked: boolean\n /** Human lines for the approval window; empty when nothing is odd. */\n warnings: string[]\n}\n\nexport class PhishingDetector {\n private readonly black: Set<string>\n private readonly white: Set<string>\n private readonly fuzzy: string[]\n private readonly tolerance: number\n\n constructor(list: PhishingList) {\n this.black = new Set(list.blacklist.map(normalizeHost))\n this.white = new Set((list.whitelist ?? []).map(normalizeHost))\n this.fuzzy = [...new Set([...(list.fuzzylist ?? []), ...(list.extraFuzzylist ?? [])].map(normalizeHost))]\n this.tolerance = list.tolerance ?? 1\n }\n\n get size(): number {\n return this.black.size\n }\n\n check(hostOrOrigin: string): HostCheck {\n const host = hostOf(hostOrOrigin)\n const warnings: string[] = []\n if (!host) return { host, blocked: false, warnings }\n if (matchesList(host, this.white)) return { host, blocked: false, warnings }\n if (matchesList(host, this.black)) return { host, blocked: true, warnings: ['This site is on the shipped phishing list.'] }\n if (host.split('.').some((l) => l.startsWith('xn--'))) warnings.push('The address uses punycode (xn--): it may imitate another site with look-alike characters.')\n const look = this.lookalike(host)\n if (look) warnings.push(`The address looks like ${look} but is not that site.`)\n else {\n const brand = this.brandInLabel(host)\n if (brand) warnings.push(`The address contains the name of ${brand.known} (“${brand.label}”) but is not that site.`)\n }\n return { host, blocked: false, warnings }\n }\n\n /**\n * `metamask.io-login.com`, `app-uniswap.com`, `uniswap.org.evil.net`: a known site's name used as (part of) a label\n * of a host that is not that site. Names shorter than 5 characters are skipped (too many honest matches).\n */\n brandInLabel(host: string): { known: string; label: string } | null {\n const labels = host.split('.')\n for (const known of this.fuzzy) {\n if (host === known || host.endsWith(`.${known}`)) return null\n const name = stripForFuzzy(known).split('.').pop() ?? ''\n if (name.length < 5) continue\n const hit = labels.find((l) => l.includes(name))\n if (hit) return { known, label: hit }\n }\n return null\n }\n\n /** eth-phishing-detect's fuzzy check: the host (minus the TLD and a www.) within `tolerance` edits of a known one. */\n lookalike(host: string): string | null {\n const probe = stripForFuzzy(host)\n const probeName = probe.split('.').pop() ?? probe\n for (const known of this.fuzzy) {\n if (host === known || host.endsWith(`.${known}`)) return null // the real site or one of its subdomains\n const stripped = stripForFuzzy(known)\n if (levenshtein(probe, stripped) <= this.tolerance) return known // same name on another TLD counts as a lookalike\n // `uniswep.org` vs the listed `app.uniswap.org`: compare the registrable labels too (names ≥ 5 chars)\n const name = stripped.split('.').pop() ?? stripped\n if (name.length >= 5 && name !== probeName && levenshtein(probeName, name) <= this.tolerance) return known\n }\n return null\n }\n}\n\nexport const normalizeHost = (h: string): string => h.trim().toLowerCase().replace(/\\.$/, '')\n\nexport function hostOf(hostOrOrigin: string): string {\n try { return normalizeHost(new URL(hostOrOrigin.includes('://') ? hostOrOrigin : `https://${hostOrOrigin}`).hostname) } catch { return normalizeHost(hostOrOrigin) }\n}\n\n/** `a.b.c` matches a list containing `a.b.c`, `b.c` (parent) — never `c` alone unless listed. */\nfunction matchesList(host: string, list: Set<string>): boolean {\n const parts = host.split('.')\n for (let i = 0; i < parts.length - 1; i++) if (list.has(parts.slice(i).join('.'))) return true\n return list.has(host)\n}\n\nfunction stripForFuzzy(host: string): string {\n const parts = host.replace(/^www\\./, '').split('.')\n if (parts.length > 1) parts.pop() // TLD\n return parts.join('.')\n}\n\nexport function levenshtein(a: string, b: string): number {\n if (a === b) return 0\n const m = a.length, n = b.length\n if (m === 0) return n\n if (n === 0) return m\n let prev = Array.from({ length: n + 1 }, (_, j) => j)\n for (let i = 1; i <= m; i++) {\n const cur = [i]\n for (let j = 1; j <= n; j++) cur[j] = Math.min(prev[j]! + 1, cur[j - 1]! + 1, prev[j - 1]! + (a[i - 1] === b[j - 1] ? 0 : 1))\n prev = cur\n }\n return prev[n]!\n}\n","/**\n * WebAuthn assertion verification for \"passkey on every signature\": the approval\n * page asks the authenticator to sign a challenge the service worker derived from\n * the request, and the worker checks the assertion against the public key the\n * vault stored at registration. The ceremony itself (`navigator.credentials`) runs\n * in an extension page; this module is pure WebCrypto so it is testable and the\n * worker never trusts the page's word that the user touched the authenticator.\n *\n * ES256 (COSE -7, P-256 + SHA-256) only — the only algorithm registration asks\n * for. The signature is DER (WebAuthn) and converted to the raw r‖s WebCrypto\n * wants.\n */\nimport { fromBase64, toArrayBuffer } from './codec.js'\nimport { fromBase64Url } from './vault.js'\n\nexport interface AssertionInput {\n /** `PublicKeyCredential.rawId`, base64url. */\n credentialId: string\n /** `AuthenticatorAssertionResponse.authenticatorData`, base64url. */\n authenticatorData: string\n /** `AuthenticatorAssertionResponse.clientDataJSON`, base64url. */\n clientDataJSON: string\n /** `AuthenticatorAssertionResponse.signature` (DER), base64url. */\n signature: string\n}\n\nexport interface AssertionExpectations {\n /** SPKI public key of the credential, base64 (what `getPublicKey()` returned at registration). */\n publicKey: string\n /** COSE alg of the key; only -7 is accepted. */\n alg: number\n /** The challenge the worker handed the page (raw bytes; the page sent it base64url in clientDataJSON). */\n challenge: Uint8Array\n /** `chrome-extension://<id>` */\n origin: string\n /** The RP id the credential was created for (the extension id); its SHA-256 must be the first 32 bytes of authenticatorData. */\n rpId: string\n /** Require the UV flag (user verification: biometric / PIN) — on for signing. */\n requireUserVerification?: boolean\n crypto?: Crypto\n}\n\nexport type AssertionVerdict = { ok: true; counter: number } | { ok: false; reason: string }\n\nconst FLAG_UP = 0x01\nconst FLAG_UV = 0x04\n\n/** Verify one assertion. Never throws on bad input — a verdict with the reason, so the worker can refuse in-band. */\nexport async function verifyAssertion(input: AssertionInput, expect: AssertionExpectations): Promise<AssertionVerdict> {\n const c = expect.crypto ?? globalThis.crypto\n try {\n if (expect.alg !== -7) return { ok: false, reason: `unsupported algorithm ${expect.alg} (ES256 only)` }\n const authData = fromBase64Url(input.authenticatorData)\n const clientData = fromBase64Url(input.clientDataJSON)\n const signature = fromBase64Url(input.signature)\n if (authData.length < 37) return { ok: false, reason: 'authenticatorData too short' }\n // 1. client data: type, challenge, origin\n let client: { type?: unknown; challenge?: unknown; origin?: unknown; crossOrigin?: unknown }\n try { client = JSON.parse(new TextDecoder().decode(clientData)) as typeof client } catch { return { ok: false, reason: 'clientDataJSON is not JSON' } }\n if (client.type !== 'webauthn.get') return { ok: false, reason: `clientData.type is ${String(client.type)}` }\n if (client.origin !== expect.origin) return { ok: false, reason: `assertion origin ${String(client.origin)} is not ${expect.origin}` }\n if (client.crossOrigin === true) return { ok: false, reason: 'cross-origin assertion' }\n if (typeof client.challenge !== 'string' || !equal(fromBase64Url(client.challenge), expect.challenge)) return { ok: false, reason: 'challenge does not match this request' }\n // 2. authenticator data: rpIdHash, flags, counter\n const rpIdHash = new Uint8Array(await c.subtle.digest('SHA-256', toArrayBuffer(new TextEncoder().encode(expect.rpId))))\n if (!equal(authData.subarray(0, 32), rpIdHash)) return { ok: false, reason: 'rpIdHash does not match this extension' }\n const flags = authData[32]!\n if (!(flags & FLAG_UP)) return { ok: false, reason: 'user presence flag not set' }\n if (expect.requireUserVerification !== false && !(flags & FLAG_UV)) return { ok: false, reason: 'user verification flag not set' }\n const counter = ((authData[33]! << 24) | (authData[34]! << 16) | (authData[35]! << 8) | authData[36]!) >>> 0\n // 3. signature over authenticatorData ‖ SHA-256(clientDataJSON)\n const clientHash = new Uint8Array(await c.subtle.digest('SHA-256', toArrayBuffer(clientData)))\n const signed = new Uint8Array(authData.length + clientHash.length)\n signed.set(authData, 0)\n signed.set(clientHash, authData.length)\n const raw = derToRaw(signature)\n if (!raw) return { ok: false, reason: 'signature is not a DER ECDSA signature' }\n const key = await c.subtle.importKey('spki', toArrayBuffer(fromBase64(expect.publicKey)), { name: 'ECDSA', namedCurve: 'P-256' }, false, ['verify'])\n const ok = await c.subtle.verify({ name: 'ECDSA', hash: 'SHA-256' }, key, toArrayBuffer(raw), toArrayBuffer(signed))\n return ok ? { ok: true, counter } : { ok: false, reason: 'signature does not verify against the registered passkey' }\n } catch (e) {\n return { ok: false, reason: e instanceof Error ? e.message : String(e) }\n }\n}\n\n/** DER `SEQUENCE { INTEGER r, INTEGER s }` → 64-byte r‖s; `null` when malformed. */\nexport function derToRaw(der: Uint8Array): Uint8Array | null {\n if (der[0] !== 0x30) return null\n let i = 2\n if (der[1]! & 0x80) i = 2 + (der[1]! & 0x7f)\n const int = (): Uint8Array | null => {\n if (der[i] !== 0x02) return null\n const len = der[i + 1]!\n const start = i + 2\n i = start + len\n let v = der.subarray(start, start + len)\n while (v.length > 32 && v[0] === 0) v = v.subarray(1)\n if (v.length > 32) return null\n const out = new Uint8Array(32)\n out.set(v, 32 - v.length)\n return out\n }\n const r = int()\n if (!r) return null\n const s = int()\n if (!s) return null\n const raw = new Uint8Array(64)\n raw.set(r, 0)\n raw.set(s, 32)\n return raw\n}\n\n/** Raw r‖s → DER (tests build assertions with WebCrypto, which signs raw). */\nexport function rawToDer(raw: Uint8Array): Uint8Array {\n const enc = (v: Uint8Array): number[] => {\n let i = 0\n while (i < v.length - 1 && v[i] === 0) i++\n let body = Array.from(v.subarray(i))\n if (body[0]! & 0x80) body = [0, ...body]\n return [0x02, body.length, ...body]\n }\n const r = enc(raw.subarray(0, 32))\n const s = enc(raw.subarray(32, 64))\n return Uint8Array.from([0x30, r.length + s.length, ...r, ...s])\n}\n\n/**\n * The challenge for one approval request: SHA-256 over the request id, kind,\n * origin and payload, so an assertion made for one sheet cannot answer another.\n */\nexport async function approvalChallenge(request: { id: string; kind: string; origin: string; payload: unknown }, c: Crypto = globalThis.crypto): Promise<Uint8Array> {\n const text = JSON.stringify([request.id, request.kind, request.origin, request.payload])\n return new Uint8Array(await c.subtle.digest('SHA-256', toArrayBuffer(new TextEncoder().encode(text))))\n}\n\nfunction equal(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false\n let d = 0\n for (let i = 0; i < a.length; i++) d |= a[i]! ^ b[i]!\n return d === 0\n}\n","/**\n * Address poisoning: an attacker sends dust from an address whose first and\n * last characters match one the user actually paid, hoping the next copy-paste\n * picks the wrong one. The wallet has no transaction history, so it keeps its\n * own book of recipients the user confirmed (per chain) and warns when a new\n * recipient looks like one of them without being it. \"Fresh address\" (no\n * activity on chain) is the other half of the signal; the EVM preview computes it.\n */\nimport type { JsonStorage } from './storage.js'\n\nexport type RecipientsState = Record<string, string[]>\n\n/** How many characters at each end must match (after any `0x`). */\nexport const LOOKALIKE_PREFIX = 4\nexport const LOOKALIKE_SUFFIX = 4\n\nconst norm = (a: string) => a.trim().toLowerCase().replace(/^0x/, '')\n\n/** A known recipient that `address` imitates (same start and end, different address), or `null`. */\nexport function lookalikeOf(address: string, known: readonly string[]): string | null {\n const a = norm(address)\n if (a.length < LOOKALIKE_PREFIX + LOOKALIKE_SUFFIX + 1) return null\n for (const k of known) {\n const b = norm(k)\n if (b === a || b.length !== a.length) continue\n if (a.startsWith(b.slice(0, LOOKALIKE_PREFIX)) && a.endsWith(b.slice(-LOOKALIKE_SUFFIX))) return k\n }\n return null\n}\n\n/** Recipients the user confirmed on each chain (`eip155`, `solana`, …), newest last, capped. */\nexport class RecipientBook {\n private _state: RecipientsState | null = null\n\n constructor(private readonly storage: JsonStorage<RecipientsState>, private readonly cap = 500) {}\n\n private async state(): Promise<RecipientsState> {\n this._state ??= (await this.storage.get()) ?? {}\n return this._state\n }\n\n async list(namespace: string): Promise<string[]> {\n return [...((await this.state())[namespace] ?? [])]\n }\n\n async remember(namespace: string, address: string): Promise<void> {\n const s = { ...(await this.state()) }\n const list = (s[namespace] ?? []).filter((a) => norm(a) !== norm(address))\n list.push(address)\n s[namespace] = list.slice(-this.cap)\n await this.storage.set(s)\n this._state = s\n }\n\n /** `known` → the address is one the user paid before; `lookalike` → it imitates one. */\n async check(namespace: string, address: string): Promise<{ known: boolean; lookalike: string | null }> {\n const list = await this.list(namespace)\n const known = list.some((a) => norm(a) === norm(address))\n return { known, lookalike: known ? null : lookalikeOf(address, list) }\n }\n}\n"],"mappings":"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","names":["kek","kdf","import_core","import_core","import_core","lc","lc","import_protocol_swap2_core","APPROVE_SELECTOR","utf8"]}
|