@augustdigital/sdk 8.3.2 → 8.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/abis/ERC20_Bytes32.d.ts +4 -0
- package/lib/abis/ERC20_Bytes32.js +4 -0
- package/lib/abis/ERC4626.d.ts +1 -0
- package/lib/abis/ERC4626.js +1 -0
- package/lib/abis/ERC721.d.ts +1 -0
- package/lib/abis/ERC721.js +1 -0
- package/lib/abis/FeeOracle.js +1 -0
- package/lib/abis/LendingPool.js +1 -0
- package/lib/abis/LendingPoolV2.js +1 -0
- package/lib/abis/Multicall3.js +3 -0
- package/lib/abis/OFT.d.ts +20 -0
- package/lib/abis/OFT.js +20 -0
- package/lib/abis/SmartAccount.d.ts +1 -0
- package/lib/abis/SmartAccount.js +3 -0
- package/lib/abis/SwapRouter.d.ts +1 -0
- package/lib/abis/SwapRouter.js +1 -0
- package/lib/abis/UniversalSignatureValidator.js +3 -0
- package/lib/abis/index.d.ts +5 -0
- package/lib/abis/index.js +5 -0
- package/lib/adapters/evm/getters.d.ts +17 -2
- package/lib/adapters/evm/getters.js +35 -3
- package/lib/adapters/evm/index.d.ts +262 -0
- package/lib/adapters/evm/index.js +268 -1
- package/lib/adapters/evm/utils.d.ts +6 -0
- package/lib/adapters/evm/utils.js +7 -0
- package/lib/adapters/solana/constants.js +4 -1
- package/lib/adapters/solana/getters.d.ts +8 -0
- package/lib/adapters/solana/getters.js +21 -0
- package/lib/adapters/solana/idl/vault-idl.js +9 -0
- package/lib/adapters/solana/index.d.ts +55 -0
- package/lib/adapters/solana/index.js +57 -0
- package/lib/adapters/solana/utils.d.ts +28 -0
- package/lib/adapters/solana/utils.js +79 -4
- package/lib/adapters/solana/vault.actions.d.ts +19 -0
- package/lib/adapters/solana/vault.actions.js +47 -3
- package/lib/adapters/stellar/actions.d.ts +25 -0
- package/lib/adapters/stellar/actions.js +33 -0
- package/lib/adapters/stellar/constants.d.ts +26 -0
- package/lib/adapters/stellar/constants.js +29 -0
- package/lib/adapters/stellar/getters.d.ts +56 -0
- package/lib/adapters/stellar/getters.js +81 -0
- package/lib/adapters/stellar/index.d.ts +48 -0
- package/lib/adapters/stellar/index.js +48 -0
- package/lib/adapters/stellar/soroban.d.ts +20 -0
- package/lib/adapters/stellar/soroban.js +46 -0
- package/lib/adapters/stellar/submit.d.ts +12 -0
- package/lib/adapters/stellar/submit.js +19 -0
- package/lib/adapters/stellar/types.d.ts +27 -0
- package/lib/adapters/stellar/types.js +3 -0
- package/lib/adapters/stellar/utils.d.ts +10 -0
- package/lib/adapters/stellar/utils.js +10 -0
- package/lib/adapters/sui/getters.d.ts +6 -0
- package/lib/adapters/sui/getters.js +6 -0
- package/lib/adapters/sui/index.d.ts +15 -0
- package/lib/adapters/sui/index.js +15 -0
- package/lib/adapters/sui/transformer.d.ts +6 -0
- package/lib/adapters/sui/transformer.js +6 -0
- package/lib/adapters/sui/utils.d.ts +6 -0
- package/lib/adapters/sui/utils.js +6 -0
- package/lib/core/analytics/chain-name.d.ts +8 -0
- package/lib/core/analytics/chain-name.js +8 -0
- package/lib/core/analytics/constants.d.ts +4 -0
- package/lib/core/analytics/constants.js +4 -0
- package/lib/core/analytics/env.d.ts +25 -0
- package/lib/core/analytics/env.js +26 -0
- package/lib/core/analytics/index.d.ts +26 -0
- package/lib/core/analytics/index.js +35 -0
- package/lib/core/analytics/instrumentation.d.ts +26 -0
- package/lib/core/analytics/instrumentation.js +66 -2
- package/lib/core/analytics/method-taxonomy.d.ts +16 -0
- package/lib/core/analytics/method-taxonomy.js +18 -0
- package/lib/core/analytics/metrics.d.ts +23 -0
- package/lib/core/analytics/metrics.js +40 -0
- package/lib/core/analytics/sanitize.d.ts +38 -0
- package/lib/core/analytics/sanitize.js +46 -0
- package/lib/core/analytics/sentry-runtime.d.ts +11 -0
- package/lib/core/analytics/sentry-runtime.js +19 -0
- package/lib/core/analytics/sentry.d.ts +45 -0
- package/lib/core/analytics/sentry.js +115 -2
- package/lib/core/analytics/types.d.ts +27 -0
- package/lib/core/analytics/user-identity.d.ts +34 -0
- package/lib/core/analytics/user-identity.js +42 -0
- package/lib/core/analytics/version.d.ts +6 -1
- package/lib/core/analytics/version.js +6 -1
- package/lib/core/auth/verify.js +5 -0
- package/lib/core/base.class.d.ts +75 -0
- package/lib/core/base.class.js +56 -0
- package/lib/core/cache.d.ts +5 -0
- package/lib/core/cache.js +6 -0
- package/lib/core/constants/adapters.d.ts +15 -0
- package/lib/core/constants/adapters.js +28 -8
- package/lib/core/constants/core.d.ts +12 -1
- package/lib/core/constants/core.js +12 -0
- package/lib/core/constants/swap-router.d.ts +46 -0
- package/lib/core/constants/swap-router.js +50 -0
- package/lib/core/constants/vaults.d.ts +56 -0
- package/lib/core/constants/vaults.js +66 -1
- package/lib/core/constants/web3.d.ts +3 -0
- package/lib/core/constants/web3.js +18 -5
- package/lib/core/errors/index.d.ts +36 -0
- package/lib/core/errors/index.js +29 -0
- package/lib/core/fetcher.d.ts +134 -0
- package/lib/core/fetcher.js +191 -5
- package/lib/core/helpers/adapters.d.ts +9 -0
- package/lib/core/helpers/adapters.js +11 -0
- package/lib/core/helpers/chain-address.d.ts +10 -0
- package/lib/core/helpers/chain-address.js +11 -0
- package/lib/core/helpers/core.d.ts +42 -0
- package/lib/core/helpers/core.js +66 -1
- package/lib/core/helpers/explorer-link.d.ts +14 -0
- package/lib/core/helpers/explorer-link.js +14 -0
- package/lib/core/helpers/signer.d.ts +26 -0
- package/lib/core/helpers/signer.js +39 -0
- package/lib/core/helpers/swap-router.d.ts +32 -0
- package/lib/core/helpers/swap-router.js +32 -0
- package/lib/core/helpers/vault-version.d.ts +1 -0
- package/lib/core/helpers/vault-version.js +2 -0
- package/lib/core/helpers/vaults.d.ts +8 -0
- package/lib/core/helpers/vaults.js +22 -8
- package/lib/core/helpers/web3.d.ts +152 -0
- package/lib/core/helpers/web3.js +183 -6
- package/lib/core/logger/index.d.ts +55 -0
- package/lib/core/logger/index.js +19 -0
- package/lib/core/logger/slack.d.ts +3 -0
- package/lib/core/logger/slack.js +3 -0
- package/lib/core/vault-metadata.d.ts +6 -0
- package/lib/core/vault-metadata.js +6 -0
- package/lib/core/version-check.d.ts +52 -0
- package/lib/core/version-check.js +81 -0
- package/lib/evm/methods/crossChainVault.d.ts +90 -0
- package/lib/evm/methods/crossChainVault.js +186 -1
- package/lib/evm/methods/crossChainVaultRegistry.d.ts +93 -0
- package/lib/evm/methods/crossChainVaultRegistry.js +240 -0
- package/lib/evm/methods/index.d.ts +1 -0
- package/lib/evm/methods/index.js +1 -0
- package/lib/evm/types/crossChain.d.ts +202 -0
- package/lib/evm/types/crossChain.js +11 -0
- package/lib/index.d.ts +16 -0
- package/lib/index.js +19 -0
- package/lib/main.d.ts +288 -5
- package/lib/main.js +305 -0
- package/lib/modules/api/index.d.ts +1 -0
- package/lib/modules/api/index.js +6 -0
- package/lib/modules/api/main.d.ts +52 -0
- package/lib/modules/api/main.js +130 -0
- package/lib/modules/sub-accounts/fetcher.d.ts +15 -0
- package/lib/modules/sub-accounts/fetcher.js +15 -0
- package/lib/modules/sub-accounts/main.d.ts +33 -0
- package/lib/modules/sub-accounts/main.js +38 -0
- package/lib/modules/sub-accounts/utils.d.ts +3 -0
- package/lib/modules/sub-accounts/utils.js +3 -0
- package/lib/modules/vaults/adapter.helpers.d.ts +18 -0
- package/lib/modules/vaults/adapter.helpers.js +34 -0
- package/lib/modules/vaults/fetcher.d.ts +20 -0
- package/lib/modules/vaults/fetcher.js +40 -3
- package/lib/modules/vaults/getters.d.ts +295 -0
- package/lib/modules/vaults/getters.js +552 -12
- package/lib/modules/vaults/index.d.ts +12 -0
- package/lib/modules/vaults/index.js +12 -0
- package/lib/modules/vaults/main.d.ts +292 -4
- package/lib/modules/vaults/main.js +379 -7
- package/lib/modules/vaults/read.actions.d.ts +168 -0
- package/lib/modules/vaults/read.actions.js +143 -0
- package/lib/modules/vaults/types.d.ts +34 -0
- package/lib/modules/vaults/utils/call-data-decoder.d.ts +47 -0
- package/lib/modules/vaults/utils/call-data-decoder.js +56 -0
- package/lib/modules/vaults/utils/date-utils.d.ts +39 -0
- package/lib/modules/vaults/utils/date-utils.js +47 -1
- package/lib/modules/vaults/utils.d.ts +69 -0
- package/lib/modules/vaults/utils.js +104 -5
- package/lib/modules/vaults/write.actions.d.ts +363 -3
- package/lib/modules/vaults/write.actions.js +364 -2
- package/lib/polyfills.js +2 -0
- package/lib/sdk.d.ts +23705 -0
- package/lib/services/coingecko/fetcher.d.ts +13 -0
- package/lib/services/coingecko/fetcher.js +17 -0
- package/lib/services/debank/fetcher.d.ts +14 -0
- package/lib/services/debank/fetcher.js +12 -0
- package/lib/services/debank/utils.js +17 -0
- package/lib/services/layerzero/deposits.d.ts +11 -0
- package/lib/services/layerzero/deposits.js +34 -11
- package/lib/services/layerzero/redeems.d.ts +10 -0
- package/lib/services/layerzero/redeems.js +13 -0
- package/lib/services/layerzero/utils.d.ts +8 -0
- package/lib/services/layerzero/utils.js +11 -0
- package/lib/services/octavfi/fetcher.d.ts +7 -0
- package/lib/services/octavfi/fetcher.js +25 -0
- package/lib/services/octavfi/utils.d.ts +12 -0
- package/lib/services/octavfi/utils.js +44 -10
- package/lib/services/subgraph/fetcher.js +4 -2
- package/lib/services/subgraph/vaults.d.ts +12 -0
- package/lib/services/subgraph/vaults.js +43 -2
- package/lib/services/swap-quotes/index.d.ts +71 -0
- package/lib/services/swap-quotes/index.js +25 -0
- package/lib/services/swap-quotes/paraswap.d.ts +17 -0
- package/lib/services/swap-quotes/paraswap.js +14 -0
- package/lib/types/pools.d.ts +3 -0
- package/lib/types/typed-contract.d.ts +64 -0
- package/lib/types/vaults.d.ts +137 -2
- package/lib/types/vaults.js +10 -0
- package/lib/types/web3.d.ts +8 -0
- package/lib/types/web3.js +1 -0
- package/lib/types/webserver.d.ts +45 -0
- package/package.json +6 -5
|
@@ -24,6 +24,10 @@ const core_1 = require("../../core");
|
|
|
24
24
|
const swap_quotes_1 = require("../../services/swap-quotes");
|
|
25
25
|
const adapter_helpers_1 = require("./adapter.helpers");
|
|
26
26
|
const utils_1 = require("./utils");
|
|
27
|
+
// Treat unparseable RPC payloads (bare "0x", etc.) as 0n with a warn log —
|
|
28
|
+
// the defensive default is "approve again," and the log surfaces flaky RPCs
|
|
29
|
+
// before they cause silent gas waste from spurious approvals.
|
|
30
|
+
/** @internal */
|
|
27
31
|
function safeBigInt(value, context = 'safeBigInt') {
|
|
28
32
|
if (value === null || value === undefined)
|
|
29
33
|
return 0n;
|
|
@@ -44,6 +48,11 @@ function safeBigInt(value, context = 'safeBigInt') {
|
|
|
44
48
|
return 0n;
|
|
45
49
|
}
|
|
46
50
|
}
|
|
51
|
+
// EVM-0/1 single-asset underlying deposits reuse vaultDecimals (vault and
|
|
52
|
+
// underlying decimals match under ERC-4626 inheritance), saving one RPC.
|
|
53
|
+
// Multi-asset / adapter / non-underlying paths must read from the deposit
|
|
54
|
+
// asset's own ERC-20 — using share decimals there silently misencodes amounts.
|
|
55
|
+
/** @internal */
|
|
47
56
|
async function resolveDepositTokenDecimals(args) {
|
|
48
57
|
const { actualDepositAsset, underlyingAsset, isNativeToken, isMultiAssetVault, vaultDecimals, readErc20Decimals, } = args;
|
|
49
58
|
if (isNativeToken)
|
|
@@ -53,6 +62,7 @@ async function resolveDepositTokenDecimals(args) {
|
|
|
53
62
|
return vaultDecimals;
|
|
54
63
|
return readErc20Decimals(actualDepositAsset);
|
|
55
64
|
}
|
|
65
|
+
/** @internal */
|
|
56
66
|
function resolveSpender(args) {
|
|
57
67
|
if (args.swapRouterAddress)
|
|
58
68
|
return args.swapRouterAddress;
|
|
@@ -62,6 +72,9 @@ function resolveSpender(args) {
|
|
|
62
72
|
return args.adapterWrapperAddress;
|
|
63
73
|
return args.target;
|
|
64
74
|
}
|
|
75
|
+
// Reject JS-number amounts past Number.MAX_SAFE_INTEGER — any larger
|
|
76
|
+
// integer the caller passes is already wrong before we hit toNormalizedBn.
|
|
77
|
+
/** @internal */
|
|
65
78
|
function validateAmountPrecision(amount) {
|
|
66
79
|
if (typeof amount === 'string' || typeof amount === 'bigint')
|
|
67
80
|
return;
|
|
@@ -75,13 +88,17 @@ function validateAmountPrecision(amount) {
|
|
|
75
88
|
throw new core_1.AugustValidationError('INVALID_INPUT', `amount ${amount} exceeds Number.MAX_SAFE_INTEGER; pass a string or bigint to preserve precision`);
|
|
76
89
|
}
|
|
77
90
|
}
|
|
91
|
+
// Tries tx.wait() first (preserves replacement detection & revert checks), then falls back to
|
|
92
|
+
// provider.waitForTransaction() for RPCs (e.g. Monad) that return malformed pending tx fields.
|
|
78
93
|
const SAFE_WAIT_TIMEOUT_MS = 120000;
|
|
94
|
+
/** @internal */
|
|
79
95
|
function isNonceParsing(error) {
|
|
80
96
|
const code = error?.code;
|
|
81
97
|
const msg = String(error).toLowerCase();
|
|
82
98
|
return ((code === 'INVALID_ARGUMENT' || code === 'BAD_DATA') &&
|
|
83
99
|
msg.includes('nonce'));
|
|
84
100
|
}
|
|
101
|
+
/** @internal */
|
|
85
102
|
async function safeWaitForTx(tx) {
|
|
86
103
|
try {
|
|
87
104
|
return await tx.wait();
|
|
@@ -102,6 +119,14 @@ async function safeWaitForTx(tx) {
|
|
|
102
119
|
throw error;
|
|
103
120
|
}
|
|
104
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* Wraps an ethers contract call that returns a TransactionResponse.
|
|
124
|
+
* Some RPCs (e.g. Monad) return malformed pending tx fields like `nonce: "undefined"`,
|
|
125
|
+
* which causes ethers.js to throw during response parsing before safeWaitForTx runs.
|
|
126
|
+
* This wrapper catches that error, extracts the tx hash from the error context, and
|
|
127
|
+
* falls back to provider.waitForTransaction().
|
|
128
|
+
*/
|
|
129
|
+
/** @internal */
|
|
105
130
|
async function safeSendTx(contractCall, provider, shouldWait) {
|
|
106
131
|
try {
|
|
107
132
|
const tx = await contractCall();
|
|
@@ -112,6 +137,8 @@ async function safeSendTx(contractCall, provider, shouldWait) {
|
|
|
112
137
|
catch (error) {
|
|
113
138
|
if (!isNonceParsing(error))
|
|
114
139
|
throw error;
|
|
140
|
+
// The tx was sent but ethers couldn't parse the response.
|
|
141
|
+
// Try to extract the hash from the error payload.
|
|
115
142
|
const errStr = String(error);
|
|
116
143
|
const hashMatch = errStr.match(/"hash"\s*:\s*"(0x[0-9a-fA-F]{64})"/);
|
|
117
144
|
if (!hashMatch?.[1])
|
|
@@ -131,6 +158,15 @@ async function safeSendTx(contractCall, provider, shouldWait) {
|
|
|
131
158
|
return { tx: null, hash: txHash };
|
|
132
159
|
}
|
|
133
160
|
}
|
|
161
|
+
/**
|
|
162
|
+
* Shared nonce-recovery helper for catch blocks. When an RPC returns a
|
|
163
|
+
* malformed nonce and ethers throws, try to extract the tx hash from the
|
|
164
|
+
* error payload. Optionally waits for confirmation (with status check).
|
|
165
|
+
*
|
|
166
|
+
* Returns the recovered hash, or null if this error is not a nonce-parse error
|
|
167
|
+
* or if no hash could be extracted (caller should re-throw the original error).
|
|
168
|
+
*/
|
|
169
|
+
/** @internal */
|
|
134
170
|
async function tryRecoverTxHash(error, signer, wait) {
|
|
135
171
|
if (!isNonceParsing(error))
|
|
136
172
|
return null;
|
|
@@ -205,6 +241,7 @@ async function approveCore(signer, options) {
|
|
|
205
241
|
const actualDepositAsset = (depositAsset || underlyingAsset);
|
|
206
242
|
const isNativeToken = actualDepositAsset === ethers_1.ZeroAddress ||
|
|
207
243
|
actualDepositAsset === '0x0000000000000000000000000000000000000000';
|
|
244
|
+
// Native tokens travel as msg.value — no ERC-20 allowance to grant.
|
|
208
245
|
if (isNativeToken)
|
|
209
246
|
return { kind: 'native' };
|
|
210
247
|
const isAdapterDeposit = actualDepositAsset.toLowerCase() !== underlyingAsset.toLowerCase();
|
|
@@ -264,13 +301,112 @@ async function approveCore(signer, options) {
|
|
|
264
301
|
throw new core_1.AugustSDKError('UNKNOWN', `Approval failed: ${e instanceof Error ? e.message : 'Unknown error'}`, { cause: e, context: { target, amount } });
|
|
265
302
|
}
|
|
266
303
|
}
|
|
304
|
+
/**
|
|
305
|
+
* Approve a vault (or the appropriate adapter wrapper) to spend a token
|
|
306
|
+
* ahead of a separate deposit call. Spender routing mirrors
|
|
307
|
+
* {@link vaultDeposit} (multi-asset → vault, adapter → wrapper, standard →
|
|
308
|
+
* vault). Returns `undefined` when the existing allowance already covers
|
|
309
|
+
* `amount` **or** when the deposit asset is native.
|
|
310
|
+
*
|
|
311
|
+
* @returns Transaction hash when an approval was sent, `undefined` when
|
|
312
|
+
* the existing allowance already covers `amount` or the deposit asset is
|
|
313
|
+
* native (no ERC-20 allowance applies). Use {@link approve} for a
|
|
314
|
+
* discriminated `ApproveResult` if you need to tell those two cases apart.
|
|
315
|
+
* @throws AugustValidationError on invalid wallet/target/amount.
|
|
316
|
+
*
|
|
317
|
+
* @example
|
|
318
|
+
* ```ts
|
|
319
|
+
* const hash = await augustSdk.evm.vaultApprove({
|
|
320
|
+
* target: '0x...', // vault contract address
|
|
321
|
+
* wallet: walletAddress,
|
|
322
|
+
* amount: '100', // 100 of the deposit token (UI units)
|
|
323
|
+
* wait: true, // wait for the approval to confirm
|
|
324
|
+
* });
|
|
325
|
+
* if (hash) console.log('approve tx', hash);
|
|
326
|
+
* // hash === undefined means the on-chain allowance already covers the
|
|
327
|
+
* // amount, or the deposit asset is native (msg.value, no allowance).
|
|
328
|
+
* ```
|
|
329
|
+
*/
|
|
267
330
|
async function vaultApprove(signer, options) {
|
|
268
331
|
const result = await approveCore(signer, options);
|
|
269
332
|
return result.kind === 'sent' ? result.hash : undefined;
|
|
270
333
|
}
|
|
334
|
+
/**
|
|
335
|
+
* Same approval logic as {@link vaultApprove} but returns a discriminated
|
|
336
|
+
* union so callers can tell `sent` apart from `sufficient` and `native`
|
|
337
|
+
* without re-reading on-chain state. Preferred shape for new integrations.
|
|
338
|
+
*
|
|
339
|
+
* @example
|
|
340
|
+
* ```ts
|
|
341
|
+
* const r = await augustSdk.evm.approve({
|
|
342
|
+
* target: vaultAddress,
|
|
343
|
+
* wallet: walletAddress,
|
|
344
|
+
* amount: '100',
|
|
345
|
+
* wait: true,
|
|
346
|
+
* });
|
|
347
|
+
* switch (r.kind) {
|
|
348
|
+
* case 'sent':
|
|
349
|
+
* showToast('Approval submitted', r.hash);
|
|
350
|
+
* break;
|
|
351
|
+
* case 'sufficient':
|
|
352
|
+
* // r.existing is the existing on-chain allowance (raw bigint)
|
|
353
|
+
* break;
|
|
354
|
+
* case 'native':
|
|
355
|
+
* // No allowance needed; native token will travel as msg.value
|
|
356
|
+
* break;
|
|
357
|
+
* }
|
|
358
|
+
* ```
|
|
359
|
+
*
|
|
360
|
+
* @throws AugustValidationError on invalid wallet/target/amount.
|
|
361
|
+
* @throws AugustSDKError when the approval submission fails.
|
|
362
|
+
*/
|
|
271
363
|
async function approve(signer, options) {
|
|
272
364
|
return approveCore(signer, options);
|
|
273
365
|
}
|
|
366
|
+
/**
|
|
367
|
+
* Deposit underlying token into the specified vault. Auto-routes to the
|
|
368
|
+
* correct contract path (single-asset ERC-4626, EVM-2 multi-asset,
|
|
369
|
+
* Paraswap adapter, native-token wrapper, depositWithPermit) based on the
|
|
370
|
+
* vault version and `depositAsset`.
|
|
371
|
+
*
|
|
372
|
+
* Amounts are encoded against the **deposit token's** decimals, not the
|
|
373
|
+
* vault's share decimals. The SDK reads the appropriate decimals via the
|
|
374
|
+
* vault metadata and the asset's ERC-20.
|
|
375
|
+
*
|
|
376
|
+
* Approval is handled automatically: if the existing allowance doesn't
|
|
377
|
+
* cover `amount`, an `approve` is sent and **always waited for** (regardless
|
|
378
|
+
* of the caller's `wait` flag) so the deposit tx can't be re-ordered ahead
|
|
379
|
+
* of the approval on Monad-style RPCs.
|
|
380
|
+
*
|
|
381
|
+
* @param signer ethers Signer / Wallet (or viem WalletClient via {@link setSigner})
|
|
382
|
+
* @param options Vault address, wallet, amount, optional `depositAsset` for
|
|
383
|
+
* adapter routes, optional `wait` to wait for the deposit receipt.
|
|
384
|
+
* @returns Deposit transaction hash.
|
|
385
|
+
* @throws AugustValidationError on invalid wallet/target/amount or missing
|
|
386
|
+
* adapter config when `depositAsset` differs from the vault underlying.
|
|
387
|
+
* @throws AugustSDKError when the deposit submission or on-chain call fails.
|
|
388
|
+
*
|
|
389
|
+
* @example
|
|
390
|
+
* ```ts
|
|
391
|
+
* const hash = await augustSdk.evm.vaultDeposit({
|
|
392
|
+
* target: '0xE9B725010A9E419412ed67d0fA5f3A5f40159D32', // vault
|
|
393
|
+
* wallet: walletAddress,
|
|
394
|
+
* amount: '100', // 100 USDC (UI units)
|
|
395
|
+
* wait: true, // wait for the deposit receipt
|
|
396
|
+
* });
|
|
397
|
+
* ```
|
|
398
|
+
*
|
|
399
|
+
* @example Adapter deposit (different deposit asset than the vault's underlying)
|
|
400
|
+
* ```ts
|
|
401
|
+
* await augustSdk.evm.vaultDeposit({
|
|
402
|
+
* target: vaultAddress,
|
|
403
|
+
* wallet: walletAddress,
|
|
404
|
+
* amount: '0.5',
|
|
405
|
+
* depositAsset: WETH_ADDRESS, // swap WETH -> vault underlying via the adapter
|
|
406
|
+
* chainId: 1,
|
|
407
|
+
* });
|
|
408
|
+
* ```
|
|
409
|
+
*/
|
|
274
410
|
async function vaultDeposit(signer, options) {
|
|
275
411
|
const { wallet, target, wait, amount, depositAsset, chainId, poolName } = options;
|
|
276
412
|
const [goodWallet, goodPool] = [
|
|
@@ -334,11 +470,13 @@ async function vaultDeposit(signer, options) {
|
|
|
334
470
|
const swapRouterAddress = wantsSwapRouter && resolvedChainId !== undefined
|
|
335
471
|
? (0, core_1.getSwapRouterAddress)(resolvedChainId)
|
|
336
472
|
: undefined;
|
|
473
|
+
// Legacy adapter uses minAmountOut: 0 (MEV-vulnerable); fall-through is unsafe.
|
|
337
474
|
if (wantsSwapRouter && !swapRouterAddress) {
|
|
338
475
|
throw new core_1.AugustValidationError('INVALID_CHAIN', resolvedChainId === undefined
|
|
339
476
|
? `vaultDeposit: vault ${target} requires SwapRouter routing but chainId could not be resolved — pass options.chainId or ensure tokenized-vault metadata is loaded`
|
|
340
477
|
: `vaultDeposit: vault ${target} is registered on SwapRouter but no SwapRouter is deployed for chainId ${resolvedChainId}`, { context: { vault: target, chainId: resolvedChainId } });
|
|
341
478
|
}
|
|
479
|
+
// SwapRouter has no permit variant; throw rather than silently drop the signature.
|
|
342
480
|
if (wantsSwapRouter && options?.isDepositWithPermit) {
|
|
343
481
|
throw new core_1.AugustValidationError('INVALID_INPUT', `vaultDeposit: isDepositWithPermit is not supported on SwapRouter-routed vaults (${target}). Call vaultDeposit without isDepositWithPermit, or use the legacy vault.deposit path directly.`, { context: { vault: target } });
|
|
344
482
|
}
|
|
@@ -403,22 +541,30 @@ async function vaultDeposit(signer, options) {
|
|
|
403
541
|
}
|
|
404
542
|
}
|
|
405
543
|
let depositTx;
|
|
544
|
+
// Route to appropriate deposit method
|
|
406
545
|
if (isMultiAssetVault) {
|
|
407
546
|
if (options?.isDepositWithPermit) {
|
|
547
|
+
// depositWithPermit flow
|
|
548
|
+
// build structure hash of permit off chain
|
|
408
549
|
const deadline = (0, utils_1.createDeadline)();
|
|
550
|
+
//sign the hash with private key of depositor
|
|
409
551
|
const { v, r, s } = await (0, utils_1.generatePermitSignature)(actualDepositAsset, wallet, await poolContract.getAddress(), normalizedAmt.raw, deadline, signer, tokenizedVault.chain);
|
|
552
|
+
//actually call depositWithPermit func
|
|
410
553
|
const { hash: permitHash } = await safeSendTx(() => poolContract
|
|
411
554
|
.connect(signer)
|
|
412
555
|
.depositWithPermit(actualDepositAsset, normalizedAmt.raw, wallet, deadline, r, s, v), signer, wait);
|
|
413
556
|
core_1.Logger.log.info('deposit:tx_hash', permitHash);
|
|
414
557
|
return permitHash;
|
|
415
558
|
}
|
|
559
|
+
// Multi-asset vault deposit (EVM-2)
|
|
416
560
|
depositTx = await poolContract
|
|
417
561
|
.connect(signer)
|
|
418
562
|
.deposit(actualDepositAsset, normalizedAmt.raw, wallet);
|
|
419
563
|
}
|
|
420
564
|
else if (isAdapterDeposit && adapterConfig) {
|
|
565
|
+
// Adapter deposit (swap or native wrapper)
|
|
421
566
|
if (adapterConfig.bridgeId === 2) {
|
|
567
|
+
// Paraswap bridge - build swap and deposit transaction
|
|
422
568
|
const adapterContract = await (0, adapter_helpers_1.buildSwapAndDepositTransaction)({
|
|
423
569
|
signer,
|
|
424
570
|
srcToken: actualDepositAsset,
|
|
@@ -436,13 +582,14 @@ async function vaultDeposit(signer, options) {
|
|
|
436
582
|
srcToken: actualDepositAsset,
|
|
437
583
|
dstToken: underlyingAsset,
|
|
438
584
|
bridgeId: adapterConfig.bridgeId,
|
|
439
|
-
quoteData: '0x',
|
|
585
|
+
quoteData: '0x', // This will be populated by buildSwapAndDepositTransaction
|
|
440
586
|
};
|
|
441
587
|
depositTx = await adapterContract
|
|
442
588
|
.connect(signer)
|
|
443
589
|
.swapAndDeposit(swapAndDepositParams);
|
|
444
590
|
}
|
|
445
591
|
else {
|
|
592
|
+
// Native/wrapped token deposit via wrapper contract
|
|
446
593
|
const nativeDepositConfig = await (0, adapter_helpers_1.buildNativeDepositTransaction)({
|
|
447
594
|
signer,
|
|
448
595
|
srcToken: actualDepositAsset,
|
|
@@ -458,12 +605,15 @@ async function vaultDeposit(signer, options) {
|
|
|
458
605
|
}
|
|
459
606
|
}
|
|
460
607
|
else {
|
|
608
|
+
// Standard deposit
|
|
461
609
|
if (isNativeToken) {
|
|
610
|
+
// Native ETH/AVAX deposit
|
|
462
611
|
depositTx = await poolContract
|
|
463
612
|
.connect(signer)
|
|
464
613
|
.deposit(normalizedAmt.raw, wallet, { value: normalizedAmt.raw });
|
|
465
614
|
}
|
|
466
615
|
else {
|
|
616
|
+
// Standard ERC20 deposit
|
|
467
617
|
depositTx = await poolContract
|
|
468
618
|
.connect(signer)
|
|
469
619
|
.deposit(normalizedAmt.raw, wallet);
|
|
@@ -486,6 +636,42 @@ async function vaultDeposit(signer, options) {
|
|
|
486
636
|
throw new core_1.AugustSDKError('UNKNOWN', `Deposit failed: ${e instanceof Error ? e.message : 'Unknown error'}`, { cause: e, context: { target, amount, depositAsset } });
|
|
487
637
|
}
|
|
488
638
|
}
|
|
639
|
+
/**
|
|
640
|
+
* Request to redeem vault shares. For EVM-1 vaults this queues a standard
|
|
641
|
+
* redemption (claimable later via `vaultRedeem`); for EVM-2 vaults this
|
|
642
|
+
* also handles the receipt-token allowance automatically. Pass
|
|
643
|
+
* `isInstantRedeem: true` for vaults that support instant settlement.
|
|
644
|
+
*
|
|
645
|
+
* Approval of the receipt token (EVM-2) is always waited on before the
|
|
646
|
+
* redeem call, regardless of the caller's `wait` flag.
|
|
647
|
+
*
|
|
648
|
+
* @param signer ethers Signer / Wallet (or viem WalletClient via {@link setSigner})
|
|
649
|
+
* @param options Vault address, wallet, amount, optional `isInstantRedeem`,
|
|
650
|
+
* optional `wait` to wait for the redeem receipt.
|
|
651
|
+
* @returns Redeem transaction hash.
|
|
652
|
+
* @throws AugustValidationError on invalid wallet/target/amount.
|
|
653
|
+
* @throws AugustSDKError when the redeem submission or on-chain call fails.
|
|
654
|
+
*
|
|
655
|
+
* @example
|
|
656
|
+
* ```ts
|
|
657
|
+
* const hash = await augustSdk.evm.vaultRequestRedeem({
|
|
658
|
+
* target: vaultAddress,
|
|
659
|
+
* wallet: walletAddress,
|
|
660
|
+
* amount: '10', // 10 shares (UI units)
|
|
661
|
+
* wait: true,
|
|
662
|
+
* });
|
|
663
|
+
* ```
|
|
664
|
+
*
|
|
665
|
+
* @example Instant redemption
|
|
666
|
+
* ```ts
|
|
667
|
+
* await augustSdk.evm.vaultRequestRedeem({
|
|
668
|
+
* target: vaultAddress,
|
|
669
|
+
* wallet: walletAddress,
|
|
670
|
+
* amount: '10',
|
|
671
|
+
* isInstantRedeem: true,
|
|
672
|
+
* });
|
|
673
|
+
* ```
|
|
674
|
+
*/
|
|
489
675
|
async function vaultRequestRedeem(signer, options) {
|
|
490
676
|
const { wallet, target, wait, amount } = options;
|
|
491
677
|
const [goodWallet, goodPool] = [
|
|
@@ -500,16 +686,21 @@ async function vaultRequestRedeem(signer, options) {
|
|
|
500
686
|
}
|
|
501
687
|
validateAmountPrecision(amount);
|
|
502
688
|
try {
|
|
689
|
+
// Get vault version to determine correct ABI
|
|
503
690
|
const tokenizedVault = (await (0, core_1.fetchTokenizedVault)(target))?.[0];
|
|
504
691
|
const vaultVersion = (0, core_1.getVaultVersionV2)(tokenizedVault);
|
|
505
692
|
let poolContract;
|
|
506
693
|
let decimals;
|
|
694
|
+
// Handle different vault versions
|
|
507
695
|
if (vaultVersion === 'evm-2') {
|
|
696
|
+
// For evm-2, always use ABI_TOKENIZED_VAULT_V2 to get lpTokenAddress
|
|
697
|
+
// even for instant redeem, we need lpTokenAddress for receipt token decimals
|
|
508
698
|
const vaultContract = (0, core_1.createContract)({
|
|
509
699
|
address: target,
|
|
510
700
|
provider: signer,
|
|
511
701
|
abi: abis_1.ABI_TOKENIZED_VAULT_V2,
|
|
512
702
|
});
|
|
703
|
+
// Get receipt token for decimals
|
|
513
704
|
const receiptTokenAddr = (await vaultContract.lpTokenAddress());
|
|
514
705
|
const receiptContract = (0, core_1.createContract)({
|
|
515
706
|
address: receiptTokenAddr,
|
|
@@ -517,13 +708,19 @@ async function vaultRequestRedeem(signer, options) {
|
|
|
517
708
|
abi: abis_1.ABI_ERC20,
|
|
518
709
|
});
|
|
519
710
|
decimals = Number(await receiptContract.decimals());
|
|
711
|
+
// Convert amount to bignumber
|
|
520
712
|
const normalizedAmt = (0, core_1.toNormalizedBn)(amount, decimals);
|
|
713
|
+
// EVM-2 lp/receipt token is a separate ERC-20: vault.transferFrom(lp)
|
|
714
|
+
// needs explicit allowance even on self-redeem (msg.sender on the lp
|
|
715
|
+
// token is the vault, not the user — no ERC-4626 owner-shortcut).
|
|
521
716
|
const allowance = await receiptContract.allowance(wallet, target);
|
|
522
717
|
if (safeBigInt(allowance, 'vaultRequestRedeem:allowance') <
|
|
523
718
|
BigInt(normalizedAmt.raw)) {
|
|
524
719
|
const { hash: approveHash } = await safeSendTx(() => receiptContract.connect(signer).approve(target, normalizedAmt.raw), signer, true);
|
|
525
720
|
core_1.Logger.log.info('approve:receipt_token:tx_hash', approveHash);
|
|
526
721
|
}
|
|
722
|
+
// For evm-2, use vaultContract for both instant and standard redeem
|
|
723
|
+
// ABI_TOKENIZED_VAULT_V2 has both instantRedeem (2 params) and requestRedeem
|
|
527
724
|
poolContract = vaultContract;
|
|
528
725
|
}
|
|
529
726
|
else {
|
|
@@ -540,26 +737,32 @@ async function vaultRequestRedeem(signer, options) {
|
|
|
540
737
|
});
|
|
541
738
|
decimals = await poolContract.decimals();
|
|
542
739
|
}
|
|
740
|
+
// Convert amount to bignumber (for non-evm-2 vaults)
|
|
543
741
|
const normalizedAmt = (0, core_1.toNormalizedBn)(amount, decimals);
|
|
742
|
+
// Withdraw from vault - EVM-2 uses 2 params, others use 3 params
|
|
544
743
|
let requestRedeemTx;
|
|
545
744
|
if (options.isInstantRedeem) {
|
|
546
745
|
if (vaultVersion === 'evm-2') {
|
|
746
|
+
// EVM-2: instantRedeem(uint256 shares, address receiverAddr) - 2 params
|
|
547
747
|
requestRedeemTx = await poolContract
|
|
548
748
|
.connect(signer)
|
|
549
749
|
.instantRedeem(BigInt(normalizedAmt.raw), wallet);
|
|
550
750
|
}
|
|
551
751
|
else {
|
|
752
|
+
// EVM-0/EVM-1: instantRedeem(uint256 shares, address receiverAddr, address holderAddr) - 3 params
|
|
552
753
|
requestRedeemTx = await poolContract
|
|
553
754
|
.connect(signer)
|
|
554
755
|
.instantRedeem(BigInt(normalizedAmt.raw), wallet, wallet);
|
|
555
756
|
}
|
|
556
757
|
}
|
|
557
758
|
else if (vaultVersion === 'evm-2') {
|
|
759
|
+
// EVM-2: requestRedeem(uint256 shares, address receiverAddr)
|
|
558
760
|
requestRedeemTx = await poolContract
|
|
559
761
|
.connect(signer)
|
|
560
762
|
.requestRedeem(BigInt(normalizedAmt.raw), wallet);
|
|
561
763
|
}
|
|
562
764
|
else {
|
|
765
|
+
// EVM-0/EVM-1: requestRedeem(uint256 shares, address receiver, address owner)
|
|
563
766
|
requestRedeemTx = await poolContract
|
|
564
767
|
.connect(signer)
|
|
565
768
|
.requestRedeem(BigInt(normalizedAmt.raw), wallet, wallet);
|
|
@@ -581,6 +784,13 @@ async function vaultRequestRedeem(signer, options) {
|
|
|
581
784
|
throw new core_1.AugustSDKError('UNKNOWN', `Request redeem failed: ${e instanceof Error ? e.message : 'Unknown error'}`, { cause: e, context: { target, amount } });
|
|
582
785
|
}
|
|
583
786
|
}
|
|
787
|
+
/**
|
|
788
|
+
* @TODO
|
|
789
|
+
* @description withdraw funds from the specified pool including accrued rewards
|
|
790
|
+
* @param signer signer / wallet object
|
|
791
|
+
* @param options object including pool contract address, user wallet address, and more
|
|
792
|
+
* @returns claim tx hash
|
|
793
|
+
*/
|
|
584
794
|
async function vaultRedeem(signer, options) {
|
|
585
795
|
const { wallet, target, wait, year, day, month, receiverIndex } = options;
|
|
586
796
|
const [goodWallet, goodPool] = [
|
|
@@ -617,6 +827,34 @@ async function vaultRedeem(signer, options) {
|
|
|
617
827
|
throw new core_1.AugustSDKError('UNKNOWN', `Redeem failed: ${e instanceof Error ? e.message : 'Unknown error'}`, { cause: e, context: { target, year, month, day, receiverIndex } });
|
|
618
828
|
}
|
|
619
829
|
}
|
|
830
|
+
/**
|
|
831
|
+
* Deposit a native token (ETH / AVAX / etc.) into a vault via the
|
|
832
|
+
* `MultiAssetNativeDepositWrapper`. The wrapper forwards `msg.value` to
|
|
833
|
+
* the vault as the deposit underlying — no allowance is required.
|
|
834
|
+
*
|
|
835
|
+
* `amount` is the **raw on-chain value in wei-equivalent** (18 decimals
|
|
836
|
+
* for ETH-family natives). If you have a UI-shaped amount in ether, scale
|
|
837
|
+
* it first.
|
|
838
|
+
*
|
|
839
|
+
* @param signer ethers Signer / Wallet
|
|
840
|
+
* @param options `wrapperAddress` is the deployed wrapper contract;
|
|
841
|
+
* `receiver` defaults to the signer's address; `amount` is the native
|
|
842
|
+
* amount in wei; `wait` waits for the deposit receipt.
|
|
843
|
+
* @returns Deposit transaction hash.
|
|
844
|
+
* @throws AugustValidationError on invalid wrapper / receiver / amount.
|
|
845
|
+
* @throws AugustSDKError when the deposit submission or on-chain call fails.
|
|
846
|
+
*
|
|
847
|
+
* @example
|
|
848
|
+
* ```ts
|
|
849
|
+
* import { parseEther } from 'ethers';
|
|
850
|
+
*
|
|
851
|
+
* await augustSdk.evm.depositNative({
|
|
852
|
+
* wrapperAddress: nativeWrapperAddress,
|
|
853
|
+
* amount: parseEther('0.5'), // 0.5 ETH in wei
|
|
854
|
+
* wait: true,
|
|
855
|
+
* });
|
|
856
|
+
* ```
|
|
857
|
+
*/
|
|
620
858
|
async function depositNative(signer, options) {
|
|
621
859
|
const { wrapperAddress, receiver, amount, wait } = options;
|
|
622
860
|
const goodWrapper = (0, core_1.checkAddress)(wrapperAddress, console, 'contract');
|
|
@@ -628,29 +866,36 @@ async function depositNative(signer, options) {
|
|
|
628
866
|
}
|
|
629
867
|
validateAmountPrecision(amount);
|
|
630
868
|
try {
|
|
869
|
+
// Create wrapper contract instance
|
|
631
870
|
const wrapperContract = (0, core_1.createContract)({
|
|
632
871
|
address: wrapperAddress,
|
|
633
872
|
provider: signer,
|
|
634
873
|
abi: abis_1.ABI_MULTI_ASSET_NATIVE_DEPOSIT_WRAPPER,
|
|
635
|
-
});
|
|
874
|
+
}); // TODO: provide typed interface
|
|
875
|
+
// Convert amount to bigint (native tokens use 18 decimals typically)
|
|
876
|
+
// For native deposits, amount should be in wei/smallest unit
|
|
636
877
|
const amountBigInt = typeof amount === 'bigint'
|
|
637
878
|
? amount
|
|
638
879
|
: typeof amount === 'string'
|
|
639
880
|
? BigInt(amount)
|
|
640
881
|
: BigInt(amount);
|
|
641
882
|
let depositTx;
|
|
883
|
+
// Connect the contract first, then get the function to disambiguate between overloads
|
|
642
884
|
const connectedContract = wrapperContract.connect(signer);
|
|
885
|
+
// Call depositNative with or without receiver parameter
|
|
643
886
|
if (receiver) {
|
|
644
887
|
const goodReceiver = (0, core_1.checkAddress)(receiver, console, 'wallet');
|
|
645
888
|
if (!goodReceiver) {
|
|
646
889
|
throw new core_1.AugustValidationError('INVALID_ADDRESS', 'depositNative: invalid receiver address');
|
|
647
890
|
}
|
|
891
|
+
// depositNative(address receiver) - with receiver
|
|
648
892
|
const depositNativeWithReceiver = connectedContract.getFunction('depositNative(address)');
|
|
649
893
|
depositTx = await depositNativeWithReceiver(receiver, {
|
|
650
894
|
value: amountBigInt,
|
|
651
895
|
});
|
|
652
896
|
}
|
|
653
897
|
else {
|
|
898
|
+
// depositNative() - without receiver (uses msg.sender as receiver)
|
|
654
899
|
const depositNativeNoParams = connectedContract.getFunction('depositNative()');
|
|
655
900
|
depositTx = await depositNativeNoParams({
|
|
656
901
|
value: amountBigInt,
|
|
@@ -673,6 +918,41 @@ async function depositNative(signer, options) {
|
|
|
673
918
|
throw new core_1.AugustSDKError('UNKNOWN', `Deposit native failed: ${e instanceof Error ? e.message : 'Unknown error'}`, { cause: e, context: { wrapperAddress, receiver, amount } });
|
|
674
919
|
}
|
|
675
920
|
}
|
|
921
|
+
/**
|
|
922
|
+
* Redeem vault shares for an underlying asset via the RwaRedeemSubaccount.
|
|
923
|
+
* Caller must approve the **vault share token** (not the output asset) to
|
|
924
|
+
* the subaccount beforehand — it pulls shares via `transferFrom`.
|
|
925
|
+
*
|
|
926
|
+
* Pass `minOut` to enforce slippage protection (in `outputDecimals` units).
|
|
927
|
+
* The SDK does not currently compute `minOut` from a slippage percentage —
|
|
928
|
+
* the caller is responsible for choosing a safe lower bound.
|
|
929
|
+
*
|
|
930
|
+
* @throws AugustValidationError on invalid addresses or amount inputs.
|
|
931
|
+
* @throws AugustSDKError when the redeem submission or on-chain call fails.
|
|
932
|
+
*
|
|
933
|
+
* @example
|
|
934
|
+
* ```ts
|
|
935
|
+
* // 1. Approve the vault share token to the subaccount first.
|
|
936
|
+
* await augustSdk.evm.vaultApprove({
|
|
937
|
+
* target: subaccountAddress,
|
|
938
|
+
* wallet: walletAddress,
|
|
939
|
+
* amount: '10',
|
|
940
|
+
* wait: true,
|
|
941
|
+
* });
|
|
942
|
+
*
|
|
943
|
+
* // 2. Redeem 10 shares for USDC, requiring at least 9.5 USDC out.
|
|
944
|
+
* await augustSdk.evm.rwaRedeemAsset({
|
|
945
|
+
* target: subaccountAddress,
|
|
946
|
+
* wallet: walletAddress,
|
|
947
|
+
* asset: USDC_ADDRESS,
|
|
948
|
+
* amount: '10',
|
|
949
|
+
* minOut: '9.5',
|
|
950
|
+
* decimals: 18, // vault share decimals
|
|
951
|
+
* outputDecimals: 6, // USDC decimals
|
|
952
|
+
* wait: true,
|
|
953
|
+
* });
|
|
954
|
+
* ```
|
|
955
|
+
*/
|
|
676
956
|
async function rwaRedeemAsset(signer, options) {
|
|
677
957
|
const { target, wallet, asset, amount, minOut, decimals, outputDecimals, wait, } = options;
|
|
678
958
|
const goodTarget = (0, core_1.checkAddress)(target, console, 'contract');
|
|
@@ -712,10 +992,12 @@ async function rwaRedeemAsset(signer, options) {
|
|
|
712
992
|
throw new core_1.AugustSDKError('UNKNOWN', `RWA redeem failed: ${e instanceof Error ? e.message : 'Unknown error'}`, { cause: e, context: { target, asset, amount, minOut } });
|
|
713
993
|
}
|
|
714
994
|
}
|
|
995
|
+
/** @internal */
|
|
715
996
|
async function dispatchViaSwapRouter(args) {
|
|
716
997
|
const amountRaw = BigInt(args.normalizedAmt.raw);
|
|
717
998
|
const sharesReceiver = args.receiver ?? args.wallet;
|
|
718
999
|
if (args.isNativeToken) {
|
|
1000
|
+
// SwapRouter native path requires underlying === wrapped native.
|
|
719
1001
|
const wrappedNative = core_1.SWAP_ROUTER_WRAPPED_NATIVE[args.chainId];
|
|
720
1002
|
if (!wrappedNative ||
|
|
721
1003
|
args.underlyingAsset.toLowerCase() !== wrappedNative.toLowerCase()) {
|
|
@@ -748,6 +1030,10 @@ async function dispatchViaSwapRouter(args) {
|
|
|
748
1030
|
wait: args.wait,
|
|
749
1031
|
});
|
|
750
1032
|
}
|
|
1033
|
+
// Vault share decimals can diverge from the underlying asset decimals
|
|
1034
|
+
// (e.g. an 18-decimal share token over an 8-decimal WBTC underlying on
|
|
1035
|
+
// a multi-asset v2 vault). The swap quote must use the underlying's
|
|
1036
|
+
// on-chain decimals so Paraswap's /prices interprets the route correctly.
|
|
751
1037
|
const underlyingErc20 = (0, core_1.createContract)({
|
|
752
1038
|
address: args.underlyingAsset,
|
|
753
1039
|
provider: args.signer,
|
|
@@ -781,6 +1067,7 @@ async function dispatchViaSwapRouter(args) {
|
|
|
781
1067
|
wait: args.wait,
|
|
782
1068
|
});
|
|
783
1069
|
}
|
|
1070
|
+
/** @internal */
|
|
784
1071
|
function resolveSwapRouterOrThrow(chainId) {
|
|
785
1072
|
const router = (0, core_1.getSwapRouterAddress)(chainId);
|
|
786
1073
|
if (!router) {
|
|
@@ -788,6 +1075,7 @@ function resolveSwapRouterOrThrow(chainId) {
|
|
|
788
1075
|
}
|
|
789
1076
|
return router;
|
|
790
1077
|
}
|
|
1078
|
+
/** @internal */
|
|
791
1079
|
async function ensureAllowance(signer, token, owner, spender, amount) {
|
|
792
1080
|
const tokenContract = (0, core_1.createContract)({
|
|
793
1081
|
address: token,
|
|
@@ -800,6 +1088,7 @@ async function ensureAllowance(signer, token, owner, spender, amount) {
|
|
|
800
1088
|
const { hash } = await safeSendTx(() => tokenContract.connect(signer).approve(spender, amount), signer, true);
|
|
801
1089
|
core_1.Logger.log.info('swapRouter:approve:tx_hash', hash);
|
|
802
1090
|
}
|
|
1091
|
+
/** @internal */
|
|
803
1092
|
function ensureSwapsValid(swaps) {
|
|
804
1093
|
if (swaps.length === 0) {
|
|
805
1094
|
throw new core_1.AugustValidationError('INVALID_INPUT', 'swapAndDeposit: at least one swap leg is required');
|
|
@@ -811,6 +1100,7 @@ function ensureSwapsValid(swaps) {
|
|
|
811
1100
|
validateSwapParams(swaps[i], i);
|
|
812
1101
|
}
|
|
813
1102
|
}
|
|
1103
|
+
/** @internal */
|
|
814
1104
|
function validateSwapParams(swap, index) {
|
|
815
1105
|
const where = `swapAndDeposit: swaps[${index}]`;
|
|
816
1106
|
if (!(0, core_1.checkAddress)(swap.tokenIn, console, 'contract')) {
|
|
@@ -835,6 +1125,7 @@ function validateSwapParams(swap, index) {
|
|
|
835
1125
|
throw new core_1.AugustValidationError('INVALID_INPUT', `${where}.payload must be ABI-encoded calldata (got "${swap.payload.slice(0, 12)}…")`);
|
|
836
1126
|
}
|
|
837
1127
|
}
|
|
1128
|
+
/** @internal */
|
|
838
1129
|
function totalInputPerToken(swaps) {
|
|
839
1130
|
const totals = new Map();
|
|
840
1131
|
for (const swap of swaps) {
|
|
@@ -843,6 +1134,9 @@ function totalInputPerToken(swaps) {
|
|
|
843
1134
|
}
|
|
844
1135
|
return totals;
|
|
845
1136
|
}
|
|
1137
|
+
// Allowance owner must equal msg.sender (contract uses transferFrom(msg.sender, ...));
|
|
1138
|
+
// smart-account wallets need explicit handling outside the SDK.
|
|
1139
|
+
/** @internal */
|
|
846
1140
|
async function resolveSignerEOA(signer, callerContext) {
|
|
847
1141
|
const getAddress = signer.getAddress;
|
|
848
1142
|
if (typeof getAddress !== 'function') {
|
|
@@ -854,6 +1148,47 @@ async function resolveSignerEOA(signer, callerContext) {
|
|
|
854
1148
|
}
|
|
855
1149
|
return eoa;
|
|
856
1150
|
}
|
|
1151
|
+
/**
|
|
1152
|
+
* Swap one or more whitelisted ERC-20s into a vault's reference asset via
|
|
1153
|
+
* the on-chain SwapRouter, then deposit the proceeds into the vault.
|
|
1154
|
+
*
|
|
1155
|
+
* Approval is sent automatically when the caller's allowance on each
|
|
1156
|
+
* `swaps[i].tokenIn` against the SwapRouter is below `amountIn`.
|
|
1157
|
+
*
|
|
1158
|
+
* @param signer - ethers `Signer` or `Wallet` with the EOA that holds the input tokens.
|
|
1159
|
+
* @param options - {@link ISwapAndDepositOptions}.
|
|
1160
|
+
* @returns The transaction hash of the `swapAndDeposit` call.
|
|
1161
|
+
*
|
|
1162
|
+
* @throws {@link AugustValidationError} for unsupported chains, invalid
|
|
1163
|
+
* addresses, empty/oversized swap arrays.
|
|
1164
|
+
* @throws {@link AugustSDKError} on unrecoverable contract or RPC failure.
|
|
1165
|
+
*
|
|
1166
|
+
* @example
|
|
1167
|
+
* ```ts
|
|
1168
|
+
* const quote = await fetchSwapQuote({
|
|
1169
|
+
* chainId: 1,
|
|
1170
|
+
* srcToken: WBTC,
|
|
1171
|
+
* srcDecimals: 8,
|
|
1172
|
+
* destToken: USDC,
|
|
1173
|
+
* destDecimals: 6,
|
|
1174
|
+
* amount: 100_000_000n,
|
|
1175
|
+
* receiver: SWAP_ROUTER_ADDRESSES[1]!,
|
|
1176
|
+
* });
|
|
1177
|
+
* const hash = await swapAndDeposit(signer, {
|
|
1178
|
+
* chainId: 1,
|
|
1179
|
+
* vault: '0x8AcA0841993ef4C87244d519166e767f49362C21',
|
|
1180
|
+
* receiver: wallet,
|
|
1181
|
+
* swaps: [{
|
|
1182
|
+
* tokenIn: WBTC,
|
|
1183
|
+
* tokenOut: USDC,
|
|
1184
|
+
* amountIn: 100_000_000n,
|
|
1185
|
+
* minAmountOut: quote.minAmountOut,
|
|
1186
|
+
* router: quote.router,
|
|
1187
|
+
* payload: quote.payload,
|
|
1188
|
+
* }],
|
|
1189
|
+
* });
|
|
1190
|
+
* ```
|
|
1191
|
+
*/
|
|
857
1192
|
async function swapAndDeposit(signer, options) {
|
|
858
1193
|
const { chainId, vault, receiver, swaps, originCode, wait } = options;
|
|
859
1194
|
const goodVault = (0, core_1.checkAddress)(vault, console, 'contract');
|
|
@@ -878,6 +1213,18 @@ async function swapAndDeposit(signer, options) {
|
|
|
878
1213
|
core_1.Logger.log.info('swapAndDeposit:tx_hash', hash);
|
|
879
1214
|
return hash;
|
|
880
1215
|
}
|
|
1216
|
+
/**
|
|
1217
|
+
* Deposit a vault's reference asset directly through the SwapRouter — no
|
|
1218
|
+
* swap. Useful when the caller already holds the reference asset but wants
|
|
1219
|
+
* the origin/referral fee accounting that only the SwapRouter path provides.
|
|
1220
|
+
*
|
|
1221
|
+
* @param signer - ethers `Signer` or `Wallet`.
|
|
1222
|
+
* @param options - {@link ISwapRouterDirectDepositOptions}.
|
|
1223
|
+
* @returns The transaction hash of the `deposit` call.
|
|
1224
|
+
*
|
|
1225
|
+
* @throws {@link AugustValidationError} for unsupported chains, invalid
|
|
1226
|
+
* addresses, or zero amount.
|
|
1227
|
+
*/
|
|
881
1228
|
async function depositViaSwapRouter(signer, options) {
|
|
882
1229
|
const { chainId, vault, receiver, asset, amount, originCode, wait } = options;
|
|
883
1230
|
const goodVault = (0, core_1.checkAddress)(vault, console, 'contract');
|
|
@@ -903,6 +1250,21 @@ async function depositViaSwapRouter(signer, options) {
|
|
|
903
1250
|
core_1.Logger.log.info('depositViaSwapRouter:tx_hash', hash);
|
|
904
1251
|
return hash;
|
|
905
1252
|
}
|
|
1253
|
+
/**
|
|
1254
|
+
* Deposit native ETH (or chain-native equivalent) into a vault via the
|
|
1255
|
+
* SwapRouter. The router wraps `amount` to the chain's wrapped-native token
|
|
1256
|
+
* before depositing — only valid when the vault's reference asset equals
|
|
1257
|
+
* the wrapped-native token.
|
|
1258
|
+
*
|
|
1259
|
+
* No ERC-20 approval is needed; `amount` travels as `msg.value`.
|
|
1260
|
+
*
|
|
1261
|
+
* @param signer - ethers `Signer` or `Wallet`.
|
|
1262
|
+
* @param options - {@link ISwapRouterNativeDepositOptions}.
|
|
1263
|
+
* @returns The transaction hash of the `depositNativeToken` call.
|
|
1264
|
+
*
|
|
1265
|
+
* @throws {@link AugustValidationError} for unsupported chains, invalid
|
|
1266
|
+
* addresses, or zero amount.
|
|
1267
|
+
*/
|
|
906
1268
|
async function depositNativeViaSwapRouter(signer, options) {
|
|
907
1269
|
const { chainId, vault, receiver, amount, originCode, wait } = options;
|
|
908
1270
|
const goodVault = (0, core_1.checkAddress)(vault, console, 'contract');
|