@anywalletkit/extension-kit 0.1.5 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -255,7 +255,7 @@ interface SessionAlarms {
255
255
  interface SessionOptions {
256
256
  storage: SessionStorage;
257
257
  alarms: SessionAlarms;
258
- /** Lock this long after the last `touch` / `unlock`. Default 15 min; 0 disables the timer (lock only on browser exit or explicit lock). */
258
+ /** Lock this long after the last `touch` / `unlock`. Default 15 min; 0 disables the timer (lock only on browser exit or explicit lock; stored as `expiresAt: null`). */
259
259
  autoLockMs?: number;
260
260
  /** Storage key and alarm name prefix. */
261
261
  name?: string;
@@ -301,6 +301,7 @@ declare class Session {
301
301
  private _lockNow;
302
302
  private _expiry;
303
303
  private _arm;
304
+ /** The stored record, or `null` when locked. A record that is there but unreadable locks the wallet (removed, listeners told). */
304
305
  private _read;
305
306
  }
306
307
  /** In-memory `chrome.storage.session` stand-in. */
@@ -410,7 +411,6 @@ declare function isPageEvent(x: unknown): x is PageEvent;
410
411
  declare function isRelayRequest(x: unknown): x is RelayRequest;
411
412
  declare function isRelayToContent(x: unknown): x is RelayToContent;
412
413
  declare function newRequestId(): string;
413
- /** The content script's stamp: {@link PageRequest} + the page origin. */
414
414
  /** What a content script's `message` listener receives (structural `MessageEvent`). */
415
415
  interface PageMessageEvent {
416
416
  data: unknown;
@@ -430,6 +430,7 @@ interface PageWindow {
430
430
  * shown in the approval window as the site (round 3, H6).
431
431
  */
432
432
  declare function pageRequestFrom(event: PageMessageEvent, page: PageWindow): PageRequest | null;
433
+ /** The content script's stamp: {@link PageRequest} + the page origin. */
433
434
  declare function stampOrigin(request: PageRequest, origin: string): RelayRequest;
434
435
  /** What `port.sender` looks like (structural `chrome.runtime.MessageSender`). */
435
436
  interface PortSender {
@@ -549,7 +550,8 @@ declare class NetworksTable {
549
550
  }
550
551
  /**
551
552
  * EIP-3085 `wallet_addEthereumChain` parameter → {@link EvmNetwork}, or the error
552
- * to answer with. https RPC urls only; the chain id must be in the catalog.
553
+ * to answer with. Public https RPC urls only (a private / local host is dropped); the chain id
554
+ * must be in the catalog.
553
555
  */
554
556
  declare function parseAddChainParams(params: unknown, known?: (caip2: string) => boolean): EvmNetwork | RelayError;
555
557
  /** Solana mainnet as the catalog names it (`solana:mainnet`); the wallet package also accepts the genesis-hash form. */
@@ -660,6 +662,11 @@ declare class QueueLimitError extends Error {
660
662
  readonly code: number;
661
663
  constructor(code: number, message: string);
662
664
  }
665
+ /** The origin is refused before any window opens (the shipped phishing list); EIP-1193 4100. */
666
+ declare class OriginRefused extends Error {
667
+ readonly code: 4100;
668
+ constructor(message: string);
669
+ }
663
670
  declare const APPROVALS_MAX_PENDING_PER_ORIGIN = 3;
664
671
  interface ApprovalRequest<P = unknown> {
665
672
  id: string;
@@ -677,6 +684,12 @@ interface ApprovalRequest<P = unknown> {
677
684
  interface ApprovalQueueOptions {
678
685
  /** Called for every request's origin; the lines are shown on the sheet (e.g. the shipped phishing list's verdict). */
679
686
  annotate?: (origin: string) => string[];
687
+ /**
688
+ * Called for every request's origin before anything is queued: a reason refuses the request with
689
+ * {@link OriginRefused} (4100) and no window opens. Wire `PhishingDetector.refusal` here — a
690
+ * warning on the sheet is one click away from a signature.
691
+ */
692
+ refuse?: (origin: string) => string | null | undefined;
680
693
  /** Requests one origin may have waiting (current + queued). Default {@link APPROVALS_MAX_PENDING_PER_ORIGIN}. */
681
694
  maxPendingPerOrigin?: number;
682
695
  }
@@ -776,6 +789,11 @@ interface RouterDeps {
776
789
  accounts: string[];
777
790
  }): Promise<unknown>;
778
791
  defaultChain?: string;
792
+ /**
793
+ * A reason to refuse every request from `origin` (reads, `eth_accounts`, an earlier permission
794
+ * included) with 4100, or nothing. Wire `PhishingDetector.refusal`.
795
+ */
796
+ refuse?(origin: string): string | null | undefined;
779
797
  }
780
798
  declare class RequestRouter {
781
799
  private readonly deps;
@@ -865,6 +883,15 @@ declare function describeSiwe(text: string, ctx: SiweContext): SiweInfo | null;
865
883
  * (Vaulty's `evmFees`), legacy `gasPrice` where a chain has no base fee, gas =
866
884
  * the page's limit or `eth_estimateGas` × 1.2.
867
885
  *
886
+ * The nonce the sheet shows is a guess: the one signed is read AFTER the
887
+ * approval, under a per-account lock that also covers the broadcast, and is
888
+ * never below the wallet's own next nonce (a node may not see the previous
889
+ * send yet). Two requests reviewed at once therefore get consecutive nonces.
890
+ * The fee caps signed are the ones shown, unless the network outgrew them
891
+ * while the sheet was open (EIP-1559: base fee + tip above the shown cap;
892
+ * legacy: a higher gas price) — then the user is asked again with the new
893
+ * numbers (`repriced: true`).
894
+ *
868
895
  * The review payload ({@link SignApproval}) carries what the window shows: the
869
896
  * classified request, the prepared fields, the fee, and the preview the wallet
870
897
  * attached (tx-preview-evm: decode, simulation, balance changes, checks). Only
@@ -922,6 +949,8 @@ interface SignApproval {
922
949
  request: SignRequestInfo;
923
950
  network: EvmNetwork;
924
951
  prepared?: PreparedTx;
952
+ /** A second sheet for the same transaction: the network's fee outgrew the cap the first one showed. */
953
+ repriced?: true;
925
954
  /** What the wallet attached (tx-preview-evm `TxPreview`, typed-data description…). */
926
955
  preview: unknown;
927
956
  }
@@ -991,17 +1020,21 @@ declare function createSignHandler(deps: SignDeps): NonNullable<RouterDeps['sign
991
1020
  * A flow that reviewed a WHOLE plan in one sheet (a swap: approvals + source
992
1021
  * leg) registers one matcher per operation it is about to perform; the
993
1022
  * reviewed account then lets exactly those operations through without a second
994
- * window, each once, within `ttlMs`. Anything else still stops at the review.
1023
+ * window, each once, within `ttlMs`, and only for the account that reviewed the
1024
+ * plan. Anything else still stops at the review.
995
1025
  */
996
- type GatedOp = {
1026
+ type GatedOp = ({
997
1027
  kind: 'evm-tx';
998
1028
  caip2: string;
999
1029
  to: string;
1000
1030
  data?: string;
1001
1031
  value: bigint;
1002
- } | {
1032
+ }
1033
+ /** EIP-712 data about to be signed: `typedDataHash` is `typedDataHash(typed)` from `@anywalletkit/wallet-evm` — the digest the account signs. */
1034
+ | {
1003
1035
  kind: 'evm-typed-data';
1004
1036
  caip2: string;
1037
+ typedDataHash: string;
1005
1038
  } | {
1006
1039
  kind: 'solana-transfer';
1007
1040
  to: string;
@@ -1027,14 +1060,21 @@ type GatedOp = {
1027
1060
  amount: bigint;
1028
1061
  token?: string | undefined;
1029
1062
  memo?: string | undefined;
1063
+ }) & {
1064
+ /** The account about to sign or send. A pre-approval bound to an account passes only ops that name it. */
1065
+ account?: string | undefined;
1030
1066
  };
1031
1067
  type GateMatcher = (op: GatedOp) => boolean;
1032
1068
  declare class ReviewGate {
1033
1069
  private readonly now;
1034
1070
  private approved;
1035
1071
  constructor(now?: () => number);
1036
- /** Each matcher passes ONE operation, within `ttlMs` (default 10 min). */
1037
- preApprove(matchers: GateMatcher[], ttlMs?: number): void;
1072
+ /**
1073
+ * Each matcher passes ONE operation, within `ttlMs` (default 10 min). With `account`, only an op
1074
+ * whose `account` is that account (an op without one does not pass). `reviewSwapPlan` and
1075
+ * `reviewEarnPlan` always bind.
1076
+ */
1077
+ preApprove(matchers: GateMatcher[], ttlMs?: number, account?: string): void;
1038
1078
  /** True (and the matcher is spent) when a pre-approval covers `op`. */
1039
1079
  consume(op: GatedOp): boolean;
1040
1080
  get pending(): number;
@@ -1047,6 +1087,11 @@ declare function evmCallMatcher(expected: {
1047
1087
  data?: string | undefined;
1048
1088
  value: bigint;
1049
1089
  }): GateMatcher;
1090
+ /** Matcher for one EIP-712 payload on one chain, by the digest the account signs (`typedDataHash` from `@anywalletkit/wallet-evm`). */
1091
+ declare function typedDataMatcher(expected: {
1092
+ caip2: string;
1093
+ typedDataHash: string;
1094
+ }): GateMatcher;
1050
1095
  /** Matcher for a non-EVM send: same chain, recipient, amount, token and memo. */
1051
1096
  declare function chainTxMatcher(expected: {
1052
1097
  chain: string;
@@ -1110,6 +1155,8 @@ declare function executionFloor(minDestAmount: bigint): bigint;
1110
1155
  interface SwapReviewMeta {
1111
1156
  /** Who runs the flow (the wallet's origin). */
1112
1157
  origin: string;
1158
+ /** The account that signs the plan: the gate passes the plan's operations for this account only. */
1159
+ account: string;
1113
1160
  providerLabel: string;
1114
1161
  fromSymbol: string;
1115
1162
  fromDecimals: number;
@@ -1166,8 +1213,12 @@ interface SwapApproval {
1166
1213
  memo?: string;
1167
1214
  } | {
1168
1215
  kind: 'serialized';
1169
- } | {
1216
+ }
1217
+ /** The EIP-712 order the account signs (gasless routes): `typedData` to render, `text` pretty JSON. */
1218
+ | {
1170
1219
  kind: 'typed-order';
1220
+ typedData: TypedData;
1221
+ text: string;
1171
1222
  };
1172
1223
  checks: {
1173
1224
  status: 'ok' | 'warn' | 'unknown';
@@ -1197,7 +1248,7 @@ declare function reviewSwapPlan(approvals: ApprovalQueue, gate: ReviewGate, meta
1197
1248
 
1198
1249
  type SwapRecordStatus = IntentStatus['state'] | 'claiming';
1199
1250
  interface SwapRecord {
1200
- /** swap2 id — `awk1.<provider>.<intentId>[.<sourceTxHash>]`. */
1251
+ /** swap2 id — `awk1.<provider>.<intentId>[.<sourceTxHash>[.<claimTxHash>]]`. */
1201
1252
  id: string;
1202
1253
  provider: string;
1203
1254
  fromChain: string;
@@ -1224,15 +1275,23 @@ interface SwapRecord {
1224
1275
  checks: number;
1225
1276
  }
1226
1277
  declare const ACTIVE_STATUSES: ReadonlySet<SwapRecordStatus>;
1278
+ /** `awk1.<provider>.<intentId>[.<sourceTxHash>[.<claimTxHash>]]` — the 4th segment is on the id `claimSwap2` returns. */
1227
1279
  declare function parseSwapId(id: string): {
1228
1280
  provider: string;
1229
1281
  intentId: string;
1230
1282
  sourceTxHash?: string;
1283
+ destTxHash?: string;
1231
1284
  } | null;
1232
1285
  declare class SwapsStore {
1233
1286
  private readonly storage;
1234
1287
  private _records;
1235
1288
  private readonly _listeners;
1289
+ /**
1290
+ * add / update / remove run here one after another, each reading the list inside its turn: an
1291
+ * alarm tick's update that read the list before a new swap was added would otherwise write the
1292
+ * old list back and drop the swap.
1293
+ */
1294
+ private _queue;
1236
1295
  constructor(storage: JsonStorage<SwapRecord[]>);
1237
1296
  list(): Promise<SwapRecord[]>;
1238
1297
  get(id: string): Promise<SwapRecord | null>;
@@ -1241,6 +1300,8 @@ declare class SwapsStore {
1241
1300
  update(id: string, patch: Partial<SwapRecord>): Promise<SwapRecord | null>;
1242
1301
  remove(id: string): Promise<void>;
1243
1302
  onChange(listener: () => void): () => void;
1303
+ private _all;
1304
+ private _serial;
1244
1305
  private write;
1245
1306
  }
1246
1307
  interface SwapTrackerDeps {
@@ -1294,6 +1355,8 @@ interface EarnPlan {
1294
1355
  }
1295
1356
  interface EarnReviewMeta {
1296
1357
  origin: string;
1358
+ /** The account that sends the plan: the gate passes its calls for this account only. */
1359
+ account: string;
1297
1360
  /** 'Aave v3', 'Morpho', … */
1298
1361
  module: string;
1299
1362
  /** 'Supply', 'Withdraw', 'Borrow', 'Repay', 'Stake', … */
@@ -1441,6 +1504,12 @@ declare class PhishingDetector {
1441
1504
  constructor(list: PhishingList);
1442
1505
  get size(): number;
1443
1506
  check(hostOrOrigin: string): HostCheck;
1507
+ /**
1508
+ * Why `hostOrOrigin` must be refused outright, or `null`: a host on the blocklist (or under a
1509
+ * listed domain) and not on the allowlist. Lookalikes and punycode only warn ({@link check}).
1510
+ * Wire it as `ApprovalQueueOptions.refuse` and `RouterDeps.refuse`.
1511
+ */
1512
+ refusal(hostOrOrigin: string): string | null;
1444
1513
  /**
1445
1514
  * `metamask.io-login.com`, `app-uniswap.com`, `uniswap.org.evil.net`: a known site's name used as (part of) a label
1446
1515
  * of a host that is not that site. Names shorter than 5 characters are skipped (too many honest matches).
@@ -1536,4 +1605,4 @@ declare class RecipientBook {
1536
1605
  }>;
1537
1606
  }
1538
1607
 
1539
- 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, 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, vaultSecretStorage, verifyAssertion };
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 };
package/dist/index.d.ts CHANGED
@@ -255,7 +255,7 @@ interface SessionAlarms {
255
255
  interface SessionOptions {
256
256
  storage: SessionStorage;
257
257
  alarms: SessionAlarms;
258
- /** Lock this long after the last `touch` / `unlock`. Default 15 min; 0 disables the timer (lock only on browser exit or explicit lock). */
258
+ /** Lock this long after the last `touch` / `unlock`. Default 15 min; 0 disables the timer (lock only on browser exit or explicit lock; stored as `expiresAt: null`). */
259
259
  autoLockMs?: number;
260
260
  /** Storage key and alarm name prefix. */
261
261
  name?: string;
@@ -301,6 +301,7 @@ declare class Session {
301
301
  private _lockNow;
302
302
  private _expiry;
303
303
  private _arm;
304
+ /** The stored record, or `null` when locked. A record that is there but unreadable locks the wallet (removed, listeners told). */
304
305
  private _read;
305
306
  }
306
307
  /** In-memory `chrome.storage.session` stand-in. */
@@ -410,7 +411,6 @@ declare function isPageEvent(x: unknown): x is PageEvent;
410
411
  declare function isRelayRequest(x: unknown): x is RelayRequest;
411
412
  declare function isRelayToContent(x: unknown): x is RelayToContent;
412
413
  declare function newRequestId(): string;
413
- /** The content script's stamp: {@link PageRequest} + the page origin. */
414
414
  /** What a content script's `message` listener receives (structural `MessageEvent`). */
415
415
  interface PageMessageEvent {
416
416
  data: unknown;
@@ -430,6 +430,7 @@ interface PageWindow {
430
430
  * shown in the approval window as the site (round 3, H6).
431
431
  */
432
432
  declare function pageRequestFrom(event: PageMessageEvent, page: PageWindow): PageRequest | null;
433
+ /** The content script's stamp: {@link PageRequest} + the page origin. */
433
434
  declare function stampOrigin(request: PageRequest, origin: string): RelayRequest;
434
435
  /** What `port.sender` looks like (structural `chrome.runtime.MessageSender`). */
435
436
  interface PortSender {
@@ -549,7 +550,8 @@ declare class NetworksTable {
549
550
  }
550
551
  /**
551
552
  * EIP-3085 `wallet_addEthereumChain` parameter → {@link EvmNetwork}, or the error
552
- * to answer with. https RPC urls only; the chain id must be in the catalog.
553
+ * to answer with. Public https RPC urls only (a private / local host is dropped); the chain id
554
+ * must be in the catalog.
553
555
  */
554
556
  declare function parseAddChainParams(params: unknown, known?: (caip2: string) => boolean): EvmNetwork | RelayError;
555
557
  /** Solana mainnet as the catalog names it (`solana:mainnet`); the wallet package also accepts the genesis-hash form. */
@@ -660,6 +662,11 @@ declare class QueueLimitError extends Error {
660
662
  readonly code: number;
661
663
  constructor(code: number, message: string);
662
664
  }
665
+ /** The origin is refused before any window opens (the shipped phishing list); EIP-1193 4100. */
666
+ declare class OriginRefused extends Error {
667
+ readonly code: 4100;
668
+ constructor(message: string);
669
+ }
663
670
  declare const APPROVALS_MAX_PENDING_PER_ORIGIN = 3;
664
671
  interface ApprovalRequest<P = unknown> {
665
672
  id: string;
@@ -677,6 +684,12 @@ interface ApprovalRequest<P = unknown> {
677
684
  interface ApprovalQueueOptions {
678
685
  /** Called for every request's origin; the lines are shown on the sheet (e.g. the shipped phishing list's verdict). */
679
686
  annotate?: (origin: string) => string[];
687
+ /**
688
+ * Called for every request's origin before anything is queued: a reason refuses the request with
689
+ * {@link OriginRefused} (4100) and no window opens. Wire `PhishingDetector.refusal` here — a
690
+ * warning on the sheet is one click away from a signature.
691
+ */
692
+ refuse?: (origin: string) => string | null | undefined;
680
693
  /** Requests one origin may have waiting (current + queued). Default {@link APPROVALS_MAX_PENDING_PER_ORIGIN}. */
681
694
  maxPendingPerOrigin?: number;
682
695
  }
@@ -776,6 +789,11 @@ interface RouterDeps {
776
789
  accounts: string[];
777
790
  }): Promise<unknown>;
778
791
  defaultChain?: string;
792
+ /**
793
+ * A reason to refuse every request from `origin` (reads, `eth_accounts`, an earlier permission
794
+ * included) with 4100, or nothing. Wire `PhishingDetector.refusal`.
795
+ */
796
+ refuse?(origin: string): string | null | undefined;
779
797
  }
780
798
  declare class RequestRouter {
781
799
  private readonly deps;
@@ -865,6 +883,15 @@ declare function describeSiwe(text: string, ctx: SiweContext): SiweInfo | null;
865
883
  * (Vaulty's `evmFees`), legacy `gasPrice` where a chain has no base fee, gas =
866
884
  * the page's limit or `eth_estimateGas` × 1.2.
867
885
  *
886
+ * The nonce the sheet shows is a guess: the one signed is read AFTER the
887
+ * approval, under a per-account lock that also covers the broadcast, and is
888
+ * never below the wallet's own next nonce (a node may not see the previous
889
+ * send yet). Two requests reviewed at once therefore get consecutive nonces.
890
+ * The fee caps signed are the ones shown, unless the network outgrew them
891
+ * while the sheet was open (EIP-1559: base fee + tip above the shown cap;
892
+ * legacy: a higher gas price) — then the user is asked again with the new
893
+ * numbers (`repriced: true`).
894
+ *
868
895
  * The review payload ({@link SignApproval}) carries what the window shows: the
869
896
  * classified request, the prepared fields, the fee, and the preview the wallet
870
897
  * attached (tx-preview-evm: decode, simulation, balance changes, checks). Only
@@ -922,6 +949,8 @@ interface SignApproval {
922
949
  request: SignRequestInfo;
923
950
  network: EvmNetwork;
924
951
  prepared?: PreparedTx;
952
+ /** A second sheet for the same transaction: the network's fee outgrew the cap the first one showed. */
953
+ repriced?: true;
925
954
  /** What the wallet attached (tx-preview-evm `TxPreview`, typed-data description…). */
926
955
  preview: unknown;
927
956
  }
@@ -991,17 +1020,21 @@ declare function createSignHandler(deps: SignDeps): NonNullable<RouterDeps['sign
991
1020
  * A flow that reviewed a WHOLE plan in one sheet (a swap: approvals + source
992
1021
  * leg) registers one matcher per operation it is about to perform; the
993
1022
  * reviewed account then lets exactly those operations through without a second
994
- * window, each once, within `ttlMs`. Anything else still stops at the review.
1023
+ * window, each once, within `ttlMs`, and only for the account that reviewed the
1024
+ * plan. Anything else still stops at the review.
995
1025
  */
996
- type GatedOp = {
1026
+ type GatedOp = ({
997
1027
  kind: 'evm-tx';
998
1028
  caip2: string;
999
1029
  to: string;
1000
1030
  data?: string;
1001
1031
  value: bigint;
1002
- } | {
1032
+ }
1033
+ /** EIP-712 data about to be signed: `typedDataHash` is `typedDataHash(typed)` from `@anywalletkit/wallet-evm` — the digest the account signs. */
1034
+ | {
1003
1035
  kind: 'evm-typed-data';
1004
1036
  caip2: string;
1037
+ typedDataHash: string;
1005
1038
  } | {
1006
1039
  kind: 'solana-transfer';
1007
1040
  to: string;
@@ -1027,14 +1060,21 @@ type GatedOp = {
1027
1060
  amount: bigint;
1028
1061
  token?: string | undefined;
1029
1062
  memo?: string | undefined;
1063
+ }) & {
1064
+ /** The account about to sign or send. A pre-approval bound to an account passes only ops that name it. */
1065
+ account?: string | undefined;
1030
1066
  };
1031
1067
  type GateMatcher = (op: GatedOp) => boolean;
1032
1068
  declare class ReviewGate {
1033
1069
  private readonly now;
1034
1070
  private approved;
1035
1071
  constructor(now?: () => number);
1036
- /** Each matcher passes ONE operation, within `ttlMs` (default 10 min). */
1037
- preApprove(matchers: GateMatcher[], ttlMs?: number): void;
1072
+ /**
1073
+ * Each matcher passes ONE operation, within `ttlMs` (default 10 min). With `account`, only an op
1074
+ * whose `account` is that account (an op without one does not pass). `reviewSwapPlan` and
1075
+ * `reviewEarnPlan` always bind.
1076
+ */
1077
+ preApprove(matchers: GateMatcher[], ttlMs?: number, account?: string): void;
1038
1078
  /** True (and the matcher is spent) when a pre-approval covers `op`. */
1039
1079
  consume(op: GatedOp): boolean;
1040
1080
  get pending(): number;
@@ -1047,6 +1087,11 @@ declare function evmCallMatcher(expected: {
1047
1087
  data?: string | undefined;
1048
1088
  value: bigint;
1049
1089
  }): GateMatcher;
1090
+ /** Matcher for one EIP-712 payload on one chain, by the digest the account signs (`typedDataHash` from `@anywalletkit/wallet-evm`). */
1091
+ declare function typedDataMatcher(expected: {
1092
+ caip2: string;
1093
+ typedDataHash: string;
1094
+ }): GateMatcher;
1050
1095
  /** Matcher for a non-EVM send: same chain, recipient, amount, token and memo. */
1051
1096
  declare function chainTxMatcher(expected: {
1052
1097
  chain: string;
@@ -1110,6 +1155,8 @@ declare function executionFloor(minDestAmount: bigint): bigint;
1110
1155
  interface SwapReviewMeta {
1111
1156
  /** Who runs the flow (the wallet's origin). */
1112
1157
  origin: string;
1158
+ /** The account that signs the plan: the gate passes the plan's operations for this account only. */
1159
+ account: string;
1113
1160
  providerLabel: string;
1114
1161
  fromSymbol: string;
1115
1162
  fromDecimals: number;
@@ -1166,8 +1213,12 @@ interface SwapApproval {
1166
1213
  memo?: string;
1167
1214
  } | {
1168
1215
  kind: 'serialized';
1169
- } | {
1216
+ }
1217
+ /** The EIP-712 order the account signs (gasless routes): `typedData` to render, `text` pretty JSON. */
1218
+ | {
1170
1219
  kind: 'typed-order';
1220
+ typedData: TypedData;
1221
+ text: string;
1171
1222
  };
1172
1223
  checks: {
1173
1224
  status: 'ok' | 'warn' | 'unknown';
@@ -1197,7 +1248,7 @@ declare function reviewSwapPlan(approvals: ApprovalQueue, gate: ReviewGate, meta
1197
1248
 
1198
1249
  type SwapRecordStatus = IntentStatus['state'] | 'claiming';
1199
1250
  interface SwapRecord {
1200
- /** swap2 id — `awk1.<provider>.<intentId>[.<sourceTxHash>]`. */
1251
+ /** swap2 id — `awk1.<provider>.<intentId>[.<sourceTxHash>[.<claimTxHash>]]`. */
1201
1252
  id: string;
1202
1253
  provider: string;
1203
1254
  fromChain: string;
@@ -1224,15 +1275,23 @@ interface SwapRecord {
1224
1275
  checks: number;
1225
1276
  }
1226
1277
  declare const ACTIVE_STATUSES: ReadonlySet<SwapRecordStatus>;
1278
+ /** `awk1.<provider>.<intentId>[.<sourceTxHash>[.<claimTxHash>]]` — the 4th segment is on the id `claimSwap2` returns. */
1227
1279
  declare function parseSwapId(id: string): {
1228
1280
  provider: string;
1229
1281
  intentId: string;
1230
1282
  sourceTxHash?: string;
1283
+ destTxHash?: string;
1231
1284
  } | null;
1232
1285
  declare class SwapsStore {
1233
1286
  private readonly storage;
1234
1287
  private _records;
1235
1288
  private readonly _listeners;
1289
+ /**
1290
+ * add / update / remove run here one after another, each reading the list inside its turn: an
1291
+ * alarm tick's update that read the list before a new swap was added would otherwise write the
1292
+ * old list back and drop the swap.
1293
+ */
1294
+ private _queue;
1236
1295
  constructor(storage: JsonStorage<SwapRecord[]>);
1237
1296
  list(): Promise<SwapRecord[]>;
1238
1297
  get(id: string): Promise<SwapRecord | null>;
@@ -1241,6 +1300,8 @@ declare class SwapsStore {
1241
1300
  update(id: string, patch: Partial<SwapRecord>): Promise<SwapRecord | null>;
1242
1301
  remove(id: string): Promise<void>;
1243
1302
  onChange(listener: () => void): () => void;
1303
+ private _all;
1304
+ private _serial;
1244
1305
  private write;
1245
1306
  }
1246
1307
  interface SwapTrackerDeps {
@@ -1294,6 +1355,8 @@ interface EarnPlan {
1294
1355
  }
1295
1356
  interface EarnReviewMeta {
1296
1357
  origin: string;
1358
+ /** The account that sends the plan: the gate passes its calls for this account only. */
1359
+ account: string;
1297
1360
  /** 'Aave v3', 'Morpho', … */
1298
1361
  module: string;
1299
1362
  /** 'Supply', 'Withdraw', 'Borrow', 'Repay', 'Stake', … */
@@ -1441,6 +1504,12 @@ declare class PhishingDetector {
1441
1504
  constructor(list: PhishingList);
1442
1505
  get size(): number;
1443
1506
  check(hostOrOrigin: string): HostCheck;
1507
+ /**
1508
+ * Why `hostOrOrigin` must be refused outright, or `null`: a host on the blocklist (or under a
1509
+ * listed domain) and not on the allowlist. Lookalikes and punycode only warn ({@link check}).
1510
+ * Wire it as `ApprovalQueueOptions.refuse` and `RouterDeps.refuse`.
1511
+ */
1512
+ refusal(hostOrOrigin: string): string | null;
1444
1513
  /**
1445
1514
  * `metamask.io-login.com`, `app-uniswap.com`, `uniswap.org.evil.net`: a known site's name used as (part of) a label
1446
1515
  * of a host that is not that site. Names shorter than 5 characters are skipped (too many honest matches).
@@ -1536,4 +1605,4 @@ declare class RecipientBook {
1536
1605
  }>;
1537
1606
  }
1538
1607
 
1539
- 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, 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, vaultSecretStorage, verifyAssertion };
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 };