@augustdigital/sdk 8.12.0 → 8.13.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.
@@ -40,6 +40,8 @@ exports.METHOD_CATEGORIES = {
40
40
  getYieldLastRealizedOn: 'read.vault',
41
41
  getVaultActivity: 'read.vault',
42
42
  getSwapRouterDepositResult: 'read.vault',
43
+ getSwapRouterWhitelistedTokens: 'read.vault',
44
+ getSwapRouterEligibleVaults: 'read.vault',
43
45
  getVaultPositions: 'read.position',
44
46
  getVaultUserHistory: 'read.position',
45
47
  getUserHistory: 'read.position',
@@ -3,4 +3,4 @@
3
3
  * Generated during publish from package.json version
4
4
  * This file is gitignored and created at publish time
5
5
  */
6
- export declare const SDK_VERSION = "8.12.0";
6
+ export declare const SDK_VERSION = "8.13.0";
@@ -6,5 +6,5 @@ exports.SDK_VERSION = void 0;
6
6
  * Generated during publish from package.json version
7
7
  * This file is gitignored and created at publish time
8
8
  */
9
- exports.SDK_VERSION = '8.12.0';
9
+ exports.SDK_VERSION = '8.13.0';
10
10
  //# sourceMappingURL=version.js.map
@@ -8,6 +8,20 @@ import type { IAddress } from '../../types';
8
8
  * @see {@link getSwapRouterAddress} for the typed lookup helper.
9
9
  */
10
10
  export declare const SWAP_ROUTER_ADDRESSES: Readonly<Record<number, IAddress>>;
11
+ /**
12
+ * Human-readable display name of the `SwapRouter` periphery contract on each
13
+ * supported chain.
14
+ *
15
+ * The contract exposes no on-chain name (no `@title` accessor), so UIs that
16
+ * want to show *which contract* performed the swap-and-deposit — rather than a
17
+ * bare address — read it from here. Display metadata only: never derive
18
+ * routing or eligibility logic from it.
19
+ *
20
+ * Missing keys mean no SwapRouter is deployed on that chain.
21
+ *
22
+ * @see {@link getSwapRouterName} for the typed lookup helper.
23
+ */
24
+ export declare const SWAP_ROUTER_NAMES: Readonly<Record<number, string>>;
11
25
  /**
12
26
  * Vaults whose UI **may offer the any-token SwapRouter deposit surface** —
13
27
  * i.e. the SwapRouter is `enableVault`-ed for them on-chain.
@@ -31,15 +45,41 @@ export declare const SWAP_ROUTER_ADDRESSES: Readonly<Record<number, IAddress>>;
31
45
  *
32
46
  * Lowercase comparison is required when checking — use
33
47
  * {@link isSwapRouterEligible} rather than reading this set directly.
48
+ *
49
+ * @deprecated Superseded by {@link getSwapRouterEligibleVaults}, which derives
50
+ * the eligible set from the router's on-chain `VaultEnabled` history and
51
+ * verifies each vault's current registration (`vaultInfo.referenceAsset != 0`)
52
+ * — so new enablements surface without an SDK release. This static set stays
53
+ * functional as the zero-RPC fallback seed (e.g. TanStack Query `initialData`)
54
+ * and for SDK-internal sync consumers.
34
55
  */
35
56
  export declare const SWAP_ROUTER_ELIGIBLE_VAULTS: ReadonlySet<string>;
36
57
  /**
37
- * @deprecated Renamed to {@link SWAP_ROUTER_ELIGIBLE_VAULTS}, and the semantics
38
- * changed: this set no longer drives `vaultDeposit` auto-routing (that branch
39
- * was removed) it now only marks vaults whose UI may offer the swap-router
40
- * deposit surface. Kept as an alias for one release; migrate to the new name.
58
+ * @deprecated Renamed to {@link SWAP_ROUTER_ELIGIBLE_VAULTS} (itself now
59
+ * superseded by {@link getSwapRouterEligibleVaults}, the on-chain-derived
60
+ * resolver), and the semantics changed: this set no longer drives
61
+ * `vaultDeposit` auto-routing (that branch was removed) it only marks vaults
62
+ * whose UI may offer the swap-router deposit surface. Kept as an alias for one
63
+ * release; migrate to the async resolver.
41
64
  */
42
65
  export declare const VAULTS_USING_SWAP_ROUTER: ReadonlySet<string>;
66
+ /**
67
+ * Block at which each chain's `SwapRouter` was deployed/configured — the safe
68
+ * lower bound for scanning its `TokenEnabled` / `VaultEnabled` log history.
69
+ *
70
+ * The router stores its allowlist as `mapping(address => bool) whitelistedTokens`
71
+ * with no on-chain enumeration, so {@link getSwapRouterWhitelistedTokens} must
72
+ * reconstruct the candidate set from `TokenEnabled` events before verifying each
73
+ * against the current mapping. Starting the `eth_getLogs` scan here (rather than
74
+ * from genesis) bounds it to the router's own lifetime — a few chunks — instead
75
+ * of the whole chain.
76
+ *
77
+ * Mainnet value is the router's deployment block (its first emitted event, the
78
+ * constructor `OwnershipTransferred`). A too-low value only costs extra empty
79
+ * log ranges; a value ABOVE the first `TokenEnabled` would silently miss tokens,
80
+ * so err on the side of earlier.
81
+ */
82
+ export declare const SWAP_ROUTER_DEPLOY_BLOCKS: Readonly<Record<number, number>>;
43
83
  /**
44
84
  * 32-byte origin codes registered on the `SwapRouter` via `addOrigin`.
45
85
  * Drives origin/referral-fee accrual. The on-chain admin must register a
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SWAP_ROUTER_DEX_AGGREGATOR = exports.SWAP_ROUTER_WRAPPED_NATIVE = exports.SWAP_ROUTER_MAX_SWAPS = exports.ORIGIN_CODES = exports.VAULTS_USING_SWAP_ROUTER = exports.SWAP_ROUTER_ELIGIBLE_VAULTS = exports.SWAP_ROUTER_ADDRESSES = void 0;
3
+ exports.SWAP_ROUTER_DEX_AGGREGATOR = exports.SWAP_ROUTER_WRAPPED_NATIVE = exports.SWAP_ROUTER_MAX_SWAPS = exports.ORIGIN_CODES = exports.SWAP_ROUTER_DEPLOY_BLOCKS = exports.VAULTS_USING_SWAP_ROUTER = exports.SWAP_ROUTER_ELIGIBLE_VAULTS = exports.SWAP_ROUTER_NAMES = exports.SWAP_ROUTER_ADDRESSES = void 0;
4
4
  /**
5
5
  * Address of the `SwapRouter` periphery contract on each supported chain.
6
6
  *
@@ -12,6 +12,22 @@ exports.SWAP_ROUTER_DEX_AGGREGATOR = exports.SWAP_ROUTER_WRAPPED_NATIVE = export
12
12
  exports.SWAP_ROUTER_ADDRESSES = {
13
13
  1: '0xAC771209FF2b71EECfF6E85a9AD01db8Ff2618B0',
14
14
  };
15
+ /**
16
+ * Human-readable display name of the `SwapRouter` periphery contract on each
17
+ * supported chain.
18
+ *
19
+ * The contract exposes no on-chain name (no `@title` accessor), so UIs that
20
+ * want to show *which contract* performed the swap-and-deposit — rather than a
21
+ * bare address — read it from here. Display metadata only: never derive
22
+ * routing or eligibility logic from it.
23
+ *
24
+ * Missing keys mean no SwapRouter is deployed on that chain.
25
+ *
26
+ * @see {@link getSwapRouterName} for the typed lookup helper.
27
+ */
28
+ exports.SWAP_ROUTER_NAMES = {
29
+ 1: 'Upshift Swap Router',
30
+ };
15
31
  /**
16
32
  * Vaults whose UI **may offer the any-token SwapRouter deposit surface** —
17
33
  * i.e. the SwapRouter is `enableVault`-ed for them on-chain.
@@ -35,6 +51,13 @@ exports.SWAP_ROUTER_ADDRESSES = {
35
51
  *
36
52
  * Lowercase comparison is required when checking — use
37
53
  * {@link isSwapRouterEligible} rather than reading this set directly.
54
+ *
55
+ * @deprecated Superseded by {@link getSwapRouterEligibleVaults}, which derives
56
+ * the eligible set from the router's on-chain `VaultEnabled` history and
57
+ * verifies each vault's current registration (`vaultInfo.referenceAsset != 0`)
58
+ * — so new enablements surface without an SDK release. This static set stays
59
+ * functional as the zero-RPC fallback seed (e.g. TanStack Query `initialData`)
60
+ * and for SDK-internal sync consumers.
38
61
  */
39
62
  exports.SWAP_ROUTER_ELIGIBLE_VAULTS = new Set([
40
63
  // Sentora USD — native multi-asset Tokenized Vault V2 (reference asset
@@ -43,12 +66,33 @@ exports.SWAP_ROUTER_ELIGIBLE_VAULTS = new Set([
43
66
  '0x74ad2f789ed583dbd141bbdafc673fe1f033718b',
44
67
  ]);
45
68
  /**
46
- * @deprecated Renamed to {@link SWAP_ROUTER_ELIGIBLE_VAULTS}, and the semantics
47
- * changed: this set no longer drives `vaultDeposit` auto-routing (that branch
48
- * was removed) it now only marks vaults whose UI may offer the swap-router
49
- * deposit surface. Kept as an alias for one release; migrate to the new name.
69
+ * @deprecated Renamed to {@link SWAP_ROUTER_ELIGIBLE_VAULTS} (itself now
70
+ * superseded by {@link getSwapRouterEligibleVaults}, the on-chain-derived
71
+ * resolver), and the semantics changed: this set no longer drives
72
+ * `vaultDeposit` auto-routing (that branch was removed) it only marks vaults
73
+ * whose UI may offer the swap-router deposit surface. Kept as an alias for one
74
+ * release; migrate to the async resolver.
50
75
  */
51
76
  exports.VAULTS_USING_SWAP_ROUTER = exports.SWAP_ROUTER_ELIGIBLE_VAULTS;
77
+ /**
78
+ * Block at which each chain's `SwapRouter` was deployed/configured — the safe
79
+ * lower bound for scanning its `TokenEnabled` / `VaultEnabled` log history.
80
+ *
81
+ * The router stores its allowlist as `mapping(address => bool) whitelistedTokens`
82
+ * with no on-chain enumeration, so {@link getSwapRouterWhitelistedTokens} must
83
+ * reconstruct the candidate set from `TokenEnabled` events before verifying each
84
+ * against the current mapping. Starting the `eth_getLogs` scan here (rather than
85
+ * from genesis) bounds it to the router's own lifetime — a few chunks — instead
86
+ * of the whole chain.
87
+ *
88
+ * Mainnet value is the router's deployment block (its first emitted event, the
89
+ * constructor `OwnershipTransferred`). A too-low value only costs extra empty
90
+ * log ranges; a value ABOVE the first `TokenEnabled` would silently miss tokens,
91
+ * so err on the side of earlier.
92
+ */
93
+ exports.SWAP_ROUTER_DEPLOY_BLOCKS = {
94
+ 1: 25237804,
95
+ };
52
96
  /**
53
97
  * 32-byte origin codes registered on the `SwapRouter` via `addOrigin`.
54
98
  * Drives origin/referral-fee accrual. The on-chain admin must register a
@@ -0,0 +1,248 @@
1
+ import { type InterfaceAbi, type JsonRpcProvider } from 'ethers';
2
+ /** The revert shapes {@link decodeRevertData} distinguishes. */
3
+ export type IRevertKind = 'error-string' | 'panic' | 'custom' | 'unknown';
4
+ /** Result of decoding a raw revert blob with {@link decodeRevertData}. */
5
+ export interface IDecodedRevert {
6
+ /**
7
+ * `'error-string'` for `Error(string)` (a `require` message), `'panic'` for
8
+ * compiler-inserted `Panic(uint256)`, `'custom'` when the selector matched a
9
+ * corpus (or caller-supplied) custom error, `'unknown'` when nothing matched.
10
+ */
11
+ kind: IRevertKind;
12
+ /** The 4-byte selector (`0x` + 8 hex chars), always present — even for `'unknown'` so callers can 4byte-lookup it. */
13
+ selector: string;
14
+ /** Error name (e.g. `'ERC20InsufficientBalance'`, `'Error'`, `'Panic'`). Absent for `'unknown'`. */
15
+ name?: string;
16
+ /** Full error signature (e.g. `'ERC20InsufficientBalance(address,uint256,uint256)'`). Absent for `'unknown'`. */
17
+ signature?: string;
18
+ /**
19
+ * Decoded arguments in declaration order (`bigint` for integers, checksummed
20
+ * strings for addresses). Absent when the selector matched but the argument
21
+ * bytes were truncated or malformed — see {@link IDecodedRevert.reason}.
22
+ */
23
+ args?: unknown[];
24
+ /**
25
+ * Human-readable summary when one exists: the `Error(string)` message, the
26
+ * named `Panic` code, or a note that the argument data was truncated.
27
+ */
28
+ reason?: string;
29
+ }
30
+ /**
31
+ * Decode a raw EVM revert blob into a named error with arguments.
32
+ *
33
+ * Pure and offline — no RPC calls, no network. Handles the three revert
34
+ * shapes the EVM produces:
35
+ *
36
+ * 1. `Error(string)` (`0x08c379a0`) — a `require`/`revert` with a message.
37
+ * 2. `Panic(uint256)` (`0x4e487b71`) — compiler-inserted checks, with the
38
+ * numeric code translated to its documented meaning (overflow, division by
39
+ * zero, …).
40
+ * 3. Custom errors — matched against a built-in corpus of OpenZeppelin
41
+ * ERC-6093 / SafeERC20 / ERC4626 / Ownable / Pausable errors, LayerZero V2
42
+ * OApp/OFT errors, and every `error` fragment in the vault ABIs the SDK
43
+ * ships (tokenized vaults, SwapRouter, lending pools, …). Callers can
44
+ * extend the corpus per call via `opts.extraAbis`, which take precedence.
45
+ *
46
+ * Truncated input degrades gracefully: when the 4-byte selector matches a
47
+ * known error but the argument bytes are incomplete (e.g. an alert pipeline
48
+ * clipped the hex), the result still carries `kind: 'custom'`, `name`, and
49
+ * `signature`, with `args` omitted and `reason` explaining the truncation.
50
+ *
51
+ * @param data - The revert blob as a `0x`-prefixed hex string (the `data`
52
+ * field of an ethers v6 `CALL_EXCEPTION`). Anything shorter than a 4-byte
53
+ * selector, or not hex at all, yields `kind: 'unknown'`.
54
+ * @param opts - Optional settings.
55
+ * @param opts.extraAbis - Additional ABIs whose `error` fragments are checked
56
+ * before the built-in corpus.
57
+ * @returns The decoded revert. Never throws; unrecognized selectors return
58
+ * `kind: 'unknown'` with the selector preserved so callers can look it up
59
+ * via {@link lookupSelector}.
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * const decoded = decodeRevertData('0xe450d38c…');
64
+ * // {
65
+ * // kind: 'custom',
66
+ * // selector: '0xe450d38c',
67
+ * // name: 'ERC20InsufficientBalance',
68
+ * // signature: 'ERC20InsufficientBalance(address,uint256,uint256)',
69
+ * // args: ['0x9281…', 487711967n, 1261711967n],
70
+ * // }
71
+ * ```
72
+ */
73
+ export declare function decodeRevertData(data: string, opts?: {
74
+ extraAbis?: InterfaceAbi[];
75
+ }): IDecodedRevert;
76
+ /** Fields recovered from an ethers v6 error string by {@link extractRevertFromErrorText}. */
77
+ export interface IExtractedRevertContext {
78
+ /** The revert blob from the top-level `data="0x…"` field, when present. */
79
+ revertData?: string;
80
+ /** The failed operation from `action="…"` (e.g. `'estimateGas'`, `'call'`). */
81
+ action?: string;
82
+ /** The ethers error code from `code=…` (e.g. `'CALL_EXCEPTION'`). */
83
+ code?: string;
84
+ /** The embedded `transaction={ … }` fields that survived, when any did. */
85
+ tx?: {
86
+ from?: string;
87
+ to?: string;
88
+ data?: string;
89
+ };
90
+ }
91
+ /**
92
+ * Parse an ethers v6 error *string* and recover the machine-readable fields
93
+ * embedded in it.
94
+ *
95
+ * ethers v6 serializes rich error objects into a single message of the shape
96
+ * `… (action="estimateGas", data="0x…", reason=…, transaction={ "data":
97
+ * "0x…", "from": "0x…", "to": "0x…" }, …, code=CALL_EXCEPTION, version=…)` —
98
+ * exactly what error-alert pipelines end up carrying once the original error
99
+ * object is stringified. This helper regex-extracts the revert `data`, the
100
+ * `action`, the `code`, and the embedded transaction fields.
101
+ *
102
+ * Pure and offline. Tolerant of truncation: alert transports often cap
103
+ * message length mid-hex, so every field is matched without requiring its
104
+ * closing quote and the result simply omits whatever did not survive.
105
+ *
106
+ * @param text - The error text to parse (an ethers v6 `error.message`, or a
107
+ * log/alert line that embeds one).
108
+ * @returns The recovered fields; an empty object when nothing matched. Never
109
+ * throws.
110
+ *
111
+ * @example
112
+ * ```ts
113
+ * const ctx = extractRevertFromErrorText(alertErrorLine);
114
+ * if (ctx.revertData) console.log(decodeRevertData(ctx.revertData));
115
+ * ```
116
+ */
117
+ export declare function extractRevertFromErrorText(text: string): IExtractedRevertContext;
118
+ /**
119
+ * Look up candidate signatures for an unknown 4-byte selector against public
120
+ * signature databases.
121
+ *
122
+ * Network helper — queries [openchain.xyz](https://openchain.xyz) first and
123
+ * falls back to [4byte.directory](https://www.4byte.directory). Kept separate
124
+ * from {@link decodeRevertData} so the core decode path stays offline.
125
+ * Worst case 2 HTTPS requests.
126
+ *
127
+ * @param selector - The selector to look up. Longer hex (a full revert blob)
128
+ * is accepted; only the first 4 bytes are used.
129
+ * @returns Candidate signatures (e.g. `['ERC20InsufficientBalance(address,uint256,uint256)']`),
130
+ * most-likely first. Empty when the input is not hex, no database knows the
131
+ * selector, or both databases were unreachable. Never throws.
132
+ *
133
+ * @example
134
+ * ```ts
135
+ * const candidates = await lookupSelector('0xe450d38c');
136
+ * ```
137
+ */
138
+ export declare function lookupSelector(selector: string): Promise<string[]>;
139
+ /** Result of an {@link simulateCall} `eth_call` replay. */
140
+ export type ISimulateCallResult = {
141
+ /** The call succeeded. */
142
+ ok: true;
143
+ /** The raw return data of the call, `0x`-prefixed. */
144
+ returnData: string;
145
+ } | {
146
+ /** The call reverted or the node rejected it. */
147
+ ok: false;
148
+ /** Fresh, untruncated revert blob when the node returned one. */
149
+ revertData?: string;
150
+ /** {@link decodeRevertData} applied to `revertData`, when present. */
151
+ decoded?: IDecodedRevert;
152
+ /** The underlying error message, for failures without revert data. */
153
+ errorMessage: string;
154
+ };
155
+ /**
156
+ * Replay a call via `eth_call` and decode the revert when it fails.
157
+ *
158
+ * The primary use is re-executing a transaction that failed at `estimateGas`
159
+ * (so no transaction hash ever existed): the node returns the *full* revert
160
+ * blob, which both confirms the failure still reproduces and recovers
161
+ * untruncated revert data even when the original error text was clipped in
162
+ * transit. Passing a historical `blockTag` replays against archival state
163
+ * (requires an archive-capable RPC).
164
+ *
165
+ * Exactly 1 RPC call (`eth_call`).
166
+ *
167
+ * @param provider - A connected `JsonRpcProvider` for the target chain, e.g.
168
+ * from `createProvider(rpcUrl, chainId)`. Note that some listed public RPCs
169
+ * reject keyless `eth_call` — supply a working endpoint via the SDK's RPC
170
+ * precedence (constructor `providers` map / `AUGUST_RPC_<chainId>` env).
171
+ * @param tx - The call to replay: `to` and `data` are required, `from`
172
+ * matters whenever the target checks `msg.sender`.
173
+ * @param blockTag - Optional block to execute against (`'latest'` by
174
+ * default; a number or hex tag replays historical state).
175
+ * @param opts - Optional settings forwarded to {@link decodeRevertData}.
176
+ * @param opts.extraAbis - Additional ABIs checked before the built-in corpus
177
+ * when decoding a revert.
178
+ * @returns `{ ok: true, returnData }` on success; on failure `{ ok: false }`
179
+ * with the fresh `revertData` and its decode when the node supplied one.
180
+ * Never throws on revert — only on programmer error (e.g. no provider).
181
+ *
182
+ * @example
183
+ * ```ts
184
+ * const result = await simulateCall(provider, {
185
+ * from: eoa,
186
+ * to: vault,
187
+ * data: calldata,
188
+ * });
189
+ * if (!result.ok && result.decoded) console.log(result.decoded.signature);
190
+ * ```
191
+ */
192
+ export declare function simulateCall(provider: JsonRpcProvider, tx: {
193
+ from?: string;
194
+ to: string;
195
+ data: string;
196
+ }, blockTag?: string | number, opts?: {
197
+ extraAbis?: InterfaceAbi[];
198
+ }): Promise<ISimulateCallResult>;
199
+ /** Snapshot of a holder's token state returned by {@link readTokenState}. */
200
+ export interface ITokenState {
201
+ /** Token symbol, when the contract implements `symbol()`. */
202
+ symbol?: string;
203
+ /** Token decimals, when the contract implements `decimals()`. */
204
+ decimals?: number;
205
+ /** The holder's raw balance in base units, when `balanceOf` resolved. */
206
+ balance?: bigint;
207
+ /** Raw allowance from holder to `spender`, only probed when `spender` was given. */
208
+ allowance?: bigint;
209
+ /**
210
+ * Whether the holder is frozen/blacklisted by the token issuer, from the
211
+ * first compliance getter the token implements (`isAccountFrozen` — Agora
212
+ * AUSD, `isBlacklisted` — USDC-style, `isFrozen`). `undefined` when the
213
+ * token exposes none of them — which is NOT evidence the holder is clear,
214
+ * only that the token has no recognized compliance getter.
215
+ */
216
+ frozen?: boolean;
217
+ }
218
+ /**
219
+ * Read a bounded, fixed set of token-state probes for a holder — the exact
220
+ * facts needed to explain a failed deposit/transfer: what the token is, what
221
+ * the holder has, what the spender may pull, and whether the issuer froze the
222
+ * holder.
223
+ *
224
+ * The probe set is deliberately fixed (no arbitrary calldata): `symbol()`,
225
+ * `decimals()`, `balanceOf(holder)`, `allowance(holder, spender)` when a
226
+ * spender is given, and the compliance getters tried in order —
227
+ * `isAccountFrozen(address)` (Agora AUSD, selector `0xe816d97f`),
228
+ * `isBlacklisted(address)` (USDC-style), `isFrozen(address)`. Probes the
229
+ * token does not implement resolve to `undefined`; this function never
230
+ * throws.
231
+ *
232
+ * Worst case 7 RPC calls (4 base probes + 3 compliance getters), batched by
233
+ * the provider where supported.
234
+ *
235
+ * @param provider - A connected `JsonRpcProvider` for the token's chain.
236
+ * @param token - The ERC-20 token contract address.
237
+ * @param holder - The account whose balance/compliance state to read.
238
+ * @param spender - Optional spender for the `allowance(holder, spender)`
239
+ * probe (e.g. the vault a deposit approves).
240
+ * @returns The token state with every unresolvable probe as `undefined`.
241
+ *
242
+ * @example
243
+ * ```ts
244
+ * const state = await readTokenState(provider, ausd, eoa, vault);
245
+ * // { symbol: 'AUSD', decimals: 6, balance: 487711967n, allowance: 0n, frozen: false }
246
+ * ```
247
+ */
248
+ export declare function readTokenState(provider: JsonRpcProvider, token: string, holder: string, spender?: string): Promise<ITokenState>;