@anywalletkit/extension-kit 0.1.4 → 0.2.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/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,6 +411,25 @@ 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;
414
+ /** What a content script's `message` listener receives (structural `MessageEvent`). */
415
+ interface PageMessageEvent {
416
+ data: unknown;
417
+ origin: string;
418
+ source: unknown;
419
+ }
420
+ /** The page window the content script shares (structural `window`). */
421
+ interface PageWindow {
422
+ location: {
423
+ origin: string;
424
+ };
425
+ }
426
+ /**
427
+ * The page's own request, or `null`. A content script must take only messages the page itself
428
+ * posted — `event.source` is the page window and `event.origin` its origin — or an iframe on the
429
+ * page (an ad, an embed) would have its `parent.postMessage` stamped with the site's origin and
430
+ * shown in the approval window as the site (round 3, H6).
431
+ */
432
+ declare function pageRequestFrom(event: PageMessageEvent, page: PageWindow): PageRequest | null;
413
433
  /** The content script's stamp: {@link PageRequest} + the page origin. */
414
434
  declare function stampOrigin(request: PageRequest, origin: string): RelayRequest;
415
435
  /** What `port.sender` looks like (structural `chrome.runtime.MessageSender`). */
@@ -530,7 +550,8 @@ declare class NetworksTable {
530
550
  }
531
551
  /**
532
552
  * EIP-3085 `wallet_addEthereumChain` parameter → {@link EvmNetwork}, or the error
533
- * 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.
534
555
  */
535
556
  declare function parseAddChainParams(params: unknown, known?: (caip2: string) => boolean): EvmNetwork | RelayError;
536
557
  /** Solana mainnet as the catalog names it (`solana:mainnet`); the wallet package also accepts the genesis-hash form. */
@@ -641,6 +662,11 @@ declare class QueueLimitError extends Error {
641
662
  readonly code: number;
642
663
  constructor(code: number, message: string);
643
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
+ }
644
670
  declare const APPROVALS_MAX_PENDING_PER_ORIGIN = 3;
645
671
  interface ApprovalRequest<P = unknown> {
646
672
  id: string;
@@ -658,6 +684,12 @@ interface ApprovalRequest<P = unknown> {
658
684
  interface ApprovalQueueOptions {
659
685
  /** Called for every request's origin; the lines are shown on the sheet (e.g. the shipped phishing list's verdict). */
660
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;
661
693
  /** Requests one origin may have waiting (current + queued). Default {@link APPROVALS_MAX_PENDING_PER_ORIGIN}. */
662
694
  maxPendingPerOrigin?: number;
663
695
  }
@@ -757,6 +789,11 @@ interface RouterDeps {
757
789
  accounts: string[];
758
790
  }): Promise<unknown>;
759
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;
760
797
  }
761
798
  declare class RequestRouter {
762
799
  private readonly deps;
@@ -846,6 +883,15 @@ declare function describeSiwe(text: string, ctx: SiweContext): SiweInfo | null;
846
883
  * (Vaulty's `evmFees`), legacy `gasPrice` where a chain has no base fee, gas =
847
884
  * the page's limit or `eth_estimateGas` × 1.2.
848
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
+ *
849
895
  * The review payload ({@link SignApproval}) carries what the window shows: the
850
896
  * classified request, the prepared fields, the fee, and the preview the wallet
851
897
  * attached (tx-preview-evm: decode, simulation, balance changes, checks). Only
@@ -903,6 +949,8 @@ interface SignApproval {
903
949
  request: SignRequestInfo;
904
950
  network: EvmNetwork;
905
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;
906
954
  /** What the wallet attached (tx-preview-evm `TxPreview`, typed-data description…). */
907
955
  preview: unknown;
908
956
  }
@@ -972,17 +1020,21 @@ declare function createSignHandler(deps: SignDeps): NonNullable<RouterDeps['sign
972
1020
  * A flow that reviewed a WHOLE plan in one sheet (a swap: approvals + source
973
1021
  * leg) registers one matcher per operation it is about to perform; the
974
1022
  * reviewed account then lets exactly those operations through without a second
975
- * 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.
976
1025
  */
977
- type GatedOp = {
1026
+ type GatedOp = ({
978
1027
  kind: 'evm-tx';
979
1028
  caip2: string;
980
1029
  to: string;
981
1030
  data?: string;
982
1031
  value: bigint;
983
- } | {
1032
+ }
1033
+ /** EIP-712 data about to be signed: `typedDataHash` is `typedDataHash(typed)` from `@anywalletkit/wallet-evm` — the digest the account signs. */
1034
+ | {
984
1035
  kind: 'evm-typed-data';
985
1036
  caip2: string;
1037
+ typedDataHash: string;
986
1038
  } | {
987
1039
  kind: 'solana-transfer';
988
1040
  to: string;
@@ -1008,14 +1060,21 @@ type GatedOp = {
1008
1060
  amount: bigint;
1009
1061
  token?: string | undefined;
1010
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;
1011
1066
  };
1012
1067
  type GateMatcher = (op: GatedOp) => boolean;
1013
1068
  declare class ReviewGate {
1014
1069
  private readonly now;
1015
1070
  private approved;
1016
1071
  constructor(now?: () => number);
1017
- /** Each matcher passes ONE operation, within `ttlMs` (default 10 min). */
1018
- 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;
1019
1078
  /** True (and the matcher is spent) when a pre-approval covers `op`. */
1020
1079
  consume(op: GatedOp): boolean;
1021
1080
  get pending(): number;
@@ -1028,6 +1087,11 @@ declare function evmCallMatcher(expected: {
1028
1087
  data?: string | undefined;
1029
1088
  value: bigint;
1030
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;
1031
1095
  /** Matcher for a non-EVM send: same chain, recipient, amount, token and memo. */
1032
1096
  declare function chainTxMatcher(expected: {
1033
1097
  chain: string;
@@ -1091,6 +1155,8 @@ declare function executionFloor(minDestAmount: bigint): bigint;
1091
1155
  interface SwapReviewMeta {
1092
1156
  /** Who runs the flow (the wallet's origin). */
1093
1157
  origin: string;
1158
+ /** The account that signs the plan: the gate passes the plan's operations for this account only. */
1159
+ account: string;
1094
1160
  providerLabel: string;
1095
1161
  fromSymbol: string;
1096
1162
  fromDecimals: number;
@@ -1147,8 +1213,12 @@ interface SwapApproval {
1147
1213
  memo?: string;
1148
1214
  } | {
1149
1215
  kind: 'serialized';
1150
- } | {
1216
+ }
1217
+ /** The EIP-712 order the account signs (gasless routes): `typedData` to render, `text` pretty JSON. */
1218
+ | {
1151
1219
  kind: 'typed-order';
1220
+ typedData: TypedData;
1221
+ text: string;
1152
1222
  };
1153
1223
  checks: {
1154
1224
  status: 'ok' | 'warn' | 'unknown';
@@ -1178,7 +1248,7 @@ declare function reviewSwapPlan(approvals: ApprovalQueue, gate: ReviewGate, meta
1178
1248
 
1179
1249
  type SwapRecordStatus = IntentStatus['state'] | 'claiming';
1180
1250
  interface SwapRecord {
1181
- /** swap2 id — `awk1.<provider>.<intentId>[.<sourceTxHash>]`. */
1251
+ /** swap2 id — `awk1.<provider>.<intentId>[.<sourceTxHash>[.<claimTxHash>]]`. */
1182
1252
  id: string;
1183
1253
  provider: string;
1184
1254
  fromChain: string;
@@ -1205,15 +1275,23 @@ interface SwapRecord {
1205
1275
  checks: number;
1206
1276
  }
1207
1277
  declare const ACTIVE_STATUSES: ReadonlySet<SwapRecordStatus>;
1278
+ /** `awk1.<provider>.<intentId>[.<sourceTxHash>[.<claimTxHash>]]` — the 4th segment is on the id `claimSwap2` returns. */
1208
1279
  declare function parseSwapId(id: string): {
1209
1280
  provider: string;
1210
1281
  intentId: string;
1211
1282
  sourceTxHash?: string;
1283
+ destTxHash?: string;
1212
1284
  } | null;
1213
1285
  declare class SwapsStore {
1214
1286
  private readonly storage;
1215
1287
  private _records;
1216
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;
1217
1295
  constructor(storage: JsonStorage<SwapRecord[]>);
1218
1296
  list(): Promise<SwapRecord[]>;
1219
1297
  get(id: string): Promise<SwapRecord | null>;
@@ -1222,6 +1300,8 @@ declare class SwapsStore {
1222
1300
  update(id: string, patch: Partial<SwapRecord>): Promise<SwapRecord | null>;
1223
1301
  remove(id: string): Promise<void>;
1224
1302
  onChange(listener: () => void): () => void;
1303
+ private _all;
1304
+ private _serial;
1225
1305
  private write;
1226
1306
  }
1227
1307
  interface SwapTrackerDeps {
@@ -1275,6 +1355,8 @@ interface EarnPlan {
1275
1355
  }
1276
1356
  interface EarnReviewMeta {
1277
1357
  origin: string;
1358
+ /** The account that sends the plan: the gate passes its calls for this account only. */
1359
+ account: string;
1278
1360
  /** 'Aave v3', 'Morpho', … */
1279
1361
  module: string;
1280
1362
  /** 'Supply', 'Withdraw', 'Borrow', 'Repay', 'Stake', … */
@@ -1368,14 +1450,14 @@ interface TonAddressParts {
1368
1450
  workchain: number;
1369
1451
  hash: Uint8Array;
1370
1452
  }
1371
- /** The bytes a wallet signs for `ton_proof` (already hashed — sign them raw with ed25519). */
1453
+ /** The 32-byte digest a wallet signs for `ton_proof` — to verify a proof; sign with `WalletAccountTon.signTonProof`. */
1372
1454
  declare function tonProofMessage(input: {
1373
1455
  address: TonAddressParts;
1374
1456
  domain: string;
1375
1457
  timestamp: number;
1376
1458
  payload: string;
1377
1459
  }): Uint8Array;
1378
- /** The bytes a wallet signs for `signData` (text / binary). */
1460
+ /** The 32-byte digest a wallet signs for `signData` (text / binary) — to verify; sign with `WalletAccountTon.signTonConnectData`. */
1379
1461
  declare function tonSignDataMessage(input: {
1380
1462
  address: TonAddressParts;
1381
1463
  domain: string;
@@ -1422,6 +1504,12 @@ declare class PhishingDetector {
1422
1504
  constructor(list: PhishingList);
1423
1505
  get size(): number;
1424
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;
1425
1513
  /**
1426
1514
  * `metamask.io-login.com`, `app-uniswap.com`, `uniswap.org.evil.net`: a known site's name used as (part of) a label
1427
1515
  * of a host that is not that site. Names shorter than 5 characters are skipped (too many honest matches).
@@ -1517,4 +1605,4 @@ declare class RecipientBook {
1517
1605
  }>;
1518
1606
  }
1519
1607
 
1520
- 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 PageRequest, type PageResponse, 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, 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,6 +411,25 @@ 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;
414
+ /** What a content script's `message` listener receives (structural `MessageEvent`). */
415
+ interface PageMessageEvent {
416
+ data: unknown;
417
+ origin: string;
418
+ source: unknown;
419
+ }
420
+ /** The page window the content script shares (structural `window`). */
421
+ interface PageWindow {
422
+ location: {
423
+ origin: string;
424
+ };
425
+ }
426
+ /**
427
+ * The page's own request, or `null`. A content script must take only messages the page itself
428
+ * posted — `event.source` is the page window and `event.origin` its origin — or an iframe on the
429
+ * page (an ad, an embed) would have its `parent.postMessage` stamped with the site's origin and
430
+ * shown in the approval window as the site (round 3, H6).
431
+ */
432
+ declare function pageRequestFrom(event: PageMessageEvent, page: PageWindow): PageRequest | null;
413
433
  /** The content script's stamp: {@link PageRequest} + the page origin. */
414
434
  declare function stampOrigin(request: PageRequest, origin: string): RelayRequest;
415
435
  /** What `port.sender` looks like (structural `chrome.runtime.MessageSender`). */
@@ -530,7 +550,8 @@ declare class NetworksTable {
530
550
  }
531
551
  /**
532
552
  * EIP-3085 `wallet_addEthereumChain` parameter → {@link EvmNetwork}, or the error
533
- * 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.
534
555
  */
535
556
  declare function parseAddChainParams(params: unknown, known?: (caip2: string) => boolean): EvmNetwork | RelayError;
536
557
  /** Solana mainnet as the catalog names it (`solana:mainnet`); the wallet package also accepts the genesis-hash form. */
@@ -641,6 +662,11 @@ declare class QueueLimitError extends Error {
641
662
  readonly code: number;
642
663
  constructor(code: number, message: string);
643
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
+ }
644
670
  declare const APPROVALS_MAX_PENDING_PER_ORIGIN = 3;
645
671
  interface ApprovalRequest<P = unknown> {
646
672
  id: string;
@@ -658,6 +684,12 @@ interface ApprovalRequest<P = unknown> {
658
684
  interface ApprovalQueueOptions {
659
685
  /** Called for every request's origin; the lines are shown on the sheet (e.g. the shipped phishing list's verdict). */
660
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;
661
693
  /** Requests one origin may have waiting (current + queued). Default {@link APPROVALS_MAX_PENDING_PER_ORIGIN}. */
662
694
  maxPendingPerOrigin?: number;
663
695
  }
@@ -757,6 +789,11 @@ interface RouterDeps {
757
789
  accounts: string[];
758
790
  }): Promise<unknown>;
759
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;
760
797
  }
761
798
  declare class RequestRouter {
762
799
  private readonly deps;
@@ -846,6 +883,15 @@ declare function describeSiwe(text: string, ctx: SiweContext): SiweInfo | null;
846
883
  * (Vaulty's `evmFees`), legacy `gasPrice` where a chain has no base fee, gas =
847
884
  * the page's limit or `eth_estimateGas` × 1.2.
848
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
+ *
849
895
  * The review payload ({@link SignApproval}) carries what the window shows: the
850
896
  * classified request, the prepared fields, the fee, and the preview the wallet
851
897
  * attached (tx-preview-evm: decode, simulation, balance changes, checks). Only
@@ -903,6 +949,8 @@ interface SignApproval {
903
949
  request: SignRequestInfo;
904
950
  network: EvmNetwork;
905
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;
906
954
  /** What the wallet attached (tx-preview-evm `TxPreview`, typed-data description…). */
907
955
  preview: unknown;
908
956
  }
@@ -972,17 +1020,21 @@ declare function createSignHandler(deps: SignDeps): NonNullable<RouterDeps['sign
972
1020
  * A flow that reviewed a WHOLE plan in one sheet (a swap: approvals + source
973
1021
  * leg) registers one matcher per operation it is about to perform; the
974
1022
  * reviewed account then lets exactly those operations through without a second
975
- * 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.
976
1025
  */
977
- type GatedOp = {
1026
+ type GatedOp = ({
978
1027
  kind: 'evm-tx';
979
1028
  caip2: string;
980
1029
  to: string;
981
1030
  data?: string;
982
1031
  value: bigint;
983
- } | {
1032
+ }
1033
+ /** EIP-712 data about to be signed: `typedDataHash` is `typedDataHash(typed)` from `@anywalletkit/wallet-evm` — the digest the account signs. */
1034
+ | {
984
1035
  kind: 'evm-typed-data';
985
1036
  caip2: string;
1037
+ typedDataHash: string;
986
1038
  } | {
987
1039
  kind: 'solana-transfer';
988
1040
  to: string;
@@ -1008,14 +1060,21 @@ type GatedOp = {
1008
1060
  amount: bigint;
1009
1061
  token?: string | undefined;
1010
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;
1011
1066
  };
1012
1067
  type GateMatcher = (op: GatedOp) => boolean;
1013
1068
  declare class ReviewGate {
1014
1069
  private readonly now;
1015
1070
  private approved;
1016
1071
  constructor(now?: () => number);
1017
- /** Each matcher passes ONE operation, within `ttlMs` (default 10 min). */
1018
- 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;
1019
1078
  /** True (and the matcher is spent) when a pre-approval covers `op`. */
1020
1079
  consume(op: GatedOp): boolean;
1021
1080
  get pending(): number;
@@ -1028,6 +1087,11 @@ declare function evmCallMatcher(expected: {
1028
1087
  data?: string | undefined;
1029
1088
  value: bigint;
1030
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;
1031
1095
  /** Matcher for a non-EVM send: same chain, recipient, amount, token and memo. */
1032
1096
  declare function chainTxMatcher(expected: {
1033
1097
  chain: string;
@@ -1091,6 +1155,8 @@ declare function executionFloor(minDestAmount: bigint): bigint;
1091
1155
  interface SwapReviewMeta {
1092
1156
  /** Who runs the flow (the wallet's origin). */
1093
1157
  origin: string;
1158
+ /** The account that signs the plan: the gate passes the plan's operations for this account only. */
1159
+ account: string;
1094
1160
  providerLabel: string;
1095
1161
  fromSymbol: string;
1096
1162
  fromDecimals: number;
@@ -1147,8 +1213,12 @@ interface SwapApproval {
1147
1213
  memo?: string;
1148
1214
  } | {
1149
1215
  kind: 'serialized';
1150
- } | {
1216
+ }
1217
+ /** The EIP-712 order the account signs (gasless routes): `typedData` to render, `text` pretty JSON. */
1218
+ | {
1151
1219
  kind: 'typed-order';
1220
+ typedData: TypedData;
1221
+ text: string;
1152
1222
  };
1153
1223
  checks: {
1154
1224
  status: 'ok' | 'warn' | 'unknown';
@@ -1178,7 +1248,7 @@ declare function reviewSwapPlan(approvals: ApprovalQueue, gate: ReviewGate, meta
1178
1248
 
1179
1249
  type SwapRecordStatus = IntentStatus['state'] | 'claiming';
1180
1250
  interface SwapRecord {
1181
- /** swap2 id — `awk1.<provider>.<intentId>[.<sourceTxHash>]`. */
1251
+ /** swap2 id — `awk1.<provider>.<intentId>[.<sourceTxHash>[.<claimTxHash>]]`. */
1182
1252
  id: string;
1183
1253
  provider: string;
1184
1254
  fromChain: string;
@@ -1205,15 +1275,23 @@ interface SwapRecord {
1205
1275
  checks: number;
1206
1276
  }
1207
1277
  declare const ACTIVE_STATUSES: ReadonlySet<SwapRecordStatus>;
1278
+ /** `awk1.<provider>.<intentId>[.<sourceTxHash>[.<claimTxHash>]]` — the 4th segment is on the id `claimSwap2` returns. */
1208
1279
  declare function parseSwapId(id: string): {
1209
1280
  provider: string;
1210
1281
  intentId: string;
1211
1282
  sourceTxHash?: string;
1283
+ destTxHash?: string;
1212
1284
  } | null;
1213
1285
  declare class SwapsStore {
1214
1286
  private readonly storage;
1215
1287
  private _records;
1216
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;
1217
1295
  constructor(storage: JsonStorage<SwapRecord[]>);
1218
1296
  list(): Promise<SwapRecord[]>;
1219
1297
  get(id: string): Promise<SwapRecord | null>;
@@ -1222,6 +1300,8 @@ declare class SwapsStore {
1222
1300
  update(id: string, patch: Partial<SwapRecord>): Promise<SwapRecord | null>;
1223
1301
  remove(id: string): Promise<void>;
1224
1302
  onChange(listener: () => void): () => void;
1303
+ private _all;
1304
+ private _serial;
1225
1305
  private write;
1226
1306
  }
1227
1307
  interface SwapTrackerDeps {
@@ -1275,6 +1355,8 @@ interface EarnPlan {
1275
1355
  }
1276
1356
  interface EarnReviewMeta {
1277
1357
  origin: string;
1358
+ /** The account that sends the plan: the gate passes its calls for this account only. */
1359
+ account: string;
1278
1360
  /** 'Aave v3', 'Morpho', … */
1279
1361
  module: string;
1280
1362
  /** 'Supply', 'Withdraw', 'Borrow', 'Repay', 'Stake', … */
@@ -1368,14 +1450,14 @@ interface TonAddressParts {
1368
1450
  workchain: number;
1369
1451
  hash: Uint8Array;
1370
1452
  }
1371
- /** The bytes a wallet signs for `ton_proof` (already hashed — sign them raw with ed25519). */
1453
+ /** The 32-byte digest a wallet signs for `ton_proof` — to verify a proof; sign with `WalletAccountTon.signTonProof`. */
1372
1454
  declare function tonProofMessage(input: {
1373
1455
  address: TonAddressParts;
1374
1456
  domain: string;
1375
1457
  timestamp: number;
1376
1458
  payload: string;
1377
1459
  }): Uint8Array;
1378
- /** The bytes a wallet signs for `signData` (text / binary). */
1460
+ /** The 32-byte digest a wallet signs for `signData` (text / binary) — to verify; sign with `WalletAccountTon.signTonConnectData`. */
1379
1461
  declare function tonSignDataMessage(input: {
1380
1462
  address: TonAddressParts;
1381
1463
  domain: string;
@@ -1422,6 +1504,12 @@ declare class PhishingDetector {
1422
1504
  constructor(list: PhishingList);
1423
1505
  get size(): number;
1424
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;
1425
1513
  /**
1426
1514
  * `metamask.io-login.com`, `app-uniswap.com`, `uniswap.org.evil.net`: a known site's name used as (part of) a label
1427
1515
  * of a host that is not that site. Names shorter than 5 characters are skipped (too many honest matches).
@@ -1517,4 +1605,4 @@ declare class RecipientBook {
1517
1605
  }>;
1518
1606
  }
1519
1607
 
1520
- 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 PageRequest, type PageResponse, 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, 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 };