@augustdigital/sdk 8.6.0 → 8.7.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.
@@ -18,6 +18,7 @@ exports.rwaRedeemAsset = rwaRedeemAsset;
18
18
  exports.swapAndDeposit = swapAndDeposit;
19
19
  exports.depositViaSwapRouter = depositViaSwapRouter;
20
20
  exports.depositNativeViaSwapRouter = depositNativeViaSwapRouter;
21
+ exports.swapRouterDeposit = swapRouterDeposit;
21
22
  const ethers_1 = require("ethers");
22
23
  const abis_1 = require("../../abis");
23
24
  const core_1 = require("../../core");
@@ -64,8 +65,6 @@ async function resolveDepositTokenDecimals(args) {
64
65
  }
65
66
  /** @internal */
66
67
  function resolveSpender(args) {
67
- if (args.swapRouterAddress)
68
- return args.swapRouterAddress;
69
68
  if (args.isMultiAssetVault)
70
69
  return args.target;
71
70
  if (args.isAdapterDeposit && args.adapterWrapperAddress)
@@ -245,16 +244,11 @@ async function approveCore(signer, options) {
245
244
  if (isNativeToken)
246
245
  return { kind: 'native' };
247
246
  const isAdapterDeposit = actualDepositAsset.toLowerCase() !== underlyingAsset.toLowerCase();
248
- const resolvedChainId = options.chainId ?? tokenizedVault?.chain;
249
- const swapRouterAddress = resolvedChainId !== undefined && (0, core_1.vaultUsesSwapRouter)(target)
250
- ? (0, core_1.getSwapRouterAddress)(resolvedChainId)
251
- : undefined;
252
247
  const spenderAddress = resolveSpender({
253
248
  target,
254
249
  isMultiAssetVault,
255
250
  isAdapterDeposit,
256
251
  adapterWrapperAddress: adapterConfig?.wrapperAddress,
257
- swapRouterAddress,
258
252
  });
259
253
  const depositTokenDecimals = await resolveDepositTokenDecimals({
260
254
  actualDepositAsset,
@@ -297,7 +291,12 @@ async function approveCore(signer, options) {
297
291
  catch (e) {
298
292
  if (e instanceof core_1.AugustSDKError)
299
293
  throw e;
300
- core_1.Logger.log.error('vaultApprove', e, { target, amount });
294
+ // A user declining the approval in their wallet is product behaviour, not
295
+ // an SDK fault — demote it to a breadcrumb so it doesn't bill as an issue.
296
+ (0, core_1.logChainError)('vaultApprove', e, (0, core_1.isUserRejectionError)(e), {
297
+ target,
298
+ amount,
299
+ });
301
300
  throw new core_1.AugustSDKError('UNKNOWN', `Approval failed: ${e instanceof Error ? e.message : 'Unknown error'}`, { cause: e, context: { target, amount } });
302
301
  }
303
302
  }
@@ -465,26 +464,12 @@ async function vaultDeposit(signer, options) {
465
464
  actualDepositAsset === '0x0000000000000000000000000000000000000000';
466
465
  const isAdapterDeposit = actualDepositAsset.toLowerCase() !== underlyingAsset.toLowerCase();
467
466
  const isMultiAssetVault = vaultVersion === 'evm-2';
468
- const resolvedChainId = chainId ?? tokenizedVault?.chain;
469
- const wantsSwapRouter = (0, core_1.vaultUsesSwapRouter)(target);
470
- const swapRouterAddress = wantsSwapRouter && resolvedChainId !== undefined
471
- ? (0, core_1.getSwapRouterAddress)(resolvedChainId)
472
- : undefined;
473
- // Legacy adapter uses minAmountOut: 0 (MEV-vulnerable); fall-through is unsafe.
474
- if (wantsSwapRouter && !swapRouterAddress) {
475
- throw new core_1.AugustValidationError('INVALID_CHAIN', resolvedChainId === undefined
476
- ? `vaultDeposit: vault ${target} requires SwapRouter routing but chainId could not be resolved — pass options.chainId or ensure tokenized-vault metadata is loaded`
477
- : `vaultDeposit: vault ${target} is registered on SwapRouter but no SwapRouter is deployed for chainId ${resolvedChainId}`, { context: { vault: target, chainId: resolvedChainId } });
478
- }
479
- // SwapRouter has no permit variant; throw rather than silently drop the signature.
480
- if (wantsSwapRouter && options?.isDepositWithPermit) {
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 } });
482
- }
483
- if (isAdapterDeposit &&
484
- !isMultiAssetVault &&
485
- !adapterConfig &&
486
- !swapRouterAddress) {
487
- throw new core_1.AugustValidationError('INVALID_INPUT', `vaultDeposit: depositAsset ${actualDepositAsset} differs from vault underlying ${underlyingAsset} but no adapter is configured for vault ${target}`);
467
+ // vaultDeposit is the NATIVE path only — it never routes through the
468
+ // SwapRouter. Any-token swap deposits are the explicit, opt-in job of
469
+ // {@link swapRouterDeposit}; keeping them out of here is what stops a
470
+ // natively-accepted asset from being silently swapped.
471
+ if (isAdapterDeposit && !isMultiAssetVault && !adapterConfig) {
472
+ throw new core_1.AugustValidationError('INVALID_INPUT', `vaultDeposit: depositAsset ${actualDepositAsset} differs from vault underlying ${underlyingAsset} but no adapter is configured for vault ${target}. For an any-token deposit into a SwapRouter-eligible vault, use swapRouterDeposit instead.`);
488
473
  }
489
474
  const depositTokenDecimals = await resolveDepositTokenDecimals({
490
475
  actualDepositAsset,
@@ -502,23 +487,6 @@ async function vaultDeposit(signer, options) {
502
487
  },
503
488
  });
504
489
  const normalizedAmt = (0, core_1.toNormalizedBn)(amount, depositTokenDecimals);
505
- if (swapRouterAddress && resolvedChainId !== undefined) {
506
- return dispatchViaSwapRouter({
507
- signer,
508
- routerAddress: swapRouterAddress,
509
- chainId: resolvedChainId,
510
- target,
511
- wallet,
512
- receiver: options.receiver,
513
- actualDepositAsset,
514
- underlyingAsset,
515
- isNativeToken,
516
- depositTokenDecimals,
517
- normalizedAmt,
518
- slippageBps: options.slippageBps,
519
- wait,
520
- });
521
- }
522
490
  if (!isNativeToken) {
523
491
  const spenderAddress = resolveSpender({
524
492
  target,
@@ -632,7 +600,12 @@ async function vaultDeposit(signer, options) {
632
600
  }
633
601
  if (e instanceof core_1.AugustSDKError)
634
602
  throw e;
635
- core_1.Logger.log.error('deposit', e, { target, amount, depositAsset });
603
+ // User-cancelled deposits are normal; only genuine failures stay at error.
604
+ (0, core_1.logChainError)('deposit', e, (0, core_1.isUserRejectionError)(e), {
605
+ target,
606
+ amount,
607
+ depositAsset,
608
+ });
636
609
  throw new core_1.AugustSDKError('UNKNOWN', `Deposit failed: ${e instanceof Error ? e.message : 'Unknown error'}`, { cause: e, context: { target, amount, depositAsset } });
637
610
  }
638
611
  }
@@ -780,7 +753,11 @@ async function vaultRequestRedeem(signer, options) {
780
753
  }
781
754
  if (e instanceof core_1.AugustSDKError)
782
755
  throw e;
783
- core_1.Logger.log.error('requestRedeem', e, { target, amount });
756
+ // User-cancelled redeem requests are normal; only genuine failures stay at error.
757
+ (0, core_1.logChainError)('requestRedeem', e, (0, core_1.isUserRejectionError)(e), {
758
+ target,
759
+ amount,
760
+ });
784
761
  throw new core_1.AugustSDKError('UNKNOWN', `Request redeem failed: ${e instanceof Error ? e.message : 'Unknown error'}`, { cause: e, context: { target, amount } });
785
762
  }
786
763
  }
@@ -823,7 +800,14 @@ async function vaultRedeem(signer, options) {
823
800
  }
824
801
  if (e instanceof core_1.AugustSDKError)
825
802
  throw e;
826
- core_1.Logger.log.error('redeem', e, { target, year, month, day, receiverIndex });
803
+ // User-cancelled redeems are normal; only genuine failures stay at error.
804
+ (0, core_1.logChainError)('redeem', e, (0, core_1.isUserRejectionError)(e), {
805
+ target,
806
+ year,
807
+ month,
808
+ day,
809
+ receiverIndex,
810
+ });
827
811
  throw new core_1.AugustSDKError('UNKNOWN', `Redeem failed: ${e instanceof Error ? e.message : 'Unknown error'}`, { cause: e, context: { target, year, month, day, receiverIndex } });
828
812
  }
829
813
  }
@@ -914,7 +898,12 @@ async function depositNative(signer, options) {
914
898
  }
915
899
  if (e instanceof core_1.AugustSDKError)
916
900
  throw e;
917
- core_1.Logger.log.error('depositNative', e, { wrapperAddress, receiver, amount });
901
+ // User-cancelled native deposits are normal; only genuine failures stay at error.
902
+ (0, core_1.logChainError)('depositNative', e, (0, core_1.isUserRejectionError)(e), {
903
+ wrapperAddress,
904
+ receiver,
905
+ amount,
906
+ });
918
907
  throw new core_1.AugustSDKError('UNKNOWN', `Deposit native failed: ${e instanceof Error ? e.message : 'Unknown error'}`, { cause: e, context: { wrapperAddress, receiver, amount } });
919
908
  }
920
909
  }
@@ -988,7 +977,13 @@ async function rwaRedeemAsset(signer, options) {
988
977
  }
989
978
  if (e instanceof core_1.AugustSDKError)
990
979
  throw e;
991
- core_1.Logger.log.error('rwaRedeemAsset', e, { target, asset, amount, minOut });
980
+ // User-cancelled RWA redeems are normal; only genuine failures stay at error.
981
+ (0, core_1.logChainError)('rwaRedeemAsset', e, (0, core_1.isUserRejectionError)(e), {
982
+ target,
983
+ asset,
984
+ amount,
985
+ minOut,
986
+ });
992
987
  throw new core_1.AugustSDKError('UNKNOWN', `RWA redeem failed: ${e instanceof Error ? e.message : 'Unknown error'}`, { cause: e, context: { target, asset, amount, minOut } });
993
988
  }
994
989
  }
@@ -1323,4 +1318,146 @@ async function depositNativeViaSwapRouter(signer, options) {
1323
1318
  core_1.Logger.log.info('depositNativeViaSwapRouter:tx_hash', hash);
1324
1319
  return hash;
1325
1320
  }
1321
+ /**
1322
+ * Deposit into an August vault through the on-chain `SwapRouter`, selecting the
1323
+ * correct router path from the deposit asset. This is the high-level, explicit
1324
+ * counterpart to the SwapRouter branch inside {@link vaultDeposit}.
1325
+ *
1326
+ * Where `vaultDeposit` decides whether to use the SwapRouter from the
1327
+ * `VAULTS_USING_SWAP_ROUTER` allowlist, this function always routes through the
1328
+ * SwapRouter because the caller asked it to. Making the intent explicit is the
1329
+ * point: a native-deposit vault (e.g. a multi-asset Tokenized Vault V2 whose
1330
+ * non-reference assets are accepted directly) is never accidentally swapped —
1331
+ * the regression that implicit, allowlist-driven routing caused. Use
1332
+ * `vaultDeposit` for native / adapter deposits and this for SwapRouter deposits.
1333
+ *
1334
+ * The vault's reference asset and its decimals are read on-chain (never trusted
1335
+ * from the caller — a wrong reference asset would mis-route the swap). The path
1336
+ * is then chosen from `depositAsset`:
1337
+ * - equals the reference asset → direct router deposit, no swap
1338
+ * ({@link depositViaSwapRouter});
1339
+ * - the zero address → native-token deposit ({@link depositNativeViaSwapRouter}),
1340
+ * valid only when the reference asset is the chain's wrapped-native token;
1341
+ * - any other ERC-20 → a swap to the reference asset (Paraswap quote pinned to
1342
+ * the chain's whitelisted aggregator, fail-closed on router/selector drift)
1343
+ * bundled into {@link swapAndDeposit}.
1344
+ *
1345
+ * Side effects: reads tokenized-vault metadata, the vault's reference asset and
1346
+ * decimals, and (on the swap path) one Paraswap quote; sends one ERC-20
1347
+ * `approve` to the SwapRouter when allowance is short, then the deposit tx.
1348
+ *
1349
+ * @param signer - ethers `Signer` or `Wallet` that signs the approval + deposit.
1350
+ * @param options - {@link ISwapRouterDepositOptions}.
1351
+ * @returns The transaction hash of the router deposit call.
1352
+ * @throws {@link AugustValidationError} for an unsupported chain (no SwapRouter
1353
+ * deployment), an invalid vault or deposit-asset address, a missing or zero
1354
+ * amount, a native deposit into a non-wrapped-native vault, or drift between
1355
+ * the aggregator quote and the on-chain router whitelist.
1356
+ * @worstCaseRpcCalls 5 on the swap path — tokenized-vault metadata, reference
1357
+ * asset + decimals, deposit-token decimals, the quote, and the allowance read.
1358
+ * @example
1359
+ * ```ts
1360
+ * // USDT deposited into a USDC-reference vault → swapped to USDC en route.
1361
+ * const hash = await augustSdk.evm.swapRouterDeposit({
1362
+ * chainId: 1,
1363
+ * vault: '0xe9b725010a9e419412ed67d0fa5f3a5f40159d32',
1364
+ * depositAsset: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
1365
+ * amount: '100',
1366
+ * slippageBps: 50,
1367
+ * });
1368
+ * ```
1369
+ */
1370
+ async function swapRouterDeposit(signer, options) {
1371
+ const { chainId, vault, depositAsset, amount, receiver, slippageBps, wait } = options;
1372
+ if (!(0, core_1.checkAddress)(vault, console, 'contract')) {
1373
+ throw new core_1.AugustValidationError('INVALID_ADDRESS', `swapRouterDeposit: invalid vault address "${vault}"`);
1374
+ }
1375
+ if (!(0, core_1.checkAddress)(depositAsset, console, 'contract')) {
1376
+ throw new core_1.AugustValidationError('INVALID_ADDRESS', `swapRouterDeposit: invalid depositAsset address "${depositAsset}"`);
1377
+ }
1378
+ if (amount === undefined || amount === null) {
1379
+ throw new core_1.AugustValidationError('INVALID_INPUT', 'swapRouterDeposit: amount is required');
1380
+ }
1381
+ validateAmountPrecision(amount);
1382
+ // Explicit opt-in: resolve the router straight from chainId rather than
1383
+ // consulting VAULTS_USING_SWAP_ROUTER, so this path never depends on the
1384
+ // implicit allowlist that could route a native-deposit vault through a swap.
1385
+ const routerAddress = resolveSwapRouterOrThrow(chainId);
1386
+ const eoa = await resolveSignerEOA(signer, 'swapRouterDeposit');
1387
+ // Reference asset + decimals from the vault on-chain. Mirrors vaultDeposit's
1388
+ // metadata resolution so the deposit-token decimals (and therefore the raw
1389
+ // amount) match exactly; kept separate to leave the vaultDeposit money path
1390
+ // untouched.
1391
+ const tokenizedVault = (await (0, core_1.fetchTokenizedVault)(vault))?.[0];
1392
+ const isMultiAssetVault = (0, core_1.getVaultVersionV2)(tokenizedVault) === 'evm-2';
1393
+ let underlyingAsset;
1394
+ let vaultDecimals;
1395
+ if (isMultiAssetVault) {
1396
+ const poolContract = (0, core_1.createContract)({
1397
+ address: vault,
1398
+ provider: signer,
1399
+ abi: abis_1.ABI_TOKENIZED_VAULT_V2,
1400
+ });
1401
+ const [asset, receiptTokenAddr] = await Promise.all([
1402
+ poolContract.asset(),
1403
+ poolContract.lpTokenAddress(),
1404
+ ]);
1405
+ underlyingAsset = asset;
1406
+ const receiptContract = (0, core_1.createContract)({
1407
+ address: receiptTokenAddr,
1408
+ provider: signer,
1409
+ abi: abis_1.ABI_ERC20,
1410
+ });
1411
+ vaultDecimals = Number(await receiptContract.decimals());
1412
+ }
1413
+ else {
1414
+ const poolContract = (0, core_1.createContract)({
1415
+ address: vault,
1416
+ provider: signer,
1417
+ abi: abis_1.ABI_LENDING_POOLS,
1418
+ });
1419
+ const [asset, rawDecimals] = await Promise.all([
1420
+ poolContract.asset(),
1421
+ poolContract.decimals(),
1422
+ ]);
1423
+ underlyingAsset = asset;
1424
+ vaultDecimals = Number(rawDecimals);
1425
+ }
1426
+ const isNativeToken = depositAsset === ethers_1.ZeroAddress ||
1427
+ depositAsset === '0x0000000000000000000000000000000000000000';
1428
+ const depositTokenDecimals = await resolveDepositTokenDecimals({
1429
+ actualDepositAsset: depositAsset,
1430
+ underlyingAsset,
1431
+ isNativeToken,
1432
+ isMultiAssetVault,
1433
+ vaultDecimals,
1434
+ readErc20Decimals: async (addr) => {
1435
+ const erc20 = (0, core_1.createContract)({
1436
+ address: addr,
1437
+ provider: signer,
1438
+ abi: abis_1.ABI_ERC20,
1439
+ });
1440
+ return Number(await erc20.decimals());
1441
+ },
1442
+ });
1443
+ const normalizedAmt = (0, core_1.toNormalizedBn)(amount, depositTokenDecimals);
1444
+ if (BigInt(normalizedAmt.raw) === 0n) {
1445
+ throw new core_1.AugustValidationError('INVALID_INPUT', 'swapRouterDeposit: amount must be greater than zero');
1446
+ }
1447
+ return dispatchViaSwapRouter({
1448
+ signer,
1449
+ routerAddress,
1450
+ chainId,
1451
+ target: vault,
1452
+ wallet: eoa,
1453
+ receiver,
1454
+ actualDepositAsset: depositAsset,
1455
+ underlyingAsset,
1456
+ isNativeToken,
1457
+ depositTokenDecimals,
1458
+ normalizedAmt,
1459
+ slippageBps,
1460
+ wait,
1461
+ });
1462
+ }
1326
1463
  //# sourceMappingURL=write.actions.js.map