@anywalletkit/extension-kit 0.2.2 → 0.3.0
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 +7 -1
- package/dist/index.cjs +64 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -3
- package/dist/index.d.ts +34 -3
- package/dist/index.js +64 -20
- package/dist/index.js.map +1 -1
- package/package.json +6 -5
package/dist/index.d.cts
CHANGED
|
@@ -110,6 +110,8 @@ interface VaultEnvelopeV2 {
|
|
|
110
110
|
createdAt: number;
|
|
111
111
|
/** When a v1 envelope was re-sealed as v2. */
|
|
112
112
|
upgradedAt?: number;
|
|
113
|
+
/** When {@link Vault.rotateVaultKey} last replaced the DEK. */
|
|
114
|
+
rotatedAt?: number;
|
|
113
115
|
}
|
|
114
116
|
type VaultEnvelope = VaultEnvelopeV1 | VaultEnvelopeV2;
|
|
115
117
|
/** Where the envelope lives. `chromeLocalVaultStorage()` for the extension, `memoryVaultStorage()` for tests. */
|
|
@@ -170,8 +172,24 @@ declare class Vault {
|
|
|
170
172
|
*/
|
|
171
173
|
unlock(password: string): Promise<Uint8Array>;
|
|
172
174
|
private _unlock;
|
|
173
|
-
/**
|
|
175
|
+
/**
|
|
176
|
+
* Re-wrap the DEK under a new password (fresh salt, current KDF). Secrets and passkeys are untouched —
|
|
177
|
+
* and so is the DEK: after a suspected compromise (a copied profile, a leaked session, a lost passkey)
|
|
178
|
+
* this is not enough, because whoever holds the DEK still opens every secret, old and new. Use
|
|
179
|
+
* {@link Vault.rotateVaultKey} then.
|
|
180
|
+
*/
|
|
174
181
|
changePassword(oldPassword: string, newPassword: string): Promise<void>;
|
|
182
|
+
/**
|
|
183
|
+
* Replace the DEK (scan 2026-10-27 modules, F30): a fresh random DEK, every secret re-sealed under it,
|
|
184
|
+
* the DEK wrapped under `password` with a fresh salt — written as one envelope, so a failure leaves the
|
|
185
|
+
* old vault as it was. Returns the new DEK: hand it to `session.unlock(dek)`, which overwrites the old
|
|
186
|
+
* one in `chrome.storage.session`. A DEK copied before the rotation opens nothing in the new envelope,
|
|
187
|
+
* and {@link Vault.setSecret} refuses it, so a stale session cannot seal new secrets under it.
|
|
188
|
+
*
|
|
189
|
+
* Passkeys are dropped — their boxes hold the old DEK and cannot be re-wrapped without their PRF
|
|
190
|
+
* output — and must be registered again ({@link Vault.addPasskey} with the new DEK).
|
|
191
|
+
*/
|
|
192
|
+
rotateVaultKey(password: string): Promise<Uint8Array>;
|
|
175
193
|
/** Public view of the registered passkeys (ids, labels; whether each can verify assertions). */
|
|
176
194
|
listPasskeys(): Promise<Array<{
|
|
177
195
|
id: string;
|
|
@@ -200,9 +218,13 @@ declare class Vault {
|
|
|
200
218
|
private _addPasskey;
|
|
201
219
|
/** Unseal the DEK with a passkey's PRF output. `wrong-password` when the box does not open, `missing` when the id is unknown. */
|
|
202
220
|
unlockWithPasskey(id: string, prf: Uint8Array): Promise<Uint8Array>;
|
|
221
|
+
/** Forget one passkey's box. A DEK that passkey already unwrapped stays valid: after a lost or compromised passkey, {@link Vault.rotateVaultKey}. */
|
|
203
222
|
removePasskey(id: string): Promise<void>;
|
|
204
223
|
listSecretIds(): Promise<string[]>;
|
|
205
|
-
/**
|
|
224
|
+
/**
|
|
225
|
+
* Seal `secret` under the DEK as `sourceId` (overwrites an entry with the same id). The DEK must open the
|
|
226
|
+
* vault's secrets (`locked` otherwise): a key retired by {@link Vault.rotateVaultKey} never seals a new one.
|
|
227
|
+
*/
|
|
206
228
|
setSecret(dek: Uint8Array, sourceId: string, secret: Uint8Array): Promise<void>;
|
|
207
229
|
/** Unseal one secret. `null` when the id is unknown; the caller zeroizes the result after use. */
|
|
208
230
|
getSecret(dek: Uint8Array, sourceId: string): Promise<Uint8Array | null>;
|
|
@@ -405,6 +427,15 @@ interface RelayEvent {
|
|
|
405
427
|
}
|
|
406
428
|
type RelayToWorker = RelayRequest;
|
|
407
429
|
type RelayToContent = RelayResponse | RelayEvent;
|
|
430
|
+
/** Longest method name a request may carry. */
|
|
431
|
+
declare const RELAY_METHOD_MAX = 128;
|
|
432
|
+
/**
|
|
433
|
+
* A method name as the providers spell them (`eth_sendTransaction`, `signAndSendTransaction`,
|
|
434
|
+
* `tron_requestAccounts`): letters, digits and `_`, at most {@link RELAY_METHOD_MAX}. Anything else
|
|
435
|
+
* is dropped at the relay, so a megabyte "method" never reaches a regex, a log or an error message
|
|
436
|
+
* (scan 2026-10-27 modules, F5).
|
|
437
|
+
*/
|
|
438
|
+
declare const isRelayMethod: (x: unknown) => x is string;
|
|
408
439
|
declare function isPageRequest(x: unknown): x is PageRequest;
|
|
409
440
|
declare function isPageResponse(x: unknown): x is PageResponse;
|
|
410
441
|
declare function isPageEvent(x: unknown): x is PageEvent;
|
|
@@ -1605,4 +1636,4 @@ declare class RecipientBook {
|
|
|
1605
1636
|
}>;
|
|
1606
1637
|
}
|
|
1607
1638
|
|
|
1608
|
-
export { ACTIVE_STATUSES, APPROVALS_MAX_PENDING_PER_ORIGIN, type AddChainApproval, type AlarmsLike, type ApprovalKind, ApprovalQueue, type ApprovalQueueOptions, type ApprovalRequest, type ApprovalWindow, type AssertionExpectations, type AssertionInput, type AssertionVerdict, BTC_CHAIN, BTC_ESPLORA, CHAIN_ACCOUNT_KEYS, type ChainAccountsKey, type ChainDescriptor, type ConnectApproval, DEFAULT_CHAIN, DEFAULT_NETWORKS, type EarnApproval, type EarnPlan, type EarnReviewMeta, type EarnTx, type EvmNetwork, type EvmSigner, FLOOR_TOLERANCE_BPS, type GateMatcher, type GatedOp, type HostCheck, type JsonStorage, KEYRING_STORAGE_KEY, LOOKALIKE_PREFIX, LOOKALIKE_SUFFIX, NEAR_CHAIN, NEAR_PROVIDERS, NON_EVM_CHAINS, NetworksTable, type OriginPermission, OriginRefused, type OriginVia, PAGE_TARGET, PORT_NAME, type PageEvent, type PageMessageEvent, type PageRequest, type PageResponse, type PageWindow, PermissionStore, type PermissionsState, PhishingDetector, type PhishingList, type PortSender, type PreparedTx, QueueLimitError, type QuoteRoutesOptions, READ_METHODS, RELAY_ERRORS, RecipientBook, type RecipientsState, type RelayChain, type RelayError, type RelayErrorOptions, type RelayEvent, type RelayRequest, type RelayResponse, type RelayToContent, type RelayToWorker, RequestRouter, ReviewDeclined, ReviewGate, type RouteListView, type RouteView, type RouterDeps, RouterError, SESSION_DEFAULT_AUTOLOCK_MS, SIGNING_METHODS, SOLANA_CHAIN, SOLANA_RPCS, type SealedBox, Session, type SessionAlarms, type SessionOptions, type SessionStorage, type SignApproval, type SignDeps, type SignRequestInfo, type SiweContext, type SiweInfo, type SiweMessage, type StorageAreaLike, type SwapApproval, type SwapRecord, type SwapRecordStatus, type SwapReviewMeta, SwapTracker, type SwapTrackerDeps, SwapsStore, type SwitchChainApproval, TONCONNECT_ERRORS, TONCONNECT_MAX_MESSAGES, TON_CHAIN, TON_ENDPOINTS, TRON_CHAIN, TRON_PROVIDERS, type TonAddressParts, TonConnectError, type TonConnectMessage, type TonConnectRequest, type TonConnectSendTransaction, type TonSignDataPayload, type TypedData, VAULT_DEFAULT_ITERATIONS, VAULT_LIMITS, VAULT_MIN_ITERATIONS, VAULT_MIN_PASSWORD_LENGTH, VAULT_MIN_SCRYPT, VAULT_SCRYPT, VAULT_STORAGE_KEY, Vault, type VaultEnvelope, type VaultEnvelopeV1, type VaultEnvelopeV2, VaultError, type VaultErrorCode, type VaultKdfInfo, type VaultOptions, type VaultPasskey, type VaultStorage, ZCASH_BLOCKCHAIR, ZCASH_CHAIN, approvalChallenge, caip2FromChainId, chainHex, chainTxMatcher, checkSenderOrigin, chromeAlarms, chromeJsonStorage, chromeKeyringStorage, chromeLocalVaultStorage, chromeSessionStorage, classifySignRequest, createSignHandler, decodedMessage, derToRaw, describeSiwe, earnApprovalPayload, earnPlanMatchers, encodeApproveCalldata, evmCallMatcher, executionFloor, fromBase64Url, hostOf, isCatalogChain, isEnvelopeV1, isEnvelopeV2, isLocalHost, isPageEvent, isPageRequest, isPageResponse, isRelayRequest, isRelayToContent, levenshtein, lookalikeOf, memoryAlarms, memoryApprovalWindow, memoryJsonStorage, memorySessionStorage, memoryVaultStorage, messageText, newRequestId, nonEvmChain, normalizeHost, pageRequestFrom, parseAddChainParams, parseConnectRequest, parseRawAddress, parseSendTransaction, parseSignData, parseSiwe, parseSwapId, planMatchers, prepareTransaction, proofDomain, quoteRoutes, rank, rawToDer, relayError, reviewEarnPlan, reviewSwapPlan, siweProblems, stampOrigin, swapApprovalPayload, toBase64Url, toRelayError, tonConnectErrorCode, tonProofMessage, tonSignDataMessage, typedDataMatcher, vaultSecretStorage, verifyAssertion };
|
|
1639
|
+
export { ACTIVE_STATUSES, APPROVALS_MAX_PENDING_PER_ORIGIN, type AddChainApproval, type AlarmsLike, type ApprovalKind, ApprovalQueue, type ApprovalQueueOptions, type ApprovalRequest, type ApprovalWindow, type AssertionExpectations, type AssertionInput, type AssertionVerdict, BTC_CHAIN, BTC_ESPLORA, CHAIN_ACCOUNT_KEYS, type ChainAccountsKey, type ChainDescriptor, type ConnectApproval, DEFAULT_CHAIN, DEFAULT_NETWORKS, type EarnApproval, type EarnPlan, type EarnReviewMeta, type EarnTx, type EvmNetwork, type EvmSigner, FLOOR_TOLERANCE_BPS, type GateMatcher, type GatedOp, type HostCheck, type JsonStorage, KEYRING_STORAGE_KEY, LOOKALIKE_PREFIX, LOOKALIKE_SUFFIX, NEAR_CHAIN, NEAR_PROVIDERS, NON_EVM_CHAINS, NetworksTable, type OriginPermission, OriginRefused, type OriginVia, PAGE_TARGET, PORT_NAME, type PageEvent, type PageMessageEvent, type PageRequest, type PageResponse, type PageWindow, PermissionStore, type PermissionsState, PhishingDetector, type PhishingList, type PortSender, type PreparedTx, QueueLimitError, type QuoteRoutesOptions, READ_METHODS, RELAY_ERRORS, RELAY_METHOD_MAX, RecipientBook, type RecipientsState, type RelayChain, type RelayError, type RelayErrorOptions, type RelayEvent, type RelayRequest, type RelayResponse, type RelayToContent, type RelayToWorker, RequestRouter, ReviewDeclined, ReviewGate, type RouteListView, type RouteView, type RouterDeps, RouterError, SESSION_DEFAULT_AUTOLOCK_MS, SIGNING_METHODS, SOLANA_CHAIN, SOLANA_RPCS, type SealedBox, Session, type SessionAlarms, type SessionOptions, type SessionStorage, type SignApproval, type SignDeps, type SignRequestInfo, type SiweContext, type SiweInfo, type SiweMessage, type StorageAreaLike, type SwapApproval, type SwapRecord, type SwapRecordStatus, type SwapReviewMeta, SwapTracker, type SwapTrackerDeps, SwapsStore, type SwitchChainApproval, TONCONNECT_ERRORS, TONCONNECT_MAX_MESSAGES, TON_CHAIN, TON_ENDPOINTS, TRON_CHAIN, TRON_PROVIDERS, type TonAddressParts, TonConnectError, type TonConnectMessage, type TonConnectRequest, type TonConnectSendTransaction, type TonSignDataPayload, type TypedData, VAULT_DEFAULT_ITERATIONS, VAULT_LIMITS, VAULT_MIN_ITERATIONS, VAULT_MIN_PASSWORD_LENGTH, VAULT_MIN_SCRYPT, VAULT_SCRYPT, VAULT_STORAGE_KEY, Vault, type VaultEnvelope, type VaultEnvelopeV1, type VaultEnvelopeV2, VaultError, type VaultErrorCode, type VaultKdfInfo, type VaultOptions, type VaultPasskey, type VaultStorage, ZCASH_BLOCKCHAIR, ZCASH_CHAIN, approvalChallenge, caip2FromChainId, chainHex, chainTxMatcher, checkSenderOrigin, chromeAlarms, chromeJsonStorage, chromeKeyringStorage, chromeLocalVaultStorage, chromeSessionStorage, classifySignRequest, createSignHandler, decodedMessage, derToRaw, describeSiwe, earnApprovalPayload, earnPlanMatchers, encodeApproveCalldata, evmCallMatcher, executionFloor, fromBase64Url, hostOf, isCatalogChain, isEnvelopeV1, isEnvelopeV2, isLocalHost, isPageEvent, isPageRequest, isPageResponse, isRelayMethod, isRelayRequest, isRelayToContent, levenshtein, lookalikeOf, memoryAlarms, memoryApprovalWindow, memoryJsonStorage, memorySessionStorage, memoryVaultStorage, messageText, newRequestId, nonEvmChain, normalizeHost, pageRequestFrom, parseAddChainParams, parseConnectRequest, parseRawAddress, parseSendTransaction, parseSignData, parseSiwe, parseSwapId, planMatchers, prepareTransaction, proofDomain, quoteRoutes, rank, rawToDer, relayError, reviewEarnPlan, reviewSwapPlan, siweProblems, stampOrigin, swapApprovalPayload, toBase64Url, toRelayError, tonConnectErrorCode, tonProofMessage, tonSignDataMessage, typedDataMatcher, vaultSecretStorage, verifyAssertion };
|
package/dist/index.d.ts
CHANGED
|
@@ -110,6 +110,8 @@ interface VaultEnvelopeV2 {
|
|
|
110
110
|
createdAt: number;
|
|
111
111
|
/** When a v1 envelope was re-sealed as v2. */
|
|
112
112
|
upgradedAt?: number;
|
|
113
|
+
/** When {@link Vault.rotateVaultKey} last replaced the DEK. */
|
|
114
|
+
rotatedAt?: number;
|
|
113
115
|
}
|
|
114
116
|
type VaultEnvelope = VaultEnvelopeV1 | VaultEnvelopeV2;
|
|
115
117
|
/** Where the envelope lives. `chromeLocalVaultStorage()` for the extension, `memoryVaultStorage()` for tests. */
|
|
@@ -170,8 +172,24 @@ declare class Vault {
|
|
|
170
172
|
*/
|
|
171
173
|
unlock(password: string): Promise<Uint8Array>;
|
|
172
174
|
private _unlock;
|
|
173
|
-
/**
|
|
175
|
+
/**
|
|
176
|
+
* Re-wrap the DEK under a new password (fresh salt, current KDF). Secrets and passkeys are untouched —
|
|
177
|
+
* and so is the DEK: after a suspected compromise (a copied profile, a leaked session, a lost passkey)
|
|
178
|
+
* this is not enough, because whoever holds the DEK still opens every secret, old and new. Use
|
|
179
|
+
* {@link Vault.rotateVaultKey} then.
|
|
180
|
+
*/
|
|
174
181
|
changePassword(oldPassword: string, newPassword: string): Promise<void>;
|
|
182
|
+
/**
|
|
183
|
+
* Replace the DEK (scan 2026-10-27 modules, F30): a fresh random DEK, every secret re-sealed under it,
|
|
184
|
+
* the DEK wrapped under `password` with a fresh salt — written as one envelope, so a failure leaves the
|
|
185
|
+
* old vault as it was. Returns the new DEK: hand it to `session.unlock(dek)`, which overwrites the old
|
|
186
|
+
* one in `chrome.storage.session`. A DEK copied before the rotation opens nothing in the new envelope,
|
|
187
|
+
* and {@link Vault.setSecret} refuses it, so a stale session cannot seal new secrets under it.
|
|
188
|
+
*
|
|
189
|
+
* Passkeys are dropped — their boxes hold the old DEK and cannot be re-wrapped without their PRF
|
|
190
|
+
* output — and must be registered again ({@link Vault.addPasskey} with the new DEK).
|
|
191
|
+
*/
|
|
192
|
+
rotateVaultKey(password: string): Promise<Uint8Array>;
|
|
175
193
|
/** Public view of the registered passkeys (ids, labels; whether each can verify assertions). */
|
|
176
194
|
listPasskeys(): Promise<Array<{
|
|
177
195
|
id: string;
|
|
@@ -200,9 +218,13 @@ declare class Vault {
|
|
|
200
218
|
private _addPasskey;
|
|
201
219
|
/** Unseal the DEK with a passkey's PRF output. `wrong-password` when the box does not open, `missing` when the id is unknown. */
|
|
202
220
|
unlockWithPasskey(id: string, prf: Uint8Array): Promise<Uint8Array>;
|
|
221
|
+
/** Forget one passkey's box. A DEK that passkey already unwrapped stays valid: after a lost or compromised passkey, {@link Vault.rotateVaultKey}. */
|
|
203
222
|
removePasskey(id: string): Promise<void>;
|
|
204
223
|
listSecretIds(): Promise<string[]>;
|
|
205
|
-
/**
|
|
224
|
+
/**
|
|
225
|
+
* Seal `secret` under the DEK as `sourceId` (overwrites an entry with the same id). The DEK must open the
|
|
226
|
+
* vault's secrets (`locked` otherwise): a key retired by {@link Vault.rotateVaultKey} never seals a new one.
|
|
227
|
+
*/
|
|
206
228
|
setSecret(dek: Uint8Array, sourceId: string, secret: Uint8Array): Promise<void>;
|
|
207
229
|
/** Unseal one secret. `null` when the id is unknown; the caller zeroizes the result after use. */
|
|
208
230
|
getSecret(dek: Uint8Array, sourceId: string): Promise<Uint8Array | null>;
|
|
@@ -405,6 +427,15 @@ interface RelayEvent {
|
|
|
405
427
|
}
|
|
406
428
|
type RelayToWorker = RelayRequest;
|
|
407
429
|
type RelayToContent = RelayResponse | RelayEvent;
|
|
430
|
+
/** Longest method name a request may carry. */
|
|
431
|
+
declare const RELAY_METHOD_MAX = 128;
|
|
432
|
+
/**
|
|
433
|
+
* A method name as the providers spell them (`eth_sendTransaction`, `signAndSendTransaction`,
|
|
434
|
+
* `tron_requestAccounts`): letters, digits and `_`, at most {@link RELAY_METHOD_MAX}. Anything else
|
|
435
|
+
* is dropped at the relay, so a megabyte "method" never reaches a regex, a log or an error message
|
|
436
|
+
* (scan 2026-10-27 modules, F5).
|
|
437
|
+
*/
|
|
438
|
+
declare const isRelayMethod: (x: unknown) => x is string;
|
|
408
439
|
declare function isPageRequest(x: unknown): x is PageRequest;
|
|
409
440
|
declare function isPageResponse(x: unknown): x is PageResponse;
|
|
410
441
|
declare function isPageEvent(x: unknown): x is PageEvent;
|
|
@@ -1605,4 +1636,4 @@ declare class RecipientBook {
|
|
|
1605
1636
|
}>;
|
|
1606
1637
|
}
|
|
1607
1638
|
|
|
1608
|
-
export { ACTIVE_STATUSES, APPROVALS_MAX_PENDING_PER_ORIGIN, type AddChainApproval, type AlarmsLike, type ApprovalKind, ApprovalQueue, type ApprovalQueueOptions, type ApprovalRequest, type ApprovalWindow, type AssertionExpectations, type AssertionInput, type AssertionVerdict, BTC_CHAIN, BTC_ESPLORA, CHAIN_ACCOUNT_KEYS, type ChainAccountsKey, type ChainDescriptor, type ConnectApproval, DEFAULT_CHAIN, DEFAULT_NETWORKS, type EarnApproval, type EarnPlan, type EarnReviewMeta, type EarnTx, type EvmNetwork, type EvmSigner, FLOOR_TOLERANCE_BPS, type GateMatcher, type GatedOp, type HostCheck, type JsonStorage, KEYRING_STORAGE_KEY, LOOKALIKE_PREFIX, LOOKALIKE_SUFFIX, NEAR_CHAIN, NEAR_PROVIDERS, NON_EVM_CHAINS, NetworksTable, type OriginPermission, OriginRefused, type OriginVia, PAGE_TARGET, PORT_NAME, type PageEvent, type PageMessageEvent, type PageRequest, type PageResponse, type PageWindow, PermissionStore, type PermissionsState, PhishingDetector, type PhishingList, type PortSender, type PreparedTx, QueueLimitError, type QuoteRoutesOptions, READ_METHODS, RELAY_ERRORS, RecipientBook, type RecipientsState, type RelayChain, type RelayError, type RelayErrorOptions, type RelayEvent, type RelayRequest, type RelayResponse, type RelayToContent, type RelayToWorker, RequestRouter, ReviewDeclined, ReviewGate, type RouteListView, type RouteView, type RouterDeps, RouterError, SESSION_DEFAULT_AUTOLOCK_MS, SIGNING_METHODS, SOLANA_CHAIN, SOLANA_RPCS, type SealedBox, Session, type SessionAlarms, type SessionOptions, type SessionStorage, type SignApproval, type SignDeps, type SignRequestInfo, type SiweContext, type SiweInfo, type SiweMessage, type StorageAreaLike, type SwapApproval, type SwapRecord, type SwapRecordStatus, type SwapReviewMeta, SwapTracker, type SwapTrackerDeps, SwapsStore, type SwitchChainApproval, TONCONNECT_ERRORS, TONCONNECT_MAX_MESSAGES, TON_CHAIN, TON_ENDPOINTS, TRON_CHAIN, TRON_PROVIDERS, type TonAddressParts, TonConnectError, type TonConnectMessage, type TonConnectRequest, type TonConnectSendTransaction, type TonSignDataPayload, type TypedData, VAULT_DEFAULT_ITERATIONS, VAULT_LIMITS, VAULT_MIN_ITERATIONS, VAULT_MIN_PASSWORD_LENGTH, VAULT_MIN_SCRYPT, VAULT_SCRYPT, VAULT_STORAGE_KEY, Vault, type VaultEnvelope, type VaultEnvelopeV1, type VaultEnvelopeV2, VaultError, type VaultErrorCode, type VaultKdfInfo, type VaultOptions, type VaultPasskey, type VaultStorage, ZCASH_BLOCKCHAIR, ZCASH_CHAIN, approvalChallenge, caip2FromChainId, chainHex, chainTxMatcher, checkSenderOrigin, chromeAlarms, chromeJsonStorage, chromeKeyringStorage, chromeLocalVaultStorage, chromeSessionStorage, classifySignRequest, createSignHandler, decodedMessage, derToRaw, describeSiwe, earnApprovalPayload, earnPlanMatchers, encodeApproveCalldata, evmCallMatcher, executionFloor, fromBase64Url, hostOf, isCatalogChain, isEnvelopeV1, isEnvelopeV2, isLocalHost, isPageEvent, isPageRequest, isPageResponse, isRelayRequest, isRelayToContent, levenshtein, lookalikeOf, memoryAlarms, memoryApprovalWindow, memoryJsonStorage, memorySessionStorage, memoryVaultStorage, messageText, newRequestId, nonEvmChain, normalizeHost, pageRequestFrom, parseAddChainParams, parseConnectRequest, parseRawAddress, parseSendTransaction, parseSignData, parseSiwe, parseSwapId, planMatchers, prepareTransaction, proofDomain, quoteRoutes, rank, rawToDer, relayError, reviewEarnPlan, reviewSwapPlan, siweProblems, stampOrigin, swapApprovalPayload, toBase64Url, toRelayError, tonConnectErrorCode, tonProofMessage, tonSignDataMessage, typedDataMatcher, vaultSecretStorage, verifyAssertion };
|
|
1639
|
+
export { ACTIVE_STATUSES, APPROVALS_MAX_PENDING_PER_ORIGIN, type AddChainApproval, type AlarmsLike, type ApprovalKind, ApprovalQueue, type ApprovalQueueOptions, type ApprovalRequest, type ApprovalWindow, type AssertionExpectations, type AssertionInput, type AssertionVerdict, BTC_CHAIN, BTC_ESPLORA, CHAIN_ACCOUNT_KEYS, type ChainAccountsKey, type ChainDescriptor, type ConnectApproval, DEFAULT_CHAIN, DEFAULT_NETWORKS, type EarnApproval, type EarnPlan, type EarnReviewMeta, type EarnTx, type EvmNetwork, type EvmSigner, FLOOR_TOLERANCE_BPS, type GateMatcher, type GatedOp, type HostCheck, type JsonStorage, KEYRING_STORAGE_KEY, LOOKALIKE_PREFIX, LOOKALIKE_SUFFIX, NEAR_CHAIN, NEAR_PROVIDERS, NON_EVM_CHAINS, NetworksTable, type OriginPermission, OriginRefused, type OriginVia, PAGE_TARGET, PORT_NAME, type PageEvent, type PageMessageEvent, type PageRequest, type PageResponse, type PageWindow, PermissionStore, type PermissionsState, PhishingDetector, type PhishingList, type PortSender, type PreparedTx, QueueLimitError, type QuoteRoutesOptions, READ_METHODS, RELAY_ERRORS, RELAY_METHOD_MAX, RecipientBook, type RecipientsState, type RelayChain, type RelayError, type RelayErrorOptions, type RelayEvent, type RelayRequest, type RelayResponse, type RelayToContent, type RelayToWorker, RequestRouter, ReviewDeclined, ReviewGate, type RouteListView, type RouteView, type RouterDeps, RouterError, SESSION_DEFAULT_AUTOLOCK_MS, SIGNING_METHODS, SOLANA_CHAIN, SOLANA_RPCS, type SealedBox, Session, type SessionAlarms, type SessionOptions, type SessionStorage, type SignApproval, type SignDeps, type SignRequestInfo, type SiweContext, type SiweInfo, type SiweMessage, type StorageAreaLike, type SwapApproval, type SwapRecord, type SwapRecordStatus, type SwapReviewMeta, SwapTracker, type SwapTrackerDeps, SwapsStore, type SwitchChainApproval, TONCONNECT_ERRORS, TONCONNECT_MAX_MESSAGES, TON_CHAIN, TON_ENDPOINTS, TRON_CHAIN, TRON_PROVIDERS, type TonAddressParts, TonConnectError, type TonConnectMessage, type TonConnectRequest, type TonConnectSendTransaction, type TonSignDataPayload, type TypedData, VAULT_DEFAULT_ITERATIONS, VAULT_LIMITS, VAULT_MIN_ITERATIONS, VAULT_MIN_PASSWORD_LENGTH, VAULT_MIN_SCRYPT, VAULT_SCRYPT, VAULT_STORAGE_KEY, Vault, type VaultEnvelope, type VaultEnvelopeV1, type VaultEnvelopeV2, VaultError, type VaultErrorCode, type VaultKdfInfo, type VaultOptions, type VaultPasskey, type VaultStorage, ZCASH_BLOCKCHAIR, ZCASH_CHAIN, approvalChallenge, caip2FromChainId, chainHex, chainTxMatcher, checkSenderOrigin, chromeAlarms, chromeJsonStorage, chromeKeyringStorage, chromeLocalVaultStorage, chromeSessionStorage, classifySignRequest, createSignHandler, decodedMessage, derToRaw, describeSiwe, earnApprovalPayload, earnPlanMatchers, encodeApproveCalldata, evmCallMatcher, executionFloor, fromBase64Url, hostOf, isCatalogChain, isEnvelopeV1, isEnvelopeV2, isLocalHost, isPageEvent, isPageRequest, isPageResponse, isRelayMethod, isRelayRequest, isRelayToContent, levenshtein, lookalikeOf, memoryAlarms, memoryApprovalWindow, memoryJsonStorage, memorySessionStorage, memoryVaultStorage, messageText, newRequestId, nonEvmChain, normalizeHost, pageRequestFrom, parseAddChainParams, parseConnectRequest, parseRawAddress, parseSendTransaction, parseSignData, parseSiwe, parseSwapId, planMatchers, prepareTransaction, proofDomain, quoteRoutes, rank, rawToDer, relayError, reviewEarnPlan, reviewSwapPlan, siweProblems, stampOrigin, swapApprovalPayload, toBase64Url, toRelayError, tonConnectErrorCode, tonProofMessage, tonSignDataMessage, typedDataMatcher, vaultSecretStorage, verifyAssertion };
|
package/dist/index.js
CHANGED
|
@@ -144,7 +144,12 @@ var Vault = class {
|
|
|
144
144
|
const kek = await this._deriveScrypt(password, fromBase64(envelope.kdf.salt), envelope.kdf);
|
|
145
145
|
return this._open(kek, envelope.dek, aadDekV2(envelope.kdf), "wrong-password");
|
|
146
146
|
}
|
|
147
|
-
/**
|
|
147
|
+
/**
|
|
148
|
+
* Re-wrap the DEK under a new password (fresh salt, current KDF). Secrets and passkeys are untouched —
|
|
149
|
+
* and so is the DEK: after a suspected compromise (a copied profile, a leaked session, a lost passkey)
|
|
150
|
+
* this is not enough, because whoever holds the DEK still opens every secret, old and new. Use
|
|
151
|
+
* {@link Vault.rotateVaultKey} then.
|
|
152
|
+
*/
|
|
148
153
|
async changePassword(oldPassword, newPassword) {
|
|
149
154
|
requirePassword(newPassword, VAULT_MIN_PASSWORD_LENGTH);
|
|
150
155
|
requirePassword(oldPassword);
|
|
@@ -160,6 +165,45 @@ var Vault = class {
|
|
|
160
165
|
}
|
|
161
166
|
});
|
|
162
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* Replace the DEK (scan 2026-10-27 modules, F30): a fresh random DEK, every secret re-sealed under it,
|
|
170
|
+
* the DEK wrapped under `password` with a fresh salt — written as one envelope, so a failure leaves the
|
|
171
|
+
* old vault as it was. Returns the new DEK: hand it to `session.unlock(dek)`, which overwrites the old
|
|
172
|
+
* one in `chrome.storage.session`. A DEK copied before the rotation opens nothing in the new envelope,
|
|
173
|
+
* and {@link Vault.setSecret} refuses it, so a stale session cannot seal new secrets under it.
|
|
174
|
+
*
|
|
175
|
+
* Passkeys are dropped — their boxes hold the old DEK and cannot be re-wrapped without their PRF
|
|
176
|
+
* output — and must be registered again ({@link Vault.addPasskey} with the new DEK).
|
|
177
|
+
*/
|
|
178
|
+
async rotateVaultKey(password) {
|
|
179
|
+
requirePassword(password);
|
|
180
|
+
return this._exclusive(async () => {
|
|
181
|
+
const oldDek = await this._unlock(password);
|
|
182
|
+
const dek = this._random(DEK_BYTES);
|
|
183
|
+
try {
|
|
184
|
+
const envelope = await this._load();
|
|
185
|
+
const [oldKey, newKey] = await Promise.all([this._importDek(oldDek), this._importDek(dek)]);
|
|
186
|
+
const secrets = {};
|
|
187
|
+
for (const [id, box] of Object.entries(envelope.secrets)) {
|
|
188
|
+
const plaintext = await this._open(oldKey, box, aadSecret(id), "locked");
|
|
189
|
+
try {
|
|
190
|
+
secrets[id] = await this._seal(newKey, plaintext, aadSecret(id));
|
|
191
|
+
} finally {
|
|
192
|
+
zeroize(plaintext);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
const next = await this._sealEnvelope(password, dek, secrets, [], envelope.createdAt);
|
|
196
|
+
const upgradedAt = isEnvelopeV2(envelope) ? envelope.upgradedAt : void 0;
|
|
197
|
+
await this._write(isEnvelopeV2(next) ? { ...next, ...upgradedAt !== void 0 ? { upgradedAt } : {}, rotatedAt: Date.now() } : next);
|
|
198
|
+
return dek;
|
|
199
|
+
} catch (e) {
|
|
200
|
+
zeroize(dek);
|
|
201
|
+
throw e;
|
|
202
|
+
} finally {
|
|
203
|
+
zeroize(oldDek);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
}
|
|
163
207
|
// ---- passkeys (v2) ----
|
|
164
208
|
/** Public view of the registered passkeys (ids, labels; whether each can verify assertions). */
|
|
165
209
|
async listPasskeys() {
|
|
@@ -217,6 +261,7 @@ var Vault = class {
|
|
|
217
261
|
zeroize(prf);
|
|
218
262
|
}
|
|
219
263
|
}
|
|
264
|
+
/** Forget one passkey's box. A DEK that passkey already unwrapped stays valid: after a lost or compromised passkey, {@link Vault.rotateVaultKey}. */
|
|
220
265
|
async removePasskey(id) {
|
|
221
266
|
requireId(id);
|
|
222
267
|
return this._exclusive(async () => {
|
|
@@ -230,13 +275,17 @@ var Vault = class {
|
|
|
230
275
|
const envelope = await this._storage.get();
|
|
231
276
|
return envelope ? Object.keys(envelope.secrets) : [];
|
|
232
277
|
}
|
|
233
|
-
/**
|
|
278
|
+
/**
|
|
279
|
+
* Seal `secret` under the DEK as `sourceId` (overwrites an entry with the same id). The DEK must open the
|
|
280
|
+
* vault's secrets (`locked` otherwise): a key retired by {@link Vault.rotateVaultKey} never seals a new one.
|
|
281
|
+
*/
|
|
234
282
|
async setSecret(dek, sourceId, secret) {
|
|
235
283
|
requireId(sourceId);
|
|
236
284
|
if (secret.length > VAULT_LIMITS.secretBytes) throw new VaultError(`A secret is at most ${VAULT_LIMITS.secretBytes} bytes.`, "invalid-input");
|
|
237
285
|
const key = await this._importDek(dek);
|
|
238
286
|
return this._exclusive(async () => {
|
|
239
287
|
const envelope = await this._load();
|
|
288
|
+
if (Object.keys(envelope.secrets).length > 0) await this._requireDek(dek, envelope);
|
|
240
289
|
if (!(sourceId in envelope.secrets) && Object.keys(envelope.secrets).length >= VAULT_LIMITS.secrets) {
|
|
241
290
|
throw new VaultError(`A vault holds at most ${VAULT_LIMITS.secrets} secrets.`, "invalid-input");
|
|
242
291
|
}
|
|
@@ -620,8 +669,10 @@ var RELAY_ERRORS = {
|
|
|
620
669
|
var CHAINS = /* @__PURE__ */ new Set(["eip155", "solana", "ton", "tron", "bip122", "near"]);
|
|
621
670
|
var isRecord = (x) => typeof x === "object" && x !== null;
|
|
622
671
|
var isId = (x) => typeof x === "string" && x.length > 0 && x.length <= 64;
|
|
672
|
+
var RELAY_METHOD_MAX = 128;
|
|
673
|
+
var isRelayMethod = (x) => typeof x === "string" && x.length > 0 && x.length <= RELAY_METHOD_MAX && /^[A-Za-z0-9_]+$/.test(x);
|
|
623
674
|
function isPageRequest(x) {
|
|
624
|
-
return isRecord(x) && x.target === PAGE_TARGET.toContent && isId(x.id) && CHAINS.has(x.chain) &&
|
|
675
|
+
return isRecord(x) && x.target === PAGE_TARGET.toContent && isId(x.id) && CHAINS.has(x.chain) && isRelayMethod(x.method);
|
|
625
676
|
}
|
|
626
677
|
function isPageResponse(x) {
|
|
627
678
|
return isRecord(x) && x.target === PAGE_TARGET.toPage && isId(x.id);
|
|
@@ -630,7 +681,7 @@ function isPageEvent(x) {
|
|
|
630
681
|
return isRecord(x) && x.target === PAGE_TARGET.toPage && !("id" in x) && CHAINS.has(x.chain) && typeof x.event === "string";
|
|
631
682
|
}
|
|
632
683
|
function isRelayRequest(x) {
|
|
633
|
-
return isRecord(x) && x.kind === "request" && isId(x.id) && typeof x.origin === "string" && CHAINS.has(x.chain) &&
|
|
684
|
+
return isRecord(x) && x.kind === "request" && isId(x.id) && typeof x.origin === "string" && CHAINS.has(x.chain) && isRelayMethod(x.method);
|
|
634
685
|
}
|
|
635
686
|
function isRelayToContent(x) {
|
|
636
687
|
return isRecord(x) && (x.kind === "response" && isId(x.id) || x.kind === "event" && typeof x.event === "string");
|
|
@@ -757,6 +808,7 @@ function vaultSecretStorage(vault, session) {
|
|
|
757
808
|
}
|
|
758
809
|
|
|
759
810
|
// src/networks.ts
|
|
811
|
+
import { isPublicHttpsUrl } from "@anywalletkit/networks/url";
|
|
760
812
|
import { ccChain } from "@anywalletkit/swap2-assets";
|
|
761
813
|
var DEFAULT_CHAIN = "eip155:1";
|
|
762
814
|
var net = (chainId, name, symbol, rpcs, explorer) => explorer === void 0 ? { caip2: `eip155:${chainId}`, chainId, name, symbol, rpcs } : { caip2: `eip155:${chainId}`, chainId, name, symbol, rpcs, explorer };
|
|
@@ -870,26 +922,14 @@ var NetworksTable = class {
|
|
|
870
922
|
return this._loading;
|
|
871
923
|
}
|
|
872
924
|
};
|
|
873
|
-
|
|
874
|
-
const m = /^https:\/\/(?:[^@/?#]*@)?(\[[^\]]+\]|[^:/?#]+)/i.exec(url);
|
|
875
|
-
if (!m) return true;
|
|
876
|
-
const h = m[1].toLowerCase().replace(/^\[|\]$/g, "").replace(/\.$/, "");
|
|
877
|
-
if (h === "localhost" || h.endsWith(".localhost") || h.endsWith(".local") || h === "0.0.0.0") return true;
|
|
878
|
-
const v4 = /^(\d{1,3})\.(\d{1,3})\.\d{1,3}\.\d{1,3}$/.exec(h);
|
|
879
|
-
if (v4) {
|
|
880
|
-
const a = Number(v4[1]), b = Number(v4[2]);
|
|
881
|
-
return a === 127 || a === 10 || a === 0 || a === 172 && b >= 16 && b <= 31 || a === 192 && b === 168 || a === 169 && b === 254;
|
|
882
|
-
}
|
|
883
|
-
if (h.includes(":")) return h === "::1" || h === "::" || /^f[cd]/.test(h) || /^fe[89ab]/.test(h);
|
|
884
|
-
return false;
|
|
885
|
-
}
|
|
925
|
+
var isSiteRpcUrl = (u) => typeof u === "string" && u.length <= 2048 && isPublicHttpsUrl(u);
|
|
886
926
|
function parseAddChainParams(params, known = isCatalogChain) {
|
|
887
927
|
const p = Array.isArray(params) ? params[0] : params;
|
|
888
928
|
if (!p || typeof p !== "object") return relayError(RELAY_ERRORS.invalidParams, "wallet_addEthereumChain expects one object parameter.");
|
|
889
929
|
const caip2 = caip2FromChainId(p.chainId);
|
|
890
930
|
if (!caip2) return relayError(RELAY_ERRORS.invalidParams, "chainId must be a 0x-prefixed hex string.");
|
|
891
931
|
if (!known(caip2)) return relayError(RELAY_ERRORS.chainNotAdded, `Chain ${String(p.chainId)} is not in this wallet's catalog.`);
|
|
892
|
-
const rpcs = Array.isArray(p.rpcUrls) ? p.rpcUrls.filter(
|
|
932
|
+
const rpcs = Array.isArray(p.rpcUrls) ? p.rpcUrls.filter(isSiteRpcUrl) : [];
|
|
893
933
|
if (rpcs.length === 0) return relayError(RELAY_ERRORS.invalidParams, "rpcUrls must contain at least one public https URL (a site cannot add a private / local endpoint).");
|
|
894
934
|
const name = typeof p.chainName === "string" && p.chainName.trim() ? p.chainName.trim().slice(0, 64) : caip2;
|
|
895
935
|
const currency = p.nativeCurrency;
|
|
@@ -1250,8 +1290,9 @@ var RouterError = class _RouterError extends Error {
|
|
|
1250
1290
|
};
|
|
1251
1291
|
var PROVIDER_CODES = /* @__PURE__ */ new Set([4001, 4100, 4200, 4900, 4901, 4902]);
|
|
1252
1292
|
var isNodeCode = (code) => typeof code === "number" && Number.isInteger(code) && (code === 3 || code >= -32768 && code <= -32e3);
|
|
1253
|
-
var URL_RE =
|
|
1254
|
-
var
|
|
1293
|
+
var URL_RE = /[a-z][a-z0-9+.-]{0,31}:\/\/[^\s"'<>()]+/gi;
|
|
1294
|
+
var PAGE_TEXT_WINDOW = 1024;
|
|
1295
|
+
var pageText = (text) => text.slice(0, PAGE_TEXT_WINDOW).split("\n", 1)[0].replace(URL_RE, "[url]").slice(0, 300);
|
|
1255
1296
|
var isHexData = (v) => typeof v === "string" && /^0x[0-9a-fA-F]*$/.test(v) && v.length <= 2 + 2 * 8192;
|
|
1256
1297
|
function nodeError(e) {
|
|
1257
1298
|
for (let cur = e, depth = 0; cur && typeof cur === "object" && depth < 8; cur = cur.cause, depth++) {
|
|
@@ -1310,6 +1351,7 @@ var RequestRouter = class {
|
|
|
1310
1351
|
async handle(origin, chain, method, rawParams) {
|
|
1311
1352
|
const refused = this.deps.refuse?.(origin);
|
|
1312
1353
|
if (refused) throw new RouterError(RELAY_ERRORS.unauthorized, refused);
|
|
1354
|
+
if (!isRelayMethod(method)) throw new RouterError(RELAY_ERRORS.invalidRequest, "The request has no valid method name.");
|
|
1313
1355
|
if (chain !== "eip155") throw new RouterError(RELAY_ERRORS.unsupportedMethod, `${chain} providers are not available yet.`);
|
|
1314
1356
|
const params = Array.isArray(rawParams) ? rawParams : rawParams === void 0 ? [] : [rawParams];
|
|
1315
1357
|
const network = await this.chainFor(origin);
|
|
@@ -2464,6 +2506,7 @@ export {
|
|
|
2464
2506
|
QueueLimitError,
|
|
2465
2507
|
READ_METHODS,
|
|
2466
2508
|
RELAY_ERRORS,
|
|
2509
|
+
RELAY_METHOD_MAX,
|
|
2467
2510
|
RecipientBook,
|
|
2468
2511
|
RequestRouter,
|
|
2469
2512
|
ReviewDeclined,
|
|
@@ -2523,6 +2566,7 @@ export {
|
|
|
2523
2566
|
isPageEvent,
|
|
2524
2567
|
isPageRequest,
|
|
2525
2568
|
isPageResponse,
|
|
2569
|
+
isRelayMethod,
|
|
2526
2570
|
isRelayRequest,
|
|
2527
2571
|
isRelayToContent,
|
|
2528
2572
|
levenshtein,
|