@anywalletkit/extension-kit 0.3.6 → 0.5.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,5 @@
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
3
  import { TonSignDataPayload } from '@anywalletkit/wallet-ton/tonconnect';
4
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';
5
5
 
@@ -178,6 +178,14 @@ declare class Vault {
178
178
  */
179
179
  unlock(password: string): Promise<Uint8Array>;
180
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;
181
189
  /**
182
190
  * Re-wrap the DEK under a new password (fresh salt, current KDF). Secrets and passkeys are untouched —
183
191
  * and so is the DEK: after a suspected compromise (a copied profile, a leaked session, a lost passkey)
@@ -194,8 +202,11 @@ declare class Vault {
194
202
  *
195
203
  * Passkeys are dropped — their boxes hold the old DEK and cannot be re-wrapped without their PRF
196
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.
197
208
  */
198
- rotateVaultKey(password: string): Promise<Uint8Array>;
209
+ rotateVaultKey(password: string, newPassword?: string): Promise<Uint8Array>;
199
210
  /** Public view of the registered passkeys (ids, labels; whether each can verify assertions). */
200
211
  listPasskeys(): Promise<Array<{
201
212
  id: string;
@@ -321,10 +332,20 @@ declare class Session {
321
332
  * a missed alarm cannot keep the key alive.
322
333
  */
323
334
  getKey(): Promise<Uint8Array>;
324
- /** 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
+ */
325
340
  touch(): Promise<void>;
326
341
  get autoLockMs(): number;
327
- /** 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
+ */
328
349
  setAutoLockMs(ms: number): Promise<void>;
329
350
  onLock(callback: () => void): () => void;
330
351
  private _serial;
@@ -587,6 +608,11 @@ declare class NetworksTable {
587
608
  /** Cache first (readers see it at once), rolled back when storage refuses. */
588
609
  private write;
589
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>;
590
616
  }
591
617
  /**
592
618
  * EIP-3085 `wallet_addEthereumChain` parameter → {@link EvmNetwork}, or the error
@@ -664,12 +690,23 @@ declare class PermissionStore {
664
690
  get(origin: string): Promise<OriginPermission | null>;
665
691
  list(): Promise<OriginPermission[]>;
666
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>;
667
699
  /** Connect another chain's accounts to the same origin (one "connected sites" list). */
668
700
  connectChain(origin: string, key: ChainAccountsKey, accounts: string[], defaultChain: string): Promise<OriginPermission>;
669
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. */
670
702
  disconnectChain(origin: string, key: 'accounts' | ChainAccountsKey): Promise<void>;
671
703
  setChain(origin: string, chain: string): Promise<OriginPermission | null>;
672
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
+ *
673
710
  * The active EVM account changed: every origin holding an EVM grant now sees `accounts` (MetaMask behaviour).
674
711
  * An origin connected only on another chain (`accounts: []` — Solana/TON/Tron/BTC/NEAR providers, a WalletConnect
675
712
  * session without eip155) is skipped: it never passed an EVM connect and must not learn the EVM address (scan F6/F8).
@@ -708,6 +745,21 @@ declare class OriginRefused extends Error {
708
745
  constructor(message: string);
709
746
  }
710
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
+ }
711
763
  interface ApprovalRequest<P = unknown> {
712
764
  id: string;
713
765
  origin: string;
@@ -732,6 +784,28 @@ interface ApprovalQueueOptions {
732
784
  refuse?: (origin: string) => string | null | undefined;
733
785
  /** Requests one origin may have waiting (current + queued). Default {@link APPROVALS_MAX_PENDING_PER_ORIGIN}. */
734
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;
735
809
  }
736
810
  /** The window side: open for one request, close when it is answered. `memoryApprovalWindow()` for tests. */
737
811
  interface ApprovalWindow {
@@ -748,15 +822,39 @@ declare class ApprovalQueue {
748
822
  private readonly _waiting;
749
823
  private readonly _listeners;
750
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;
751
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;
752
840
  /** Enqueue and wait for the user's answer. Refuses (never queues) past the per-origin limits. */
753
- 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>;
754
842
  /** Attach (or clear) the transport note every later request from `origin` carries. */
755
843
  setVia(origin: string, via: OriginVia | null): void;
756
844
  /** The transport note later requests from `origin` carry (WalletConnect Verify's verdict for `wc:<topic>`), if any. */
757
845
  viaFor(origin: string): OriginVia | undefined;
846
+ private isExempt;
758
847
  /** Requests waiting for `origin` (current + queued). */
759
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;
760
858
  /** The request currently shown (the window asks for it by id on load). */
761
859
  get current(): ApprovalRequest | null;
762
860
  get queued(): number;
@@ -797,6 +895,14 @@ interface RelayErrorOptions {
797
895
  declare function toRelayError(e: unknown, options?: RelayErrorOptions): RelayError;
798
896
  /** Read-only methods answered from our RPC without asking the user. */
799
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;
800
906
  /** Methods that produce a signature — the review flow's business (step 4), never answered here. */
801
907
  declare const SIGNING_METHODS: ReadonlySet<string>;
802
908
  interface ConnectApproval {
@@ -843,9 +949,12 @@ declare class RequestRouter {
843
949
  handle(origin: string, chain: RelayChain, method: string, rawParams: unknown): Promise<unknown>;
844
950
  /** What a connected origin sees right now: its permitted accounts that the wallet can expose (none while locked). */
845
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;
846
954
  /**
847
955
  * Connected and unlocked → the accounts; otherwise the approval window (which
848
- * 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`.
849
958
  */
850
959
  private connect;
851
960
  disconnect(origin: string): Promise<void>;
@@ -887,7 +996,22 @@ interface SiweInfo {
887
996
  problems: string[];
888
997
  /** The header said "sign-in" but the rest did not parse as EIP-4361 (`message` then holds what could be read). */
889
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
+ };
890
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;
891
1015
  interface SiweContext {
892
1016
  /** The page that asked, as the browser recorded it (`https://…`), or a transport pseudo-origin (`wc:<topic>`). */
893
1017
  origin: string;
@@ -905,6 +1029,15 @@ declare function parseSiwe(text: string): SiweMessage | null;
905
1029
  declare function isLocalHost(host: string): boolean;
906
1030
  /** The checks; `origin` is the page that asked (as the browser recorded it), `account` the signing address, `chainId` the site's chain. */
907
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;
908
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. */
909
1042
  declare function describeSiwe(text: string, ctx: SiweContext): SiweInfo | null;
910
1043
 
@@ -930,7 +1063,10 @@ declare function describeSiwe(text: string, ctx: SiweContext): SiweInfo | null;
930
1063
  * The fee caps signed are the ones shown, unless the network outgrew them
931
1064
  * while the sheet was open (EIP-1559: base fee + tip above the shown cap;
932
1065
  * legacy: a higher gas price) — then the user is asked again with the new
933
- * 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.
934
1070
  *
935
1071
  * The review payload ({@link SignApproval}) carries what the window shows: the
936
1072
  * classified request, the prepared fields, the fee, and the preview the wallet
@@ -943,16 +1079,20 @@ declare function describeSiwe(text: string, ctx: SiweContext): SiweInfo | null;
943
1079
  type SignRequestInfo = {
944
1080
  kind: 'sign-message';
945
1081
  method: 'personal_sign';
946
- 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}). */
947
1083
  text: string; /** What is actually signed (hex or utf-8 string). */
948
1084
  raw: string; /** Parsed Sign-In with Ethereum (EIP-4361) with the checks against the asking origin, when the text is one. */
949
- siwe?: SiweInfo;
1085
+ siwe?: SiweInfo; /** `text` had invisible or direction-changing characters (now escaped): the sheet should warn. */
1086
+ hiddenChars?: true; /** The bytes signed are exactly 32: a blind hash signature that CoW Protocol (`ethsign`), Safe (v > 30) and others accept as an order or a transfer. The sheet must make it a danger screen with Reject / Sign anyway; `blindHashForm` says how the message came. */
1087
+ blindHash?: true; /** With `blindHash`: `'hex'` — `0x` + 64 hex, only with the wallet's opt-in ({@link SignDeps.allowBlindHash}); `'text'` — text whose UTF-8 encoding is 32 bytes (a digest a site ground to valid UTF-8, sent as text), always shown, never refused. */
1088
+ blindHashForm?: PersonalSignBlindHashForm;
950
1089
  } | {
951
1090
  kind: 'sign-typed-data';
952
1091
  method: string;
953
- account: string; /** Pretty-printed JSON. */
1092
+ account: string; /** Pretty-printed JSON, invisible / direction-changing characters escaped. */
954
1093
  text: string;
955
- typedData: TypedData;
1094
+ typedData: TypedData; /** `text` had invisible or direction-changing characters (now escaped): the sheet should warn. */
1095
+ hiddenChars?: true;
956
1096
  } | {
957
1097
  kind: 'send-transaction';
958
1098
  method: 'eth_sendTransaction';
@@ -964,6 +1104,12 @@ type SignRequestInfo = {
964
1104
  gas: string | null;
965
1105
  };
966
1106
  };
1107
+ /**
1108
+ * How a 32-byte personal_sign message came ({@link SignRequestInfo} `blindHashForm`): `0x` + 64 hex, or text whose
1109
+ * UTF-8 encoding is 32 bytes. (kit's `EvmSignBlindHashForm` for `WriteIntent` also has `'bytes'`, a raw `Uint8Array`,
1110
+ * which a personal_sign from a site cannot be.)
1111
+ */
1112
+ type PersonalSignBlindHashForm = 'hex' | 'text';
967
1113
  interface TypedData {
968
1114
  domain: Record<string, unknown>;
969
1115
  types: Record<string, Array<{
@@ -983,6 +1129,15 @@ interface PreparedTx {
983
1129
  gasPrice?: string;
984
1130
  /** gasLimit × max fee, base units. */
985
1131
  maxFee: string;
1132
+ /**
1133
+ * Set when the page chose the gas limit and the wallet's own `eth_estimateGas` answered: the estimate
1134
+ * (0x hex) and whether the page's limit is above max(estimate × 1.5, estimate + 50 000) — then the sheet
1135
+ * should warn with the max fee. The page's limit is still the one signed.
1136
+ */
1137
+ gasCheck?: {
1138
+ estimate: string;
1139
+ excessive: boolean;
1140
+ };
986
1141
  }
987
1142
  /** The approval window's payload for the three signing kinds. */
988
1143
  interface SignApproval {
@@ -991,10 +1146,17 @@ interface SignApproval {
991
1146
  prepared?: PreparedTx;
992
1147
  /** A second sheet for the same transaction: the network's fee outgrew the cap the first one showed. */
993
1148
  repriced?: true;
1149
+ /** With `repriced`: the max fee (`prepared.maxFee`, base units) the sheet before this one showed. */
1150
+ repricedFrom?: string;
994
1151
  /** What the wallet attached (tx-preview-evm `TxPreview`, typed-data description…). */
995
1152
  preview: unknown;
996
1153
  }
997
1154
  interface EvmSigner {
1155
+ /**
1156
+ * EIP-191 personal_sign. Bytes are signed as given, a string as its UTF-8 encoding (what viem
1157
+ * `signMessage`, ethers and wallet-evm `sign` do): the 32-byte check of {@link classifySignRequest}
1158
+ * measures the message that way.
1159
+ */
998
1160
  signMessage(message: string | Uint8Array): Promise<string>;
999
1161
  signTypedData(typed: TypedData): Promise<string>;
1000
1162
  /** Fully specified tx (chainId, nonce, gas, fees) → signed raw transaction. */
@@ -1026,8 +1188,35 @@ interface SignDeps {
1026
1188
  }): Promise<unknown>;
1027
1189
  /** Tip floor per chain id in wei (default 0.1 gwei everywhere). */
1028
1190
  tipFloor?: (chainId: number) => bigint;
1191
+ /**
1192
+ * Whether a personal_sign of a raw 32-byte hash (`0x` + 64 hex) may reach the sheet (read per request). Default:
1193
+ * refused — a blind hash signature can be a CoW order or a Safe transaction paying someone else (extension
1194
+ * audit E55). Text whose UTF-8 encoding is 32 bytes is not affected: it always reaches the sheet, marked
1195
+ * `blindHash` with `blindHashForm: 'text'`.
1196
+ */
1197
+ allowBlindHash?: () => boolean | Promise<boolean>;
1198
+ /**
1199
+ * The most one transaction may cost in fee on `network` (base units), when the wallet has such a limit
1200
+ * (the one its signer enforces). A fee that rose above it after the sheet is refused right away, with
1201
+ * no second sheet. The first sheet is not checked here: the signer is the guard for it.
1202
+ */
1203
+ feeCeiling?: (network: EvmNetwork) => bigint | undefined;
1029
1204
  }
1030
- /** Vaulty's `messageText`: hex that decodes to printable text is shown decoded; binary payloads stay hex. */
1205
+ /** 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. */
1206
+ declare const MAX_FEE_REASKS = 3;
1207
+ /**
1208
+ * Text for a review sheet: every invisible or direction-changing character replaced by a visible
1209
+ * `⟨U+XXXX⟩`, so the order on screen is the order of the bytes (a right-to-left override can make
1210
+ * "exe.gnp" read as "png.exe"). `hidden` says whether anything was replaced — the sheet should warn.
1211
+ */
1212
+ declare function revealHidden(text: string): {
1213
+ text: string;
1214
+ hidden: boolean;
1215
+ };
1216
+ /**
1217
+ * Vaulty's `messageText`: hex that decodes to printable text is shown decoded; binary payloads stay hex.
1218
+ * Invisible and direction-changing characters come back escaped ({@link revealHidden}).
1219
+ */
1031
1220
  declare function messageText(value: unknown): string;
1032
1221
  /**
1033
1222
  * The message as the signer will sign it: hex decoded when it is valid UTF-8, whatever
@@ -1043,9 +1232,16 @@ declare function classifySignRequest(input: {
1043
1232
  accounts: string[]; /** The asking page (browser-recorded) — needed for the SIWE domain check. */
1044
1233
  origin?: string; /** Transport note for pseudo-origins (WalletConnect Verify), for the SIWE check. */
1045
1234
  via?: OriginVia;
1046
- now?: number;
1235
+ now?: number; /** Let a 32-byte hash personal_sign in its hex form (`0x` + 64 hex) reach the sheet (marked `blindHash`) instead of refusing it. Default false. Text whose UTF-8 encoding is 32 bytes always reaches it, marked. */
1236
+ allowBlindHash?: boolean;
1047
1237
  }): SignRequestInfo | RelayError;
1048
- /** Nonce, gas, fees from the wallet's RPC. */
1238
+ /** A page's gas limit above max(estimate × 1.5, estimate + 50 000) is flagged on the sheet (never replaced). */
1239
+ declare function gasLimitExcessive(limit: bigint, estimate: bigint): boolean;
1240
+ /**
1241
+ * Nonce, gas, fees from the wallet's RPC. A gas limit the page set is used as given, but it is checked
1242
+ * against the wallet's own estimate ({@link PreparedTx.gasCheck}); a failed estimate (a call that
1243
+ * reverts now) leaves the check out instead of failing the request.
1244
+ */
1049
1245
  declare function prepareTransaction(deps: Pick<SignDeps, 'rpc' | 'tipFloor'>, network: EvmNetwork, from: string, tx: {
1050
1246
  to: string;
1051
1247
  value: string;
@@ -1168,6 +1364,40 @@ interface RouteView {
1168
1364
  etaSeconds: number;
1169
1365
  validUntilMs: number;
1170
1366
  tags: ('best' | 'fastest')[];
1367
+ /** Why this route is not a plain pick: a flagged route is never BEST (see {@link rank}). Absent when there is nothing to say. */
1368
+ warnings?: RouteWarning[];
1369
+ }
1370
+ /**
1371
+ * What the wallet cannot vouch for on a route — data for the app's list and sheet, never a refusal:
1372
+ * - `min-below-slippage`: the provider's minimum sits `minGapBps` under its own quote, further than the `slippageBps`
1373
+ * the app asked for (a backend that inflates the output and drops the minimum would otherwise win BEST);
1374
+ * - `deposit-address`: the route pays an address the provider's server assigns (a 1Click deposit address, a THORChain
1375
+ * inbound vault on a non-EVM source chain, a Bitcoin deposit address), so where the funds end up is that server's
1376
+ * word, not calldata the wallet can check.
1377
+ */
1378
+ type RouteWarning = {
1379
+ kind: 'min-below-slippage';
1380
+ slippageBps: number;
1381
+ minGapBps: number;
1382
+ } | {
1383
+ kind: 'deposit-address';
1384
+ };
1385
+ /** The app's route policy inputs for {@link rank}. */
1386
+ interface RankOptions {
1387
+ /** The slippage the quotes were requested at (bps): a route whose minimum sits further under its output is flagged and never BEST. */
1388
+ slippageBps?: number;
1389
+ /**
1390
+ * Providers whose routes pay an address their server assigns (NEAR Intents 1Click): flagged, and BEST only when no
1391
+ * route from any other provider exists. Which providers these are is the app's call.
1392
+ */
1393
+ depositAddressProviders?: readonly string[];
1394
+ /**
1395
+ * The same flag per route, for a provider that pays a server-assigned address only on some routes (a THORChain
1396
+ * inbound vault on a non-EVM source chain, a Bitcoin deposit address) and verifiable calldata on the rest. A route is
1397
+ * flagged when its provider is listed above OR this returns true; a throw counts as flagged. BEST goes to a flagged
1398
+ * route only when every route is flagged. Which routes these are is the app's call.
1399
+ */
1400
+ depositAddressRoute?: (quote: Quote) => boolean;
1171
1401
  }
1172
1402
  interface RouteListView {
1173
1403
  routes: RouteView[];
@@ -1180,6 +1410,10 @@ interface RouteListView {
1180
1410
  }
1181
1411
  interface QuoteRoutesOptions {
1182
1412
  onUpdate?: (view: RouteListView) => void;
1413
+ /** See {@link RankOptions.depositAddressProviders}; the slippage comes from `params.slippageBps`. */
1414
+ depositAddressProviders?: readonly string[];
1415
+ /** {@link RankOptions.depositAddressRoute} with the request next to the quote (a quote does not name its source chain). */
1416
+ depositAddressRoute?: (quote: Quote, params: QuoteParams) => boolean;
1183
1417
  /** Per-provider wall clock (default 20 s). */
1184
1418
  timeoutMs?: number;
1185
1419
  signal?: AbortSignal;
@@ -1187,8 +1421,15 @@ interface QuoteRoutesOptions {
1187
1421
  }
1188
1422
  /** Dry quotes from every enabled provider that claims the route, progressively. */
1189
1423
  declare function quoteRoutes(providers: readonly CrossChainProvider[], params: QuoteParams, options?: QuoteRoutesOptions): Promise<RouteListView>;
1190
- /** Highest output first (same destination token for every quote); FASTEST = lowest ETA among them. */
1191
- declare function rank(quotes: Quote[]): RouteView[];
1424
+ /**
1425
+ * Highest output first (same destination token for every quote); FASTEST = lowest ETA among them.
1426
+ *
1427
+ * BEST goes to the highest output among the routes without a {@link RouteWarning} that bars it: never a route whose
1428
+ * minimum is below the requested slippage, and a deposit-address route only when every route is one (no route with
1429
+ * verifiable calldata exists).
1430
+ * The BEST route is listed first; the rest keep the output order. With no route eligible there is no BEST.
1431
+ */
1432
+ declare function rank(quotes: Quote[], options?: RankOptions): RouteView[];
1192
1433
  /** Vaulty's execution floor: 50 bps under the quoted minimum rides normal drift while the user reviews, still refuses a real reprice. */
1193
1434
  declare const FLOOR_TOLERANCE_BPS = 50n;
1194
1435
  declare function executionFloor(minDestAmount: bigint): bigint;
@@ -1206,6 +1447,14 @@ interface SwapReviewMeta {
1206
1447
  toChainName: string;
1207
1448
  /** All of the user's addresses — recipient own/foreign. */
1208
1449
  own: string[];
1450
+ /** The slippage the swap was quoted at (bps): a plan minimum further under its output is warned on the sheet (never refused). */
1451
+ slippageBps?: number;
1452
+ /**
1453
+ * The route pays an address the provider's server assigned (a NEAR Intents 1Click deposit address, a THORChain
1454
+ * inbound vault on a non-EVM source chain, a Bitcoin deposit address — the app's call per route): the sheet warns,
1455
+ * and the recipient check does not pass on `plan.recipient` alone — the transaction does not carry it.
1456
+ */
1457
+ depositAddressAssignedByProvider?: boolean;
1209
1458
  }
1210
1459
  /** What the swap sheet renders. Amounts are base-unit strings. */
1211
1460
  interface SwapApproval {
@@ -1264,6 +1513,14 @@ interface SwapApproval {
1264
1513
  status: 'ok' | 'warn' | 'unknown';
1265
1514
  label: string;
1266
1515
  }[];
1516
+ /** With `meta.slippageBps`: how far the minimum sits under the output, and whether that is more than the slippage. */
1517
+ slippage?: {
1518
+ bps: number;
1519
+ minGapBps: number;
1520
+ below: boolean;
1521
+ };
1522
+ /** With `meta.depositAddressAssignedByProvider`: the funds go to an address the provider's server named. */
1523
+ depositAssignedByProvider?: true;
1267
1524
  }
1268
1525
  declare const encodeApproveCalldata: (spender: string, amount: bigint) => string;
1269
1526
  declare function swapApprovalPayload(plan: Swap2ExecutionPlan, meta: SwapReviewMeta): SwapApproval;
@@ -1606,6 +1863,8 @@ declare class RecipientBook {
1606
1863
  private state;
1607
1864
  list(namespace: string): Promise<string[]>;
1608
1865
  remember(namespace: string, address: string): Promise<void>;
1866
+ /** Forget the cached book: the next read asks storage again (e.g. a storage that only answers once the wallet is unlocked). */
1867
+ reload(): void;
1609
1868
  /** `known` → the address is one the user paid before; `lookalike` → it imitates one. */
1610
1869
  check(namespace: string, address: string): Promise<{
1611
1870
  known: boolean;
@@ -1613,4 +1872,209 @@ declare class RecipientBook {
1613
1872
  }>;
1614
1873
  }
1615
1874
 
1616
- 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, TON_CHAIN, TON_ENDPOINTS, TRON_CHAIN, TRON_PROVIDERS, 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, 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, parseRawAddress, parseSiwe, parseSwapId, planMatchers, prepareTransaction, proofDomain, quoteRoutes, rank, rawToDer, relayError, reviewEarnPlan, reviewSwapPlan, siweProblems, stampOrigin, swapApprovalPayload, toBase64Url, toRelayError, tonConnectErrorCode, tonProofMessage, tonSignDataMessage, typedDataMatcher, vaultSecretStorage, verifyAssertion };
1875
+ /** Field of the stored envelope that holds the MAC (base64), or `null` for a value written without a key. */
1876
+ declare const STORAGE_MAC_FIELD = "anywalletkit.mac/1";
1877
+ /** Field of the stored envelope that holds the value's version (a positive integer, inside the MAC) when the store has a {@link storageVersionLedger}. */
1878
+ declare const STORAGE_VERSION_FIELD = "anywalletkit.ver/1";
1879
+ /**
1880
+ * The storage MAC key: HKDF-SHA256(ikm = DEK, salt = none, info = "anywalletkit/storage-mac/1"), 32
1881
+ * bytes. One-way — it reveals nothing about the DEK — so a wallet may keep it in
1882
+ * `chrome.storage.session` while locked. The same DEK always gives the same key; a rotated DEK a new one.
1883
+ */
1884
+ declare function deriveStorageMacKey(dek: Uint8Array, crypto?: Crypto): Promise<Uint8Array>;
1885
+ /**
1886
+ * What a read found:
1887
+ * - `ok`: a value with a valid MAC;
1888
+ * - `empty`: nothing stored;
1889
+ * - `unsigned`: a value without a MAC (written before the wrapper existed, or while no key was there);
1890
+ * - `invalid`: a MAC that does not match (edited, from another store, or under another key);
1891
+ * - `no-key`: something is stored but there is no key to check it with;
1892
+ * - `stale` (only with a {@link storageVersionLedger}): the MAC is valid — or nothing is stored — but
1893
+ * this is not the latest value the ledger knows: an older signed value put back, a deleted one, or
1894
+ * a ledger that was itself removed, edited or rolled back.
1895
+ */
1896
+ type MacState = 'ok' | 'empty' | 'unsigned' | 'invalid' | 'no-key' | 'stale';
1897
+ interface MacRead<T> {
1898
+ state: MacState;
1899
+ /** The stored value — verified only when `state` is `ok`. */
1900
+ value: T | null;
1901
+ /** With a ledger, for a value whose MAC is valid: its version (`0` = signed before versions existed). */
1902
+ version?: number;
1903
+ }
1904
+ interface MacJsonStorageOptions {
1905
+ /** Names the store inside the MAC: a value signed for one store does not verify in another. */
1906
+ label: string;
1907
+ /** The MAC key ({@link deriveStorageMacKey}), or `null` when the wallet has none (locked). The wrapper zeroizes the copy it gets. */
1908
+ key: () => Promise<Uint8Array | null>;
1909
+ /** `get()` without a key: the stored value unverified (`'unverified'`, default) or `null`. */
1910
+ readWithoutKey?: 'unverified' | 'null';
1911
+ /** `set()` without a key: store the value with no MAC (`'unsigned'`, default — it fails verification later) or throw `VaultError('locked')`. */
1912
+ writeWithoutKey?: 'unsigned' | 'refuse';
1913
+ /**
1914
+ * Rollback protection: the ledger shared by the wallet's signed stores. Every signed write takes the
1915
+ * store's next version (inside the MAC) and records it; a read whose version the ledger does not
1916
+ * agree with is `stale`. The label must not contain a line break.
1917
+ */
1918
+ versions?: StorageVersionLedger;
1919
+ }
1920
+ interface MacJsonStorage<T> extends JsonStorage<T> {
1921
+ /** The verified value (`null` when empty, unsigned or invalid); without a key, per `readWithoutKey`. */
1922
+ get(): Promise<T | null>;
1923
+ /** Sign with the current key; without one, per `writeWithoutKey`. */
1924
+ set(value: T): Promise<void>;
1925
+ /** The stored value and what verification found, under `key` (default: the current key). */
1926
+ read(key?: Uint8Array): Promise<MacRead<T>>;
1927
+ /** Store `value` signed under `key` (default: the current key; refused without one). */
1928
+ write(value: T, key?: Uint8Array): Promise<void>;
1929
+ /**
1930
+ * Re-sign the stored value under `newKey` when it verifies under `oldKey`; anything else is left as it is. Returns what `oldKey` found.
1931
+ * With a ledger: rekey the ledger first ({@link StorageVersionLedger.rekey}); the value keeps its version, and is re-signed only when the
1932
+ * re-signed ledger agrees with it (`stale` otherwise).
1933
+ */
1934
+ rekey(oldKey: Uint8Array, newKey: Uint8Array): Promise<MacState>;
1935
+ }
1936
+ /** Wrap `inner` (e.g. `chromeJsonStorage(chrome.storage.local, key)`) with a MAC; see the module comment. */
1937
+ declare function macJsonStorage<T>(inner: JsonStorage<unknown>, options: MacJsonStorageOptions): MacJsonStorage<T>;
1938
+ /** Deterministic JSON: the same data gives the same text whatever order its keys were stored in. */
1939
+ declare function canonicalJson(value: unknown): string;
1940
+ /** What a {@link StorageVersionLedger} holds, as {@link StorageVersionLedger.read} found it. */
1941
+ interface StorageVersions {
1942
+ /** `ok`; `empty` (no manifest and none expected); `invalid` (unsigned, edited, or another key); `stale` (missing or older than this browser session has seen). */
1943
+ state: 'ok' | 'empty' | 'invalid' | 'stale';
1944
+ /** Goes up by one with every manifest write. `0` when there is no readable manifest. */
1945
+ epoch: number;
1946
+ /** Where this manifest's numbering started: a store's first version is `base + 1`. */
1947
+ base: number;
1948
+ /** After {@link StorageVersionLedger.condemn}: a store the manifest does not list is not trusted, stored or not. */
1949
+ sealed: boolean;
1950
+ /** The latest version of each store, by label. */
1951
+ versions: Record<string, number>;
1952
+ }
1953
+ /** The ledger operations a store runs inside {@link StorageVersionLedger.exclusive}. */
1954
+ interface StorageVersionOps {
1955
+ /**
1956
+ * Is `version` the latest for `label`? `null` = nothing is stored, `0` = a signed value without a
1957
+ * version. A value exactly one ahead of the manifest is accepted and recorded (an interrupted write).
1958
+ */
1959
+ check(label: string, version: number | null, key: Uint8Array): Promise<'ok' | 'stale'>;
1960
+ /**
1961
+ * One write: `write(version)` stores the value signed with the next version, then the manifest records
1962
+ * it. `seen()` is the version of the value stored now (0 when none this key signed). A missing manifest
1963
+ * is created first; a refused one is replaced by a sealed one ({@link StorageVersionLedger.condemn}).
1964
+ */
1965
+ advance(label: string, key: Uint8Array, seen: () => Promise<number>, write: (version: number) => Promise<void>): Promise<number>;
1966
+ }
1967
+ interface StorageVersionLedgerOptions {
1968
+ /** Where the manifest lives — the same area as the stores it covers (`chrome.storage.local`). */
1969
+ manifest: JsonStorage<unknown>;
1970
+ /**
1971
+ * The highest manifest epoch seen, kept where a write to the stores' area cannot reach it and where it
1972
+ * dies with the browser session (`chrome.storage.session`). `set(null)` clears it.
1973
+ */
1974
+ mark: JsonStorage<unknown>;
1975
+ /** Names the manifest inside its MAC. No store may use it. */
1976
+ label?: string;
1977
+ /**
1978
+ * Accept a validly signed value that carries no version (written before the ledger existed) for a
1979
+ * store the manifest has no record of. Off by default: such a value can be replayed for as long as it
1980
+ * is accepted, so switch it on only to migrate, write every store once, and switch it off again.
1981
+ */
1982
+ acceptUnversioned?: boolean;
1983
+ /** Milliseconds since the epoch — where a new manifest starts numbering. */
1984
+ now?: () => number;
1985
+ }
1986
+ interface StorageVersionLedger {
1987
+ /** Run `fn` with no other ledger operation in between (stores use it for read-and-check and for a write). Do not nest. */
1988
+ exclusive<R>(fn: (ops: StorageVersionOps) => Promise<R>): Promise<R>;
1989
+ /**
1990
+ * Stop trusting everything signed so far: a fresh, sealed manifest numbered above all it replaces.
1991
+ * Every store then reads `stale` — also one with nothing stored — until it is written again.
1992
+ */
1993
+ condemn(key: Uint8Array): Promise<void>;
1994
+ /** 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. */
1995
+ rekey(oldKey: Uint8Array, newKey: Uint8Array): Promise<StorageVersions['state']>;
1996
+ /** The manifest as `key` sees it. */
1997
+ read(key: Uint8Array): Promise<StorageVersions>;
1998
+ /** Forget manifest and mark — only when the stores are wiped with them (a new vault). */
1999
+ reset(): Promise<void>;
2000
+ }
2001
+ /**
2002
+ * Rollback protection for {@link macJsonStorage} stores: one signed manifest that says which version
2003
+ * of each store is the latest.
2004
+ *
2005
+ * - Every signed value carries its version inside the MAC. A write stores the value with the store's
2006
+ * next version, then the manifest (its `epoch` goes up by one), then the session mark. A value the
2007
+ * manifest lists another version for — or lists, when nothing is stored — is `stale`: putting ONE
2008
+ * store back, or deleting it, is caught, across browser restarts too.
2009
+ * - The manifest lives next to the stores, so the whole area can be put back together. `mark` — the
2010
+ * highest epoch seen, in session storage — catches that for as long as the browser session lives: a
2011
+ * manifest older than the mark, or missing while there is a mark, makes every store `stale`.
2012
+ * - A manifest that is unsigned, edited or under another key makes every store `stale`. So does a
2013
+ * signed value with a version when there is no manifest at all.
2014
+ * - A worker killed between the value and the manifest write leaves a value exactly one version ahead.
2015
+ * That is accepted and recorded: only the key holder can sign that version, so it is the wallet's own
2016
+ * last write. Until it is recorded the previous value still verifies — the same as the interrupted
2017
+ * write never having happened.
2018
+ *
2019
+ * What it cannot see: the whole area (manifest and stores together) put back to an earlier state when
2020
+ * there is no mark — after a browser restart, or an extension reload — and likewise everything deleted
2021
+ * together. Nothing an extension can store survives that and is out of the same writer's reach; it is
2022
+ * what restoring a profile backup looks like. Versions start from the clock (`now`) so that a manifest
2023
+ * created after a loss does not hand out numbers already used; a clock set far back defeats that.
2024
+ *
2025
+ * The ledger never repairs on a read (beyond recording an interrupted write): the wallet decides what
2026
+ * a `stale` store falls back to, calls {@link StorageVersionLedger.condemn} when the manifest itself was
2027
+ * refused, and writes the stores again.
2028
+ */
2029
+ declare function storageVersionLedger(options: StorageVersionLedgerOptions): StorageVersionLedger;
2030
+
2031
+ /**
2032
+ * "Same site" for limits: the registrable domain (eTLD+1) of an origin, and a
2033
+ * token bucket keyed by any string. Both exist so a page cannot multiply its
2034
+ * allowance by spreading requests over subdomains (`a1.evil.tld`, `a2.evil.tld`…).
2035
+ *
2036
+ * There is no Public Suffix List in this package (it is large and changes); the
2037
+ * helper is conservative instead: the last two labels, or three when the last two
2038
+ * are a known multi-label public suffix ({@link MULTI_LABEL_SUFFIXES}: country
2039
+ * second-level domains such as `co.uk`, and hosting domains where anyone gets a
2040
+ * subdomain, such as `github.io` or `vercel.app`). A suffix that is missing from
2041
+ * the list makes unrelated sites under it share one limit (stricter, never looser);
2042
+ * pass your own `siteOf` to the queue when you ship a full list.
2043
+ */
2044
+ /**
2045
+ * Multi-label public suffixes the helper knows. Two groups: country second-level
2046
+ * registries, and hosting platforms that hand out subdomains to anyone (the
2047
+ * Public Suffix List's private section).
2048
+ */
2049
+ declare const MULTI_LABEL_SUFFIXES: ReadonlySet<string>;
2050
+ /**
2051
+ * The site an origin belongs to: `https://a.b.example.co.uk:8443` → `example.co.uk`,
2052
+ * `https://x.vercel.app` → `x.vercel.app`. IP addresses and single-label hosts
2053
+ * (`localhost`) are their own site. A pseudo-origin that is not a URL (`wc:<topic>`)
2054
+ * is returned unchanged.
2055
+ */
2056
+ declare function siteOf(origin: string): string;
2057
+ interface TokenBucketOptions {
2058
+ /** Tokens a key holds when full (the burst). */
2059
+ capacity: number;
2060
+ /** Tokens added per second. */
2061
+ refillPerSecond: number;
2062
+ /** Clock (ms), injectable for tests. */
2063
+ now?: () => number;
2064
+ /** Keys tracked before full buckets are dropped (memory bound). Default 2000. */
2065
+ maxKeys?: number;
2066
+ }
2067
+ /** A token bucket per key: `take(key)` spends one token, `false` when the key is out of tokens. Memory only. */
2068
+ declare class TokenBucket {
2069
+ private readonly options;
2070
+ private readonly buckets;
2071
+ constructor(options: TokenBucketOptions);
2072
+ take(key: string, cost?: number): boolean;
2073
+ /** Tokens `key` holds right now (full for an unknown key). */
2074
+ available(key: string): number;
2075
+ private refill;
2076
+ /** Drop buckets that are full again (they carry no state); the oldest half when every one is in use. */
2077
+ private prune;
2078
+ }
2079
+
2080
+ 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, type PersonalSignBlindHashForm, 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 };