@gauntlet-xyz/sdk 3.0.1 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -3
- package/dist/api/activity.d.ts +3 -1
- package/dist/api/activity.d.ts.map +1 -1
- package/dist/api/activityRows.d.ts +11 -0
- package/dist/api/activityRows.d.ts.map +1 -0
- package/dist/api/caip.d.ts.map +1 -1
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/decimal.d.ts.map +1 -1
- package/dist/api/http.d.ts.map +1 -1
- package/dist/api/index.js +7 -8
- package/dist/api/positionHistory.d.ts.map +1 -1
- package/dist/attribution/index.d.ts +5 -2
- package/dist/attribution/index.d.ts.map +1 -1
- package/dist/{chunk-HC2BS7MK.js → chunk-JJOLVL5V.js} +113 -6
- package/dist/chunk-JJOLVL5V.js.map +7 -0
- package/dist/{chunk-S2TTA45N.js → chunk-JRSNLXFY.js} +2 -2
- package/dist/{chunk-SU6JAKIA.js → chunk-MEKISE2T.js} +131 -47
- package/dist/chunk-MEKISE2T.js.map +7 -0
- package/dist/{chunk-7TA2OJUK.js → chunk-YQXTLIJA.js} +209 -96
- package/dist/chunk-YQXTLIJA.js.map +7 -0
- package/dist/cjs/api/activity.d.ts +3 -1
- package/dist/cjs/api/activity.d.ts.map +1 -1
- package/dist/cjs/api/activity.js +14 -12
- package/dist/cjs/api/activity.js.map +2 -2
- package/dist/cjs/api/activityRows.d.ts +11 -0
- package/dist/cjs/api/activityRows.d.ts.map +1 -0
- package/dist/cjs/api/activityRows.js +139 -0
- package/dist/cjs/api/activityRows.js.map +7 -0
- package/dist/cjs/api/caip.d.ts.map +1 -1
- package/dist/cjs/api/caip.js +3 -1
- package/dist/cjs/api/caip.js.map +2 -2
- package/dist/cjs/api/client.d.ts.map +1 -1
- package/dist/cjs/api/client.js +29 -1
- package/dist/cjs/api/client.js.map +2 -2
- package/dist/cjs/api/decimal.d.ts.map +1 -1
- package/dist/cjs/api/decimal.js +1 -0
- package/dist/cjs/api/decimal.js.map +2 -2
- package/dist/cjs/api/http.d.ts.map +1 -1
- package/dist/cjs/api/http.js +1 -0
- package/dist/cjs/api/http.js.map +2 -2
- package/dist/cjs/api/positionHistory.d.ts.map +1 -1
- package/dist/cjs/api/positionHistory.js +17 -4
- package/dist/cjs/api/positionHistory.js.map +2 -2
- package/dist/cjs/attribution/index.d.ts +5 -2
- package/dist/cjs/attribution/index.d.ts.map +1 -1
- package/dist/cjs/attribution/index.js +3 -1
- package/dist/cjs/attribution/index.js.map +2 -2
- package/dist/cjs/evm/adapters/aera.d.ts.map +1 -1
- package/dist/cjs/evm/adapters/aera.js +16 -7
- package/dist/cjs/evm/adapters/aera.js.map +2 -2
- package/dist/cjs/evm/adapters/types.d.ts +1 -0
- package/dist/cjs/evm/adapters/types.d.ts.map +1 -1
- package/dist/cjs/evm/adapters/types.js.map +1 -1
- package/dist/cjs/evm/aeraContracts.d.ts.map +1 -1
- package/dist/cjs/evm/aeraContracts.js +21 -11
- package/dist/cjs/evm/aeraContracts.js.map +2 -2
- package/dist/cjs/evm/deposit.d.ts +3 -2
- package/dist/cjs/evm/deposit.d.ts.map +1 -1
- package/dist/cjs/evm/deposit.js +40 -10
- package/dist/cjs/evm/deposit.js.map +2 -2
- package/dist/cjs/evm/depositQuote.d.ts.map +1 -1
- package/dist/cjs/evm/depositQuote.js +1 -0
- package/dist/cjs/evm/depositQuote.js.map +2 -2
- package/dist/cjs/evm/depositReceiverApproval.d.ts.map +1 -1
- package/dist/cjs/evm/depositReceiverApproval.js +14 -9
- package/dist/cjs/evm/depositReceiverApproval.js.map +2 -2
- package/dist/cjs/evm/userCurrentBalance.d.ts +15 -1
- package/dist/cjs/evm/userCurrentBalance.d.ts.map +1 -1
- package/dist/cjs/evm/userCurrentBalance.js +94 -51
- package/dist/cjs/evm/userCurrentBalance.js.map +2 -2
- package/dist/cjs/evm/withdraw.d.ts +2 -0
- package/dist/cjs/evm/withdraw.d.ts.map +1 -1
- package/dist/cjs/evm/withdraw.js +14 -1
- package/dist/cjs/evm/withdraw.js.map +2 -2
- package/dist/cjs/evm/withdrawQuote.d.ts.map +1 -1
- package/dist/cjs/evm/withdrawQuote.js +1 -0
- package/dist/cjs/evm/withdrawQuote.js.map +2 -2
- package/dist/evm/adapters/aera.d.ts.map +1 -1
- package/dist/evm/adapters/types.d.ts +1 -0
- package/dist/evm/adapters/types.d.ts.map +1 -1
- package/dist/evm/aeraContracts.d.ts.map +1 -1
- package/dist/evm/deposit.d.ts +3 -2
- package/dist/evm/deposit.d.ts.map +1 -1
- package/dist/evm/depositQuote.d.ts.map +1 -1
- package/dist/evm/depositReceiverApproval.d.ts.map +1 -1
- package/dist/evm/index.js +6 -8
- package/dist/evm/userCurrentBalance.d.ts +15 -1
- package/dist/evm/userCurrentBalance.d.ts.map +1 -1
- package/dist/evm/withdraw.d.ts +2 -0
- package/dist/evm/withdraw.d.ts.map +1 -1
- package/dist/evm/withdrawQuote.d.ts.map +1 -1
- package/dist/index.js +11 -13
- package/dist/privy/index.js +2 -2
- package/package.json +1 -1
- package/src/api/activity.ts +18 -15
- package/src/api/activityRows.ts +143 -0
- package/src/api/caip.ts +3 -1
- package/src/api/client.ts +36 -1
- package/src/api/decimal.ts +1 -0
- package/src/api/http.ts +1 -0
- package/src/api/positionHistory.ts +20 -5
- package/src/attribution/index.ts +6 -2
- package/src/evm/adapters/aera.ts +26 -8
- package/src/evm/adapters/types.ts +1 -0
- package/src/evm/aeraContracts.ts +29 -14
- package/src/evm/deposit.ts +43 -12
- package/src/evm/depositQuote.ts +1 -0
- package/src/evm/depositReceiverApproval.ts +14 -9
- package/src/evm/userCurrentBalance.ts +144 -60
- package/src/evm/withdraw.ts +20 -1
- package/src/evm/withdrawQuote.ts +1 -0
- package/dist/chunk-7TA2OJUK.js.map +0 -7
- package/dist/chunk-HC2BS7MK.js.map +0 -7
- package/dist/chunk-STIV2CC4.js +0 -57
- package/dist/chunk-STIV2CC4.js.map +0 -7
- package/dist/chunk-SU6JAKIA.js.map +0 -7
- /package/dist/{chunk-S2TTA45N.js.map → chunk-JRSNLXFY.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deposit.d.ts","sourceRoot":"","sources":["../../../src/evm/deposit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAkB;AAGhD,OAAO,EAAoC,UAAU,EAAE,gCAAuB;AAsB9E,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IAEf,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kGAAkG;IAClG,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wFAAwF;IACxF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED
|
|
1
|
+
{"version":3,"file":"deposit.d.ts","sourceRoot":"","sources":["../../../src/evm/deposit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAkB;AAGhD,OAAO,EAAoC,UAAU,EAAE,gCAAuB;AAsB9E,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IAEf,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kGAAkG;IAClG,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wFAAwF;IACxF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,UAAU,EAAE,CAAC,CAqIvB"}
|
package/dist/cjs/evm/deposit.js
CHANGED
|
@@ -29,6 +29,7 @@ var import_vaults = require("./vaults");
|
|
|
29
29
|
var import_constants = require("../constants");
|
|
30
30
|
var import_operationMode = require("./operationMode");
|
|
31
31
|
async function getDepositTx(client, params) {
|
|
32
|
+
params = structuredClone(params);
|
|
32
33
|
const slippageBps = params.slippageBps ?? import_constants.DEFAULT_BPS;
|
|
33
34
|
if (!Number.isInteger(slippageBps) || slippageBps < 0 || slippageBps > Number(import_constants.MAX_BPS)) {
|
|
34
35
|
throw new import_errors.InvalidSlippageBPSError(slippageBps);
|
|
@@ -70,7 +71,7 @@ async function getDepositTx(client, params) {
|
|
|
70
71
|
modifiedDepositMode = (0, import_operationMode.resolveSyncOnlyOperationMode)(params.vaultId, requestedDepositMode);
|
|
71
72
|
}
|
|
72
73
|
const spender = protocol === "aera" && modifiedDepositMode === "async" ? aeraRuntime.provisioner.address : vault.vaultAddress;
|
|
73
|
-
const { sufficient } = await adapter.checkAllowance({
|
|
74
|
+
const { sufficient, current } = await adapter.checkAllowance({
|
|
74
75
|
publicClient,
|
|
75
76
|
token: token.address,
|
|
76
77
|
owner: account,
|
|
@@ -79,14 +80,43 @@ async function getDepositTx(client, params) {
|
|
|
79
80
|
});
|
|
80
81
|
const steps = [];
|
|
81
82
|
if (!sufficient) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
83
|
+
const approval = adapter.buildApproval({
|
|
84
|
+
token: token.address,
|
|
85
|
+
spender,
|
|
86
|
+
amount: params.amount,
|
|
87
|
+
account
|
|
88
|
+
});
|
|
89
|
+
if (current > 0n && params.amount > 0n) {
|
|
90
|
+
try {
|
|
91
|
+
await publicClient.estimateContractGas({
|
|
92
|
+
address: approval.address,
|
|
93
|
+
abi: approval.abi,
|
|
94
|
+
functionName: "approve",
|
|
95
|
+
args: approval.args,
|
|
96
|
+
account
|
|
97
|
+
});
|
|
98
|
+
} catch (approvalError) {
|
|
99
|
+
const reset = adapter.buildApproval({
|
|
100
|
+
token: token.address,
|
|
101
|
+
spender,
|
|
102
|
+
amount: 0n,
|
|
103
|
+
account
|
|
104
|
+
});
|
|
105
|
+
try {
|
|
106
|
+
await publicClient.estimateContractGas({
|
|
107
|
+
address: reset.address,
|
|
108
|
+
abi: reset.abi,
|
|
109
|
+
functionName: "approve",
|
|
110
|
+
args: reset.args,
|
|
111
|
+
account
|
|
112
|
+
});
|
|
113
|
+
} catch {
|
|
114
|
+
throw approvalError;
|
|
115
|
+
}
|
|
116
|
+
steps.push(reset);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
steps.push(approval);
|
|
90
120
|
}
|
|
91
121
|
const depositSteps = await adapter.buildDeposit({
|
|
92
122
|
vault,
|
|
@@ -103,7 +133,7 @@ async function getDepositTx(client, params) {
|
|
|
103
133
|
minUnitsOut: params.minUnitsOut
|
|
104
134
|
});
|
|
105
135
|
steps.push(...depositSteps);
|
|
106
|
-
return Promise.all(steps.map((step) => (0, import_attribution.encodeTransactionWithAttribution)(client, step)));
|
|
136
|
+
return Promise.all(steps.map((step) => (0, import_attribution.encodeTransactionWithAttribution)(client, step, chainId)));
|
|
107
137
|
}
|
|
108
138
|
// Annotate the CommonJS export names for ESM import in node:
|
|
109
139
|
0 && (module.exports = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/evm/deposit.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Address } from 'viem';\nimport type { GauntletClient } from '../client';\nimport type { EvmTxStep } from './adapters/types';\nimport { getAdapter } from './adapters';\nimport { encodeTransactionWithAttribution, PreparedTx } from '../attribution';\nimport {\n AccountRequiredError,\n VaultNotFoundError,\n UnsupportedAssetError,\n InvalidSlippageBPSError,\n InvalidSyncDepositBoundError,\n} from '../errors';\nimport {\n resolveAeraRuntimeContracts,\n resolveAeraTokenModeSupport,\n type AeraRuntimeContracts,\n} from './aeraContracts';\nimport { resolveVault } from './vaults';\nimport { DEFAULT_BPS, MAX_BPS } from '../constants';\nimport {\n parseOperationMode,\n resolveOperationMode,\n resolveSyncOnlyOperationMode,\n type OperationMode,\n} from './operationMode';\n\nexport interface EvmDepositParams {\n vaultId: string;\n amount: bigint;\n // Required for multichain vaults, will default to base\n chainId?: number;\n // Required for multiasset vaults, not utilized yet\n assetSymbol?: string;\n /** Request async (queued) or sync deposit. Availability is read from live vault configuration. */\n depositMode?: string;\n // So a developer is able to specify a separate receiver than the tx sender\n receiver?: Address;\n /** Slippage tolerance in basis points (e.g. 100 = 1%). Defaults to 100. */\n slippageBps?: number;\n /** Solver tip passed to async Aera provisioner requests. Defaults to 0. */\n solverTip?: bigint;\n /** Maximum price age passed to async Aera provisioner requests. Defaults to 10 days. */\n maxPriceAge?: bigint;\n /** Caller-reviewed minimum output for an explicit Aera synchronous deposit. */\n minUnitsOut?: bigint;\n}\n\n/**\n * Builds the ordered list of EVM transactions required to deposit into a Gauntlet vault.\n *\n * Returns
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,sBAA2B;AAC3B,yBAA6D;AAC7D,oBAMO;AACP,2BAIO;AACP,oBAA6B;AAC7B,uBAAqC;AACrC,2BAKO;
|
|
4
|
+
"sourcesContent": ["import type { Address } from 'viem';\nimport type { GauntletClient } from '../client';\nimport type { EvmTxStep } from './adapters/types';\nimport { getAdapter } from './adapters';\nimport { encodeTransactionWithAttribution, PreparedTx } from '../attribution';\nimport {\n AccountRequiredError,\n VaultNotFoundError,\n UnsupportedAssetError,\n InvalidSlippageBPSError,\n InvalidSyncDepositBoundError,\n} from '../errors';\nimport {\n resolveAeraRuntimeContracts,\n resolveAeraTokenModeSupport,\n type AeraRuntimeContracts,\n} from './aeraContracts';\nimport { resolveVault } from './vaults';\nimport { DEFAULT_BPS, MAX_BPS } from '../constants';\nimport {\n parseOperationMode,\n resolveOperationMode,\n resolveSyncOnlyOperationMode,\n type OperationMode,\n} from './operationMode';\n\nexport interface EvmDepositParams {\n vaultId: string;\n amount: bigint;\n // Required for multichain vaults, will default to base\n chainId?: number;\n // Required for multiasset vaults, not utilized yet\n assetSymbol?: string;\n /** Request async (queued) or sync deposit. Availability is read from live vault configuration. */\n depositMode?: string;\n // So a developer is able to specify a separate receiver than the tx sender\n receiver?: Address;\n /** Slippage tolerance in basis points (e.g. 100 = 1%). Defaults to 100. */\n slippageBps?: number;\n /** Solver tip passed to async Aera provisioner requests. Defaults to 0. */\n solverTip?: bigint;\n /** Maximum price age passed to async Aera provisioner requests. Defaults to 10 days. */\n maxPriceAge?: bigint;\n /** Caller-reviewed minimum output for an explicit Aera synchronous deposit. */\n minUnitsOut?: bigint;\n}\n\n/**\n * Builds the ordered list of EVM transactions required to deposit into a Gauntlet vault.\n *\n * Returns ordered transactions: ERC-20 approvals (if the allowance is insufficient),\n * followed by the deposit or async deposit request. Some tokens require an approval\n * of zero before a new nonzero approval. Each transaction is\n * returned as a `PreparedTx` object ready to be signed and sent.\n *\n * @param client - A configured `GauntletClient` instance with an EVM public client and wallet.\n * @param params - Deposit parameters including the vault identifier, token amount, and optional\n * chain, asset symbol, deposit mode (`'sync'` | `'async'`), and receiver address.\n * @returns Ordered array of prepared transactions to execute in sequence.\n *\n * @throws {VaultNotFoundError} If the vault ID is not found in the manifest.\n * @throws {AccountRequiredError} If no wallet account is set on the client.\n * @throws {UnsupportedDepositModeError} If the requested deposit mode is not supported by the vault.\n * @throws {UnsupportedAssetError} If the specified asset symbol is not accepted by the vault.\n *\n * @example\n * ```ts\n * const txs = await getDepositTx(client, {\n * vaultId: 'baseUsdcPrime',\n * amount: 100_000_000n, // 100 USDC (6 decimals)\n * });\n * for (const tx of txs) {\n * await walletClient.sendTransaction(tx.tx);\n * }\n * ```\n */\nexport async function getDepositTx(\n client: GauntletClient,\n params: EvmDepositParams\n): Promise<PreparedTx[]> {\n params = structuredClone(params);\n const slippageBps = params.slippageBps ?? DEFAULT_BPS;\n if (!Number.isInteger(slippageBps) || slippageBps < 0 || slippageBps > Number(MAX_BPS)) {\n throw new InvalidSlippageBPSError(slippageBps);\n }\n if (\n params.minUnitsOut !== undefined &&\n (typeof params.minUnitsOut !== 'bigint' || params.minUnitsOut <= 0n)\n ) {\n throw new InvalidSyncDepositBoundError();\n }\n\n const resolved = await resolveVault(client, params.vaultId, params.chainId);\n if (!resolved) throw new VaultNotFoundError(params.vaultId);\n\n const chainId = params.chainId ?? resolved.vault.chainId;\n\n const account = client.wallet?.account?.address;\n if (!account) throw new AccountRequiredError();\n\n const { vault, protocol } = resolved;\n\n const adapter = getAdapter(protocol);\n const publicClient = client.getPublicClient(chainId);\n const token =\n vault.supplyToken.length > 1\n ? vault.supplyToken.find((tInfo) => tInfo.symbol === params.assetSymbol)\n : vault.supplyToken[0];\n\n if (token === undefined) {\n throw new UnsupportedAssetError(params.assetSymbol ?? 'unknown', params.vaultId);\n }\n\n const requestedDepositMode = parseOperationMode(params.vaultId, params.depositMode);\n if (\n params.minUnitsOut !== undefined &&\n (protocol !== 'aera' || requestedDepositMode !== 'sync')\n ) {\n throw new InvalidSyncDepositBoundError();\n }\n let modifiedDepositMode: OperationMode;\n let aeraRuntime: AeraRuntimeContracts | undefined;\n\n if (protocol === 'aera') {\n aeraRuntime = await resolveAeraRuntimeContracts(publicClient, vault);\n const tokenModeSupport = await resolveAeraTokenModeSupport(\n publicClient,\n aeraRuntime,\n token.address,\n { includeSyncModes: requestedDepositMode !== 'async' }\n );\n modifiedDepositMode = resolveOperationMode(params.vaultId, requestedDepositMode, {\n async: tokenModeSupport.asyncDeposit,\n sync: tokenModeSupport.syncDeposit,\n });\n } else {\n modifiedDepositMode = resolveSyncOnlyOperationMode(params.vaultId, requestedDepositMode);\n }\n\n const spender =\n protocol === 'aera' && modifiedDepositMode === 'async'\n ? aeraRuntime!.provisioner.address\n : vault.vaultAddress;\n\n // NOTE: this could be moved to the buildDeposit level\n const { sufficient, current } = await adapter.checkAllowance({\n publicClient,\n token: token.address,\n owner: account,\n spender,\n amount: params.amount,\n });\n\n const steps: EvmTxStep[] = [];\n\n if (!sufficient) {\n const approval = adapter.buildApproval({\n token: token.address,\n spender,\n amount: params.amount,\n account,\n });\n if (current > 0n && params.amount > 0n) {\n try {\n await publicClient.estimateContractGas({\n address: approval.address,\n abi: approval.abi,\n functionName: 'approve',\n args: approval.args,\n account,\n });\n } catch (approvalError) {\n const reset = adapter.buildApproval({\n token: token.address,\n spender,\n amount: 0n,\n account,\n });\n try {\n await publicClient.estimateContractGas({\n address: reset.address,\n abi: reset.abi,\n functionName: 'approve',\n args: reset.args,\n account,\n });\n } catch {\n throw approvalError;\n }\n steps.push(reset);\n }\n }\n steps.push(approval);\n }\n\n const depositSteps = await adapter.buildDeposit({\n vault,\n amount: params.amount,\n receiver: params.receiver ?? account,\n account,\n async: modifiedDepositMode === 'async',\n asset: token,\n publicClient,\n slippageBps,\n solverTip: params.solverTip,\n maxPriceAge: params.maxPriceAge,\n aeraRuntime,\n minUnitsOut: params.minUnitsOut,\n });\n steps.push(...depositSteps);\n\n return Promise.all(steps.map((step) => encodeTransactionWithAttribution(client, step, chainId)));\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"depositQuote.d.ts","sourceRoot":"","sources":["../../../src/evm/depositQuote.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAkB;AAmBhD,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,uFAAuF;IACvF,YAAY,EAAE,MAAM,CAAC;IACrB,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AA6CH,mEAAmE;AACnE,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,gBAAgB,CAAC,
|
|
1
|
+
{"version":3,"file":"depositQuote.d.ts","sourceRoot":"","sources":["../../../src/evm/depositQuote.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAkB;AAmBhD,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,uFAAuF;IACvF,YAAY,EAAE,MAAM,CAAC;IACrB,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AA6CH,mEAAmE;AACnE,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,gBAAgB,CAAC,CA0B3B;AAED,+FAA+F;AAC/F,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,eAAe,CAAC,CAS1B"}
|
|
@@ -57,6 +57,7 @@ async function resolveSyncDepositContext(client, params, readKind) {
|
|
|
57
57
|
return { publicClient, vault, token, runtime };
|
|
58
58
|
}
|
|
59
59
|
async function getSyncDepositQuote(client, params) {
|
|
60
|
+
params = structuredClone(params);
|
|
60
61
|
const slippageBps = params.slippageBps ?? import_constants.DEFAULT_BPS;
|
|
61
62
|
if (!Number.isInteger(slippageBps) || slippageBps < 0 || slippageBps > Number(import_constants.MAX_BPS)) {
|
|
62
63
|
throw new import_errors.InvalidSlippageBPSError(slippageBps);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/evm/depositQuote.ts"],
|
|
4
|
-
"sourcesContent": ["import type { GauntletClient } from '../client';\nimport { DEFAULT_BPS, MAX_BPS } from '../constants';\nimport {\n InvalidSlippageBPSError,\n InvalidSyncDepositBoundError,\n UnsupportedAssetError,\n UnsupportedFeatureError,\n VaultNotFoundError,\n} from '../errors';\nimport {\n applySlippageDown,\n resolveAeraRuntimeContracts,\n resolveAeraTokenModeSupport,\n} from './aeraContracts';\nimport { getSyncDepositFeeBps, getSyncDepositQuoteValues } from './aeraContracts/v2';\nimport { resolveOperationMode } from './operationMode';\nimport { ContractVersion } from './types';\nimport { resolveVault } from './vaults';\n\nexport type SyncDepositQuote = Readonly<{\n unitsOut: bigint;\n minUnitsOut: bigint;\n /** Deposit amount converted to the vault's numeraire, after the Instant Supply fee. */\n numeraireOut: bigint;\n /** Instant Supply fee applied to the deposited token amount, in basis points. */\n feeBps: bigint;\n /** Slippage tolerance used to derive `minUnitsOut`, in basis points. */\n slippageBps: number;\n}>;\n\nexport type SyncDepositQuoteParams = {\n vaultId: string;\n chainId?: number;\n assetSymbol?: string;\n amount: bigint;\n slippageBps?: number;\n};\n\nexport type SyncDepositRateParams = {\n vaultId: string;\n chainId?: number;\n assetSymbol?: string;\n};\n\nexport type SyncDepositRate = Readonly<{\n /** Instant Supply fee, in basis points. Independent of the deposit amount. */\n feeBps: bigint;\n}>;\n\nasync function resolveSyncDepositContext(\n client: GauntletClient,\n params: SyncDepositRateParams,\n readKind: 'quote' | 'rate'\n) {\n const resolved = await resolveVault(client, params.vaultId, params.chainId);\n if (!resolved) throw new VaultNotFoundError(params.vaultId, params.chainId);\n if (resolved.protocol !== 'aera') {\n throw new UnsupportedFeatureError(\n readKind === 'quote'\n ? 'Sync deposit quote is only available for Aera vaults'\n : 'Sync deposit rate is only available for Aera vaults'\n );\n }\n\n const { vault } = resolved;\n const token =\n vault.supplyToken.length > 1\n ? vault.supplyToken.find(({ symbol }) => symbol === params.assetSymbol)\n : vault.supplyToken[0];\n if (!token) throw new UnsupportedAssetError(params.assetSymbol ?? 'unknown', params.vaultId);\n\n const publicClient = client.getPublicClient(params.chainId ?? vault.chainId);\n const runtime = await resolveAeraRuntimeContracts(publicClient, vault);\n if (runtime.provisioner.version !== ContractVersion.V2) {\n throw new UnsupportedFeatureError(\n readKind === 'quote'\n ? 'Sync deposit quote requires an Aera V2 provisioner'\n : 'Sync deposit rate requires an Aera V2 provisioner'\n );\n }\n\n const tokenModeSupport = await resolveAeraTokenModeSupport(publicClient, runtime, token.address, {\n includeSyncModes: true,\n });\n resolveOperationMode(params.vaultId, 'sync', {\n async: tokenModeSupport.asyncDeposit,\n sync: tokenModeSupport.syncDeposit,\n });\n\n return { publicClient, vault, token, runtime };\n}\n\n/** Quotes an Aera synchronous deposit and its execution bounds. */\nexport async function getSyncDepositQuote(\n client: GauntletClient,\n params: SyncDepositQuoteParams\n): Promise<SyncDepositQuote> {\n const slippageBps = params.slippageBps ?? DEFAULT_BPS;\n if (!Number.isInteger(slippageBps) || slippageBps < 0 || slippageBps > Number(MAX_BPS)) {\n throw new InvalidSlippageBPSError(slippageBps);\n }\n\n const { publicClient, vault, token, runtime } = await resolveSyncDepositContext(\n client,\n params,\n 'quote'\n );\n\n const { unitsOut, feeBps, numeraireOut } = await getSyncDepositQuoteValues(\n publicClient,\n runtime.provisioner.address,\n runtime.feeCalculator.address,\n runtime.feeCalculator.version,\n vault.vaultAddress,\n token.address,\n params.amount\n );\n const minUnitsOut = applySlippageDown(unitsOut, slippageBps);\n if (minUnitsOut <= 0n) throw new InvalidSyncDepositBoundError();\n\n return { unitsOut, minUnitsOut, numeraireOut, feeBps, slippageBps };\n}\n\n/** Reads the live Instant Supply fee for a vault token, without requiring a deposit amount. */\nexport async function getSyncDepositRate(\n client: GauntletClient,\n params: SyncDepositRateParams\n): Promise<SyncDepositRate> {\n const { publicClient, runtime, token } = await resolveSyncDepositContext(client, params, 'rate');\n\n const feeBps = await getSyncDepositFeeBps(\n publicClient,\n runtime.provisioner.address,\n token.address\n );\n return { feeBps };\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,uBAAqC;AACrC,oBAMO;AACP,2BAIO;AACP,gBAAgE;AAChE,2BAAqC;AACrC,mBAAgC;AAChC,oBAA6B;AAgC7B,eAAe,0BACb,QACA,QACA,UACA;AACA,QAAM,WAAW,UAAM,4BAAa,QAAQ,OAAO,SAAS,OAAO,OAAO;AAC1E,MAAI,CAAC,SAAU,OAAM,IAAI,iCAAmB,OAAO,SAAS,OAAO,OAAO;AAC1E,MAAI,SAAS,aAAa,QAAQ;AAChC,UAAM,IAAI;AAAA,MACR,aAAa,UACT,yDACA;AAAA,IACN;AAAA,EACF;AAEA,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,QACJ,MAAM,YAAY,SAAS,IACvB,MAAM,YAAY,KAAK,CAAC,EAAE,OAAO,MAAM,WAAW,OAAO,WAAW,IACpE,MAAM,YAAY,CAAC;AACzB,MAAI,CAAC,MAAO,OAAM,IAAI,oCAAsB,OAAO,eAAe,WAAW,OAAO,OAAO;AAE3F,QAAM,eAAe,OAAO,gBAAgB,OAAO,WAAW,MAAM,OAAO;AAC3E,QAAM,UAAU,UAAM,kDAA4B,cAAc,KAAK;AACrE,MAAI,QAAQ,YAAY,YAAY,6BAAgB,IAAI;AACtD,UAAM,IAAI;AAAA,MACR,aAAa,UACT,uDACA;AAAA,IACN;AAAA,EACF;AAEA,QAAM,mBAAmB,UAAM,kDAA4B,cAAc,SAAS,MAAM,SAAS;AAAA,IAC/F,kBAAkB;AAAA,EACpB,CAAC;AACD,iDAAqB,OAAO,SAAS,QAAQ;AAAA,IAC3C,OAAO,iBAAiB;AAAA,IACxB,MAAM,iBAAiB;AAAA,EACzB,CAAC;AAED,SAAO,EAAE,cAAc,OAAO,OAAO,QAAQ;AAC/C;AAGA,eAAsB,oBACpB,QACA,QAC2B;AAC3B,QAAM,cAAc,OAAO,eAAe;AAC1C,MAAI,CAAC,OAAO,UAAU,WAAW,KAAK,cAAc,KAAK,cAAc,OAAO,wBAAO,GAAG;AACtF,UAAM,IAAI,sCAAwB,WAAW;AAAA,EAC/C;AAEA,QAAM,EAAE,cAAc,OAAO,OAAO,QAAQ,IAAI,MAAM;AAAA,IACpD;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,EAAE,UAAU,QAAQ,aAAa,IAAI,UAAM;AAAA,IAC/C;AAAA,IACA,QAAQ,YAAY;AAAA,IACpB,QAAQ,cAAc;AAAA,IACtB,QAAQ,cAAc;AAAA,IACtB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AACA,QAAM,kBAAc,wCAAkB,UAAU,WAAW;AAC3D,MAAI,eAAe,GAAI,OAAM,IAAI,2CAA6B;AAE9D,SAAO,EAAE,UAAU,aAAa,cAAc,QAAQ,YAAY;AACpE;AAGA,eAAsB,mBACpB,QACA,QAC0B;AAC1B,QAAM,EAAE,cAAc,SAAS,MAAM,IAAI,MAAM,0BAA0B,QAAQ,QAAQ,MAAM;AAE/F,QAAM,SAAS,UAAM;AAAA,IACnB;AAAA,IACA,QAAQ,YAAY;AAAA,IACpB,MAAM;AAAA,EACR;AACA,SAAO,EAAE,OAAO;AAClB;",
|
|
4
|
+
"sourcesContent": ["import type { GauntletClient } from '../client';\nimport { DEFAULT_BPS, MAX_BPS } from '../constants';\nimport {\n InvalidSlippageBPSError,\n InvalidSyncDepositBoundError,\n UnsupportedAssetError,\n UnsupportedFeatureError,\n VaultNotFoundError,\n} from '../errors';\nimport {\n applySlippageDown,\n resolveAeraRuntimeContracts,\n resolveAeraTokenModeSupport,\n} from './aeraContracts';\nimport { getSyncDepositFeeBps, getSyncDepositQuoteValues } from './aeraContracts/v2';\nimport { resolveOperationMode } from './operationMode';\nimport { ContractVersion } from './types';\nimport { resolveVault } from './vaults';\n\nexport type SyncDepositQuote = Readonly<{\n unitsOut: bigint;\n minUnitsOut: bigint;\n /** Deposit amount converted to the vault's numeraire, after the Instant Supply fee. */\n numeraireOut: bigint;\n /** Instant Supply fee applied to the deposited token amount, in basis points. */\n feeBps: bigint;\n /** Slippage tolerance used to derive `minUnitsOut`, in basis points. */\n slippageBps: number;\n}>;\n\nexport type SyncDepositQuoteParams = {\n vaultId: string;\n chainId?: number;\n assetSymbol?: string;\n amount: bigint;\n slippageBps?: number;\n};\n\nexport type SyncDepositRateParams = {\n vaultId: string;\n chainId?: number;\n assetSymbol?: string;\n};\n\nexport type SyncDepositRate = Readonly<{\n /** Instant Supply fee, in basis points. Independent of the deposit amount. */\n feeBps: bigint;\n}>;\n\nasync function resolveSyncDepositContext(\n client: GauntletClient,\n params: SyncDepositRateParams,\n readKind: 'quote' | 'rate'\n) {\n const resolved = await resolveVault(client, params.vaultId, params.chainId);\n if (!resolved) throw new VaultNotFoundError(params.vaultId, params.chainId);\n if (resolved.protocol !== 'aera') {\n throw new UnsupportedFeatureError(\n readKind === 'quote'\n ? 'Sync deposit quote is only available for Aera vaults'\n : 'Sync deposit rate is only available for Aera vaults'\n );\n }\n\n const { vault } = resolved;\n const token =\n vault.supplyToken.length > 1\n ? vault.supplyToken.find(({ symbol }) => symbol === params.assetSymbol)\n : vault.supplyToken[0];\n if (!token) throw new UnsupportedAssetError(params.assetSymbol ?? 'unknown', params.vaultId);\n\n const publicClient = client.getPublicClient(params.chainId ?? vault.chainId);\n const runtime = await resolveAeraRuntimeContracts(publicClient, vault);\n if (runtime.provisioner.version !== ContractVersion.V2) {\n throw new UnsupportedFeatureError(\n readKind === 'quote'\n ? 'Sync deposit quote requires an Aera V2 provisioner'\n : 'Sync deposit rate requires an Aera V2 provisioner'\n );\n }\n\n const tokenModeSupport = await resolveAeraTokenModeSupport(publicClient, runtime, token.address, {\n includeSyncModes: true,\n });\n resolveOperationMode(params.vaultId, 'sync', {\n async: tokenModeSupport.asyncDeposit,\n sync: tokenModeSupport.syncDeposit,\n });\n\n return { publicClient, vault, token, runtime };\n}\n\n/** Quotes an Aera synchronous deposit and its execution bounds. */\nexport async function getSyncDepositQuote(\n client: GauntletClient,\n params: SyncDepositQuoteParams\n): Promise<SyncDepositQuote> {\n params = structuredClone(params);\n const slippageBps = params.slippageBps ?? DEFAULT_BPS;\n if (!Number.isInteger(slippageBps) || slippageBps < 0 || slippageBps > Number(MAX_BPS)) {\n throw new InvalidSlippageBPSError(slippageBps);\n }\n\n const { publicClient, vault, token, runtime } = await resolveSyncDepositContext(\n client,\n params,\n 'quote'\n );\n\n const { unitsOut, feeBps, numeraireOut } = await getSyncDepositQuoteValues(\n publicClient,\n runtime.provisioner.address,\n runtime.feeCalculator.address,\n runtime.feeCalculator.version,\n vault.vaultAddress,\n token.address,\n params.amount\n );\n const minUnitsOut = applySlippageDown(unitsOut, slippageBps);\n if (minUnitsOut <= 0n) throw new InvalidSyncDepositBoundError();\n\n return { unitsOut, minUnitsOut, numeraireOut, feeBps, slippageBps };\n}\n\n/** Reads the live Instant Supply fee for a vault token, without requiring a deposit amount. */\nexport async function getSyncDepositRate(\n client: GauntletClient,\n params: SyncDepositRateParams\n): Promise<SyncDepositRate> {\n const { publicClient, runtime, token } = await resolveSyncDepositContext(client, params, 'rate');\n\n const feeBps = await getSyncDepositFeeBps(\n publicClient,\n runtime.provisioner.address,\n token.address\n );\n return { feeBps };\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,uBAAqC;AACrC,oBAMO;AACP,2BAIO;AACP,gBAAgE;AAChE,2BAAqC;AACrC,mBAAgC;AAChC,oBAA6B;AAgC7B,eAAe,0BACb,QACA,QACA,UACA;AACA,QAAM,WAAW,UAAM,4BAAa,QAAQ,OAAO,SAAS,OAAO,OAAO;AAC1E,MAAI,CAAC,SAAU,OAAM,IAAI,iCAAmB,OAAO,SAAS,OAAO,OAAO;AAC1E,MAAI,SAAS,aAAa,QAAQ;AAChC,UAAM,IAAI;AAAA,MACR,aAAa,UACT,yDACA;AAAA,IACN;AAAA,EACF;AAEA,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,QACJ,MAAM,YAAY,SAAS,IACvB,MAAM,YAAY,KAAK,CAAC,EAAE,OAAO,MAAM,WAAW,OAAO,WAAW,IACpE,MAAM,YAAY,CAAC;AACzB,MAAI,CAAC,MAAO,OAAM,IAAI,oCAAsB,OAAO,eAAe,WAAW,OAAO,OAAO;AAE3F,QAAM,eAAe,OAAO,gBAAgB,OAAO,WAAW,MAAM,OAAO;AAC3E,QAAM,UAAU,UAAM,kDAA4B,cAAc,KAAK;AACrE,MAAI,QAAQ,YAAY,YAAY,6BAAgB,IAAI;AACtD,UAAM,IAAI;AAAA,MACR,aAAa,UACT,uDACA;AAAA,IACN;AAAA,EACF;AAEA,QAAM,mBAAmB,UAAM,kDAA4B,cAAc,SAAS,MAAM,SAAS;AAAA,IAC/F,kBAAkB;AAAA,EACpB,CAAC;AACD,iDAAqB,OAAO,SAAS,QAAQ;AAAA,IAC3C,OAAO,iBAAiB;AAAA,IACxB,MAAM,iBAAiB;AAAA,EACzB,CAAC;AAED,SAAO,EAAE,cAAc,OAAO,OAAO,QAAQ;AAC/C;AAGA,eAAsB,oBACpB,QACA,QAC2B;AAC3B,WAAS,gBAAgB,MAAM;AAC/B,QAAM,cAAc,OAAO,eAAe;AAC1C,MAAI,CAAC,OAAO,UAAU,WAAW,KAAK,cAAc,KAAK,cAAc,OAAO,wBAAO,GAAG;AACtF,UAAM,IAAI,sCAAwB,WAAW;AAAA,EAC/C;AAEA,QAAM,EAAE,cAAc,OAAO,OAAO,QAAQ,IAAI,MAAM;AAAA,IACpD;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,EAAE,UAAU,QAAQ,aAAa,IAAI,UAAM;AAAA,IAC/C;AAAA,IACA,QAAQ,YAAY;AAAA,IACpB,QAAQ,cAAc;AAAA,IACtB,QAAQ,cAAc;AAAA,IACtB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AACA,QAAM,kBAAc,wCAAkB,UAAU,WAAW;AAC3D,MAAI,eAAe,GAAI,OAAM,IAAI,2CAA6B;AAE9D,SAAO,EAAE,UAAU,aAAa,cAAc,QAAQ,YAAY;AACpE;AAGA,eAAsB,mBACpB,QACA,QAC0B;AAC1B,QAAM,EAAE,cAAc,SAAS,MAAM,IAAI,MAAM,0BAA0B,QAAQ,QAAQ,MAAM;AAE/F,QAAM,SAAS,UAAM;AAAA,IACnB;AAAA,IACA,QAAQ,YAAY;AAAA,IACpB,MAAM;AAAA,EACR;AACA,SAAO,EAAE,OAAO;AAClB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"depositReceiverApproval.d.ts","sourceRoot":"","sources":["../../../src/evm/depositReceiverApproval.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAkB;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,gCAAuB;AAQjD,MAAM,WAAW,gCAAgC;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,gCAAgC,GACvC,OAAO,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"depositReceiverApproval.d.ts","sourceRoot":"","sources":["../../../src/evm/depositReceiverApproval.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAkB;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,gCAAuB;AAQjD,MAAM,WAAW,gCAAgC;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,gCAAgC,GACvC,OAAO,CAAC,UAAU,CAAC,CA6BrB"}
|
|
@@ -38,6 +38,7 @@ var provisionerV2 = __toESM(require("./aeraContracts/v2"), 1);
|
|
|
38
38
|
var import_types = require("./types");
|
|
39
39
|
var import_vaults = require("./vaults");
|
|
40
40
|
async function getDepositReceiverApprovalTx(client, params) {
|
|
41
|
+
params = { ...params };
|
|
41
42
|
const resolved = await (0, import_vaults.resolveVault)(client, params.vaultId, params.chainId);
|
|
42
43
|
if (!resolved) throw new import_errors.VaultNotFoundError(params.vaultId);
|
|
43
44
|
const chainId = params.chainId ?? resolved.vault.chainId;
|
|
@@ -49,15 +50,19 @@ async function getDepositReceiverApprovalTx(client, params) {
|
|
|
49
50
|
if (runtime.provisioner.version !== import_types.ContractVersion.V2) {
|
|
50
51
|
throw new import_errors.UnsupportedFeatureError("Aera: deposit receiver approval on V1");
|
|
51
52
|
}
|
|
52
|
-
return (0, import_attribution.encodeTransactionWithAttribution)(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
53
|
+
return (0, import_attribution.encodeTransactionWithAttribution)(
|
|
54
|
+
client,
|
|
55
|
+
{
|
|
56
|
+
type: "setDepositReceiverApproval",
|
|
57
|
+
...provisionerV2.setDepositReceiverApprovalTxRequest(
|
|
58
|
+
runtime.provisioner.address,
|
|
59
|
+
params.depositor,
|
|
60
|
+
params.approved ?? true,
|
|
61
|
+
receiver
|
|
62
|
+
)
|
|
63
|
+
},
|
|
64
|
+
chainId
|
|
65
|
+
);
|
|
61
66
|
}
|
|
62
67
|
// Annotate the CommonJS export names for ESM import in node:
|
|
63
68
|
0 && (module.exports = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/evm/depositReceiverApproval.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Address } from 'viem';\nimport type { GauntletClient } from '../client';\nimport type { PreparedTx } from '../attribution';\nimport { encodeTransactionWithAttribution } from '../attribution';\nimport { AccountRequiredError, UnsupportedFeatureError, VaultNotFoundError } from '../errors';\nimport { resolveAeraRuntimeContracts } from './aeraContracts';\nimport * as provisionerV2 from './aeraContracts/v2';\nimport { ContractVersion } from './types';\nimport { resolveVault } from './vaults';\n\nexport interface EvmDepositReceiverApprovalParams {\n vaultId: string;\n depositor: Address;\n approved?: boolean;\n chainId?: number;\n}\n\n/**\n * Builds the V2 receiver-side approval transaction required before a depositor\n * can make sync deposits to a separate receiver.\n *\n * The wallet account on the client is the receiver and must sign this transaction.\n */\nexport async function getDepositReceiverApprovalTx(\n client: GauntletClient,\n params: EvmDepositReceiverApprovalParams\n): Promise<PreparedTx> {\n const resolved = await resolveVault(client, params.vaultId, params.chainId);\n if (!resolved) throw new VaultNotFoundError(params.vaultId);\n\n const chainId = params.chainId ?? resolved.vault.chainId;\n const receiver = client.wallet?.account?.address;\n if (!receiver) throw new AccountRequiredError();\n\n const { vault } = resolved;\n const publicClient = client.getPublicClient(chainId);\n const runtime = await resolveAeraRuntimeContracts(publicClient, vault);\n if (runtime.provisioner.version !== ContractVersion.V2) {\n throw new UnsupportedFeatureError('Aera: deposit receiver approval on V1');\n }\n\n return encodeTransactionWithAttribution(client
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,yBAAiD;AACjD,oBAAkF;AAClF,2BAA4C;AAC5C,oBAA+B;AAC/B,mBAAgC;AAChC,oBAA6B;AAe7B,eAAsB,6BACpB,QACA,QACqB;AACrB,QAAM,WAAW,UAAM,4BAAa,QAAQ,OAAO,SAAS,OAAO,OAAO;AAC1E,MAAI,CAAC,SAAU,OAAM,IAAI,iCAAmB,OAAO,OAAO;AAE1D,QAAM,UAAU,OAAO,WAAW,SAAS,MAAM;AACjD,QAAM,WAAW,OAAO,QAAQ,SAAS;AACzC,MAAI,CAAC,SAAU,OAAM,IAAI,mCAAqB;AAE9C,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,eAAe,OAAO,gBAAgB,OAAO;AACnD,QAAM,UAAU,UAAM,kDAA4B,cAAc,KAAK;AACrE,MAAI,QAAQ,YAAY,YAAY,6BAAgB,IAAI;AACtD,UAAM,IAAI,sCAAwB,uCAAuC;AAAA,EAC3E;AAEA,aAAO,
|
|
4
|
+
"sourcesContent": ["import type { Address } from 'viem';\nimport type { GauntletClient } from '../client';\nimport type { PreparedTx } from '../attribution';\nimport { encodeTransactionWithAttribution } from '../attribution';\nimport { AccountRequiredError, UnsupportedFeatureError, VaultNotFoundError } from '../errors';\nimport { resolveAeraRuntimeContracts } from './aeraContracts';\nimport * as provisionerV2 from './aeraContracts/v2';\nimport { ContractVersion } from './types';\nimport { resolveVault } from './vaults';\n\nexport interface EvmDepositReceiverApprovalParams {\n vaultId: string;\n depositor: Address;\n approved?: boolean;\n chainId?: number;\n}\n\n/**\n * Builds the V2 receiver-side approval transaction required before a depositor\n * can make sync deposits to a separate receiver.\n *\n * The wallet account on the client is the receiver and must sign this transaction.\n */\nexport async function getDepositReceiverApprovalTx(\n client: GauntletClient,\n params: EvmDepositReceiverApprovalParams\n): Promise<PreparedTx> {\n params = { ...params };\n const resolved = await resolveVault(client, params.vaultId, params.chainId);\n if (!resolved) throw new VaultNotFoundError(params.vaultId);\n\n const chainId = params.chainId ?? resolved.vault.chainId;\n const receiver = client.wallet?.account?.address;\n if (!receiver) throw new AccountRequiredError();\n\n const { vault } = resolved;\n const publicClient = client.getPublicClient(chainId);\n const runtime = await resolveAeraRuntimeContracts(publicClient, vault);\n if (runtime.provisioner.version !== ContractVersion.V2) {\n throw new UnsupportedFeatureError('Aera: deposit receiver approval on V1');\n }\n\n return encodeTransactionWithAttribution(\n client,\n {\n type: 'setDepositReceiverApproval',\n ...provisionerV2.setDepositReceiverApprovalTxRequest(\n runtime.provisioner.address,\n params.depositor,\n params.approved ?? true,\n receiver\n ),\n },\n chainId\n );\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,yBAAiD;AACjD,oBAAkF;AAClF,2BAA4C;AAC5C,oBAA+B;AAC/B,mBAAgC;AAChC,oBAA6B;AAe7B,eAAsB,6BACpB,QACA,QACqB;AACrB,WAAS,EAAE,GAAG,OAAO;AACrB,QAAM,WAAW,UAAM,4BAAa,QAAQ,OAAO,SAAS,OAAO,OAAO;AAC1E,MAAI,CAAC,SAAU,OAAM,IAAI,iCAAmB,OAAO,OAAO;AAE1D,QAAM,UAAU,OAAO,WAAW,SAAS,MAAM;AACjD,QAAM,WAAW,OAAO,QAAQ,SAAS;AACzC,MAAI,CAAC,SAAU,OAAM,IAAI,mCAAqB;AAE9C,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,eAAe,OAAO,gBAAgB,OAAO;AACnD,QAAM,UAAU,UAAM,kDAA4B,cAAc,KAAK;AACrE,MAAI,QAAQ,YAAY,YAAY,6BAAgB,IAAI;AACtD,UAAM,IAAI,sCAAwB,uCAAuC;AAAA,EAC3E;AAEA,aAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,GAAG,cAAc;AAAA,QACf,QAAQ,YAAY;AAAA,QACpB,OAAO;AAAA,QACP,OAAO,YAAY;AAAA,QACnB;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -4,8 +4,19 @@ export interface UserCurrentBalanceParams {
|
|
|
4
4
|
vaultId: string;
|
|
5
5
|
address: Address;
|
|
6
6
|
chainId?: number;
|
|
7
|
+
/** Required for deployments that support multiple assets, ignored otherwise. */
|
|
8
|
+
assetSymbol?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Scan from this block, including expired requests that still hold escrow.
|
|
11
|
+
* Requires `chainId` for a vault with more than one deployment.
|
|
12
|
+
*/
|
|
13
|
+
fromBlock?: bigint;
|
|
7
14
|
}
|
|
8
15
|
export interface UserCurrentBalance {
|
|
16
|
+
/** Block used for balances, conversions, and request state. */
|
|
17
|
+
blockNumber: bigint;
|
|
18
|
+
/** First block included in the request scan. Older escrow is outside this result. */
|
|
19
|
+
fromBlock: bigint;
|
|
9
20
|
/** Chain identifier, e.g. "base" */
|
|
10
21
|
chain: string;
|
|
11
22
|
/** EVM chain id of the deployment, e.g. 8453 */
|
|
@@ -30,7 +41,9 @@ export interface UserCurrentBalance {
|
|
|
30
41
|
* - `pendingWithdraw` — vault units locked in a pending async redeem request (converted to tokens).
|
|
31
42
|
*
|
|
32
43
|
* Only supported for Aera multi-depositor vaults. Pending amounts are detected by scanning
|
|
33
|
-
* the
|
|
44
|
+
* the configured request lifetime, with a minimum of three days. Set `fromBlock` (with `chainId`
|
|
45
|
+
* on a multi-chain vault) for older escrow.
|
|
46
|
+
* All state reads use one block. The returned range identifies the scanned history.
|
|
34
47
|
*
|
|
35
48
|
* @param client - A configured `GauntletClient` instance with an EVM public client for each
|
|
36
49
|
* chain the vault is deployed on.
|
|
@@ -41,6 +54,7 @@ export interface UserCurrentBalance {
|
|
|
41
54
|
* @throws {VaultNotFoundError} If the vault ID is not found in the manifest.
|
|
42
55
|
* @throws {UnsupportedProtocolError} If the vault is not an Aera multi-depositor vault.
|
|
43
56
|
* @throws {ChainMismatchError} If `chainId` is specified but no deployment exists for that chain.
|
|
57
|
+
* @throws {UnsupportedAssetError} If a multi-asset deployment gets no matching `assetSymbol`.
|
|
44
58
|
*
|
|
45
59
|
* @example
|
|
46
60
|
* ```ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userCurrentBalance.d.ts","sourceRoot":"","sources":["../../../src/evm/userCurrentBalance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,OAAO,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAkB;
|
|
1
|
+
{"version":3,"file":"userCurrentBalance.d.ts","sourceRoot":"","sources":["../../../src/evm/userCurrentBalance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,OAAO,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAkB;AAmEhD,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,+DAA+D;IAC/D,WAAW,EAAE,MAAM,CAAC;IACpB,qFAAqF;IACrF,SAAS,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,cAAc,EAAE,MAAM,CAAC;IACvB,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,eAAe,EAAE,MAAM,CAAC;IACxB,oEAAoE;IACpE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AA2ND;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC,kBAAkB,EAAE,CAAC,CA6B/B"}
|
|
@@ -29,6 +29,7 @@ var import_v2 = require("./aeraContracts/v2");
|
|
|
29
29
|
var import_provisionerV2 = require("./abis/provisionerV2");
|
|
30
30
|
var import_types = require("./types");
|
|
31
31
|
var import_constants = require("../constants");
|
|
32
|
+
const LOG_CHUNK_CONCURRENCY = 16;
|
|
32
33
|
const DEPOSIT_REQUESTED_V1_ABI = [
|
|
33
34
|
{
|
|
34
35
|
type: "event",
|
|
@@ -76,71 +77,105 @@ function dedupeByRequestHash(logs, hashKey) {
|
|
|
76
77
|
return true;
|
|
77
78
|
});
|
|
78
79
|
}
|
|
79
|
-
async function
|
|
80
|
+
async function requestScanStart(publicClient, chainId, blockNumber, days, cutoff) {
|
|
81
|
+
let span = (import_constants.BLOCKS_3_DAYS[chainId] ?? import_constants.DEFAULT_BLOCKS_3_DAYS) * BigInt(days) / 3n;
|
|
82
|
+
for (; ; ) {
|
|
83
|
+
if (span >= blockNumber) return 0n;
|
|
84
|
+
const start = blockNumber - span;
|
|
85
|
+
const block = await publicClient.getBlock({ blockNumber: start });
|
|
86
|
+
if (block.timestamp <= cutoff) return start;
|
|
87
|
+
span *= 2n;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async function mapInBatches(items, size, fn) {
|
|
91
|
+
const results = [];
|
|
92
|
+
for (let i = 0; i < items.length; i += size) {
|
|
93
|
+
results.push(...await Promise.all(items.slice(i, i + size).map(fn)));
|
|
94
|
+
}
|
|
95
|
+
return results;
|
|
96
|
+
}
|
|
97
|
+
async function queryDeploymentBalance(client, deployment, params) {
|
|
80
98
|
const publicClient = client.getPublicClient(deployment.chainId);
|
|
81
|
-
const
|
|
99
|
+
const { address } = params;
|
|
100
|
+
const token = deployment.supplyToken.length > 1 ? deployment.supplyToken.find((candidate) => candidate.symbol === params.assetSymbol) : deployment.supplyToken[0];
|
|
101
|
+
if (token === void 0)
|
|
102
|
+
throw new import_errors.UnsupportedAssetError(params.assetSymbol ?? "unknown", params.vaultId);
|
|
103
|
+
const snapshot = await publicClient.getBlock({ blockTag: "latest" });
|
|
104
|
+
if (snapshot.number === null) {
|
|
105
|
+
throw new import_errors.GauntletSDKError("The balance snapshot has no block number");
|
|
106
|
+
}
|
|
107
|
+
const blockNumber = snapshot.number;
|
|
108
|
+
const readOptions = { blockNumber };
|
|
109
|
+
const expirationDays = deployment.expirationDays ?? 3;
|
|
110
|
+
if (!Number.isSafeInteger(expirationDays) || expirationDays <= 0) {
|
|
111
|
+
throw new import_errors.GauntletSDKError("The request expiration must be a positive integer number of days");
|
|
112
|
+
}
|
|
113
|
+
const scanDays = Math.max(3, expirationDays);
|
|
114
|
+
const cutoff = snapshot.timestamp - BigInt(import_constants.DAY) * BigInt(scanDays);
|
|
115
|
+
const fromBlock = params.fromBlock ?? await requestScanStart(publicClient, deployment.chainId, blockNumber, scanDays, cutoff);
|
|
116
|
+
if (fromBlock < 0n || fromBlock > blockNumber) {
|
|
117
|
+
throw new import_errors.GauntletSDKError("The request scan range is invalid");
|
|
118
|
+
}
|
|
82
119
|
const vaultContract = (0, import_aeraContracts.getMultiDepositorVault)(publicClient, deployment.vaultAddress);
|
|
83
120
|
const [runtime, units] = await Promise.all([
|
|
84
|
-
(0, import_aeraContracts.resolveAeraRuntimeContracts)(publicClient, deployment),
|
|
85
|
-
vaultContract.read.balanceOf([address])
|
|
121
|
+
(0, import_aeraContracts.resolveAeraRuntimeContracts)(publicClient, deployment, readOptions),
|
|
122
|
+
vaultContract.read.balanceOf([address], readOptions)
|
|
86
123
|
]);
|
|
87
124
|
const provisionerAddress = runtime.provisioner.address;
|
|
88
125
|
const isV2 = runtime.provisioner.version === import_types.ContractVersion.V2;
|
|
89
|
-
const unitsLockedUntilPromise = isV2 ? (0, import_v2.getUserUnitsRefundableUntil)(publicClient, provisionerAddress, address) : Promise.resolve(void 0);
|
|
126
|
+
const unitsLockedUntilPromise = isV2 ? (0, import_v2.getUserUnitsRefundableUntil)(publicClient, provisionerAddress, address, readOptions) : Promise.resolve(void 0);
|
|
90
127
|
const balance = await (0, import_priceAndFeeCalculator.convertUnitsToToken)(
|
|
91
128
|
publicClient,
|
|
92
129
|
runtime.feeCalculator.address,
|
|
93
130
|
runtime.feeCalculator.version,
|
|
94
131
|
deployment.vaultAddress,
|
|
95
132
|
token.address,
|
|
96
|
-
units
|
|
133
|
+
units,
|
|
134
|
+
readOptions
|
|
97
135
|
);
|
|
98
|
-
const currentBlock = await publicClient.getBlockNumber();
|
|
99
|
-
const lookback = import_constants.BLOCKS_3_DAYS[deployment.chainId] ?? import_constants.DEFAULT_BLOCKS_3_DAYS;
|
|
100
|
-
const fromBlock = currentBlock > lookback ? currentBlock - lookback : 0n;
|
|
101
136
|
const chunks = [];
|
|
102
|
-
for (let cursor = fromBlock; cursor <=
|
|
103
|
-
const end = cursor + import_constants.LOG_PAGE_SIZE <=
|
|
137
|
+
for (let cursor = fromBlock; cursor <= blockNumber; cursor += import_constants.LOG_PAGE_SIZE + 1n) {
|
|
138
|
+
const end = cursor + import_constants.LOG_PAGE_SIZE <= blockNumber ? cursor + import_constants.LOG_PAGE_SIZE : blockNumber;
|
|
104
139
|
chunks.push([cursor, end]);
|
|
105
140
|
}
|
|
106
141
|
const [depositPages, redeemPages] = await Promise.all([
|
|
107
|
-
|
|
108
|
-
chunks
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
)
|
|
142
|
+
mapInBatches(
|
|
143
|
+
chunks,
|
|
144
|
+
LOG_CHUNK_CONCURRENCY,
|
|
145
|
+
([from, to]) => isV2 ? publicClient.getContractEvents({
|
|
146
|
+
address: provisionerAddress,
|
|
147
|
+
abi: import_provisionerV2.provisionerV2Abi,
|
|
148
|
+
eventName: "DepositRequested",
|
|
149
|
+
args: { receiver: address, token: token.address },
|
|
150
|
+
fromBlock: from,
|
|
151
|
+
toBlock: to
|
|
152
|
+
}) : publicClient.getContractEvents({
|
|
153
|
+
address: provisionerAddress,
|
|
154
|
+
abi: DEPOSIT_REQUESTED_V1_ABI,
|
|
155
|
+
eventName: "DepositRequested",
|
|
156
|
+
args: { user: address, token: token.address },
|
|
157
|
+
fromBlock: from,
|
|
158
|
+
toBlock: to
|
|
159
|
+
})
|
|
125
160
|
),
|
|
126
|
-
|
|
127
|
-
chunks
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
)
|
|
161
|
+
mapInBatches(
|
|
162
|
+
chunks,
|
|
163
|
+
LOG_CHUNK_CONCURRENCY,
|
|
164
|
+
([from, to]) => isV2 ? publicClient.getContractEvents({
|
|
165
|
+
address: provisionerAddress,
|
|
166
|
+
abi: import_provisionerV2.provisionerV2Abi,
|
|
167
|
+
eventName: "RedeemRequested",
|
|
168
|
+
args: { user: address, token: token.address },
|
|
169
|
+
fromBlock: from,
|
|
170
|
+
toBlock: to
|
|
171
|
+
}) : publicClient.getContractEvents({
|
|
172
|
+
address: provisionerAddress,
|
|
173
|
+
abi: REDEEM_REQUESTED_V1_ABI,
|
|
174
|
+
eventName: "RedeemRequested",
|
|
175
|
+
args: { user: address, token: token.address },
|
|
176
|
+
fromBlock: from,
|
|
177
|
+
toBlock: to
|
|
178
|
+
})
|
|
144
179
|
)
|
|
145
180
|
]);
|
|
146
181
|
const depositLogs = dedupeByRequestHash(depositPages.flat(), "depositRequestHash");
|
|
@@ -160,7 +195,8 @@ async function queryDeploymentBalance(client, deployment, address) {
|
|
|
160
195
|
args: [log.args.redeemRequestHash]
|
|
161
196
|
}))
|
|
162
197
|
],
|
|
163
|
-
allowFailure: false
|
|
198
|
+
allowFailure: false,
|
|
199
|
+
blockNumber
|
|
164
200
|
});
|
|
165
201
|
const depositChecks = pendingChecks.slice(0, depositLogs.length);
|
|
166
202
|
const redeemChecks = pendingChecks.slice(depositLogs.length);
|
|
@@ -182,10 +218,13 @@ async function queryDeploymentBalance(client, deployment, address) {
|
|
|
182
218
|
runtime.feeCalculator.version,
|
|
183
219
|
deployment.vaultAddress,
|
|
184
220
|
token.address,
|
|
185
|
-
pendingWithdrawUnits
|
|
221
|
+
pendingWithdrawUnits,
|
|
222
|
+
readOptions
|
|
186
223
|
) : 0n;
|
|
187
224
|
const unitsLockedUntil = await unitsLockedUntilPromise;
|
|
188
225
|
return {
|
|
226
|
+
blockNumber,
|
|
227
|
+
fromBlock,
|
|
189
228
|
chain: import_constants.CHAIN_NAMES[deployment.chainId] ?? `chain-${deployment.chainId}`,
|
|
190
229
|
chainId: deployment.chainId,
|
|
191
230
|
token: token.address,
|
|
@@ -197,6 +236,7 @@ async function queryDeploymentBalance(client, deployment, address) {
|
|
|
197
236
|
};
|
|
198
237
|
}
|
|
199
238
|
async function getUserCurrentBalance(client, params) {
|
|
239
|
+
params = { ...params };
|
|
200
240
|
const manifest = await client.manifest;
|
|
201
241
|
const vaultInfo = manifest.vaults.find((v) => v.vaultId === params.vaultId);
|
|
202
242
|
if (!vaultInfo) throw new import_errors.VaultNotFoundError(params.vaultId);
|
|
@@ -214,9 +254,12 @@ async function getUserCurrentBalance(client, params) {
|
|
|
214
254
|
evmDeployments.map((d) => `${d.chainId}`).join(", ")
|
|
215
255
|
);
|
|
216
256
|
}
|
|
217
|
-
return [await queryDeploymentBalance(client, deployment, params
|
|
257
|
+
return [await queryDeploymentBalance(client, deployment, params)];
|
|
258
|
+
}
|
|
259
|
+
if (params.fromBlock !== void 0 && evmDeployments.length > 1) {
|
|
260
|
+
throw new import_errors.GauntletSDKError("fromBlock requires chainId for a vault with several deployments");
|
|
218
261
|
}
|
|
219
|
-
return Promise.all(evmDeployments.map((d) => queryDeploymentBalance(client, d, params
|
|
262
|
+
return Promise.all(evmDeployments.map((d) => queryDeploymentBalance(client, d, params)));
|
|
220
263
|
}
|
|
221
264
|
// Annotate the CommonJS export names for ESM import in node:
|
|
222
265
|
0 && (module.exports = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/evm/userCurrentBalance.ts"],
|
|
4
|
-
"sourcesContent": ["import { parseAbi, type Address } from 'viem';\nimport type { GauntletClient } from '../client';\nimport type { EvmVaultDeployment } from './types';\nimport { ChainMismatchError, UnsupportedProtocolError, VaultNotFoundError } from '../errors';\nimport { getMultiDepositorVault, resolveAeraRuntimeContracts } from './aeraContracts';\nimport { convertUnitsToToken } from './aeraContracts/priceAndFeeCalculator';\nimport { getUserUnitsRefundableUntil } from './aeraContracts/v2';\nimport { provisionerV2Abi } from './abis/provisionerV2';\nimport { ContractVersion } from './types';\nimport { BLOCKS_3_DAYS, CHAIN_NAMES, DEFAULT_BLOCKS_3_DAYS, LOG_PAGE_SIZE } from '../constants';\n\n// Inline as-const ABI items give viem full type inference for args and return types.\nconst DEPOSIT_REQUESTED_V1_ABI = [\n {\n type: 'event',\n name: 'DepositRequested',\n inputs: [\n { type: 'address', name: 'user', indexed: true },\n { type: 'address', name: 'token', indexed: true },\n { type: 'uint256', name: 'tokensIn', indexed: false },\n { type: 'uint256', name: 'minUnitsOut', indexed: false },\n { type: 'uint256', name: 'solverTip', indexed: false },\n { type: 'uint256', name: 'deadline', indexed: false },\n { type: 'uint256', name: 'maxPriceAge', indexed: false },\n { type: 'bool', name: 'isFixedPrice', indexed: false },\n { type: 'bytes32', name: 'depositRequestHash', indexed: false },\n ],\n },\n] as const;\n\nconst REDEEM_REQUESTED_V1_ABI = [\n {\n type: 'event',\n name: 'RedeemRequested',\n inputs: [\n { type: 'address', name: 'user', indexed: true },\n { type: 'address', name: 'token', indexed: true },\n { type: 'uint256', name: 'minTokensOut', indexed: false },\n { type: 'uint256', name: 'unitsIn', indexed: false },\n { type: 'uint256', name: 'solverTip', indexed: false },\n { type: 'uint256', name: 'deadline', indexed: false },\n { type: 'uint256', name: 'maxPriceAge', indexed: false },\n { type: 'bool', name: 'isFixedPrice', indexed: false },\n { type: 'bytes32', name: 'redeemRequestHash', indexed: false },\n ],\n },\n] as const;\n\nconst provisionerV1StateAbi = parseAbi([\n 'function asyncDepositHashes(bytes32 asyncDepositHash) view returns (bool exists)',\n 'function asyncRedeemHashes(bytes32 asyncRedeemHash) view returns (bool exists)',\n]);\n\nexport interface UserCurrentBalanceParams {\n vaultId: string;\n address: Address;\n chainId?: number;\n}\n\nexport interface UserCurrentBalance {\n /** Chain identifier, e.g. \"base\" */\n chain: string;\n /** EVM chain id of the deployment, e.g. 8453 */\n chainId: number;\n token: Address;\n decimals: number;\n /** Assets queued via async deposit, not yet earning */\n pendingDeposit: bigint;\n /** Assets actively earning in the vault */\n balance: bigint;\n /** Assets queued via async withdraw, not yet claimable */\n pendingWithdraw: bigint;\n /** Timestamp until which this account cannot redeem vault units. */\n unitsLockedUntil?: bigint;\n}\n\n// V2 legacy wrapper calls can emit both receiver-aware and legacy events for one request.\n// Keep one row per request hash before state checks and summing pending amounts.\nfunction dedupeByRequestHash<TLog extends { args: { [key: string]: unknown } }>(\n logs: TLog[],\n hashKey: 'depositRequestHash' | 'redeemRequestHash'\n): TLog[] {\n const seen = new Set<unknown>();\n\n return logs.filter((log) => {\n const hash = log.args[hashKey];\n // Drop malformed events and duplicates so one pending request cannot be counted twice.\n if (hash == null || seen.has(hash)) return false;\n seen.add(hash);\n return true;\n });\n}\n\nasync function queryDeploymentBalance(\n client: GauntletClient,\n deployment: EvmVaultDeployment,\n address: Address\n): Promise<UserCurrentBalance> {\n const publicClient = client.getPublicClient(deployment.chainId);\n const token = deployment.supplyToken[0];\n\n const vaultContract = getMultiDepositorVault(publicClient, deployment.vaultAddress);\n const [runtime, units] = await Promise.all([\n resolveAeraRuntimeContracts(publicClient, deployment),\n vaultContract.read.balanceOf([address]),\n ]);\n const provisionerAddress = runtime.provisioner.address;\n const isV2 = runtime.provisioner.version === ContractVersion.V2;\n const unitsLockedUntilPromise = isV2\n ? getUserUnitsRefundableUntil(publicClient, provisionerAddress, address)\n : Promise.resolve(undefined);\n\n const balance = await convertUnitsToToken(\n publicClient,\n runtime.feeCalculator.address,\n runtime.feeCalculator.version,\n deployment.vaultAddress,\n token.address,\n units\n );\n\n // Look back ~3 days for pending async requests\n const currentBlock = await publicClient.getBlockNumber();\n const lookback = BLOCKS_3_DAYS[deployment.chainId] ?? DEFAULT_BLOCKS_3_DAYS;\n const fromBlock = currentBlock > lookback ? currentBlock - lookback : 0n;\n\n // Compute block-range chunks to stay within the 10,000-block RPC limit, then fetch in parallel\n const chunks: [bigint, bigint][] = [];\n for (let cursor = fromBlock; cursor <= currentBlock; cursor += LOG_PAGE_SIZE + 1n) {\n const end = cursor + LOG_PAGE_SIZE <= currentBlock ? cursor + LOG_PAGE_SIZE : currentBlock;\n chunks.push([cursor, end]);\n }\n\n const [depositPages, redeemPages] = await Promise.all([\n Promise.all(\n chunks.map(([from, to]) =>\n isV2\n ? publicClient.getContractEvents({\n address: provisionerAddress,\n abi: provisionerV2Abi,\n eventName: 'DepositRequested',\n args: { receiver: address },\n fromBlock: from,\n toBlock: to,\n })\n : publicClient.getContractEvents({\n address: provisionerAddress,\n abi: DEPOSIT_REQUESTED_V1_ABI,\n eventName: 'DepositRequested',\n args: { user: address },\n fromBlock: from,\n toBlock: to,\n })\n )\n ),\n Promise.all(\n chunks.map(([from, to]) =>\n isV2\n ? publicClient.getContractEvents({\n address: provisionerAddress,\n abi: provisionerV2Abi,\n eventName: 'RedeemRequested',\n args: { user: address },\n fromBlock: from,\n toBlock: to,\n })\n : publicClient.getContractEvents({\n address: provisionerAddress,\n abi: REDEEM_REQUESTED_V1_ABI,\n eventName: 'RedeemRequested',\n args: { user: address },\n fromBlock: from,\n toBlock: to,\n })\n )\n ),\n ]);\n\n const depositLogs = dedupeByRequestHash(depositPages.flat(), 'depositRequestHash');\n const redeemLogs = dedupeByRequestHash(redeemPages.flat(), 'redeemRequestHash');\n\n // Check which requests are still pending on-chain via a single multicall\n const pendingChecks = await publicClient.multicall({\n contracts: [\n ...depositLogs.map((log) => ({\n address: provisionerAddress,\n abi: isV2 ? provisionerV2Abi : provisionerV1StateAbi,\n functionName: isV2 ? ('asyncRequestHashes' as const) : ('asyncDepositHashes' as const),\n args: [log.args.depositRequestHash!] as const,\n })),\n ...redeemLogs.map((log) => ({\n address: provisionerAddress,\n abi: isV2 ? provisionerV2Abi : provisionerV1StateAbi,\n functionName: isV2 ? ('asyncRequestHashes' as const) : ('asyncRedeemHashes' as const),\n args: [log.args.redeemRequestHash!] as const,\n })),\n ],\n allowFailure: false,\n });\n\n const depositChecks = pendingChecks.slice(0, depositLogs.length);\n const redeemChecks = pendingChecks.slice(depositLogs.length);\n\n let pendingDeposit = 0n;\n for (let i = 0; i < depositLogs.length; i++) {\n if (depositChecks[i]) {\n pendingDeposit += depositLogs[i].args.tokensIn ?? 0n;\n }\n }\n\n let pendingWithdrawUnits = 0n;\n for (let i = 0; i < redeemLogs.length; i++) {\n if (redeemChecks[i]) {\n pendingWithdrawUnits += redeemLogs[i].args.unitsIn ?? 0n;\n }\n }\n\n const pendingWithdraw =\n pendingWithdrawUnits > 0n\n ? await convertUnitsToToken(\n publicClient,\n runtime.feeCalculator.address,\n runtime.feeCalculator.version,\n deployment.vaultAddress,\n token.address,\n pendingWithdrawUnits\n )\n : 0n;\n const unitsLockedUntil = await unitsLockedUntilPromise;\n\n return {\n chain: CHAIN_NAMES[deployment.chainId] ?? `chain-${deployment.chainId}`,\n chainId: deployment.chainId,\n token: token.address,\n decimals: token.decimals,\n pendingDeposit,\n balance,\n pendingWithdraw,\n ...(unitsLockedUntil !== undefined ? { unitsLockedUntil } : {}),\n };\n}\n\n/**\n * Returns the current balance breakdown for a user across all EVM deployments of a vault.\n *\n * Queries the vault's on-chain state to split the user's position into three buckets:\n * - `balance` \u2014 assets actively earning inside the vault (converted from vault units to tokens).\n * - `pendingDeposit` \u2014 tokens submitted via async deposit but not yet processed by a solver.\n * - `pendingWithdraw` \u2014 vault units locked in a pending async redeem request (converted to tokens).\n *\n * Only supported for Aera multi-depositor vaults. Pending amounts are detected by scanning\n * the last ~3 days of provisioner events and cross-checking hash existence on-chain.\n *\n * @param client - A configured `GauntletClient` instance with an EVM public client for each\n * chain the vault is deployed on.\n * @param params - Query parameters including `vaultId`, the user `address`, and an optional\n * `chainId` to limit the query to a single deployment.\n * @returns One `UserCurrentBalance` entry per chain queried.\n *\n * @throws {VaultNotFoundError} If the vault ID is not found in the manifest.\n * @throws {UnsupportedProtocolError} If the vault is not an Aera multi-depositor vault.\n * @throws {ChainMismatchError} If `chainId` is specified but no deployment exists for that chain.\n *\n * @example\n * ```ts\n * const balances = await getUserCurrentBalance(client, {\n * vaultId: 'baseUsdcPrime',\n * address: '0xYourWalletAddress',\n * });\n * // [{ chain: 'base', chainId: 8453, token: '0x...', decimals: 6, balance: 100_000_000n, pendingDeposit: 0n, pendingWithdraw: 0n }]\n * ```\n */\nexport async function getUserCurrentBalance(\n client: GauntletClient,\n params: UserCurrentBalanceParams\n): Promise<UserCurrentBalance[]> {\n const manifest = await client.manifest;\n const vaultInfo = manifest.vaults.find((v) => v.vaultId === params.vaultId);\n if (!vaultInfo) throw new VaultNotFoundError(params.vaultId);\n\n const evmDeployments = vaultInfo.deployments.filter(\n (d): d is EvmVaultDeployment => d.chain === 'evm' && d.vaultType === 'multi-depositor'\n );\n\n if (vaultInfo.protocol !== 'aera' || evmDeployments.length === 0) {\n throw new UnsupportedProtocolError(vaultInfo.protocol);\n }\n\n if (params.chainId !== undefined) {\n const deployment = evmDeployments.find((d) => d.chainId === params.chainId);\n if (!deployment) {\n throw new ChainMismatchError(\n `${params.chainId}`,\n evmDeployments.map((d) => `${d.chainId}`).join(', ')\n );\n }\n return [await queryDeploymentBalance(client, deployment, params.address)];\n }\n\n return Promise.all(evmDeployments.map((d) => queryDeploymentBalance(client, d, params.address)));\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAuC;AAGvC,
|
|
4
|
+
"sourcesContent": ["import { parseAbi, type Address } from 'viem';\nimport type { GauntletClient } from '../client';\nimport type { EvmVaultDeployment } from './types';\nimport {\n ChainMismatchError,\n GauntletSDKError,\n UnsupportedAssetError,\n UnsupportedProtocolError,\n VaultNotFoundError,\n} from '../errors';\nimport { getMultiDepositorVault, resolveAeraRuntimeContracts } from './aeraContracts';\nimport { convertUnitsToToken } from './aeraContracts/priceAndFeeCalculator';\nimport { getUserUnitsRefundableUntil } from './aeraContracts/v2';\nimport { provisionerV2Abi } from './abis/provisionerV2';\nimport { ContractVersion } from './types';\nimport {\n BLOCKS_3_DAYS,\n CHAIN_NAMES,\n DAY,\n DEFAULT_BLOCKS_3_DAYS,\n LOG_PAGE_SIZE,\n} from '../constants';\n\n// Log chunks fetched at once per event type.\nconst LOG_CHUNK_CONCURRENCY = 16;\n\n// Inline as-const ABI items give viem full type inference for args and return types.\nconst DEPOSIT_REQUESTED_V1_ABI = [\n {\n type: 'event',\n name: 'DepositRequested',\n inputs: [\n { type: 'address', name: 'user', indexed: true },\n { type: 'address', name: 'token', indexed: true },\n { type: 'uint256', name: 'tokensIn', indexed: false },\n { type: 'uint256', name: 'minUnitsOut', indexed: false },\n { type: 'uint256', name: 'solverTip', indexed: false },\n { type: 'uint256', name: 'deadline', indexed: false },\n { type: 'uint256', name: 'maxPriceAge', indexed: false },\n { type: 'bool', name: 'isFixedPrice', indexed: false },\n { type: 'bytes32', name: 'depositRequestHash', indexed: false },\n ],\n },\n] as const;\n\nconst REDEEM_REQUESTED_V1_ABI = [\n {\n type: 'event',\n name: 'RedeemRequested',\n inputs: [\n { type: 'address', name: 'user', indexed: true },\n { type: 'address', name: 'token', indexed: true },\n { type: 'uint256', name: 'minTokensOut', indexed: false },\n { type: 'uint256', name: 'unitsIn', indexed: false },\n { type: 'uint256', name: 'solverTip', indexed: false },\n { type: 'uint256', name: 'deadline', indexed: false },\n { type: 'uint256', name: 'maxPriceAge', indexed: false },\n { type: 'bool', name: 'isFixedPrice', indexed: false },\n { type: 'bytes32', name: 'redeemRequestHash', indexed: false },\n ],\n },\n] as const;\n\nconst provisionerV1StateAbi = parseAbi([\n 'function asyncDepositHashes(bytes32 asyncDepositHash) view returns (bool exists)',\n 'function asyncRedeemHashes(bytes32 asyncRedeemHash) view returns (bool exists)',\n]);\n\nexport interface UserCurrentBalanceParams {\n vaultId: string;\n address: Address;\n chainId?: number;\n /** Required for deployments that support multiple assets, ignored otherwise. */\n assetSymbol?: string;\n /**\n * Scan from this block, including expired requests that still hold escrow.\n * Requires `chainId` for a vault with more than one deployment.\n */\n fromBlock?: bigint;\n}\n\nexport interface UserCurrentBalance {\n /** Block used for balances, conversions, and request state. */\n blockNumber: bigint;\n /** First block included in the request scan. Older escrow is outside this result. */\n fromBlock: bigint;\n /** Chain identifier, e.g. \"base\" */\n chain: string;\n /** EVM chain id of the deployment, e.g. 8453 */\n chainId: number;\n token: Address;\n decimals: number;\n /** Assets queued via async deposit, not yet earning */\n pendingDeposit: bigint;\n /** Assets actively earning in the vault */\n balance: bigint;\n /** Assets queued via async withdraw, not yet claimable */\n pendingWithdraw: bigint;\n /** Timestamp until which this account cannot redeem vault units. */\n unitsLockedUntil?: bigint;\n}\n\n// V2 legacy wrapper calls can emit both receiver-aware and legacy events for one request.\n// Keep one row per request hash before state checks and summing pending amounts.\nfunction dedupeByRequestHash<TLog extends { args: { [key: string]: unknown } }>(\n logs: TLog[],\n hashKey: 'depositRequestHash' | 'redeemRequestHash'\n): TLog[] {\n const seen = new Set<unknown>();\n\n return logs.filter((log) => {\n const hash = log.args[hashKey];\n // Drop malformed events and duplicates so one pending request cannot be counted twice.\n if (hash == null || seen.has(hash)) return false;\n seen.add(hash);\n return true;\n });\n}\n\n/** Step back by the expected block count, and widen until the block predates the cutoff. */\nasync function requestScanStart(\n publicClient: ReturnType<GauntletClient['getPublicClient']>,\n chainId: number,\n blockNumber: bigint,\n days: number,\n cutoff: bigint\n): Promise<bigint> {\n let span = ((BLOCKS_3_DAYS[chainId] ?? DEFAULT_BLOCKS_3_DAYS) * BigInt(days)) / 3n;\n for (;;) {\n if (span >= blockNumber) return 0n;\n const start = blockNumber - span;\n const block = await publicClient.getBlock({ blockNumber: start });\n if (block.timestamp <= cutoff) return start;\n span *= 2n;\n }\n}\n\nasync function mapInBatches<T, P extends Promise<unknown>>(\n items: T[],\n size: number,\n fn: (item: T) => P\n): Promise<Awaited<P>[]> {\n const results: Awaited<P>[] = [];\n for (let i = 0; i < items.length; i += size) {\n results.push(...(await Promise.all(items.slice(i, i + size).map(fn))));\n }\n return results;\n}\n\nasync function queryDeploymentBalance(\n client: GauntletClient,\n deployment: EvmVaultDeployment,\n params: UserCurrentBalanceParams\n): Promise<UserCurrentBalance> {\n const publicClient = client.getPublicClient(deployment.chainId);\n const { address } = params;\n const token =\n deployment.supplyToken.length > 1\n ? deployment.supplyToken.find((candidate) => candidate.symbol === params.assetSymbol)\n : deployment.supplyToken[0];\n if (token === undefined)\n throw new UnsupportedAssetError(params.assetSymbol ?? 'unknown', params.vaultId);\n const snapshot = await publicClient.getBlock({ blockTag: 'latest' });\n if (snapshot.number === null) {\n throw new GauntletSDKError('The balance snapshot has no block number');\n }\n const blockNumber = snapshot.number;\n const readOptions = { blockNumber };\n const expirationDays = deployment.expirationDays ?? 3;\n if (!Number.isSafeInteger(expirationDays) || expirationDays <= 0) {\n throw new GauntletSDKError('The request expiration must be a positive integer number of days');\n }\n const scanDays = Math.max(3, expirationDays);\n const cutoff = snapshot.timestamp - BigInt(DAY) * BigInt(scanDays);\n const fromBlock =\n params.fromBlock ??\n (await requestScanStart(publicClient, deployment.chainId, blockNumber, scanDays, cutoff));\n if (fromBlock < 0n || fromBlock > blockNumber) {\n throw new GauntletSDKError('The request scan range is invalid');\n }\n\n const vaultContract = getMultiDepositorVault(publicClient, deployment.vaultAddress);\n const [runtime, units] = await Promise.all([\n resolveAeraRuntimeContracts(publicClient, deployment, readOptions),\n vaultContract.read.balanceOf([address], readOptions),\n ]);\n const provisionerAddress = runtime.provisioner.address;\n const isV2 = runtime.provisioner.version === ContractVersion.V2;\n const unitsLockedUntilPromise = isV2\n ? getUserUnitsRefundableUntil(publicClient, provisionerAddress, address, readOptions)\n : Promise.resolve(undefined);\n\n const balance = await convertUnitsToToken(\n publicClient,\n runtime.feeCalculator.address,\n runtime.feeCalculator.version,\n deployment.vaultAddress,\n token.address,\n units,\n readOptions\n );\n\n // Compute block-range chunks to stay within the 10,000-block RPC limit, then fetch in bounded batches\n const chunks: [bigint, bigint][] = [];\n for (let cursor = fromBlock; cursor <= blockNumber; cursor += LOG_PAGE_SIZE + 1n) {\n const end = cursor + LOG_PAGE_SIZE <= blockNumber ? cursor + LOG_PAGE_SIZE : blockNumber;\n chunks.push([cursor, end]);\n }\n\n // Each map keeps LOG_CHUNK_CONCURRENCY queries in flight.\n const [depositPages, redeemPages] = await Promise.all([\n mapInBatches(chunks, LOG_CHUNK_CONCURRENCY, ([from, to]) =>\n isV2\n ? publicClient.getContractEvents({\n address: provisionerAddress,\n abi: provisionerV2Abi,\n eventName: 'DepositRequested',\n args: { receiver: address, token: token.address },\n fromBlock: from,\n toBlock: to,\n })\n : publicClient.getContractEvents({\n address: provisionerAddress,\n abi: DEPOSIT_REQUESTED_V1_ABI,\n eventName: 'DepositRequested',\n args: { user: address, token: token.address },\n fromBlock: from,\n toBlock: to,\n })\n ),\n mapInBatches(chunks, LOG_CHUNK_CONCURRENCY, ([from, to]) =>\n isV2\n ? publicClient.getContractEvents({\n address: provisionerAddress,\n abi: provisionerV2Abi,\n eventName: 'RedeemRequested',\n args: { user: address, token: token.address },\n fromBlock: from,\n toBlock: to,\n })\n : publicClient.getContractEvents({\n address: provisionerAddress,\n abi: REDEEM_REQUESTED_V1_ABI,\n eventName: 'RedeemRequested',\n args: { user: address, token: token.address },\n fromBlock: from,\n toBlock: to,\n })\n ),\n ]);\n\n const depositLogs = dedupeByRequestHash(depositPages.flat(), 'depositRequestHash');\n const redeemLogs = dedupeByRequestHash(redeemPages.flat(), 'redeemRequestHash');\n\n // Check which requests are still pending on-chain via a single multicall\n const pendingChecks = await publicClient.multicall({\n contracts: [\n ...depositLogs.map((log) => ({\n address: provisionerAddress,\n abi: isV2 ? provisionerV2Abi : provisionerV1StateAbi,\n functionName: isV2 ? ('asyncRequestHashes' as const) : ('asyncDepositHashes' as const),\n args: [log.args.depositRequestHash!] as const,\n })),\n ...redeemLogs.map((log) => ({\n address: provisionerAddress,\n abi: isV2 ? provisionerV2Abi : provisionerV1StateAbi,\n functionName: isV2 ? ('asyncRequestHashes' as const) : ('asyncRedeemHashes' as const),\n args: [log.args.redeemRequestHash!] as const,\n })),\n ],\n allowFailure: false,\n blockNumber,\n });\n\n const depositChecks = pendingChecks.slice(0, depositLogs.length);\n const redeemChecks = pendingChecks.slice(depositLogs.length);\n\n let pendingDeposit = 0n;\n for (let i = 0; i < depositLogs.length; i++) {\n if (depositChecks[i]) {\n pendingDeposit += depositLogs[i].args.tokensIn ?? 0n;\n }\n }\n\n let pendingWithdrawUnits = 0n;\n for (let i = 0; i < redeemLogs.length; i++) {\n if (redeemChecks[i]) {\n pendingWithdrawUnits += redeemLogs[i].args.unitsIn ?? 0n;\n }\n }\n\n const pendingWithdraw =\n pendingWithdrawUnits > 0n\n ? await convertUnitsToToken(\n publicClient,\n runtime.feeCalculator.address,\n runtime.feeCalculator.version,\n deployment.vaultAddress,\n token.address,\n pendingWithdrawUnits,\n readOptions\n )\n : 0n;\n const unitsLockedUntil = await unitsLockedUntilPromise;\n\n return {\n blockNumber,\n fromBlock,\n chain: CHAIN_NAMES[deployment.chainId] ?? `chain-${deployment.chainId}`,\n chainId: deployment.chainId,\n token: token.address,\n decimals: token.decimals,\n pendingDeposit,\n balance,\n pendingWithdraw,\n ...(unitsLockedUntil !== undefined ? { unitsLockedUntil } : {}),\n };\n}\n\n/**\n * Returns the current balance breakdown for a user across all EVM deployments of a vault.\n *\n * Queries the vault's on-chain state to split the user's position into three buckets:\n * - `balance` \u2014 assets actively earning inside the vault (converted from vault units to tokens).\n * - `pendingDeposit` \u2014 tokens submitted via async deposit but not yet processed by a solver.\n * - `pendingWithdraw` \u2014 vault units locked in a pending async redeem request (converted to tokens).\n *\n * Only supported for Aera multi-depositor vaults. Pending amounts are detected by scanning\n * the configured request lifetime, with a minimum of three days. Set `fromBlock` (with `chainId`\n * on a multi-chain vault) for older escrow.\n * All state reads use one block. The returned range identifies the scanned history.\n *\n * @param client - A configured `GauntletClient` instance with an EVM public client for each\n * chain the vault is deployed on.\n * @param params - Query parameters including `vaultId`, the user `address`, and an optional\n * `chainId` to limit the query to a single deployment.\n * @returns One `UserCurrentBalance` entry per chain queried.\n *\n * @throws {VaultNotFoundError} If the vault ID is not found in the manifest.\n * @throws {UnsupportedProtocolError} If the vault is not an Aera multi-depositor vault.\n * @throws {ChainMismatchError} If `chainId` is specified but no deployment exists for that chain.\n * @throws {UnsupportedAssetError} If a multi-asset deployment gets no matching `assetSymbol`.\n *\n * @example\n * ```ts\n * const balances = await getUserCurrentBalance(client, {\n * vaultId: 'baseUsdcPrime',\n * address: '0xYourWalletAddress',\n * });\n * // [{ chain: 'base', chainId: 8453, token: '0x...', decimals: 6, balance: 100_000_000n, pendingDeposit: 0n, pendingWithdraw: 0n }]\n * ```\n */\nexport async function getUserCurrentBalance(\n client: GauntletClient,\n params: UserCurrentBalanceParams\n): Promise<UserCurrentBalance[]> {\n params = { ...params };\n const manifest = await client.manifest;\n const vaultInfo = manifest.vaults.find((v) => v.vaultId === params.vaultId);\n if (!vaultInfo) throw new VaultNotFoundError(params.vaultId);\n\n const evmDeployments = vaultInfo.deployments.filter(\n (d): d is EvmVaultDeployment => d.chain === 'evm' && d.vaultType === 'multi-depositor'\n );\n\n if (vaultInfo.protocol !== 'aera' || evmDeployments.length === 0) {\n throw new UnsupportedProtocolError(vaultInfo.protocol);\n }\n\n if (params.chainId !== undefined) {\n const deployment = evmDeployments.find((d) => d.chainId === params.chainId);\n if (!deployment) {\n throw new ChainMismatchError(\n `${params.chainId}`,\n evmDeployments.map((d) => `${d.chainId}`).join(', ')\n );\n }\n return [await queryDeploymentBalance(client, deployment, params)];\n }\n if (params.fromBlock !== undefined && evmDeployments.length > 1) {\n throw new GauntletSDKError('fromBlock requires chainId for a vault with several deployments');\n }\n\n return Promise.all(evmDeployments.map((d) => queryDeploymentBalance(client, d, params)));\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|