@anywalletkit/extension-kit 0.3.5 → 0.4.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
@@ -1,5 +1,7 @@
1
1
  import { KeyringStorage, SecretStorage } from '@anywalletkit/keyring';
2
- import { Quote, Swap2ExecutionPlan, CrossChainProvider, QuoteParams, IntentStatus } from '@anywalletkit/protocol-swap2-core';
2
+ import { Quote, QuoteParams, Swap2ExecutionPlan, CrossChainProvider, IntentStatus } from '@anywalletkit/protocol-swap2-core';
3
+ import { TonSignDataPayload } from '@anywalletkit/wallet-ton/tonconnect';
4
+ export { TONCONNECT_ERRORS, TONCONNECT_MAX_MESSAGES, TONCONNECT_NETWORKS, TONCONNECT_SIGN_DATA_MAX, TonConnectError, TonConnectMessage, TonConnectParseOptions, TonConnectRequest, TonConnectSendOptions, TonConnectSendTransaction, TonSignDataPayload, parseConnectRequest, parseSendTransaction, parseSignData, sameTonConnectAddress, tonConnectFriendlyAddress, tonConnectRawAddress } from '@anywalletkit/wallet-ton/tonconnect';
3
5
 
4
6
  /** A vault or session rule was broken. Messages are safe to show the user and never contain secrets. */
5
7
  declare class VaultError extends Error {
@@ -176,6 +178,14 @@ declare class Vault {
176
178
  */
177
179
  unlock(password: string): Promise<Uint8Array>;
178
180
  private _unlock;
181
+ /**
182
+ * A DEK unwrapped from a dek / passkey box must be the key this vault's secrets are sealed under
183
+ * (audit 2026-11-09 E21): a box spliced in from another vault, under another password or passkey,
184
+ * opens with that password but holds a foreign key. Proven with the DEK check, or — in an envelope
185
+ * written before it — the first secret; an old empty envelope has nothing to prove it with. Returns
186
+ * `dek`; on a mismatch zeroizes it and fails as `wrong-password` (the same failure as tampering).
187
+ */
188
+ private _proveOwn;
179
189
  /**
180
190
  * Re-wrap the DEK under a new password (fresh salt, current KDF). Secrets and passkeys are untouched —
181
191
  * and so is the DEK: after a suspected compromise (a copied profile, a leaked session, a lost passkey)
@@ -192,8 +202,11 @@ declare class Vault {
192
202
  *
193
203
  * Passkeys are dropped — their boxes hold the old DEK and cannot be re-wrapped without their PRF
194
204
  * output — and must be registered again ({@link Vault.addPasskey} with the new DEK).
205
+ *
206
+ * With `newPassword` this is also the password change: the new DEK is wrapped under `newPassword`
207
+ * (at least {@link VAULT_MIN_PASSWORD_LENGTH} characters), and `password` must be the current one.
195
208
  */
196
- rotateVaultKey(password: string): Promise<Uint8Array>;
209
+ rotateVaultKey(password: string, newPassword?: string): Promise<Uint8Array>;
197
210
  /** Public view of the registered passkeys (ids, labels; whether each can verify assertions). */
198
211
  listPasskeys(): Promise<Array<{
199
212
  id: string;
@@ -319,10 +332,20 @@ declare class Session {
319
332
  * a missed alarm cannot keep the key alive.
320
333
  */
321
334
  getKey(): Promise<Uint8Array>;
322
- /** User activity: push the auto-lock out again. No-op when locked. */
335
+ /**
336
+ * User activity: push the auto-lock out again. No-op when locked. Call it for explicit user
337
+ * gestures only (unlock, send, approve / decline, an action in the wallet's own UI) — not for
338
+ * passive polls, page requests or worker restarts, or the timer never runs out.
339
+ */
323
340
  touch(): Promise<void>;
324
341
  get autoLockMs(): number;
325
- /** Change the timer (options page); re-arms from now when unlocked. 0 disables. */
342
+ /**
343
+ * Set the timer period (0 disables). Never pushes the deadline out — call this at every worker
344
+ * start with the stored setting: it re-arms the alarm at the stored deadline (a restart must not
345
+ * count as activity, audit 2026-11-09 E11), and only brings the deadline forward when the new
346
+ * period ends sooner. A longer period (or 0) applies from the next {@link Session.touch} /
347
+ * {@link Session.unlock}; call `touch()` right after when the user changed it explicitly.
348
+ */
326
349
  setAutoLockMs(ms: number): Promise<void>;
327
350
  onLock(callback: () => void): () => void;
328
351
  private _serial;
@@ -585,6 +608,11 @@ declare class NetworksTable {
585
608
  /** Cache first (readers see it at once), rolled back when storage refuses. */
586
609
  private write;
587
610
  private custom;
611
+ /**
612
+ * Forget the cached table: the next read asks storage again. For a storage whose answer changes under
613
+ * the table — e.g. one that only hands out the user's networks once the wallet is unlocked.
614
+ */
615
+ reload(): Promise<void>;
588
616
  }
589
617
  /**
590
618
  * EIP-3085 `wallet_addEthereumChain` parameter → {@link EvmNetwork}, or the error
@@ -662,12 +690,23 @@ declare class PermissionStore {
662
690
  get(origin: string): Promise<OriginPermission | null>;
663
691
  list(): Promise<OriginPermission[]>;
664
692
  connect(origin: string, accounts: string[], chain: string): Promise<OriginPermission>;
693
+ /**
694
+ * Add EVM accounts to an origin's grant (per-site grants): the new ones first, the ones it already
695
+ * holds stay. The chain stays the origin's own when it has one. Used by the router's connect; `connect`
696
+ * replaces the list instead.
697
+ */
698
+ grant(origin: string, accounts: string[], chain: string): Promise<OriginPermission>;
665
699
  /** Connect another chain's accounts to the same origin (one "connected sites" list). */
666
700
  connectChain(origin: string, key: ChainAccountsKey, accounts: string[], defaultChain: string): Promise<OriginPermission>;
667
701
  /** Drop one chain's accounts; the origin stays connected while any chain remains. A no-op (no write) when there is nothing to drop. */
668
702
  disconnectChain(origin: string, key: 'accounts' | ChainAccountsKey): Promise<void>;
669
703
  setChain(origin: string, chain: string): Promise<OriginPermission | null>;
670
704
  /**
705
+ * @deprecated Rewrites every origin's grant to the active account, which shows that account to sites
706
+ * the user never connected it to (and links accounts across sites). Grants are per site now: the
707
+ * router shows an origin its granted accounts that are also active, and connecting another account
708
+ * adds it to that one origin ({@link grant}). Kept for compatibility; nothing in this package calls it.
709
+ *
671
710
  * The active EVM account changed: every origin holding an EVM grant now sees `accounts` (MetaMask behaviour).
672
711
  * An origin connected only on another chain (`accounts: []` — Solana/TON/Tron/BTC/NEAR providers, a WalletConnect
673
712
  * session without eip155) is skipped: it never passed an EVM connect and must not learn the EVM address (scan F6/F8).
@@ -706,6 +745,21 @@ declare class OriginRefused extends Error {
706
745
  constructor(message: string);
707
746
  }
708
747
  declare const APPROVALS_MAX_PENDING_PER_ORIGIN = 3;
748
+ /** Requests one site (registrable domain: every subdomain counts) may have waiting. */
749
+ declare const APPROVALS_MAX_PENDING_PER_SITE = 5;
750
+ /** Requests the whole queue holds (exempt origins not counted). */
751
+ declare const APPROVALS_MAX_PENDING_TOTAL = 20;
752
+ /** How fast one site may open sheets: a token bucket per site; running dry refuses for a cooldown that doubles on every repeat. */
753
+ interface ApprovalRateOptions {
754
+ /** Sheets a site may open at once. Default 10. */
755
+ burst?: number;
756
+ /** Sheets per second a site earns back. Default 1/6 (10 a minute). */
757
+ refillPerSecond?: number;
758
+ /** First cooldown after the bucket ran dry. Default 30 s. */
759
+ backoffMs?: number;
760
+ /** Longest cooldown; also how long a site must stay quiet for its strikes to reset. Default 10 min. */
761
+ maxBackoffMs?: number;
762
+ }
709
763
  interface ApprovalRequest<P = unknown> {
710
764
  id: string;
711
765
  origin: string;
@@ -730,6 +784,28 @@ interface ApprovalQueueOptions {
730
784
  refuse?: (origin: string) => string | null | undefined;
731
785
  /** Requests one origin may have waiting (current + queued). Default {@link APPROVALS_MAX_PENDING_PER_ORIGIN}. */
732
786
  maxPendingPerOrigin?: number;
787
+ /** Requests one site may have waiting. Default {@link APPROVALS_MAX_PENDING_PER_SITE}. */
788
+ maxPendingPerSite?: number;
789
+ /** Requests the queue holds in all. Default {@link APPROVALS_MAX_PENDING_TOTAL}. */
790
+ maxPendingTotal?: number;
791
+ /** Origin → site for the per-site limits. Default {@link defaultSiteOf siteOf} (conservative eTLD+1; pass a Public Suffix List based one if you ship it). */
792
+ siteOf?: (origin: string) => string;
793
+ /** Origins that skip every limit (the wallet's own pages: Send, swaps). They still queue behind other requests. */
794
+ exempt?: (origin: string) => boolean;
795
+ /** Sheet-opening rate per site; `false` turns it off. */
796
+ openRate?: ApprovalRateOptions | false;
797
+ /** Clock (ms), injectable for tests. */
798
+ now?: () => number;
799
+ }
800
+ /** Options of one {@link ApprovalQueue.request}. */
801
+ interface ApprovalRequestOptions {
802
+ /**
803
+ * Another sheet for a request the user has just approved (the fee changed before signing). It skips
804
+ * the queue and rate limits and is shown ahead of the requests already waiting — once per approval
805
+ * of the same origin, kind and chain; with no such approval behind it, it is an ordinary request.
806
+ * `refuse` still applies.
807
+ */
808
+ followUp?: boolean;
733
809
  }
734
810
  /** The window side: open for one request, close when it is answered. `memoryApprovalWindow()` for tests. */
735
811
  interface ApprovalWindow {
@@ -746,15 +822,39 @@ declare class ApprovalQueue {
746
822
  private readonly _waiting;
747
823
  private readonly _listeners;
748
824
  private readonly _via;
825
+ private readonly _rate;
826
+ /** Per site: cooldown end and strikes (how many times the bucket ran dry recently). */
827
+ private readonly _cooldown;
828
+ /** Per origin + kind + chain: approvals that have not been followed up (see {@link ApprovalRequestOptions.followUp}). */
829
+ private readonly _approved;
749
830
  constructor(window: ApprovalWindow, newId?: () => string, options?: ApprovalQueueOptions);
831
+ private site;
832
+ private get all();
833
+ /** The per-site rate: a reason to refuse, or null (and one token spent). */
834
+ private rateRefusal;
835
+ private static followUpKey;
836
+ /** The user approved `r`: it may be followed up once. */
837
+ private approved;
838
+ /** Spends one approval of the same origin, kind and chain; false when there is none. */
839
+ private spendApproval;
750
840
  /** Enqueue and wait for the user's answer. Refuses (never queues) past the per-origin limits. */
751
- request<T = unknown>(input: Omit<ApprovalRequest, 'id' | 'createdAt' | 'originWarnings' | 'via'>): Promise<T>;
841
+ request<T = unknown>(input: Omit<ApprovalRequest, 'id' | 'createdAt' | 'originWarnings' | 'via'>, opts?: ApprovalRequestOptions): Promise<T>;
752
842
  /** Attach (or clear) the transport note every later request from `origin` carries. */
753
843
  setVia(origin: string, via: OriginVia | null): void;
754
844
  /** The transport note later requests from `origin` carry (WalletConnect Verify's verdict for `wc:<topic>`), if any. */
755
845
  viaFor(origin: string): OriginVia | undefined;
846
+ private isExempt;
756
847
  /** Requests waiting for `origin` (current + queued). */
757
848
  pendingFor(origin: string): number;
849
+ /** Requests waiting for any origin of `site` (current + queued). */
850
+ pendingForSite(site: string): number;
851
+ /** The site (registrable domain) the queue's limits put `origin` under. */
852
+ siteFor(origin: string): string;
853
+ /** Decline everything waiting for `origin` (its last page closed). Returns how many requests were declined. */
854
+ declineOrigin(origin: string, error?: Error): number;
855
+ /** "Decline all from this site": everything waiting for any origin of `site` (see {@link siteFor}). */
856
+ declineSite(site: string, error?: Error): number;
857
+ private declineWhere;
758
858
  /** The request currently shown (the window asks for it by id on load). */
759
859
  get current(): ApprovalRequest | null;
760
860
  get queued(): number;
@@ -795,6 +895,14 @@ interface RelayErrorOptions {
795
895
  declare function toRelayError(e: unknown, options?: RelayErrorOptions): RelayError;
796
896
  /** Read-only methods answered from our RPC without asking the user. */
797
897
  declare const READ_METHODS: ReadonlySet<string>;
898
+ /**
899
+ * Blocks an `eth_getLogs` from an origin without an EVM grant may span. A page that is not connected
900
+ * reads recent events (a token's latest transfers, a pool's last swaps), not history: 1000 blocks is
901
+ * ~3.3 h on Ethereum and ~30 min on 2 s chains, and stays inside every public RPC's own range cap,
902
+ * so one call cannot make the wallet's RPC scan millions of blocks for a page nobody connected.
903
+ * Connected origins are not bounded here (the node's own limits apply).
904
+ */
905
+ declare const GETLOGS_MAX_SPAN_UNCONNECTED = 1000;
798
906
  /** Methods that produce a signature — the review flow's business (step 4), never answered here. */
799
907
  declare const SIGNING_METHODS: ReadonlySet<string>;
800
908
  interface ConnectApproval {
@@ -841,9 +949,12 @@ declare class RequestRouter {
841
949
  handle(origin: string, chain: RelayChain, method: string, rawParams: unknown): Promise<unknown>;
842
950
  /** What a connected origin sees right now: its permitted accounts that the wallet can expose (none while locked). */
843
951
  private visibleAccounts;
952
+ /** An unconnected origin's `eth_getLogs`: a block hash, or a range of at most {@link GETLOGS_MAX_SPAN_UNCONNECTED} blocks. */
953
+ private boundLogs;
844
954
  /**
845
955
  * Connected and unlocked → the accounts; otherwise the approval window (which
846
- * unlocks first when needed) picks them. Emits `connect` + `accountsChanged`.
956
+ * unlocks first when needed) picks them, and they are ADDED to this origin's
957
+ * grant (other origins are untouched). Emits `connect` + `accountsChanged`.
847
958
  */
848
959
  private connect;
849
960
  disconnect(origin: string): Promise<void>;
@@ -885,7 +996,22 @@ interface SiweInfo {
885
996
  problems: string[];
886
997
  /** The header said "sign-in" but the rest did not parse as EIP-4361 (`message` then holds what could be read). */
887
998
  malformed?: boolean;
999
+ /**
1000
+ * Set when the sign-in names another site than the one asking (its host differs from the page's
1001
+ * host, or from a WalletConnect Verify-attested URL): `domain` as written in the message, `origin`
1002
+ * the asking site as `scheme://host`. A sheet should make this its headline, not one warning among many.
1003
+ */
1004
+ crossSite?: {
1005
+ domain: string;
1006
+ origin: string;
1007
+ };
888
1008
  }
1009
+ /**
1010
+ * Characters a sign-in message is refused for: bidi controls (ALM, LRM / RLM, embeddings, overrides,
1011
+ * isolates), zero-width space / joiners, word joiner and invisible operators, BOM — they can make the
1012
+ * domain or the statement read differently from the bytes that are signed.
1013
+ */
1014
+ declare const SIWE_FORBIDDEN_CHARS: RegExp;
889
1015
  interface SiweContext {
890
1016
  /** The page that asked, as the browser recorded it (`https://…`), or a transport pseudo-origin (`wc:<topic>`). */
891
1017
  origin: string;
@@ -903,6 +1029,15 @@ declare function parseSiwe(text: string): SiweMessage | null;
903
1029
  declare function isLocalHost(host: string): boolean;
904
1030
  /** The checks; `origin` is the page that asked (as the browser recorded it), `account` the signing address, `chainId` the site's chain. */
905
1031
  declare function siweProblems(m: SiweMessage, ctx: SiweContext): string[];
1032
+ /**
1033
+ * The asking site when the sign-in names a different host: the browser-recorded origin, or for a
1034
+ * WalletConnect pseudo-origin the URL Verify attested (VALID, not scam). `null` when the hosts agree
1035
+ * or when no site can be vouched for at all (that case is a separate "cannot verify" problem).
1036
+ */
1037
+ declare function siweCrossSite(m: SiweMessage, ctx: SiweContext): {
1038
+ domain: string;
1039
+ origin: string;
1040
+ } | null;
906
1041
  /** `null` only when the text does not start with an EIP-4361 header; a header with unreadable fields comes back with a "malformed sign-in message" problem. */
907
1042
  declare function describeSiwe(text: string, ctx: SiweContext): SiweInfo | null;
908
1043
 
@@ -928,7 +1063,10 @@ declare function describeSiwe(text: string, ctx: SiweContext): SiweInfo | null;
928
1063
  * The fee caps signed are the ones shown, unless the network outgrew them
929
1064
  * while the sheet was open (EIP-1559: base fee + tip above the shown cap;
930
1065
  * legacy: a higher gas price) — then the user is asked again with the new
931
- * numbers (`repriced: true`).
1066
+ * numbers (`repriced: true`, `repricedFrom` = the max fee shown before) on a
1067
+ * follow-up sheet the queue limits do not refuse, at most {@link MAX_FEE_REASKS}
1068
+ * times in a row; declining it signs nothing. A new max fee above the wallet's
1069
+ * own ceiling ({@link SignDeps.feeCeiling}) is refused without a sheet.
932
1070
  *
933
1071
  * The review payload ({@link SignApproval}) carries what the window shows: the
934
1072
  * classified request, the prepared fields, the fee, and the preview the wallet
@@ -941,16 +1079,19 @@ declare function describeSiwe(text: string, ctx: SiweContext): SiweInfo | null;
941
1079
  type SignRequestInfo = {
942
1080
  kind: 'sign-message';
943
1081
  method: 'personal_sign';
944
- account: string; /** Decoded text when printable, else the hex. */
1082
+ account: string; /** Decoded text when printable, else the hex; invisible / direction-changing characters shown as `⟨U+XXXX⟩` ({@link revealHidden}). */
945
1083
  text: string; /** What is actually signed (hex or utf-8 string). */
946
1084
  raw: string; /** Parsed Sign-In with Ethereum (EIP-4361) with the checks against the asking origin, when the text is one. */
947
- siwe?: SiweInfo;
1085
+ siwe?: SiweInfo; /** `text` had invisible or direction-changing characters (now escaped): the sheet should warn. */
1086
+ hiddenChars?: true; /** The message is exactly 32 bytes (`0x` + 64 hex): a blind hash signature that CoW Protocol (`ethsign`), Safe (v > 30) and others accept as an order or a transfer. Only with the wallet's opt-in ({@link SignDeps.allowBlindHash}); the sheet must make it a danger screen. */
1087
+ blindHash?: true;
948
1088
  } | {
949
1089
  kind: 'sign-typed-data';
950
1090
  method: string;
951
- account: string; /** Pretty-printed JSON. */
1091
+ account: string; /** Pretty-printed JSON, invisible / direction-changing characters escaped. */
952
1092
  text: string;
953
- typedData: TypedData;
1093
+ typedData: TypedData; /** `text` had invisible or direction-changing characters (now escaped): the sheet should warn. */
1094
+ hiddenChars?: true;
954
1095
  } | {
955
1096
  kind: 'send-transaction';
956
1097
  method: 'eth_sendTransaction';
@@ -981,6 +1122,15 @@ interface PreparedTx {
981
1122
  gasPrice?: string;
982
1123
  /** gasLimit × max fee, base units. */
983
1124
  maxFee: string;
1125
+ /**
1126
+ * Set when the page chose the gas limit and the wallet's own `eth_estimateGas` answered: the estimate
1127
+ * (0x hex) and whether the page's limit is above max(estimate × 1.5, estimate + 50 000) — then the sheet
1128
+ * should warn with the max fee. The page's limit is still the one signed.
1129
+ */
1130
+ gasCheck?: {
1131
+ estimate: string;
1132
+ excessive: boolean;
1133
+ };
984
1134
  }
985
1135
  /** The approval window's payload for the three signing kinds. */
986
1136
  interface SignApproval {
@@ -989,6 +1139,8 @@ interface SignApproval {
989
1139
  prepared?: PreparedTx;
990
1140
  /** A second sheet for the same transaction: the network's fee outgrew the cap the first one showed. */
991
1141
  repriced?: true;
1142
+ /** With `repriced`: the max fee (`prepared.maxFee`, base units) the sheet before this one showed. */
1143
+ repricedFrom?: string;
992
1144
  /** What the wallet attached (tx-preview-evm `TxPreview`, typed-data description…). */
993
1145
  preview: unknown;
994
1146
  }
@@ -1024,8 +1176,33 @@ interface SignDeps {
1024
1176
  }): Promise<unknown>;
1025
1177
  /** Tip floor per chain id in wei (default 0.1 gwei everywhere). */
1026
1178
  tipFloor?: (chainId: number) => bigint;
1179
+ /**
1180
+ * Whether a personal_sign of a raw 32-byte hash may reach the sheet (read per request). Default: refused — a
1181
+ * blind hash signature can be a CoW order or a Safe transaction paying someone else (extension audit E55).
1182
+ */
1183
+ allowBlindHash?: () => boolean | Promise<boolean>;
1184
+ /**
1185
+ * The most one transaction may cost in fee on `network` (base units), when the wallet has such a limit
1186
+ * (the one its signer enforces). A fee that rose above it after the sheet is refused right away, with
1187
+ * no second sheet. The first sheet is not checked here: the signer is the guard for it.
1188
+ */
1189
+ feeCeiling?: (network: EvmNetwork) => bigint | undefined;
1027
1190
  }
1028
- /** Vaulty's `messageText`: hex that decodes to printable text is shown decoded; binary payloads stay hex. */
1191
+ /** How many times in a row one transaction's fee may be asked again ({@link SignApproval.repriced}); the next rise stops the request, nothing signed. */
1192
+ declare const MAX_FEE_REASKS = 3;
1193
+ /**
1194
+ * Text for a review sheet: every invisible or direction-changing character replaced by a visible
1195
+ * `⟨U+XXXX⟩`, so the order on screen is the order of the bytes (a right-to-left override can make
1196
+ * "exe.gnp" read as "png.exe"). `hidden` says whether anything was replaced — the sheet should warn.
1197
+ */
1198
+ declare function revealHidden(text: string): {
1199
+ text: string;
1200
+ hidden: boolean;
1201
+ };
1202
+ /**
1203
+ * Vaulty's `messageText`: hex that decodes to printable text is shown decoded; binary payloads stay hex.
1204
+ * Invisible and direction-changing characters come back escaped ({@link revealHidden}).
1205
+ */
1029
1206
  declare function messageText(value: unknown): string;
1030
1207
  /**
1031
1208
  * The message as the signer will sign it: hex decoded when it is valid UTF-8, whatever
@@ -1033,7 +1210,6 @@ declare function messageText(value: unknown): string;
1033
1210
  * signed, not the hex fallback `messageText` shows for unprintable text).
1034
1211
  */
1035
1212
  declare function decodedMessage(value: unknown): string | null;
1036
- /** Signing method + params → what the window reviews, or the error to answer with. */
1037
1213
  declare function classifySignRequest(input: {
1038
1214
  network: EvmNetwork;
1039
1215
  method: string;
@@ -1041,9 +1217,16 @@ declare function classifySignRequest(input: {
1041
1217
  accounts: string[]; /** The asking page (browser-recorded) — needed for the SIWE domain check. */
1042
1218
  origin?: string; /** Transport note for pseudo-origins (WalletConnect Verify), for the SIWE check. */
1043
1219
  via?: OriginVia;
1044
- now?: number;
1220
+ now?: number; /** Let a 32-byte hash personal_sign reach the sheet (marked `blindHash`) instead of refusing it. Default false. */
1221
+ allowBlindHash?: boolean;
1045
1222
  }): SignRequestInfo | RelayError;
1046
- /** Nonce, gas, fees from the wallet's RPC. */
1223
+ /** A page's gas limit above max(estimate × 1.5, estimate + 50 000) is flagged on the sheet (never replaced). */
1224
+ declare function gasLimitExcessive(limit: bigint, estimate: bigint): boolean;
1225
+ /**
1226
+ * Nonce, gas, fees from the wallet's RPC. A gas limit the page set is used as given, but it is checked
1227
+ * against the wallet's own estimate ({@link PreparedTx.gasCheck}); a failed estimate (a call that
1228
+ * reverts now) leaves the check out instead of failing the request.
1229
+ */
1047
1230
  declare function prepareTransaction(deps: Pick<SignDeps, 'rpc' | 'tipFloor'>, network: EvmNetwork, from: string, tx: {
1048
1231
  to: string;
1049
1232
  value: string;
@@ -1166,6 +1349,40 @@ interface RouteView {
1166
1349
  etaSeconds: number;
1167
1350
  validUntilMs: number;
1168
1351
  tags: ('best' | 'fastest')[];
1352
+ /** Why this route is not a plain pick: a flagged route is never BEST (see {@link rank}). Absent when there is nothing to say. */
1353
+ warnings?: RouteWarning[];
1354
+ }
1355
+ /**
1356
+ * What the wallet cannot vouch for on a route — data for the app's list and sheet, never a refusal:
1357
+ * - `min-below-slippage`: the provider's minimum sits `minGapBps` under its own quote, further than the `slippageBps`
1358
+ * the app asked for (a backend that inflates the output and drops the minimum would otherwise win BEST);
1359
+ * - `deposit-address`: the route pays an address the provider's server assigns (a 1Click deposit address, a THORChain
1360
+ * inbound vault on a non-EVM source chain, a Bitcoin deposit address), so where the funds end up is that server's
1361
+ * word, not calldata the wallet can check.
1362
+ */
1363
+ type RouteWarning = {
1364
+ kind: 'min-below-slippage';
1365
+ slippageBps: number;
1366
+ minGapBps: number;
1367
+ } | {
1368
+ kind: 'deposit-address';
1369
+ };
1370
+ /** The app's route policy inputs for {@link rank}. */
1371
+ interface RankOptions {
1372
+ /** The slippage the quotes were requested at (bps): a route whose minimum sits further under its output is flagged and never BEST. */
1373
+ slippageBps?: number;
1374
+ /**
1375
+ * Providers whose routes pay an address their server assigns (NEAR Intents 1Click): flagged, and BEST only when no
1376
+ * route from any other provider exists. Which providers these are is the app's call.
1377
+ */
1378
+ depositAddressProviders?: readonly string[];
1379
+ /**
1380
+ * The same flag per route, for a provider that pays a server-assigned address only on some routes (a THORChain
1381
+ * inbound vault on a non-EVM source chain, a Bitcoin deposit address) and verifiable calldata on the rest. A route is
1382
+ * flagged when its provider is listed above OR this returns true; a throw counts as flagged. BEST goes to a flagged
1383
+ * route only when every route is flagged. Which routes these are is the app's call.
1384
+ */
1385
+ depositAddressRoute?: (quote: Quote) => boolean;
1169
1386
  }
1170
1387
  interface RouteListView {
1171
1388
  routes: RouteView[];
@@ -1178,6 +1395,10 @@ interface RouteListView {
1178
1395
  }
1179
1396
  interface QuoteRoutesOptions {
1180
1397
  onUpdate?: (view: RouteListView) => void;
1398
+ /** See {@link RankOptions.depositAddressProviders}; the slippage comes from `params.slippageBps`. */
1399
+ depositAddressProviders?: readonly string[];
1400
+ /** {@link RankOptions.depositAddressRoute} with the request next to the quote (a quote does not name its source chain). */
1401
+ depositAddressRoute?: (quote: Quote, params: QuoteParams) => boolean;
1181
1402
  /** Per-provider wall clock (default 20 s). */
1182
1403
  timeoutMs?: number;
1183
1404
  signal?: AbortSignal;
@@ -1185,8 +1406,15 @@ interface QuoteRoutesOptions {
1185
1406
  }
1186
1407
  /** Dry quotes from every enabled provider that claims the route, progressively. */
1187
1408
  declare function quoteRoutes(providers: readonly CrossChainProvider[], params: QuoteParams, options?: QuoteRoutesOptions): Promise<RouteListView>;
1188
- /** Highest output first (same destination token for every quote); FASTEST = lowest ETA among them. */
1189
- declare function rank(quotes: Quote[]): RouteView[];
1409
+ /**
1410
+ * Highest output first (same destination token for every quote); FASTEST = lowest ETA among them.
1411
+ *
1412
+ * BEST goes to the highest output among the routes without a {@link RouteWarning} that bars it: never a route whose
1413
+ * minimum is below the requested slippage, and a deposit-address route only when every route is one (no route with
1414
+ * verifiable calldata exists).
1415
+ * The BEST route is listed first; the rest keep the output order. With no route eligible there is no BEST.
1416
+ */
1417
+ declare function rank(quotes: Quote[], options?: RankOptions): RouteView[];
1190
1418
  /** Vaulty's execution floor: 50 bps under the quoted minimum rides normal drift while the user reviews, still refuses a real reprice. */
1191
1419
  declare const FLOOR_TOLERANCE_BPS = 50n;
1192
1420
  declare function executionFloor(minDestAmount: bigint): bigint;
@@ -1204,6 +1432,14 @@ interface SwapReviewMeta {
1204
1432
  toChainName: string;
1205
1433
  /** All of the user's addresses — recipient own/foreign. */
1206
1434
  own: string[];
1435
+ /** The slippage the swap was quoted at (bps): a plan minimum further under its output is warned on the sheet (never refused). */
1436
+ slippageBps?: number;
1437
+ /**
1438
+ * The route pays an address the provider's server assigned (a NEAR Intents 1Click deposit address, a THORChain
1439
+ * inbound vault on a non-EVM source chain, a Bitcoin deposit address — the app's call per route): the sheet warns,
1440
+ * and the recipient check does not pass on `plan.recipient` alone — the transaction does not carry it.
1441
+ */
1442
+ depositAddressAssignedByProvider?: boolean;
1207
1443
  }
1208
1444
  /** What the swap sheet renders. Amounts are base-unit strings. */
1209
1445
  interface SwapApproval {
@@ -1262,6 +1498,14 @@ interface SwapApproval {
1262
1498
  status: 'ok' | 'warn' | 'unknown';
1263
1499
  label: string;
1264
1500
  }[];
1501
+ /** With `meta.slippageBps`: how far the minimum sits under the output, and whether that is more than the slippage. */
1502
+ slippage?: {
1503
+ bps: number;
1504
+ minGapBps: number;
1505
+ below: boolean;
1506
+ };
1507
+ /** With `meta.depositAddressAssignedByProvider`: the funds go to an address the provider's server named. */
1508
+ depositAssignedByProvider?: true;
1265
1509
  }
1266
1510
  declare const encodeApproveCalldata: (spender: string, amount: bigint) => string;
1267
1511
  declare function swapApprovalPayload(plan: Swap2ExecutionPlan, meta: SwapReviewMeta): SwapApproval;
@@ -1438,56 +1682,20 @@ declare function earnApprovalPayload(plan: EarnPlan, meta: EarnReviewMeta): Earn
1438
1682
  /** One sheet for the plan; approve → pre-approve exactly its calls; decline → ReviewDeclined, nothing sent. */
1439
1683
  declare function reviewEarnPlan(approvals: ApprovalQueue, gate: ReviewGate, meta: EarnReviewMeta, plan: EarnPlan): Promise<void>;
1440
1684
 
1441
- declare const TONCONNECT_ERRORS: {
1442
- readonly unknown: 0;
1443
- readonly badRequest: 1;
1444
- readonly manifestNotFound: 2;
1445
- readonly manifestContent: 3;
1446
- readonly unknownApp: 100;
1447
- readonly userDeclined: 300;
1448
- readonly methodNotSupported: 400;
1449
- };
1450
- declare class TonConnectError extends Error {
1451
- readonly code: number;
1452
- constructor(code: number, message: string);
1453
- }
1454
- interface TonConnectRequest {
1455
- manifestUrl: string;
1456
- /** `ton_addr` always; `ton_proof` with the dApp's payload when asked. */
1457
- proofPayload?: string;
1458
- }
1459
- declare function parseConnectRequest(message: unknown): TonConnectRequest;
1460
- interface TonConnectMessage {
1461
- /** Destination, as given (friendly or raw). */
1462
- address: string;
1463
- /** Nanotons, decimal string. */
1464
- amount: string;
1465
- /** base64 BoC body. */
1466
- payload?: string;
1467
- /** base64 BoC state init. */
1468
- stateInit?: string;
1469
- }
1470
- interface TonConnectSendTransaction {
1471
- validUntil?: number;
1472
- network?: string;
1473
- from?: string;
1474
- messages: TonConnectMessage[];
1475
- }
1476
- declare const TONCONNECT_MAX_MESSAGES = 4;
1477
- /** `sendTransaction` params[0] (a JSON string per the spec, or an object). */
1478
- declare function parseSendTransaction(param: unknown, options?: {
1479
- maxMessages?: number;
1480
- network?: string;
1481
- }): TonConnectSendTransaction;
1482
- type TonSignDataPayload = {
1483
- type: 'text';
1484
- text: string;
1485
- } | {
1486
- type: 'binary';
1487
- bytes: string;
1488
- };
1489
- /** `signData` params[0]: text or binary only — `cell` payloads need schema-aware rendering and are refused by name. */
1490
- declare function parseSignData(param: unknown): TonSignDataPayload;
1685
+ /**
1686
+ * TON Connect protocol v2 for the extension's JS bridge. Request parsing, error codes and the
1687
+ * signature digests live in one place, `@anywalletkit/wallet-ton/tonconnect`, shared with the
1688
+ * WalletConnect transport (`@anywalletkit/walletconnect-ton`); this module re-exports them and
1689
+ * keeps the bridge-side helpers (the page origin as the proof domain, relay errors as TON Connect
1690
+ * codes). The wallet side (keys, sheet, broadcast) lives in the extension; nothing here touches a key.
1691
+ *
1692
+ * To SIGN, use `WalletAccountTon.signTonProof` / `signTonConnectData` (wallet-ton): they build the
1693
+ * same digests from the request and the account's own address. `account.sign()` refuses these
1694
+ * 32-byte digests — 32 raw bytes may as well be the hash of a transfer — so the digest functions
1695
+ * here are for checking a proof, not for feeding `sign()`.
1696
+ */
1697
+
1698
+ /** Workchain and 32-byte account hash of a TON address. */
1491
1699
  interface TonAddressParts {
1492
1700
  workchain: number;
1493
1701
  hash: Uint8Array;
@@ -1506,7 +1714,7 @@ declare function tonSignDataMessage(input: {
1506
1714
  timestamp: number;
1507
1715
  payload: TonSignDataPayload;
1508
1716
  }): Uint8Array;
1509
- /** `0:abcd…` → parts; friendly addresses are the wallet package's job (it hands us the raw form). */
1717
+ /** `0:abcd…` → parts. Friendly addresses are the wallet package's job (it hands us the raw form). */
1510
1718
  declare function parseRawAddress(raw: string): TonAddressParts;
1511
1719
  /** The dApp's domain for proofs, from the page origin (host only, as the spec's `domain.value`). */
1512
1720
  declare function proofDomain(origin: string): string;
@@ -1640,6 +1848,8 @@ declare class RecipientBook {
1640
1848
  private state;
1641
1849
  list(namespace: string): Promise<string[]>;
1642
1850
  remember(namespace: string, address: string): Promise<void>;
1851
+ /** Forget the cached book: the next read asks storage again (e.g. a storage that only answers once the wallet is unlocked). */
1852
+ reload(): void;
1643
1853
  /** `known` → the address is one the user paid before; `lookalike` → it imitates one. */
1644
1854
  check(namespace: string, address: string): Promise<{
1645
1855
  known: boolean;
@@ -1647,4 +1857,209 @@ declare class RecipientBook {
1647
1857
  }>;
1648
1858
  }
1649
1859
 
1650
- 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 };
1860
+ /** Field of the stored envelope that holds the MAC (base64), or `null` for a value written without a key. */
1861
+ declare const STORAGE_MAC_FIELD = "anywalletkit.mac/1";
1862
+ /** Field of the stored envelope that holds the value's version (a positive integer, inside the MAC) when the store has a {@link storageVersionLedger}. */
1863
+ declare const STORAGE_VERSION_FIELD = "anywalletkit.ver/1";
1864
+ /**
1865
+ * The storage MAC key: HKDF-SHA256(ikm = DEK, salt = none, info = "anywalletkit/storage-mac/1"), 32
1866
+ * bytes. One-way — it reveals nothing about the DEK — so a wallet may keep it in
1867
+ * `chrome.storage.session` while locked. The same DEK always gives the same key; a rotated DEK a new one.
1868
+ */
1869
+ declare function deriveStorageMacKey(dek: Uint8Array, crypto?: Crypto): Promise<Uint8Array>;
1870
+ /**
1871
+ * What a read found:
1872
+ * - `ok`: a value with a valid MAC;
1873
+ * - `empty`: nothing stored;
1874
+ * - `unsigned`: a value without a MAC (written before the wrapper existed, or while no key was there);
1875
+ * - `invalid`: a MAC that does not match (edited, from another store, or under another key);
1876
+ * - `no-key`: something is stored but there is no key to check it with;
1877
+ * - `stale` (only with a {@link storageVersionLedger}): the MAC is valid — or nothing is stored — but
1878
+ * this is not the latest value the ledger knows: an older signed value put back, a deleted one, or
1879
+ * a ledger that was itself removed, edited or rolled back.
1880
+ */
1881
+ type MacState = 'ok' | 'empty' | 'unsigned' | 'invalid' | 'no-key' | 'stale';
1882
+ interface MacRead<T> {
1883
+ state: MacState;
1884
+ /** The stored value — verified only when `state` is `ok`. */
1885
+ value: T | null;
1886
+ /** With a ledger, for a value whose MAC is valid: its version (`0` = signed before versions existed). */
1887
+ version?: number;
1888
+ }
1889
+ interface MacJsonStorageOptions {
1890
+ /** Names the store inside the MAC: a value signed for one store does not verify in another. */
1891
+ label: string;
1892
+ /** The MAC key ({@link deriveStorageMacKey}), or `null` when the wallet has none (locked). The wrapper zeroizes the copy it gets. */
1893
+ key: () => Promise<Uint8Array | null>;
1894
+ /** `get()` without a key: the stored value unverified (`'unverified'`, default) or `null`. */
1895
+ readWithoutKey?: 'unverified' | 'null';
1896
+ /** `set()` without a key: store the value with no MAC (`'unsigned'`, default — it fails verification later) or throw `VaultError('locked')`. */
1897
+ writeWithoutKey?: 'unsigned' | 'refuse';
1898
+ /**
1899
+ * Rollback protection: the ledger shared by the wallet's signed stores. Every signed write takes the
1900
+ * store's next version (inside the MAC) and records it; a read whose version the ledger does not
1901
+ * agree with is `stale`. The label must not contain a line break.
1902
+ */
1903
+ versions?: StorageVersionLedger;
1904
+ }
1905
+ interface MacJsonStorage<T> extends JsonStorage<T> {
1906
+ /** The verified value (`null` when empty, unsigned or invalid); without a key, per `readWithoutKey`. */
1907
+ get(): Promise<T | null>;
1908
+ /** Sign with the current key; without one, per `writeWithoutKey`. */
1909
+ set(value: T): Promise<void>;
1910
+ /** The stored value and what verification found, under `key` (default: the current key). */
1911
+ read(key?: Uint8Array): Promise<MacRead<T>>;
1912
+ /** Store `value` signed under `key` (default: the current key; refused without one). */
1913
+ write(value: T, key?: Uint8Array): Promise<void>;
1914
+ /**
1915
+ * Re-sign the stored value under `newKey` when it verifies under `oldKey`; anything else is left as it is. Returns what `oldKey` found.
1916
+ * With a ledger: rekey the ledger first ({@link StorageVersionLedger.rekey}); the value keeps its version, and is re-signed only when the
1917
+ * re-signed ledger agrees with it (`stale` otherwise).
1918
+ */
1919
+ rekey(oldKey: Uint8Array, newKey: Uint8Array): Promise<MacState>;
1920
+ }
1921
+ /** Wrap `inner` (e.g. `chromeJsonStorage(chrome.storage.local, key)`) with a MAC; see the module comment. */
1922
+ declare function macJsonStorage<T>(inner: JsonStorage<unknown>, options: MacJsonStorageOptions): MacJsonStorage<T>;
1923
+ /** Deterministic JSON: the same data gives the same text whatever order its keys were stored in. */
1924
+ declare function canonicalJson(value: unknown): string;
1925
+ /** What a {@link StorageVersionLedger} holds, as {@link StorageVersionLedger.read} found it. */
1926
+ interface StorageVersions {
1927
+ /** `ok`; `empty` (no manifest and none expected); `invalid` (unsigned, edited, or another key); `stale` (missing or older than this browser session has seen). */
1928
+ state: 'ok' | 'empty' | 'invalid' | 'stale';
1929
+ /** Goes up by one with every manifest write. `0` when there is no readable manifest. */
1930
+ epoch: number;
1931
+ /** Where this manifest's numbering started: a store's first version is `base + 1`. */
1932
+ base: number;
1933
+ /** After {@link StorageVersionLedger.condemn}: a store the manifest does not list is not trusted, stored or not. */
1934
+ sealed: boolean;
1935
+ /** The latest version of each store, by label. */
1936
+ versions: Record<string, number>;
1937
+ }
1938
+ /** The ledger operations a store runs inside {@link StorageVersionLedger.exclusive}. */
1939
+ interface StorageVersionOps {
1940
+ /**
1941
+ * Is `version` the latest for `label`? `null` = nothing is stored, `0` = a signed value without a
1942
+ * version. A value exactly one ahead of the manifest is accepted and recorded (an interrupted write).
1943
+ */
1944
+ check(label: string, version: number | null, key: Uint8Array): Promise<'ok' | 'stale'>;
1945
+ /**
1946
+ * One write: `write(version)` stores the value signed with the next version, then the manifest records
1947
+ * it. `seen()` is the version of the value stored now (0 when none this key signed). A missing manifest
1948
+ * is created first; a refused one is replaced by a sealed one ({@link StorageVersionLedger.condemn}).
1949
+ */
1950
+ advance(label: string, key: Uint8Array, seen: () => Promise<number>, write: (version: number) => Promise<void>): Promise<number>;
1951
+ }
1952
+ interface StorageVersionLedgerOptions {
1953
+ /** Where the manifest lives — the same area as the stores it covers (`chrome.storage.local`). */
1954
+ manifest: JsonStorage<unknown>;
1955
+ /**
1956
+ * The highest manifest epoch seen, kept where a write to the stores' area cannot reach it and where it
1957
+ * dies with the browser session (`chrome.storage.session`). `set(null)` clears it.
1958
+ */
1959
+ mark: JsonStorage<unknown>;
1960
+ /** Names the manifest inside its MAC. No store may use it. */
1961
+ label?: string;
1962
+ /**
1963
+ * Accept a validly signed value that carries no version (written before the ledger existed) for a
1964
+ * store the manifest has no record of. Off by default: such a value can be replayed for as long as it
1965
+ * is accepted, so switch it on only to migrate, write every store once, and switch it off again.
1966
+ */
1967
+ acceptUnversioned?: boolean;
1968
+ /** Milliseconds since the epoch — where a new manifest starts numbering. */
1969
+ now?: () => number;
1970
+ }
1971
+ interface StorageVersionLedger {
1972
+ /** Run `fn` with no other ledger operation in between (stores use it for read-and-check and for a write). Do not nest. */
1973
+ exclusive<R>(fn: (ops: StorageVersionOps) => Promise<R>): Promise<R>;
1974
+ /**
1975
+ * Stop trusting everything signed so far: a fresh, sealed manifest numbered above all it replaces.
1976
+ * Every store then reads `stale` — also one with nothing stored — until it is written again.
1977
+ */
1978
+ condemn(key: Uint8Array): Promise<void>;
1979
+ /** Re-sign the manifest under `newKey` when it is `ok` under `oldKey` (one epoch up); otherwise it is left as it is. Returns what `oldKey` found. Then rekey the stores. */
1980
+ rekey(oldKey: Uint8Array, newKey: Uint8Array): Promise<StorageVersions['state']>;
1981
+ /** The manifest as `key` sees it. */
1982
+ read(key: Uint8Array): Promise<StorageVersions>;
1983
+ /** Forget manifest and mark — only when the stores are wiped with them (a new vault). */
1984
+ reset(): Promise<void>;
1985
+ }
1986
+ /**
1987
+ * Rollback protection for {@link macJsonStorage} stores: one signed manifest that says which version
1988
+ * of each store is the latest.
1989
+ *
1990
+ * - Every signed value carries its version inside the MAC. A write stores the value with the store's
1991
+ * next version, then the manifest (its `epoch` goes up by one), then the session mark. A value the
1992
+ * manifest lists another version for — or lists, when nothing is stored — is `stale`: putting ONE
1993
+ * store back, or deleting it, is caught, across browser restarts too.
1994
+ * - The manifest lives next to the stores, so the whole area can be put back together. `mark` — the
1995
+ * highest epoch seen, in session storage — catches that for as long as the browser session lives: a
1996
+ * manifest older than the mark, or missing while there is a mark, makes every store `stale`.
1997
+ * - A manifest that is unsigned, edited or under another key makes every store `stale`. So does a
1998
+ * signed value with a version when there is no manifest at all.
1999
+ * - A worker killed between the value and the manifest write leaves a value exactly one version ahead.
2000
+ * That is accepted and recorded: only the key holder can sign that version, so it is the wallet's own
2001
+ * last write. Until it is recorded the previous value still verifies — the same as the interrupted
2002
+ * write never having happened.
2003
+ *
2004
+ * What it cannot see: the whole area (manifest and stores together) put back to an earlier state when
2005
+ * there is no mark — after a browser restart, or an extension reload — and likewise everything deleted
2006
+ * together. Nothing an extension can store survives that and is out of the same writer's reach; it is
2007
+ * what restoring a profile backup looks like. Versions start from the clock (`now`) so that a manifest
2008
+ * created after a loss does not hand out numbers already used; a clock set far back defeats that.
2009
+ *
2010
+ * The ledger never repairs on a read (beyond recording an interrupted write): the wallet decides what
2011
+ * a `stale` store falls back to, calls {@link StorageVersionLedger.condemn} when the manifest itself was
2012
+ * refused, and writes the stores again.
2013
+ */
2014
+ declare function storageVersionLedger(options: StorageVersionLedgerOptions): StorageVersionLedger;
2015
+
2016
+ /**
2017
+ * "Same site" for limits: the registrable domain (eTLD+1) of an origin, and a
2018
+ * token bucket keyed by any string. Both exist so a page cannot multiply its
2019
+ * allowance by spreading requests over subdomains (`a1.evil.tld`, `a2.evil.tld`…).
2020
+ *
2021
+ * There is no Public Suffix List in this package (it is large and changes); the
2022
+ * helper is conservative instead: the last two labels, or three when the last two
2023
+ * are a known multi-label public suffix ({@link MULTI_LABEL_SUFFIXES}: country
2024
+ * second-level domains such as `co.uk`, and hosting domains where anyone gets a
2025
+ * subdomain, such as `github.io` or `vercel.app`). A suffix that is missing from
2026
+ * the list makes unrelated sites under it share one limit (stricter, never looser);
2027
+ * pass your own `siteOf` to the queue when you ship a full list.
2028
+ */
2029
+ /**
2030
+ * Multi-label public suffixes the helper knows. Two groups: country second-level
2031
+ * registries, and hosting platforms that hand out subdomains to anyone (the
2032
+ * Public Suffix List's private section).
2033
+ */
2034
+ declare const MULTI_LABEL_SUFFIXES: ReadonlySet<string>;
2035
+ /**
2036
+ * The site an origin belongs to: `https://a.b.example.co.uk:8443` → `example.co.uk`,
2037
+ * `https://x.vercel.app` → `x.vercel.app`. IP addresses and single-label hosts
2038
+ * (`localhost`) are their own site. A pseudo-origin that is not a URL (`wc:<topic>`)
2039
+ * is returned unchanged.
2040
+ */
2041
+ declare function siteOf(origin: string): string;
2042
+ interface TokenBucketOptions {
2043
+ /** Tokens a key holds when full (the burst). */
2044
+ capacity: number;
2045
+ /** Tokens added per second. */
2046
+ refillPerSecond: number;
2047
+ /** Clock (ms), injectable for tests. */
2048
+ now?: () => number;
2049
+ /** Keys tracked before full buckets are dropped (memory bound). Default 2000. */
2050
+ maxKeys?: number;
2051
+ }
2052
+ /** A token bucket per key: `take(key)` spends one token, `false` when the key is out of tokens. Memory only. */
2053
+ declare class TokenBucket {
2054
+ private readonly options;
2055
+ private readonly buckets;
2056
+ constructor(options: TokenBucketOptions);
2057
+ take(key: string, cost?: number): boolean;
2058
+ /** Tokens `key` holds right now (full for an unknown key). */
2059
+ available(key: string): number;
2060
+ private refill;
2061
+ /** Drop buckets that are full again (they carry no state); the oldest half when every one is in use. */
2062
+ private prune;
2063
+ }
2064
+
2065
+ export { ACTIVE_STATUSES, APPROVALS_MAX_PENDING_PER_ORIGIN, APPROVALS_MAX_PENDING_PER_SITE, APPROVALS_MAX_PENDING_TOTAL, type AddChainApproval, type AlarmsLike, type ApprovalKind, ApprovalQueue, type ApprovalQueueOptions, type ApprovalRateOptions, type ApprovalRequest, type ApprovalRequestOptions, 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, GETLOGS_MAX_SPAN_UNCONNECTED, type GateMatcher, type GatedOp, type HostCheck, type JsonStorage, KEYRING_STORAGE_KEY, LOOKALIKE_PREFIX, LOOKALIKE_SUFFIX, MAX_FEE_REASKS, MULTI_LABEL_SUFFIXES, type MacJsonStorage, type MacJsonStorageOptions, type MacRead, type MacState, 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, type RankOptions, 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 RouteWarning, type RouterDeps, RouterError, SESSION_DEFAULT_AUTOLOCK_MS, SIGNING_METHODS, SIWE_FORBIDDEN_CHARS, SOLANA_CHAIN, SOLANA_RPCS, STORAGE_MAC_FIELD, STORAGE_VERSION_FIELD, type SealedBox, Session, type SessionAlarms, type SessionOptions, type SessionStorage, type SignApproval, type SignDeps, type SignRequestInfo, type SiweContext, type SiweInfo, type SiweMessage, type StorageAreaLike, type StorageVersionLedger, type StorageVersionLedgerOptions, type StorageVersionOps, type StorageVersions, type SwapApproval, type SwapRecord, type SwapRecordStatus, type SwapReviewMeta, SwapTracker, type SwapTrackerDeps, SwapsStore, type SwitchChainApproval, TON_CHAIN, TON_ENDPOINTS, TRON_CHAIN, TRON_PROVIDERS, TokenBucket, type TokenBucketOptions, type TonAddressParts, 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, canonicalJson, chainHex, chainTxMatcher, checkSenderOrigin, chromeAlarms, chromeJsonStorage, chromeKeyringStorage, chromeLocalVaultStorage, chromeSessionStorage, classifySignRequest, createSignHandler, decodedMessage, derToRaw, deriveStorageMacKey, describeSiwe, earnApprovalPayload, earnPlanMatchers, encodeApproveCalldata, evmCallMatcher, executionFloor, fromBase64Url, gasLimitExcessive, hostOf, isCatalogChain, isEnvelopeV1, isEnvelopeV2, isLocalHost, isPageEvent, isPageRequest, isPageResponse, isRelayMethod, isRelayRequest, isRelayToContent, levenshtein, lookalikeOf, macJsonStorage, memoryAlarms, memoryApprovalWindow, memoryJsonStorage, memorySessionStorage, memoryVaultStorage, messageText, newRequestId, nonEvmChain, normalizeHost, pageRequestFrom, parseAddChainParams, parseRawAddress, parseSiwe, parseSwapId, planMatchers, prepareTransaction, proofDomain, quoteRoutes, rank, rawToDer, relayError, revealHidden, reviewEarnPlan, reviewSwapPlan, siteOf, siweCrossSite, siweProblems, stampOrigin, storageVersionLedger, swapApprovalPayload, toBase64Url, toRelayError, tonConnectErrorCode, tonProofMessage, tonSignDataMessage, typedDataMatcher, vaultSecretStorage, verifyAssertion };