@augustdigital/sdk 6.0.1 → 7.0.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/adapters/evm/getters.d.ts +1 -1
- package/lib/adapters/evm/getters.js +14 -19
- package/lib/adapters/evm/index.d.ts +8 -1
- package/lib/adapters/evm/index.js +24 -0
- package/lib/adapters/solana/index.d.ts +4 -4
- package/lib/adapters/solana/utils.d.ts +5 -4
- package/lib/adapters/solana/utils.js +82 -45
- package/lib/adapters/solana/vault.actions.d.ts +2 -2
- package/lib/adapters/solana/vault.actions.js +112 -74
- package/lib/adapters/stellar/actions.js +3 -2
- package/lib/adapters/stellar/constants.d.ts +2 -0
- package/lib/adapters/stellar/constants.js +3 -1
- package/lib/adapters/stellar/getters.js +2 -2
- package/lib/adapters/stellar/soroban.js +19 -8
- package/lib/adapters/stellar/submit.js +16 -6
- package/lib/adapters/stellar/utils.d.ts +2 -1
- package/lib/adapters/stellar/utils.js +7 -15
- package/lib/adapters/sui/utils.d.ts +1 -1
- package/lib/adapters/sui/utils.js +3 -7
- package/lib/core/analytics/chain-name.d.ts +1 -0
- package/lib/core/analytics/chain-name.js +26 -0
- package/lib/core/analytics/env.d.ts +4 -0
- package/lib/core/analytics/env.js +33 -0
- package/lib/core/analytics/index.d.ts +6 -2
- package/lib/core/analytics/index.js +16 -1
- package/lib/core/analytics/instrumentation.js +56 -48
- package/lib/core/analytics/method-taxonomy.d.ts +3 -0
- package/lib/core/analytics/method-taxonomy.js +82 -0
- package/lib/core/analytics/metrics.js +18 -42
- package/lib/core/analytics/sanitize.d.ts +1 -0
- package/lib/core/analytics/sanitize.js +34 -0
- package/lib/core/analytics/sentry-runtime.d.ts +4 -0
- package/lib/core/analytics/sentry-runtime.js +78 -0
- package/lib/core/analytics/sentry.d.ts +7 -1
- package/lib/core/analytics/sentry.js +107 -51
- package/lib/core/analytics/types.d.ts +2 -0
- package/lib/core/analytics/version.d.ts +1 -1
- package/lib/core/analytics/version.js +1 -1
- package/lib/core/base.class.d.ts +2 -1
- package/lib/core/base.class.js +5 -1
- package/lib/core/cache.d.ts +4 -0
- package/lib/core/cache.js +25 -0
- package/lib/core/fetcher.d.ts +4 -4
- package/lib/core/fetcher.js +49 -60
- package/lib/core/helpers/chain-address.d.ts +3 -0
- package/lib/core/helpers/chain-address.js +36 -0
- package/lib/core/helpers/explorer-link.d.ts +2 -0
- package/lib/core/helpers/explorer-link.js +11 -0
- package/lib/core/helpers/vault-version.d.ts +4 -0
- package/lib/core/helpers/vault-version.js +59 -0
- package/lib/core/helpers/vaults.d.ts +3 -4
- package/lib/core/helpers/vaults.js +12 -62
- package/lib/core/helpers/web3.d.ts +6 -6
- package/lib/core/helpers/web3.js +142 -79
- package/lib/core/logger/slack.js +2 -2
- package/lib/core/vault-metadata.d.ts +6 -0
- package/lib/core/vault-metadata.js +36 -0
- package/lib/evm/methods/crossChainVault.js +72 -16
- package/lib/evm/types/crossChain.d.ts +4 -0
- package/lib/evm/types/crossChain.js +6 -0
- package/lib/modules/vaults/fetcher.d.ts +1 -6
- package/lib/modules/vaults/fetcher.js +27 -36
- package/lib/modules/vaults/getters.d.ts +1 -1
- package/lib/modules/vaults/getters.js +3 -2
- package/lib/modules/vaults/read.actions.d.ts +27 -0
- package/lib/modules/vaults/read.actions.js +220 -0
- package/lib/modules/vaults/utils/date-utils.js +1 -2
- package/lib/modules/vaults/utils.js +57 -36
- package/lib/modules/vaults/write.actions.d.ts +35 -2
- package/lib/modules/vaults/write.actions.js +254 -94
- package/package.json +3 -1
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.safeBigInt = safeBigInt;
|
|
4
|
+
exports.resolveDepositTokenDecimals = resolveDepositTokenDecimals;
|
|
5
|
+
exports.resolveSpender = resolveSpender;
|
|
6
|
+
exports.validateAmountPrecision = validateAmountPrecision;
|
|
7
|
+
exports.isNonceParsing = isNonceParsing;
|
|
8
|
+
exports.safeWaitForTx = safeWaitForTx;
|
|
9
|
+
exports.safeSendTx = safeSendTx;
|
|
10
|
+
exports.tryRecoverTxHash = tryRecoverTxHash;
|
|
3
11
|
exports.vaultApprove = vaultApprove;
|
|
12
|
+
exports.approve = approve;
|
|
4
13
|
exports.vaultDeposit = vaultDeposit;
|
|
5
14
|
exports.vaultRequestRedeem = vaultRequestRedeem;
|
|
6
15
|
exports.vaultRedeem = vaultRedeem;
|
|
@@ -9,22 +18,57 @@ exports.rwaRedeemAsset = rwaRedeemAsset;
|
|
|
9
18
|
const ethers_1 = require("ethers");
|
|
10
19
|
const abis_1 = require("../../abis");
|
|
11
20
|
const core_1 = require("../../core");
|
|
12
|
-
const read_actions_1 = require("./read.actions");
|
|
13
21
|
const adapter_helpers_1 = require("./adapter.helpers");
|
|
14
22
|
const utils_1 = require("./utils");
|
|
15
|
-
function safeBigInt(value) {
|
|
23
|
+
function safeBigInt(value, context = 'safeBigInt') {
|
|
16
24
|
if (value === null || value === undefined)
|
|
17
25
|
return 0n;
|
|
18
26
|
const s = String(value);
|
|
19
|
-
if (s === '
|
|
27
|
+
if (s === '' || s === '0x') {
|
|
28
|
+
if (s === '0x') {
|
|
29
|
+
core_1.Logger.log.warn(context, 'RPC returned bare "0x"; treating as 0', {
|
|
30
|
+
raw: s,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
20
33
|
return 0n;
|
|
34
|
+
}
|
|
21
35
|
try {
|
|
22
36
|
return BigInt(s);
|
|
23
37
|
}
|
|
24
|
-
catch {
|
|
38
|
+
catch (err) {
|
|
39
|
+
core_1.Logger.log.warn(context, 'Could not parse RPC value as BigInt; treating as 0', { raw: s, error: String(err) });
|
|
25
40
|
return 0n;
|
|
26
41
|
}
|
|
27
42
|
}
|
|
43
|
+
async function resolveDepositTokenDecimals(args) {
|
|
44
|
+
const { actualDepositAsset, underlyingAsset, isNativeToken, isMultiAssetVault, vaultDecimals, readErc20Decimals, } = args;
|
|
45
|
+
if (isNativeToken)
|
|
46
|
+
return 18;
|
|
47
|
+
const isUnderlying = actualDepositAsset.toLowerCase() === underlyingAsset.toLowerCase();
|
|
48
|
+
if (isUnderlying && !isMultiAssetVault)
|
|
49
|
+
return vaultDecimals;
|
|
50
|
+
return readErc20Decimals(actualDepositAsset);
|
|
51
|
+
}
|
|
52
|
+
function resolveSpender(args) {
|
|
53
|
+
if (args.isMultiAssetVault)
|
|
54
|
+
return args.target;
|
|
55
|
+
if (args.isAdapterDeposit && args.adapterWrapperAddress)
|
|
56
|
+
return args.adapterWrapperAddress;
|
|
57
|
+
return args.target;
|
|
58
|
+
}
|
|
59
|
+
function validateAmountPrecision(amount) {
|
|
60
|
+
if (typeof amount === 'string' || typeof amount === 'bigint')
|
|
61
|
+
return;
|
|
62
|
+
if (!Number.isFinite(amount)) {
|
|
63
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', `amount must be finite, got ${amount}`);
|
|
64
|
+
}
|
|
65
|
+
if (amount < 0) {
|
|
66
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', `amount must be non-negative, got ${amount}`);
|
|
67
|
+
}
|
|
68
|
+
if (Number.isInteger(amount) && !Number.isSafeInteger(amount)) {
|
|
69
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', `amount ${amount} exceeds Number.MAX_SAFE_INTEGER; pass a string or bigint to preserve precision`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
28
72
|
const SAFE_WAIT_TIMEOUT_MS = 120000;
|
|
29
73
|
function isNonceParsing(error) {
|
|
30
74
|
const code = error?.code;
|
|
@@ -100,64 +144,142 @@ async function tryRecoverTxHash(error, signer, wait) {
|
|
|
100
144
|
}
|
|
101
145
|
return txHash;
|
|
102
146
|
}
|
|
103
|
-
async function
|
|
104
|
-
const { wallet, target, wait, amount } = options;
|
|
147
|
+
async function approveCore(signer, options) {
|
|
148
|
+
const { wallet, target, wait, amount, depositAsset } = options;
|
|
105
149
|
const [goodWallet, goodPool] = [
|
|
106
150
|
(0, core_1.checkAddress)(wallet, console, 'wallet'),
|
|
107
151
|
(0, core_1.checkAddress)(target, console),
|
|
108
152
|
];
|
|
109
|
-
if (!goodWallet || !goodPool
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (
|
|
113
|
-
|
|
114
|
-
|
|
153
|
+
if (!goodWallet || !goodPool) {
|
|
154
|
+
throw new core_1.AugustValidationError('INVALID_ADDRESS', `vaultApprove: invalid ${!goodWallet ? 'wallet' : 'target'} address`);
|
|
155
|
+
}
|
|
156
|
+
if (amount === undefined || amount === null) {
|
|
157
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', 'vaultApprove: amount is required');
|
|
158
|
+
}
|
|
159
|
+
validateAmountPrecision(amount);
|
|
160
|
+
try {
|
|
161
|
+
const tokenizedVault = (await (0, core_1.fetchTokenizedVault)(target))?.[0];
|
|
162
|
+
const vaultVersion = (0, core_1.getVaultVersionV2)(tokenizedVault);
|
|
163
|
+
const adapterConfig = (0, core_1.getVaultAdapterConfig)(target);
|
|
164
|
+
const isMultiAssetVault = vaultVersion === 'evm-2';
|
|
165
|
+
const poolContract = isMultiAssetVault
|
|
166
|
+
? (0, core_1.createContract)({
|
|
167
|
+
address: target,
|
|
168
|
+
provider: signer,
|
|
169
|
+
abi: abis_1.ABI_TOKENIZED_VAULT_V2,
|
|
170
|
+
})
|
|
171
|
+
: (0, core_1.createContract)({
|
|
115
172
|
address: target,
|
|
116
173
|
provider: signer,
|
|
117
174
|
abi: abis_1.ABI_LENDING_POOLS,
|
|
118
175
|
});
|
|
119
|
-
|
|
176
|
+
let underlyingAsset;
|
|
177
|
+
let vaultDecimals;
|
|
178
|
+
if (isMultiAssetVault) {
|
|
179
|
+
const [asset, receiptTokenAddr] = await Promise.all([
|
|
120
180
|
poolContract.asset(),
|
|
121
|
-
poolContract.
|
|
181
|
+
poolContract.lpTokenAddress(),
|
|
122
182
|
]);
|
|
123
|
-
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
address: asset,
|
|
127
|
-
abi: abis_1.ABI_ERC20,
|
|
183
|
+
underlyingAsset = asset;
|
|
184
|
+
const receiptContract = (0, core_1.createContract)({
|
|
185
|
+
address: receiptTokenAddr,
|
|
128
186
|
provider: signer,
|
|
187
|
+
abi: abis_1.ABI_ERC20,
|
|
129
188
|
});
|
|
130
|
-
|
|
131
|
-
.connect(signer)
|
|
132
|
-
.approve(target, normalizedAmt.raw), signer, wait);
|
|
133
|
-
core_1.Logger.log.info('approve:tx_hash', approvalHash);
|
|
134
|
-
return approvalHash;
|
|
189
|
+
vaultDecimals = Number(await receiptContract.decimals());
|
|
135
190
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
191
|
+
else {
|
|
192
|
+
const [asset, rawDecimals] = await Promise.all([
|
|
193
|
+
poolContract.asset(),
|
|
194
|
+
poolContract.decimals(),
|
|
195
|
+
]);
|
|
196
|
+
underlyingAsset = asset;
|
|
197
|
+
vaultDecimals = Number(rawDecimals);
|
|
139
198
|
}
|
|
199
|
+
const actualDepositAsset = (depositAsset || underlyingAsset);
|
|
200
|
+
const isNativeToken = actualDepositAsset === ethers_1.ZeroAddress ||
|
|
201
|
+
actualDepositAsset === '0x0000000000000000000000000000000000000000';
|
|
202
|
+
if (isNativeToken)
|
|
203
|
+
return { kind: 'native' };
|
|
204
|
+
const isAdapterDeposit = actualDepositAsset.toLowerCase() !== underlyingAsset.toLowerCase();
|
|
205
|
+
const spenderAddress = resolveSpender({
|
|
206
|
+
target,
|
|
207
|
+
isMultiAssetVault,
|
|
208
|
+
isAdapterDeposit,
|
|
209
|
+
adapterWrapperAddress: adapterConfig?.wrapperAddress,
|
|
210
|
+
});
|
|
211
|
+
const depositTokenDecimals = await resolveDepositTokenDecimals({
|
|
212
|
+
actualDepositAsset,
|
|
213
|
+
underlyingAsset,
|
|
214
|
+
isNativeToken: false,
|
|
215
|
+
isMultiAssetVault,
|
|
216
|
+
vaultDecimals,
|
|
217
|
+
readErc20Decimals: async (addr) => {
|
|
218
|
+
const erc20 = (0, core_1.createContract)({
|
|
219
|
+
address: addr,
|
|
220
|
+
provider: signer,
|
|
221
|
+
abi: abis_1.ABI_ERC20,
|
|
222
|
+
});
|
|
223
|
+
return Number(await erc20.decimals());
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
const normalizedAmt = (0, core_1.toNormalizedBn)(amount, depositTokenDecimals);
|
|
227
|
+
const needed = BigInt(normalizedAmt.raw);
|
|
228
|
+
const tokenContract = (0, core_1.createContract)({
|
|
229
|
+
address: actualDepositAsset,
|
|
230
|
+
abi: abis_1.ABI_ERC20,
|
|
231
|
+
provider: signer,
|
|
232
|
+
});
|
|
233
|
+
const currentAllowance = await tokenContract.allowance(wallet, spenderAddress);
|
|
234
|
+
const existing = safeBigInt(currentAllowance, 'vaultApprove:allowance');
|
|
235
|
+
if (existing >= needed) {
|
|
236
|
+
core_1.Logger.log.info('approve:allowance-sufficient', {
|
|
237
|
+
target,
|
|
238
|
+
spender: spenderAddress,
|
|
239
|
+
amount,
|
|
240
|
+
});
|
|
241
|
+
return { kind: 'sufficient', existing };
|
|
242
|
+
}
|
|
243
|
+
const { hash: approvalHash } = await safeSendTx(() => tokenContract
|
|
244
|
+
.connect(signer)
|
|
245
|
+
.approve(spenderAddress, normalizedAmt.raw), signer, wait);
|
|
246
|
+
core_1.Logger.log.info('approve:tx_hash', approvalHash);
|
|
247
|
+
return { kind: 'sent', hash: approvalHash };
|
|
140
248
|
}
|
|
141
|
-
|
|
142
|
-
|
|
249
|
+
catch (e) {
|
|
250
|
+
if (e instanceof core_1.AugustSDKError)
|
|
251
|
+
throw e;
|
|
252
|
+
core_1.Logger.log.error('vaultApprove', e, { target, amount });
|
|
253
|
+
throw new core_1.AugustSDKError('UNKNOWN', `Approval failed: ${e instanceof Error ? e.message : 'Unknown error'}`, { cause: e, context: { target, amount } });
|
|
143
254
|
}
|
|
144
255
|
}
|
|
256
|
+
async function vaultApprove(signer, options) {
|
|
257
|
+
const result = await approveCore(signer, options);
|
|
258
|
+
return result.kind === 'sent' ? result.hash : undefined;
|
|
259
|
+
}
|
|
260
|
+
async function approve(signer, options) {
|
|
261
|
+
return approveCore(signer, options);
|
|
262
|
+
}
|
|
145
263
|
async function vaultDeposit(signer, options) {
|
|
146
264
|
const { wallet, target, wait, amount, depositAsset, chainId, poolName } = options;
|
|
147
265
|
const [goodWallet, goodPool] = [
|
|
148
266
|
(0, core_1.checkAddress)(wallet, console, 'wallet'),
|
|
149
267
|
(0, core_1.checkAddress)(target, console),
|
|
150
268
|
];
|
|
151
|
-
if (!goodWallet || !goodPool)
|
|
152
|
-
|
|
269
|
+
if (!goodWallet || !goodPool) {
|
|
270
|
+
throw new core_1.AugustValidationError('INVALID_ADDRESS', `vaultDeposit: invalid ${!goodWallet ? 'wallet' : 'target'} address`);
|
|
271
|
+
}
|
|
272
|
+
if (amount === undefined || amount === null) {
|
|
273
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', 'vaultDeposit: amount is required');
|
|
274
|
+
}
|
|
275
|
+
validateAmountPrecision(amount);
|
|
153
276
|
try {
|
|
154
277
|
const tokenizedVault = (await (0, core_1.fetchTokenizedVault)(target))?.[0];
|
|
155
278
|
const vaultVersion = (0, core_1.getVaultVersionV2)(tokenizedVault);
|
|
156
279
|
const adapterConfig = (0, core_1.getVaultAdapterConfig)(target);
|
|
157
280
|
let poolContract;
|
|
158
281
|
let underlyingAsset;
|
|
159
|
-
let
|
|
160
|
-
let depositTokenDecimals;
|
|
282
|
+
let vaultDecimals;
|
|
161
283
|
if (vaultVersion === 'evm-2') {
|
|
162
284
|
poolContract = (0, core_1.createContract)({
|
|
163
285
|
address: target,
|
|
@@ -176,7 +298,7 @@ async function vaultDeposit(signer, options) {
|
|
|
176
298
|
provider: signer,
|
|
177
299
|
abi: abis_1.ABI_ERC20,
|
|
178
300
|
});
|
|
179
|
-
|
|
301
|
+
vaultDecimals = Number(await receiptContract.decimals());
|
|
180
302
|
}
|
|
181
303
|
else {
|
|
182
304
|
poolContract = (0, core_1.createContract)({
|
|
@@ -188,7 +310,7 @@ async function vaultDeposit(signer, options) {
|
|
|
188
310
|
poolContract.asset(),
|
|
189
311
|
poolContract.decimals(),
|
|
190
312
|
]);
|
|
191
|
-
|
|
313
|
+
vaultDecimals = Number(rawDecimals);
|
|
192
314
|
underlyingAsset = fetchedUnderlyingAsset;
|
|
193
315
|
}
|
|
194
316
|
const actualDepositAsset = depositAsset || underlyingAsset;
|
|
@@ -196,39 +318,43 @@ async function vaultDeposit(signer, options) {
|
|
|
196
318
|
actualDepositAsset === '0x0000000000000000000000000000000000000000';
|
|
197
319
|
const isAdapterDeposit = actualDepositAsset.toLowerCase() !== underlyingAsset.toLowerCase();
|
|
198
320
|
const isMultiAssetVault = vaultVersion === 'evm-2';
|
|
199
|
-
if (isAdapterDeposit && !
|
|
200
|
-
|
|
201
|
-
address: actualDepositAsset,
|
|
202
|
-
provider: signer,
|
|
203
|
-
abi: abis_1.ABI_ERC20,
|
|
204
|
-
});
|
|
205
|
-
depositTokenDecimals = Number(await depositTokenContract.decimals());
|
|
321
|
+
if (isAdapterDeposit && !isMultiAssetVault && !adapterConfig) {
|
|
322
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', `vaultDeposit: depositAsset ${actualDepositAsset} differs from vault underlying ${underlyingAsset} but no adapter is configured for vault ${target}`);
|
|
206
323
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
324
|
+
const depositTokenDecimals = await resolveDepositTokenDecimals({
|
|
325
|
+
actualDepositAsset,
|
|
326
|
+
underlyingAsset,
|
|
327
|
+
isNativeToken,
|
|
328
|
+
isMultiAssetVault,
|
|
329
|
+
vaultDecimals,
|
|
330
|
+
readErc20Decimals: async (addr) => {
|
|
331
|
+
const erc20 = (0, core_1.createContract)({
|
|
332
|
+
address: addr,
|
|
333
|
+
provider: signer,
|
|
334
|
+
abi: abis_1.ABI_ERC20,
|
|
335
|
+
});
|
|
336
|
+
return Number(await erc20.decimals());
|
|
337
|
+
},
|
|
338
|
+
});
|
|
339
|
+
const normalizedAmt = (0, core_1.toNormalizedBn)(amount, depositTokenDecimals);
|
|
211
340
|
if (!isNativeToken) {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
219
|
-
else {
|
|
220
|
-
spenderAddress = target;
|
|
221
|
-
}
|
|
341
|
+
const spenderAddress = resolveSpender({
|
|
342
|
+
target,
|
|
343
|
+
isMultiAssetVault,
|
|
344
|
+
isAdapterDeposit,
|
|
345
|
+
adapterWrapperAddress: adapterConfig?.wrapperAddress,
|
|
346
|
+
});
|
|
222
347
|
const depositTokenContract = (0, core_1.createContract)({
|
|
223
348
|
address: actualDepositAsset,
|
|
224
349
|
provider: signer,
|
|
225
350
|
abi: abis_1.ABI_ERC20,
|
|
226
351
|
});
|
|
227
352
|
const currentAllowance = await depositTokenContract.allowance(wallet, spenderAddress);
|
|
228
|
-
if (safeBigInt(currentAllowance) <
|
|
353
|
+
if (safeBigInt(currentAllowance, 'vaultDeposit:allowance') <
|
|
354
|
+
BigInt(normalizedAmt.raw)) {
|
|
229
355
|
const { hash: approveHash } = await safeSendTx(() => depositTokenContract
|
|
230
356
|
.connect(signer)
|
|
231
|
-
.approve(spenderAddress, normalizedAmt.raw), signer,
|
|
357
|
+
.approve(spenderAddress, normalizedAmt.raw), signer, true);
|
|
232
358
|
core_1.Logger.log.info('approve:tx_hash', approveHash);
|
|
233
359
|
}
|
|
234
360
|
}
|
|
@@ -254,7 +380,7 @@ async function vaultDeposit(signer, options) {
|
|
|
254
380
|
srcToken: actualDepositAsset,
|
|
255
381
|
srcDecimals: depositTokenDecimals,
|
|
256
382
|
destToken: underlyingAsset,
|
|
257
|
-
destDecimals:
|
|
383
|
+
destDecimals: vaultDecimals,
|
|
258
384
|
amount: normalizedAmt.raw.toString(),
|
|
259
385
|
network: chainId?.toString() || '1',
|
|
260
386
|
adapterConfig,
|
|
@@ -308,8 +434,10 @@ async function vaultDeposit(signer, options) {
|
|
|
308
434
|
core_1.Logger.log.warn('deposit:nonce-fallback', { hash: recovered });
|
|
309
435
|
return recovered;
|
|
310
436
|
}
|
|
437
|
+
if (e instanceof core_1.AugustSDKError)
|
|
438
|
+
throw e;
|
|
311
439
|
core_1.Logger.log.error('deposit', e, { target, amount, depositAsset });
|
|
312
|
-
throw new
|
|
440
|
+
throw new core_1.AugustSDKError('UNKNOWN', `Deposit failed: ${e instanceof Error ? e.message : 'Unknown error'}`, { cause: e, context: { target, amount, depositAsset } });
|
|
313
441
|
}
|
|
314
442
|
}
|
|
315
443
|
async function vaultRequestRedeem(signer, options) {
|
|
@@ -318,8 +446,13 @@ async function vaultRequestRedeem(signer, options) {
|
|
|
318
446
|
(0, core_1.checkAddress)(wallet, console, 'wallet'),
|
|
319
447
|
(0, core_1.checkAddress)(target, console),
|
|
320
448
|
];
|
|
321
|
-
if (!goodWallet || !goodPool)
|
|
322
|
-
|
|
449
|
+
if (!goodWallet || !goodPool) {
|
|
450
|
+
throw new core_1.AugustValidationError('INVALID_ADDRESS', `vaultRequestRedeem: invalid ${!goodWallet ? 'wallet' : 'target'} address`);
|
|
451
|
+
}
|
|
452
|
+
if (amount === undefined || amount === null) {
|
|
453
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', 'vaultRequestRedeem: amount is required');
|
|
454
|
+
}
|
|
455
|
+
validateAmountPrecision(amount);
|
|
323
456
|
try {
|
|
324
457
|
const tokenizedVault = (await (0, core_1.fetchTokenizedVault)(target))?.[0];
|
|
325
458
|
const vaultVersion = (0, core_1.getVaultVersionV2)(tokenizedVault);
|
|
@@ -340,13 +473,10 @@ async function vaultRequestRedeem(signer, options) {
|
|
|
340
473
|
decimals = Number(await receiptContract.decimals());
|
|
341
474
|
const normalizedAmt = (0, core_1.toNormalizedBn)(amount, decimals);
|
|
342
475
|
const allowance = await receiptContract.allowance(wallet, target);
|
|
343
|
-
if (safeBigInt(allowance) <
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
if (wait)
|
|
348
|
-
await safeWaitForTx(approveTx);
|
|
349
|
-
core_1.Logger.log.info('approve:receipt_token:tx_hash', approveTx?.hash);
|
|
476
|
+
if (safeBigInt(allowance, 'vaultRequestRedeem:allowance') <
|
|
477
|
+
BigInt(normalizedAmt.raw)) {
|
|
478
|
+
const { hash: approveHash } = await safeSendTx(() => receiptContract.connect(signer).approve(target, normalizedAmt.raw), signer, true);
|
|
479
|
+
core_1.Logger.log.info('approve:receipt_token:tx_hash', approveHash);
|
|
350
480
|
}
|
|
351
481
|
poolContract = vaultContract;
|
|
352
482
|
}
|
|
@@ -399,8 +529,10 @@ async function vaultRequestRedeem(signer, options) {
|
|
|
399
529
|
core_1.Logger.log.warn('requestRedeem:nonce-fallback', { hash: recovered });
|
|
400
530
|
return recovered;
|
|
401
531
|
}
|
|
532
|
+
if (e instanceof core_1.AugustSDKError)
|
|
533
|
+
throw e;
|
|
402
534
|
core_1.Logger.log.error('requestRedeem', e, { target, amount });
|
|
403
|
-
throw new
|
|
535
|
+
throw new core_1.AugustSDKError('UNKNOWN', `Request redeem failed: ${e instanceof Error ? e.message : 'Unknown error'}`, { cause: e, context: { target, amount } });
|
|
404
536
|
}
|
|
405
537
|
}
|
|
406
538
|
async function vaultRedeem(signer, options) {
|
|
@@ -409,32 +541,46 @@ async function vaultRedeem(signer, options) {
|
|
|
409
541
|
(0, core_1.checkAddress)(wallet, console, 'wallet'),
|
|
410
542
|
(0, core_1.checkAddress)(target, console),
|
|
411
543
|
];
|
|
412
|
-
if (!
|
|
413
|
-
|
|
544
|
+
if (!goodWallet || !goodPool) {
|
|
545
|
+
throw new core_1.AugustValidationError('INVALID_ADDRESS', `vaultRedeem: invalid ${!goodWallet ? 'wallet' : 'target'} address`);
|
|
546
|
+
}
|
|
547
|
+
if (!year || !month || !day || !receiverIndex) {
|
|
548
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', 'vaultRedeem: year, month, day, and receiverIndex are required');
|
|
549
|
+
}
|
|
414
550
|
try {
|
|
415
551
|
const poolContract = (0, core_1.createContract)({
|
|
416
552
|
address: target,
|
|
417
553
|
provider: signer,
|
|
418
554
|
abi: abis_1.ABI_LENDING_POOLS,
|
|
419
555
|
});
|
|
420
|
-
const
|
|
556
|
+
const { hash: redeemHash } = await safeSendTx(() => poolContract
|
|
421
557
|
.connect(signer)
|
|
422
|
-
.redeem(year, month, day, receiverIndex, wallet);
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
core_1.Logger.log.info('redeem:tx_hash', redeemTx?.hash);
|
|
426
|
-
return redeemTx?.hash;
|
|
558
|
+
.redeem(year, month, day, receiverIndex, wallet), signer, wait);
|
|
559
|
+
core_1.Logger.log.info('redeem:tx_hash', redeemHash);
|
|
560
|
+
return redeemHash;
|
|
427
561
|
}
|
|
428
562
|
catch (e) {
|
|
563
|
+
const recovered = await tryRecoverTxHash(e, signer, wait);
|
|
564
|
+
if (recovered) {
|
|
565
|
+
core_1.Logger.log.warn('redeem:nonce-fallback', { hash: recovered });
|
|
566
|
+
return recovered;
|
|
567
|
+
}
|
|
568
|
+
if (e instanceof core_1.AugustSDKError)
|
|
569
|
+
throw e;
|
|
429
570
|
core_1.Logger.log.error('redeem', e, { target, year, month, day, receiverIndex });
|
|
430
|
-
throw new
|
|
571
|
+
throw new core_1.AugustSDKError('UNKNOWN', `Redeem failed: ${e instanceof Error ? e.message : 'Unknown error'}`, { cause: e, context: { target, year, month, day, receiverIndex } });
|
|
431
572
|
}
|
|
432
573
|
}
|
|
433
574
|
async function depositNative(signer, options) {
|
|
434
575
|
const { wrapperAddress, receiver, amount, wait } = options;
|
|
435
576
|
const goodWrapper = (0, core_1.checkAddress)(wrapperAddress, console, 'contract');
|
|
436
|
-
if (!goodWrapper
|
|
437
|
-
|
|
577
|
+
if (!goodWrapper) {
|
|
578
|
+
throw new core_1.AugustValidationError('INVALID_ADDRESS', 'depositNative: invalid wrapper address');
|
|
579
|
+
}
|
|
580
|
+
if (amount === undefined || amount === null) {
|
|
581
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', 'depositNative: amount is required');
|
|
582
|
+
}
|
|
583
|
+
validateAmountPrecision(amount);
|
|
438
584
|
try {
|
|
439
585
|
const wrapperContract = (0, core_1.createContract)({
|
|
440
586
|
address: wrapperAddress,
|
|
@@ -450,8 +596,9 @@ async function depositNative(signer, options) {
|
|
|
450
596
|
const connectedContract = wrapperContract.connect(signer);
|
|
451
597
|
if (receiver) {
|
|
452
598
|
const goodReceiver = (0, core_1.checkAddress)(receiver, console, 'wallet');
|
|
453
|
-
if (!goodReceiver)
|
|
454
|
-
|
|
599
|
+
if (!goodReceiver) {
|
|
600
|
+
throw new core_1.AugustValidationError('INVALID_ADDRESS', 'depositNative: invalid receiver address');
|
|
601
|
+
}
|
|
455
602
|
const depositNativeWithReceiver = connectedContract.getFunction('depositNative(address)');
|
|
456
603
|
depositTx = await depositNativeWithReceiver(receiver, {
|
|
457
604
|
value: amountBigInt,
|
|
@@ -474,8 +621,10 @@ async function depositNative(signer, options) {
|
|
|
474
621
|
core_1.Logger.log.warn('depositNative:nonce-fallback', { hash: recovered });
|
|
475
622
|
return recovered;
|
|
476
623
|
}
|
|
624
|
+
if (e instanceof core_1.AugustSDKError)
|
|
625
|
+
throw e;
|
|
477
626
|
core_1.Logger.log.error('depositNative', e, { wrapperAddress, receiver, amount });
|
|
478
|
-
throw new
|
|
627
|
+
throw new core_1.AugustSDKError('UNKNOWN', `Deposit native failed: ${e instanceof Error ? e.message : 'Unknown error'}`, { cause: e, context: { wrapperAddress, receiver, amount } });
|
|
479
628
|
}
|
|
480
629
|
}
|
|
481
630
|
async function rwaRedeemAsset(signer, options) {
|
|
@@ -483,27 +632,38 @@ async function rwaRedeemAsset(signer, options) {
|
|
|
483
632
|
const goodTarget = (0, core_1.checkAddress)(target, console, 'contract');
|
|
484
633
|
const goodAsset = (0, core_1.checkAddress)(asset, console, 'contract');
|
|
485
634
|
const goodWallet = (0, core_1.checkAddress)(wallet, console, 'wallet');
|
|
486
|
-
if (!goodTarget || !goodAsset || !goodWallet)
|
|
487
|
-
|
|
635
|
+
if (!goodTarget || !goodAsset || !goodWallet) {
|
|
636
|
+
throw new core_1.AugustValidationError('INVALID_ADDRESS', `rwaRedeemAsset: invalid ${!goodTarget ? 'target' : !goodAsset ? 'asset' : 'wallet'} address`);
|
|
637
|
+
}
|
|
638
|
+
validateAmountPrecision(amount);
|
|
639
|
+
validateAmountPrecision(minOut);
|
|
488
640
|
try {
|
|
489
641
|
const subaccountContract = (0, core_1.createContract)({
|
|
490
642
|
address: target,
|
|
491
643
|
provider: signer,
|
|
492
644
|
abi: abis_1.RWA_REDEEM_SUBACCOUNT,
|
|
493
645
|
});
|
|
494
|
-
if (!subaccountContract)
|
|
495
|
-
|
|
646
|
+
if (!subaccountContract) {
|
|
647
|
+
throw new Error(`rwaRedeemAsset: failed to instantiate subaccount contract at ${target}`);
|
|
648
|
+
}
|
|
496
649
|
const normalizedAmt = (0, core_1.toNormalizedBn)(amount, decimals);
|
|
497
650
|
const normalizedMinOut = (0, core_1.toNormalizedBn)(minOut, outputDecimals);
|
|
498
|
-
const
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
core_1.Logger.log.info('rwaRedeemAsset:tx_hash',
|
|
502
|
-
return
|
|
651
|
+
const { hash: redeemHash } = await safeSendTx(() => subaccountContract
|
|
652
|
+
.connect(signer)
|
|
653
|
+
.redeemAsset(asset, BigInt(normalizedAmt.raw), BigInt(normalizedMinOut.raw)), signer, wait);
|
|
654
|
+
core_1.Logger.log.info('rwaRedeemAsset:tx_hash', redeemHash);
|
|
655
|
+
return redeemHash;
|
|
503
656
|
}
|
|
504
657
|
catch (e) {
|
|
658
|
+
const recovered = await tryRecoverTxHash(e, signer, wait);
|
|
659
|
+
if (recovered) {
|
|
660
|
+
core_1.Logger.log.warn('rwaRedeemAsset:nonce-fallback', { hash: recovered });
|
|
661
|
+
return recovered;
|
|
662
|
+
}
|
|
663
|
+
if (e instanceof core_1.AugustSDKError)
|
|
664
|
+
throw e;
|
|
505
665
|
core_1.Logger.log.error('rwaRedeemAsset', e, { target, asset, amount, minOut });
|
|
506
|
-
throw new
|
|
666
|
+
throw new core_1.AugustSDKError('UNKNOWN', `RWA redeem failed: ${e instanceof Error ? e.message : 'Unknown error'}`, { cause: e, context: { target, asset, amount, minOut } });
|
|
507
667
|
}
|
|
508
668
|
}
|
|
509
669
|
//# sourceMappingURL=write.actions.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@augustdigital/sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.0",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"augustdigital",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@coral-xyz/anchor": "^0.31.1",
|
|
40
40
|
"@sentry/browser": "^8.0.0",
|
|
41
|
+
"@sentry/node": "^8.0.0",
|
|
41
42
|
"@solana/spl-token": "^0.4.14",
|
|
42
43
|
"@solana/wallet-adapter-base": "^0.9.27",
|
|
43
44
|
"@solana/web3.js": "^1.98.4",
|
|
@@ -70,6 +71,7 @@
|
|
|
70
71
|
"test:jest": "jest",
|
|
71
72
|
"test:jest:watch": "jest --watch",
|
|
72
73
|
"test:jest:coverage": "jest --coverage",
|
|
74
|
+
"test:forknet": "node tests/forknet/run.mjs",
|
|
73
75
|
"clean": "rm -rf ./lib",
|
|
74
76
|
"format": "eslint . --fix",
|
|
75
77
|
"lint-sdk": "lint-staged",
|