@paxoslabs/amplify-sdk 0.5.3 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +113 -91
  3. package/dist/index.d.mts +3081 -759
  4. package/dist/index.d.ts +3081 -759
  5. package/dist/index.js +14775 -186
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +14834 -6
  8. package/dist/index.mjs.map +1 -1
  9. package/package.json +25 -86
  10. package/CHANGELOG.md +0 -320
  11. package/dist/chain-utils-5r2UnCDS.d.mts +0 -380
  12. package/dist/chain-utils-5r2UnCDS.d.ts +0 -380
  13. package/dist/chunk-4NQPS3JC.js +0 -2101
  14. package/dist/chunk-4NQPS3JC.js.map +0 -1
  15. package/dist/chunk-6CU533DM.mjs +0 -39
  16. package/dist/chunk-6CU533DM.mjs.map +0 -1
  17. package/dist/chunk-6JLKHV6O.js +0 -128
  18. package/dist/chunk-6JLKHV6O.js.map +0 -1
  19. package/dist/chunk-FHE43NKY.js +0 -1143
  20. package/dist/chunk-FHE43NKY.js.map +0 -1
  21. package/dist/chunk-GOJQYEJQ.js +0 -3212
  22. package/dist/chunk-GOJQYEJQ.js.map +0 -1
  23. package/dist/chunk-LMNADWTH.mjs +0 -2073
  24. package/dist/chunk-LMNADWTH.mjs.map +0 -1
  25. package/dist/chunk-ODXJYXUH.mjs +0 -3168
  26. package/dist/chunk-ODXJYXUH.mjs.map +0 -1
  27. package/dist/chunk-QMFYPHX5.mjs +0 -690
  28. package/dist/chunk-QMFYPHX5.mjs.map +0 -1
  29. package/dist/chunk-TNL23CO2.js +0 -45
  30. package/dist/chunk-TNL23CO2.js.map +0 -1
  31. package/dist/chunk-UY2WD7MF.mjs +0 -1133
  32. package/dist/chunk-UY2WD7MF.mjs.map +0 -1
  33. package/dist/chunk-WD6QFSXZ.js +0 -701
  34. package/dist/chunk-WD6QFSXZ.js.map +0 -1
  35. package/dist/chunk-Y5LBT2WT.mjs +0 -118
  36. package/dist/chunk-Y5LBT2WT.mjs.map +0 -1
  37. package/dist/core.d.mts +0 -195
  38. package/dist/core.d.ts +0 -195
  39. package/dist/core.js +0 -1236
  40. package/dist/core.js.map +0 -1
  41. package/dist/core.mjs +0 -1194
  42. package/dist/core.mjs.map +0 -1
  43. package/dist/display.d.mts +0 -472
  44. package/dist/display.d.ts +0 -472
  45. package/dist/display.js +0 -52
  46. package/dist/display.js.map +0 -1
  47. package/dist/display.mjs +0 -7
  48. package/dist/display.mjs.map +0 -1
  49. package/dist/index-D8RtV9cB.d.mts +0 -5114
  50. package/dist/index-ev_V5sjt.d.ts +0 -5114
  51. package/dist/utils.d.mts +0 -112
  52. package/dist/utils.d.ts +0 -112
  53. package/dist/utils.js +0 -67
  54. package/dist/utils.js.map +0 -1
  55. package/dist/utils.mjs +0 -25
  56. package/dist/utils.mjs.map +0 -1
  57. package/dist/vaults.d.mts +0 -4
  58. package/dist/vaults.d.ts +0 -4
  59. package/dist/vaults.js +0 -96
  60. package/dist/vaults.js.map +0 -1
  61. package/dist/vaults.mjs +0 -7
  62. package/dist/vaults.mjs.map +0 -1
@@ -1,2073 +0,0 @@
1
- import { resolveVault, InvalidChainIdError, TransactionDataError, WithdrawError } from './chunk-Y5LBT2WT.mjs';
2
- import { getTokenPermitInfoWithAllowance, getErc20AllowanceWithDecimals, getRateInQuoteWithAssetDecimals, erc2612Abi, getErc20Decimals, BoringVaultAbi, AccountantAbi } from './chunk-UY2WD7MF.mjs';
3
- import { WAD } from './chunk-6CU533DM.mjs';
4
- import { getLogger, APIError, getRestV2BaseURL, getRequestHeaders, createTimeoutSignal, DEFAULT_TIMEOUT, toChainId, getSupportedAssets, DEFAULT_APPROVAL_AMOUNT, DEFAULT_SLIPPAGE_BPS, DistributorCodeDepositorAbiV0, getClient, WithdrawQueueAbi, readDepositFeeStructure, readSupplyCapInBase } from './chunk-ODXJYXUH.mjs';
5
- import { formatUnits, parseUnits, erc20Abi, stringToHex, zeroAddress, hexToSignature, maxUint256 } from 'viem';
6
-
7
- // src/client/kyt-client.ts
8
- var CHAIN_ID_TO_PREDICATE_CHAIN = {
9
- 1: "ethereum",
10
- 11155111: "sepolia",
11
- 8453: "base",
12
- 84532: "base-sepolia",
13
- 999: "hyperevm",
14
- 2201: "stable-testnet"
15
- };
16
- async function fetchKytAttestation(params) {
17
- const { to, from, chainId } = params;
18
- const logger = getLogger();
19
- const chain = CHAIN_ID_TO_PREDICATE_CHAIN[chainId];
20
- if (!chain) {
21
- throw new APIError(
22
- `KYT attestation not supported for chain ID ${chainId}. Supported chains: ${Object.keys(CHAIN_ID_TO_PREDICATE_CHAIN).join(", ")}`,
23
- { endpoint: "kytAttestation" }
24
- );
25
- }
26
- const url = `${getRestV2BaseURL()}/kytAttestation`;
27
- const headers = getRequestHeaders();
28
- logger.debug("Fetching KYT attestation", { to, from, chain });
29
- let response;
30
- try {
31
- response = await fetch(url, {
32
- method: "POST",
33
- headers,
34
- body: JSON.stringify({ to, from, chain }),
35
- signal: createTimeoutSignal(DEFAULT_TIMEOUT)
36
- });
37
- } catch (error) {
38
- if (error instanceof Error && error.name === "AbortError") {
39
- throw new APIError("KYT attestation request timed out", {
40
- endpoint: "kytAttestation",
41
- cause: error
42
- });
43
- }
44
- throw new APIError(
45
- `KYT attestation request failed: ${error instanceof Error ? error.message : String(error)}`,
46
- { endpoint: "kytAttestation", cause: error }
47
- );
48
- }
49
- if (!response.ok) {
50
- let serverMessage;
51
- try {
52
- const errorBody = await response.json();
53
- serverMessage = errorBody?.error?.message;
54
- } catch {
55
- }
56
- if (response.status === 403) {
57
- throw new APIError(
58
- serverMessage ?? "Deposit blocked: transaction is not compliant with KYT policy",
59
- { endpoint: "kytAttestation", statusCode: 403 }
60
- );
61
- }
62
- if (response.status === 400) {
63
- throw new APIError(
64
- serverMessage ?? "KYT attestation request was rejected: invalid parameters",
65
- { endpoint: "kytAttestation", statusCode: 400 }
66
- );
67
- }
68
- throw new APIError(
69
- serverMessage ?? `KYT attestation request failed (HTTP ${response.status})`,
70
- { endpoint: "kytAttestation", statusCode: response.status }
71
- );
72
- }
73
- let body;
74
- try {
75
- body = await response.json();
76
- } catch (error) {
77
- throw new APIError("KYT attestation response contained invalid JSON", {
78
- endpoint: "kytAttestation",
79
- cause: error
80
- });
81
- }
82
- if (!body.attestation) {
83
- throw new APIError("KYT attestation response missing attestation field", {
84
- endpoint: "kytAttestation"
85
- });
86
- }
87
- const { attestation } = body;
88
- const missingFields = ["uuid", "attester", "signature", "expiration"].filter((f) => attestation[f] == null);
89
- if (missingFields.length > 0) {
90
- throw new APIError(
91
- `KYT attestation response missing required fields: ${missingFields.join(", ")}`,
92
- { endpoint: "kytAttestation" }
93
- );
94
- }
95
- if (typeof attestation.expiration !== "number" && typeof attestation.expiration !== "string") {
96
- throw new APIError(
97
- "KYT attestation response has invalid expiration value",
98
- { endpoint: "kytAttestation" }
99
- );
100
- }
101
- const sig = attestation.signature.startsWith("0x") ? attestation.signature : `0x${attestation.signature}`;
102
- return {
103
- uuid: attestation.uuid,
104
- expiration: BigInt(attestation.expiration),
105
- attester: attestation.attester,
106
- signature: sig
107
- };
108
- }
109
- var isDepositSpendApproved = async ({
110
- vaultName,
111
- chainId,
112
- depositAssetAddress,
113
- recipientAddress
114
- }) => {
115
- try {
116
- const normalizedChainId = toChainId(chainId);
117
- const config = await resolveVault({
118
- vaultName,
119
- chainId: normalizedChainId,
120
- assetAddress: depositAssetAddress,
121
- callerEndpoint: "isDepositSpendApproved"
122
- });
123
- const communityCodeDepositorAddress = config.vault.communityCodeDepositorAddress;
124
- if (!communityCodeDepositorAddress) {
125
- throw new APIError(
126
- `Community code depositor contract address not configured for vault ${config.id}`,
127
- {
128
- endpoint: "isDepositSpendApproved"
129
- }
130
- );
131
- }
132
- const {
133
- decimals,
134
- allowance,
135
- supportsPermit,
136
- nonce,
137
- domainSeparator,
138
- tokenName,
139
- tokenVersion
140
- } = await getTokenPermitInfoWithAllowance({
141
- chainId: normalizedChainId,
142
- tokenAddress: depositAssetAddress,
143
- owner: recipientAddress,
144
- spender: communityCodeDepositorAddress
145
- });
146
- return {
147
- isApproved: allowance > 0n,
148
- allowance: formatUnits(allowance, decimals),
149
- allowanceAsBigInt: allowance.toString(),
150
- decimals,
151
- supportsPermit,
152
- nonce,
153
- domainSeparator,
154
- tokenName,
155
- tokenVersion,
156
- error: null
157
- };
158
- } catch (error) {
159
- if (error instanceof APIError) {
160
- throw error;
161
- }
162
- throw new APIError(
163
- `Failed to check deposit approval: ${error instanceof Error ? error.message : String(error)}`,
164
- {
165
- endpoint: "isDepositSpendApproved",
166
- cause: error
167
- }
168
- );
169
- }
170
- };
171
- var isWithdrawalSpendApproved = async ({
172
- vaultName,
173
- chainId,
174
- wantAssetAddress,
175
- recipientAddress
176
- }) => {
177
- try {
178
- const normalizedChainId = toChainId(chainId);
179
- const config = await resolveVault({
180
- vaultName,
181
- chainId: normalizedChainId,
182
- assetAddress: wantAssetAddress,
183
- callerEndpoint: "isWithdrawalSpendApproved"
184
- });
185
- const boringVaultAddress = config.vault.boringVaultAddress;
186
- if (!boringVaultAddress) {
187
- throw new APIError(
188
- `BoringVault contract address not configured for vault ${config.id}`,
189
- {
190
- endpoint: "isWithdrawalSpendApproved"
191
- }
192
- );
193
- }
194
- const withdrawQueueAddress = config.vault.withdrawQueueAddress;
195
- if (!withdrawQueueAddress) {
196
- throw new APIError(
197
- `WithdrawQueue contract address not configured for vault ${config.id}`,
198
- {
199
- endpoint: "isWithdrawalSpendApproved"
200
- }
201
- );
202
- }
203
- const [allowance, decimals] = await getErc20AllowanceWithDecimals({
204
- chainId: normalizedChainId,
205
- tokenAddress: boringVaultAddress,
206
- recipientAddress,
207
- spenderAddress: withdrawQueueAddress
208
- });
209
- if (allowance.status === "failure" || decimals.status === "failure") {
210
- return {
211
- isApproved: false,
212
- allowance: "0",
213
- allowanceAsBigInt: "0",
214
- decimals: "0",
215
- error: allowance.error || decimals.error
216
- };
217
- }
218
- return {
219
- isApproved: allowance.result > 0n,
220
- allowance: formatUnits(allowance.result, decimals.result),
221
- allowanceAsBigInt: allowance.result.toString(),
222
- decimals: decimals.result,
223
- error: null
224
- };
225
- } catch (error) {
226
- if (error instanceof APIError) {
227
- throw error;
228
- }
229
- throw new APIError(
230
- `Failed to check withdrawal approval: ${error instanceof Error ? error.message : String(error)}`,
231
- { endpoint: "isWithdrawalSpendApproved", cause: error }
232
- );
233
- }
234
- };
235
- async function prepareApproveDepositTokenTxData({
236
- vaultName,
237
- depositAsset,
238
- approvalAmount,
239
- chainId
240
- }) {
241
- const normalizedChainId = toChainId(chainId);
242
- try {
243
- const config = await resolveVault({
244
- vaultName,
245
- assetAddress: depositAsset,
246
- chainId: normalizedChainId,
247
- callerEndpoint: "prepareApproveDepositToken"
248
- });
249
- const communityCodeDepositorAddress = config.vault.communityCodeDepositorAddress;
250
- if (!communityCodeDepositorAddress) {
251
- throw new APIError(
252
- `Community Code Depositor contract address not configured for vault ${config.id}`,
253
- { endpoint: "prepareApproveDepositToken" }
254
- );
255
- }
256
- const assets = await getSupportedAssets({ address: depositAsset });
257
- if (assets.length === 0) {
258
- throw new APIError(
259
- `Asset metadata not found for token ${depositAsset} on chain ${normalizedChainId}`,
260
- { endpoint: "prepareApproveDepositToken" }
261
- );
262
- }
263
- const verifiedAsset = assets.find(
264
- (asset) => asset.address.toLowerCase() === depositAsset.toLowerCase() && asset.chains.includes(normalizedChainId)
265
- );
266
- if (!verifiedAsset) {
267
- throw new APIError(
268
- `Asset ${depositAsset} not verified on chain ${normalizedChainId}`,
269
- { endpoint: "prepareApproveDepositToken" }
270
- );
271
- }
272
- const decimals = verifiedAsset.decimals;
273
- const amount = approvalAmount ? parseUnits(approvalAmount, decimals) : DEFAULT_APPROVAL_AMOUNT;
274
- return {
275
- abi: erc20Abi,
276
- address: depositAsset,
277
- functionName: "approve",
278
- args: [communityCodeDepositorAddress, amount]
279
- };
280
- } catch (error) {
281
- if (error instanceof APIError) {
282
- throw error;
283
- }
284
- throw new APIError(
285
- `Failed to prepare approval transaction: ${error instanceof Error ? error.message : String(error)}`,
286
- {
287
- endpoint: "prepareApproveDepositToken",
288
- cause: error
289
- }
290
- );
291
- }
292
- }
293
-
294
- // src/abi/distributor-code-depositor-abi-v1.ts
295
- var DistributorCodeDepositorAbiV1 = [
296
- {
297
- inputs: [
298
- {
299
- internalType: "contract TellerWithMultiAssetSupport",
300
- name: "_teller",
301
- type: "address"
302
- },
303
- {
304
- internalType: "contract INativeWrapper",
305
- name: "_nativeWrapper",
306
- type: "address"
307
- },
308
- {
309
- internalType: "contract Authority",
310
- name: "_rolesAuthority",
311
- type: "address"
312
- },
313
- { internalType: "bool", name: "_isNativeDepositSupported", type: "bool" },
314
- { internalType: "uint256", name: "_supplyCap", type: "uint256" },
315
- {
316
- internalType: "contract IFeeModule",
317
- name: "_feeModule",
318
- type: "address"
319
- },
320
- { internalType: "address", name: "_feeRecipient", type: "address" },
321
- { internalType: "address", name: "_registry", type: "address" },
322
- { internalType: "string", name: "_policyID", type: "string" },
323
- { internalType: "address", name: "_owner", type: "address" }
324
- ],
325
- stateMutability: "nonpayable",
326
- type: "constructor"
327
- },
328
- { inputs: [], name: "FeesExceedOrEqualAmount", type: "error" },
329
- { inputs: [], name: "IncorrectNativeDepositAmount", type: "error" },
330
- {
331
- inputs: [
332
- { internalType: "uint256", name: "actual", type: "uint256" },
333
- { internalType: "uint256", name: "minimum", type: "uint256" }
334
- ],
335
- name: "InsufficientSharesAfterFees",
336
- type: "error"
337
- },
338
- { inputs: [], name: "NativeDepositNotSupported", type: "error" },
339
- {
340
- inputs: [],
341
- name: "NativeWrapperAccountantDecimalsMismatch",
342
- type: "error"
343
- },
344
- {
345
- inputs: [
346
- { internalType: "address", name: "addressEmptyCode", type: "address" }
347
- ],
348
- name: "NoCode",
349
- type: "error"
350
- },
351
- { inputs: [], name: "PermitFailedAndAllowanceTooLow", type: "error" },
352
- {
353
- inputs: [
354
- { internalType: "uint256", name: "resultingValue", type: "uint256" },
355
- { internalType: "uint256", name: "supplyCapInBase", type: "uint256" }
356
- ],
357
- name: "SupplyCapInBaseError",
358
- type: "error"
359
- },
360
- { inputs: [], name: "UnauthorizedTransaction", type: "error" },
361
- { inputs: [], name: "ZeroAddress", type: "error" },
362
- {
363
- anonymous: false,
364
- inputs: [
365
- { indexed: true, internalType: "address", name: "user", type: "address" },
366
- {
367
- indexed: true,
368
- internalType: "contract Authority",
369
- name: "newAuthority",
370
- type: "address"
371
- }
372
- ],
373
- name: "AuthorityUpdated",
374
- type: "event"
375
- },
376
- {
377
- anonymous: false,
378
- inputs: [
379
- {
380
- indexed: true,
381
- internalType: "address",
382
- name: "depositor",
383
- type: "address"
384
- },
385
- {
386
- indexed: true,
387
- internalType: "contract ERC20",
388
- name: "depositAsset",
389
- type: "address"
390
- },
391
- {
392
- indexed: false,
393
- internalType: "uint256",
394
- name: "depositAmount",
395
- type: "uint256"
396
- },
397
- {
398
- indexed: false,
399
- internalType: "uint256",
400
- name: "minimumMint",
401
- type: "uint256"
402
- },
403
- { indexed: false, internalType: "address", name: "to", type: "address" },
404
- {
405
- indexed: false,
406
- internalType: "bytes32",
407
- name: "depositHash",
408
- type: "bytes32"
409
- },
410
- {
411
- indexed: true,
412
- internalType: "bytes",
413
- name: "distributorCode",
414
- type: "bytes"
415
- }
416
- ],
417
- name: "DepositWithDistributorCode",
418
- type: "event"
419
- },
420
- {
421
- anonymous: false,
422
- inputs: [
423
- {
424
- indexed: true,
425
- internalType: "contract IFeeModule",
426
- name: "newFeeModule",
427
- type: "address"
428
- }
429
- ],
430
- name: "FeeModuleUpdated",
431
- type: "event"
432
- },
433
- {
434
- anonymous: false,
435
- inputs: [
436
- {
437
- indexed: true,
438
- internalType: "address",
439
- name: "newFeeRecipient",
440
- type: "address"
441
- }
442
- ],
443
- name: "FeeRecipientUpdated",
444
- type: "event"
445
- },
446
- {
447
- anonymous: false,
448
- inputs: [
449
- {
450
- indexed: true,
451
- internalType: "contract ERC20",
452
- name: "depositAsset",
453
- type: "address"
454
- },
455
- { indexed: true, internalType: "bool", name: "enabled", type: "bool" }
456
- ],
457
- name: "KytStatusUpdated",
458
- type: "event"
459
- },
460
- {
461
- anonymous: false,
462
- inputs: [
463
- { indexed: true, internalType: "address", name: "user", type: "address" },
464
- {
465
- indexed: true,
466
- internalType: "address",
467
- name: "newOwner",
468
- type: "address"
469
- }
470
- ],
471
- name: "OwnershipTransferred",
472
- type: "event"
473
- },
474
- {
475
- anonymous: false,
476
- inputs: [
477
- {
478
- indexed: false,
479
- internalType: "string",
480
- name: "oldPolicyID",
481
- type: "string"
482
- },
483
- {
484
- indexed: false,
485
- internalType: "string",
486
- name: "newPolicyID",
487
- type: "string"
488
- }
489
- ],
490
- name: "PredicatePolicyIDUpdated",
491
- type: "event"
492
- },
493
- {
494
- anonymous: false,
495
- inputs: [
496
- {
497
- indexed: true,
498
- internalType: "address",
499
- name: "oldRegistry",
500
- type: "address"
501
- },
502
- {
503
- indexed: true,
504
- internalType: "address",
505
- name: "newRegistry",
506
- type: "address"
507
- }
508
- ],
509
- name: "PredicateRegistryUpdated",
510
- type: "event"
511
- },
512
- {
513
- anonymous: false,
514
- inputs: [
515
- {
516
- indexed: false,
517
- internalType: "uint256",
518
- name: "newSupplyCapInBase",
519
- type: "uint256"
520
- }
521
- ],
522
- name: "SupplyCapInBaseUpdated",
523
- type: "event"
524
- },
525
- {
526
- inputs: [],
527
- name: "PREDICATE_DEPOSIT_SIGNATURE",
528
- outputs: [{ internalType: "string", name: "", type: "string" }],
529
- stateMutability: "view",
530
- type: "function"
531
- },
532
- {
533
- inputs: [],
534
- name: "authority",
535
- outputs: [
536
- { internalType: "contract Authority", name: "", type: "address" }
537
- ],
538
- stateMutability: "view",
539
- type: "function"
540
- },
541
- {
542
- inputs: [],
543
- name: "boringVault",
544
- outputs: [{ internalType: "address", name: "", type: "address" }],
545
- stateMutability: "view",
546
- type: "function"
547
- },
548
- {
549
- inputs: [
550
- { internalType: "contract ERC20", name: "depositAsset", type: "address" },
551
- { internalType: "uint256", name: "depositAmount", type: "uint256" },
552
- { internalType: "uint256", name: "minimumMint", type: "uint256" },
553
- { internalType: "address", name: "to", type: "address" },
554
- { internalType: "bytes", name: "distributorCode", type: "bytes" },
555
- {
556
- components: [
557
- { internalType: "string", name: "uuid", type: "string" },
558
- { internalType: "uint256", name: "expiration", type: "uint256" },
559
- { internalType: "address", name: "attester", type: "address" },
560
- { internalType: "bytes", name: "signature", type: "bytes" }
561
- ],
562
- internalType: "struct Attestation",
563
- name: "_attestation",
564
- type: "tuple"
565
- }
566
- ],
567
- name: "deposit",
568
- outputs: [{ internalType: "uint256", name: "shares", type: "uint256" }],
569
- stateMutability: "nonpayable",
570
- type: "function"
571
- },
572
- {
573
- inputs: [
574
- { internalType: "uint256", name: "depositAmount", type: "uint256" },
575
- { internalType: "uint256", name: "minimumMint", type: "uint256" },
576
- { internalType: "address", name: "to", type: "address" },
577
- { internalType: "bytes", name: "distributorCode", type: "bytes" },
578
- {
579
- components: [
580
- { internalType: "string", name: "uuid", type: "string" },
581
- { internalType: "uint256", name: "expiration", type: "uint256" },
582
- { internalType: "address", name: "attester", type: "address" },
583
- { internalType: "bytes", name: "signature", type: "bytes" }
584
- ],
585
- internalType: "struct Attestation",
586
- name: "_attestation",
587
- type: "tuple"
588
- }
589
- ],
590
- name: "depositNative",
591
- outputs: [{ internalType: "uint256", name: "shares", type: "uint256" }],
592
- stateMutability: "payable",
593
- type: "function"
594
- },
595
- {
596
- inputs: [],
597
- name: "depositNonce",
598
- outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
599
- stateMutability: "view",
600
- type: "function"
601
- },
602
- {
603
- inputs: [
604
- { internalType: "contract ERC20", name: "depositAsset", type: "address" },
605
- { internalType: "uint256", name: "depositAmount", type: "uint256" },
606
- { internalType: "uint256", name: "minimumMint", type: "uint256" },
607
- { internalType: "address", name: "to", type: "address" },
608
- { internalType: "bytes", name: "distributorCode", type: "bytes" },
609
- {
610
- components: [
611
- { internalType: "string", name: "uuid", type: "string" },
612
- { internalType: "uint256", name: "expiration", type: "uint256" },
613
- { internalType: "address", name: "attester", type: "address" },
614
- { internalType: "bytes", name: "signature", type: "bytes" }
615
- ],
616
- internalType: "struct Attestation",
617
- name: "_attestation",
618
- type: "tuple"
619
- },
620
- { internalType: "uint256", name: "deadline", type: "uint256" },
621
- { internalType: "uint8", name: "v", type: "uint8" },
622
- { internalType: "bytes32", name: "r", type: "bytes32" },
623
- { internalType: "bytes32", name: "s", type: "bytes32" }
624
- ],
625
- name: "depositWithPermit",
626
- outputs: [{ internalType: "uint256", name: "shares", type: "uint256" }],
627
- stateMutability: "nonpayable",
628
- type: "function"
629
- },
630
- {
631
- inputs: [],
632
- name: "feeModule",
633
- outputs: [
634
- { internalType: "contract IFeeModule", name: "", type: "address" }
635
- ],
636
- stateMutability: "view",
637
- type: "function"
638
- },
639
- {
640
- inputs: [],
641
- name: "feeRecipient",
642
- outputs: [{ internalType: "address", name: "", type: "address" }],
643
- stateMutability: "view",
644
- type: "function"
645
- },
646
- {
647
- inputs: [],
648
- name: "getPolicyID",
649
- outputs: [{ internalType: "string", name: "policyID", type: "string" }],
650
- stateMutability: "view",
651
- type: "function"
652
- },
653
- {
654
- inputs: [],
655
- name: "getRegistry",
656
- outputs: [{ internalType: "address", name: "", type: "address" }],
657
- stateMutability: "view",
658
- type: "function"
659
- },
660
- {
661
- inputs: [],
662
- name: "isNativeDepositSupported",
663
- outputs: [{ internalType: "bool", name: "", type: "bool" }],
664
- stateMutability: "view",
665
- type: "function"
666
- },
667
- {
668
- inputs: [{ internalType: "contract ERC20", name: "", type: "address" }],
669
- name: "kytEnabled",
670
- outputs: [{ internalType: "bool", name: "", type: "bool" }],
671
- stateMutability: "view",
672
- type: "function"
673
- },
674
- {
675
- inputs: [],
676
- name: "nativeWrapper",
677
- outputs: [
678
- { internalType: "contract INativeWrapper", name: "", type: "address" }
679
- ],
680
- stateMutability: "view",
681
- type: "function"
682
- },
683
- {
684
- inputs: [],
685
- name: "owner",
686
- outputs: [{ internalType: "address", name: "", type: "address" }],
687
- stateMutability: "view",
688
- type: "function"
689
- },
690
- {
691
- inputs: [
692
- {
693
- internalType: "contract Authority",
694
- name: "newAuthority",
695
- type: "address"
696
- }
697
- ],
698
- name: "setAuthority",
699
- outputs: [],
700
- stateMutability: "nonpayable",
701
- type: "function"
702
- },
703
- {
704
- inputs: [{ internalType: "string", name: "_policyID", type: "string" }],
705
- name: "setPolicyID",
706
- outputs: [],
707
- stateMutability: "nonpayable",
708
- type: "function"
709
- },
710
- {
711
- inputs: [{ internalType: "address", name: "_registry", type: "address" }],
712
- name: "setRegistry",
713
- outputs: [],
714
- stateMutability: "nonpayable",
715
- type: "function"
716
- },
717
- {
718
- inputs: [],
719
- name: "supplyCapInBase",
720
- outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
721
- stateMutability: "view",
722
- type: "function"
723
- },
724
- {
725
- inputs: [],
726
- name: "teller",
727
- outputs: [
728
- {
729
- internalType: "contract TellerWithMultiAssetSupport",
730
- name: "",
731
- type: "address"
732
- }
733
- ],
734
- stateMutability: "view",
735
- type: "function"
736
- },
737
- {
738
- inputs: [{ internalType: "address", name: "newOwner", type: "address" }],
739
- name: "transferOwnership",
740
- outputs: [],
741
- stateMutability: "nonpayable",
742
- type: "function"
743
- },
744
- {
745
- inputs: [
746
- {
747
- internalType: "contract IFeeModule",
748
- name: "newFeeModule",
749
- type: "address"
750
- }
751
- ],
752
- name: "updateFeeModule",
753
- outputs: [],
754
- stateMutability: "nonpayable",
755
- type: "function"
756
- },
757
- {
758
- inputs: [
759
- { internalType: "address", name: "newFeeRecipient", type: "address" }
760
- ],
761
- name: "updateFeeRecipient",
762
- outputs: [],
763
- stateMutability: "nonpayable",
764
- type: "function"
765
- },
766
- {
767
- inputs: [
768
- { internalType: "contract ERC20", name: "depositAsset", type: "address" },
769
- { internalType: "bool", name: "enabled", type: "bool" }
770
- ],
771
- name: "updateKytStatus",
772
- outputs: [],
773
- stateMutability: "nonpayable",
774
- type: "function"
775
- },
776
- {
777
- inputs: [
778
- { internalType: "uint256", name: "newSupplyCapInBase", type: "uint256" }
779
- ],
780
- name: "updateSupplyCapInBase",
781
- outputs: [],
782
- stateMutability: "nonpayable",
783
- type: "function"
784
- }
785
- ];
786
- var calculateMinimumMint = (depositAmount, rate, vaultTokenDecimals, slippage) => {
787
- const slippageValue = slippage ?? DEFAULT_SLIPPAGE_BPS;
788
- const slippageAsBigInt = BigInt(slippageValue) * WAD.bigint / BigInt(1e4);
789
- const minimumMint = depositAmount * WAD.bigint / rate;
790
- const slippageAmount = minimumMint * slippageAsBigInt / WAD.bigint;
791
- if (vaultTokenDecimals > 18) {
792
- return (minimumMint - slippageAmount) * BigInt(10) ** (BigInt(vaultTokenDecimals) - BigInt(18));
793
- }
794
- return (minimumMint - slippageAmount) / BigInt(10) ** (BigInt(18) - BigInt(vaultTokenDecimals));
795
- };
796
- async function getDepositFeeForAmount(depositFeeModuleAddress, depositAsset, depositAmount, chainId) {
797
- if (!depositFeeModuleAddress || depositFeeModuleAddress === zeroAddress) {
798
- return 0n;
799
- }
800
- const { feePercentage, flatFee, oneHundredPercent } = await readDepositFeeStructure(
801
- depositFeeModuleAddress,
802
- depositAsset,
803
- chainId
804
- );
805
- const variableFee = oneHundredPercent > 0n ? depositAmount * feePercentage / oneHundredPercent : 0n;
806
- return variableFee + flatFee;
807
- }
808
- async function assertDepositWithinCap(vault, depositAmountRaw, depositAssetAddress, chainId, callerEndpoint) {
809
- let supplyCapInBase = null;
810
- let hasDepositCap = false;
811
- if (vault.depositCap) {
812
- supplyCapInBase = vault.depositCap.supplyCapInBase;
813
- hasDepositCap = vault.depositCap.hasDepositCap;
814
- } else if (vault.vault.communityCodeDepositorAddress && vault.vault.depositFeeModuleAddress) {
815
- const onChainCap = await readSupplyCapInBase(
816
- vault.vault.communityCodeDepositorAddress,
817
- chainId
818
- );
819
- supplyCapInBase = onChainCap;
820
- hasDepositCap = onChainCap !== 0n && onChainCap !== maxUint256;
821
- }
822
- if (!hasDepositCap || supplyCapInBase == null) return;
823
- const client = await getClient(chainId);
824
- const [supplyResult, baseRateResult, quoteRateResult, decResult] = await client.multicall({
825
- contracts: [
826
- {
827
- abi: BoringVaultAbi,
828
- address: vault.vault.boringVaultAddress,
829
- functionName: "totalSupply"
830
- },
831
- {
832
- abi: AccountantAbi,
833
- address: vault.vault.accountantAddress,
834
- functionName: "getRate"
835
- },
836
- {
837
- abi: AccountantAbi,
838
- address: vault.vault.accountantAddress,
839
- functionName: "getRateInQuote",
840
- args: [depositAssetAddress]
841
- },
842
- {
843
- abi: AccountantAbi,
844
- address: vault.vault.accountantAddress,
845
- functionName: "decimals"
846
- }
847
- ]
848
- });
849
- if (supplyResult.status !== "success" || baseRateResult.status !== "success" || quoteRateResult.status !== "success" || decResult.status !== "success") {
850
- throw new APIError(
851
- "Unable to verify deposit against supply cap: on-chain read failed",
852
- { endpoint: callerEndpoint }
853
- );
854
- }
855
- const currentValueInBase = supplyResult.result * baseRateResult.result / 10n ** BigInt(decResult.result);
856
- const depositAmountInBase = quoteRateResult.result > 0n ? depositAmountRaw * baseRateResult.result / quoteRateResult.result : depositAmountRaw;
857
- const remaining = supplyCapInBase > currentValueInBase ? supplyCapInBase - currentValueInBase : 0n;
858
- if (depositAmountInBase > remaining) {
859
- throw new APIError(
860
- `Deposit would exceed vault supply cap. Remaining capacity: ${remaining}, deposit amount (in base): ${depositAmountInBase}`,
861
- { endpoint: callerEndpoint }
862
- );
863
- }
864
- }
865
-
866
- // src/vaults/deposit/deposit.ts
867
- var DepositType = {
868
- STANDARD: "standard",
869
- KYT: "kyt"
870
- };
871
- function isKytDeposit(data) {
872
- return data.depositType === DepositType.KYT;
873
- }
874
- function isStandardDeposit(data) {
875
- return data.depositType === DepositType.STANDARD;
876
- }
877
- async function prepareDepositTxData(params) {
878
- const {
879
- vaultName,
880
- depositAsset,
881
- depositAmount,
882
- chainId,
883
- slippage = DEFAULT_SLIPPAGE_BPS,
884
- to,
885
- distributorCode
886
- } = params;
887
- try {
888
- const normalizedChainId = toChainId(chainId);
889
- const vault = await resolveVault({
890
- vaultName,
891
- assetAddress: depositAsset,
892
- chainId: normalizedChainId,
893
- callerEndpoint: "prepareDepositTransactionData"
894
- });
895
- if (vault.inDeprecation) {
896
- getLogger().warn(
897
- `Vault "${vault.name}" is being deprecated. Please contact the Paxos Labs team for migration guidance.`
898
- );
899
- }
900
- const assets = await getSupportedAssets({ address: depositAsset });
901
- const asset = assets.find((a) => a.chains.includes(normalizedChainId)) || assets.find((a) => a.address.toLowerCase() === depositAsset.toLowerCase());
902
- if (!asset) {
903
- throw new APIError(
904
- `Asset metadata not found for token ${depositAsset} on chain ${normalizedChainId}`,
905
- {
906
- endpoint: "prepareDepositTransactionData"
907
- }
908
- );
909
- }
910
- const communityCodeDepositorAddress = vault.vault.communityCodeDepositorAddress;
911
- if (!communityCodeDepositorAddress) {
912
- throw new APIError(
913
- `Community Code Depositor contract address not found for vault ${vault.id}`,
914
- { endpoint: "prepareDepositTransactionData" }
915
- );
916
- }
917
- const accountantAddress = vault.vault.accountantAddress;
918
- if (!accountantAddress) {
919
- throw new APIError(
920
- `Accountant contract address not found for vault ${vault.id}`,
921
- { endpoint: "prepareDepositTransactionData" }
922
- );
923
- }
924
- const depositAssetAddress = asset.address;
925
- const [depositAssetDecimalsResult, rateInQuoteResult] = await getRateInQuoteWithAssetDecimals({
926
- assetAddress: depositAssetAddress,
927
- accountantAddress,
928
- chainId: normalizedChainId
929
- });
930
- if (depositAssetDecimalsResult.status === "failure") {
931
- throw new APIError(
932
- `Failed to get asset decimals: ${depositAssetDecimalsResult.error?.message || "Unknown error"}`,
933
- {
934
- endpoint: "prepareDepositTransactionData",
935
- cause: depositAssetDecimalsResult.error
936
- }
937
- );
938
- }
939
- if (rateInQuoteResult.status === "failure") {
940
- throw new APIError(
941
- `Failed to get exchange rate: ${rateInQuoteResult.error?.message || "Unknown error"}`,
942
- {
943
- endpoint: "prepareDepositTransactionData",
944
- cause: rateInQuoteResult.error
945
- }
946
- );
947
- }
948
- const depositAmountAsBigInt = parseUnits(
949
- depositAmount,
950
- depositAssetDecimalsResult.result
951
- );
952
- const totalFee = await getDepositFeeForAmount(
953
- vault.vault.depositFeeModuleAddress,
954
- depositAssetAddress,
955
- depositAmountAsBigInt,
956
- normalizedChainId
957
- );
958
- if (totalFee >= depositAmountAsBigInt) {
959
- throw new APIError(
960
- "Deposit amount is entirely consumed by fees. Increase the deposit amount.",
961
- { endpoint: "prepareDepositTransactionData" }
962
- );
963
- }
964
- const depositAmountAfterFees = depositAmountAsBigInt - totalFee;
965
- await assertDepositWithinCap(
966
- vault,
967
- depositAmountAfterFees,
968
- depositAssetAddress,
969
- normalizedChainId,
970
- "prepareDepositTransactionData"
971
- );
972
- const minimumMint = calculateMinimumMint(
973
- depositAmountAfterFees,
974
- rateInQuoteResult.result,
975
- depositAssetDecimalsResult.result,
976
- slippage
977
- );
978
- const distributorCodeHex = stringToHex(distributorCode || "");
979
- const policyId = vault.enterpriseConfig?.predicatePolicyId;
980
- if (policyId === void 0) {
981
- return {
982
- depositType: DepositType.STANDARD,
983
- abi: DistributorCodeDepositorAbiV0,
984
- address: communityCodeDepositorAddress,
985
- functionName: "deposit",
986
- args: [
987
- depositAssetAddress,
988
- depositAmountAsBigInt,
989
- minimumMint,
990
- to,
991
- distributorCodeHex
992
- ],
993
- chainId: normalizedChainId
994
- };
995
- }
996
- if (policyId === null) {
997
- const emptyAttestation = {
998
- uuid: "",
999
- expiration: 0n,
1000
- attester: zeroAddress,
1001
- signature: "0x"
1002
- };
1003
- return {
1004
- depositType: DepositType.KYT,
1005
- address: communityCodeDepositorAddress,
1006
- abi: DistributorCodeDepositorAbiV1,
1007
- functionName: "deposit",
1008
- args: [
1009
- depositAssetAddress,
1010
- depositAmountAsBigInt,
1011
- minimumMint,
1012
- to,
1013
- distributorCodeHex,
1014
- emptyAttestation
1015
- ],
1016
- chainId: normalizedChainId
1017
- };
1018
- }
1019
- const attestation = await fetchKytAttestation({
1020
- to: communityCodeDepositorAddress,
1021
- from: to,
1022
- chainId: normalizedChainId
1023
- });
1024
- return {
1025
- depositType: DepositType.KYT,
1026
- address: communityCodeDepositorAddress,
1027
- abi: DistributorCodeDepositorAbiV1,
1028
- functionName: "deposit",
1029
- args: [
1030
- depositAssetAddress,
1031
- depositAmountAsBigInt,
1032
- minimumMint,
1033
- to,
1034
- distributorCodeHex,
1035
- attestation
1036
- ],
1037
- chainId: normalizedChainId
1038
- };
1039
- } catch (error) {
1040
- if (error instanceof APIError) {
1041
- throw error;
1042
- }
1043
- throw new APIError(
1044
- `Failed to prepare deposit transaction: ${error instanceof Error ? error.message : String(error)}`,
1045
- {
1046
- endpoint: "prepareDepositTransactionData",
1047
- cause: error
1048
- }
1049
- );
1050
- }
1051
- }
1052
- var PERMIT_TYPES = {
1053
- Permit: [
1054
- { name: "owner", type: "address" },
1055
- { name: "spender", type: "address" },
1056
- { name: "value", type: "uint256" },
1057
- { name: "nonce", type: "uint256" },
1058
- { name: "deadline", type: "uint256" }
1059
- ]
1060
- };
1061
- var EIP712_DOMAIN_TYPE = [
1062
- { name: "name", type: "string" },
1063
- { name: "version", type: "string" },
1064
- { name: "chainId", type: "uint256" },
1065
- { name: "verifyingContract", type: "address" }
1066
- ];
1067
- function toEthSignTypedDataV4(permitData) {
1068
- return JSON.stringify({
1069
- domain: permitData.domain,
1070
- types: {
1071
- EIP712Domain: EIP712_DOMAIN_TYPE,
1072
- ...permitData.types
1073
- },
1074
- primaryType: permitData.primaryType,
1075
- message: {
1076
- owner: permitData.message.owner,
1077
- spender: permitData.message.spender,
1078
- value: permitData.message.value.toString(),
1079
- nonce: permitData.message.nonce.toString(),
1080
- deadline: permitData.message.deadline.toString()
1081
- }
1082
- });
1083
- }
1084
- async function prepareDepositPermitSignature(params) {
1085
- const {
1086
- vaultName,
1087
- depositAsset,
1088
- depositAmount,
1089
- to,
1090
- chainId,
1091
- deadline,
1092
- // Optional pre-fetched data to skip RPC calls
1093
- nonce: prefetchedNonce,
1094
- decimals: prefetchedDecimals,
1095
- tokenName: prefetchedTokenName,
1096
- tokenVersion: prefetchedTokenVersion
1097
- } = params;
1098
- try {
1099
- const normalizedChainId = toChainId(chainId);
1100
- const vault = await resolveVault({
1101
- vaultName,
1102
- assetAddress: depositAsset,
1103
- chainId: normalizedChainId,
1104
- callerEndpoint: "prepareDepositPermitSignature"
1105
- });
1106
- const communityCodeDepositorAddress = vault.vault.communityCodeDepositorAddress;
1107
- if (!communityCodeDepositorAddress) {
1108
- throw new APIError(
1109
- `CommunityCodeDepositor contract address not found for vault ${vault.id}`,
1110
- { endpoint: "prepareDepositPermitSignature" }
1111
- );
1112
- }
1113
- let resolvedTokenName;
1114
- let resolvedTokenVersion;
1115
- let resolvedNonce;
1116
- const hasAllPrefetchedData = prefetchedTokenName !== void 0 && prefetchedTokenVersion !== void 0 && prefetchedNonce !== void 0;
1117
- if (hasAllPrefetchedData) {
1118
- resolvedTokenName = prefetchedTokenName;
1119
- resolvedTokenVersion = prefetchedTokenVersion;
1120
- resolvedNonce = prefetchedNonce;
1121
- } else {
1122
- const client = await getClient(normalizedChainId);
1123
- try {
1124
- const [nameResult, versionResult, nonceResult] = await client.multicall(
1125
- {
1126
- contracts: [
1127
- {
1128
- address: depositAsset,
1129
- abi: erc2612Abi,
1130
- functionName: "name"
1131
- },
1132
- {
1133
- address: depositAsset,
1134
- abi: erc2612Abi,
1135
- functionName: "version"
1136
- },
1137
- {
1138
- address: depositAsset,
1139
- abi: erc2612Abi,
1140
- functionName: "nonces",
1141
- args: [to]
1142
- }
1143
- ]
1144
- }
1145
- );
1146
- if (prefetchedTokenName !== void 0) {
1147
- resolvedTokenName = prefetchedTokenName;
1148
- } else if (nameResult.status === "success") {
1149
- resolvedTokenName = nameResult.result;
1150
- } else {
1151
- throw new APIError(`Failed to read token name from ${depositAsset}`, {
1152
- endpoint: "prepareDepositPermitSignature",
1153
- cause: nameResult.error
1154
- });
1155
- }
1156
- if (prefetchedTokenVersion !== void 0) {
1157
- resolvedTokenVersion = prefetchedTokenVersion;
1158
- } else if (versionResult.status === "success") {
1159
- resolvedTokenVersion = versionResult.result;
1160
- } else {
1161
- resolvedTokenVersion = "1";
1162
- }
1163
- if (prefetchedNonce !== void 0) {
1164
- resolvedNonce = prefetchedNonce;
1165
- } else if (nonceResult.status === "success") {
1166
- resolvedNonce = nonceResult.result;
1167
- } else {
1168
- throw new APIError(
1169
- `Token ${depositAsset} does not support EIP-2612 permit. Missing required function: nonces()`,
1170
- {
1171
- endpoint: "prepareDepositPermitSignature",
1172
- cause: nonceResult.error
1173
- }
1174
- );
1175
- }
1176
- } catch (error) {
1177
- if (error instanceof APIError) {
1178
- throw error;
1179
- }
1180
- throw new APIError(
1181
- `Failed to read token metadata: ${error instanceof Error ? error.message : "Unknown error"}`,
1182
- {
1183
- endpoint: "prepareDepositPermitSignature",
1184
- cause: error
1185
- }
1186
- );
1187
- }
1188
- }
1189
- const permitDeadline = deadline ?? BigInt(Math.floor(Date.now() / 1e3) + 3600);
1190
- let resolvedDecimals;
1191
- if (prefetchedDecimals !== void 0) {
1192
- resolvedDecimals = prefetchedDecimals;
1193
- } else {
1194
- resolvedDecimals = await getErc20Decimals({
1195
- tokenAddress: depositAsset,
1196
- chainId: normalizedChainId
1197
- });
1198
- }
1199
- const value = parseUnits(depositAmount, resolvedDecimals);
1200
- const domain = {
1201
- name: resolvedTokenName,
1202
- version: resolvedTokenVersion,
1203
- chainId: normalizedChainId,
1204
- verifyingContract: depositAsset
1205
- };
1206
- const message = {
1207
- owner: to,
1208
- spender: communityCodeDepositorAddress,
1209
- value,
1210
- nonce: resolvedNonce,
1211
- deadline: permitDeadline
1212
- };
1213
- return {
1214
- account: to,
1215
- domain,
1216
- types: PERMIT_TYPES,
1217
- primaryType: "Permit",
1218
- message
1219
- };
1220
- } catch (error) {
1221
- if (error instanceof APIError) {
1222
- throw error;
1223
- }
1224
- throw new APIError(
1225
- `Failed to prepare permit signature: ${error instanceof Error ? error.message : String(error)}`,
1226
- {
1227
- endpoint: "prepareDepositPermitSignature",
1228
- cause: error
1229
- }
1230
- );
1231
- }
1232
- }
1233
- function parsePermitSignature(signature) {
1234
- try {
1235
- const parsed = hexToSignature(signature);
1236
- let v;
1237
- if (parsed.v !== void 0) {
1238
- v = Number(parsed.v);
1239
- } else if (parsed.yParity !== void 0) {
1240
- v = parsed.yParity + 27;
1241
- } else {
1242
- v = 27;
1243
- }
1244
- return {
1245
- v,
1246
- r: parsed.r,
1247
- s: parsed.s
1248
- };
1249
- } catch (error) {
1250
- throw new APIError(
1251
- `Invalid permit signature format. Expected hex string but received: ${signature}. ${error instanceof Error ? error.message : "Unknown error"}`,
1252
- {
1253
- endpoint: "parsePermitSignature",
1254
- cause: error
1255
- }
1256
- );
1257
- }
1258
- }
1259
- async function prepareDepositWithPermitTxData(params) {
1260
- const {
1261
- vaultName,
1262
- depositAsset,
1263
- depositAmount,
1264
- chainId,
1265
- signature,
1266
- deadline,
1267
- slippage = DEFAULT_SLIPPAGE_BPS,
1268
- to,
1269
- distributorCode
1270
- } = params;
1271
- try {
1272
- const { v, r, s } = parsePermitSignature(signature);
1273
- if (slippage < 0 || slippage > 1e4) {
1274
- throw new APIError(
1275
- `Invalid slippage value: ${slippage}. Slippage must be between 0 and 10000 basis points.`,
1276
- {
1277
- endpoint: "prepareDepositWithPermitTxData"
1278
- }
1279
- );
1280
- }
1281
- const normalizedChainId = toChainId(chainId);
1282
- const vault = await resolveVault({
1283
- vaultName,
1284
- assetAddress: depositAsset,
1285
- chainId: normalizedChainId,
1286
- callerEndpoint: "prepareDepositWithPermitTxData"
1287
- });
1288
- if (vault.inDeprecation) {
1289
- getLogger().warn(
1290
- `Vault "${vault.name}" is being deprecated. Please contact the Paxos Labs team for migration guidance.`
1291
- );
1292
- }
1293
- let asset = null;
1294
- const assets = await getSupportedAssets({ address: depositAsset });
1295
- if (assets.length > 0) {
1296
- asset = assets.find((a) => a.chains.includes(normalizedChainId)) || assets[0] || null;
1297
- }
1298
- if (!asset) {
1299
- throw new APIError(
1300
- `Asset metadata not found for token ${depositAsset} on chain ${normalizedChainId}`,
1301
- {
1302
- endpoint: "prepareDepositWithPermitTxData"
1303
- }
1304
- );
1305
- }
1306
- if (!asset.chains || !asset.chains.includes(normalizedChainId)) {
1307
- throw new APIError(
1308
- `Token ${asset.symbol || depositAsset} not supported on chain ${normalizedChainId}`,
1309
- {
1310
- endpoint: "prepareDepositWithPermitTxData"
1311
- }
1312
- );
1313
- }
1314
- const communityCodeDepositorAddress = vault.vault.communityCodeDepositorAddress;
1315
- const accountantAddress = vault.vault.accountantAddress;
1316
- const depositAssetAddress = depositAsset;
1317
- if (!communityCodeDepositorAddress) {
1318
- throw new APIError(
1319
- `CommunityCodeDepositor contract address not found for vault ${vault.id}`,
1320
- { endpoint: "prepareDepositWithPermitTxData" }
1321
- );
1322
- }
1323
- if (!accountantAddress) {
1324
- throw new APIError(
1325
- `Accountant contract address not found for vault ${vault.id}`,
1326
- { endpoint: "prepareDepositWithPermitTxData" }
1327
- );
1328
- }
1329
- const rateAndDecimalResults = await getRateInQuoteWithAssetDecimals({
1330
- assetAddress: depositAssetAddress,
1331
- accountantAddress,
1332
- chainId: normalizedChainId
1333
- });
1334
- const [depositAssetDecimalsResult, rateInQuoteResult] = rateAndDecimalResults;
1335
- if (depositAssetDecimalsResult.status === "failure") {
1336
- throw new APIError(
1337
- `Failed to get asset decimals: ${depositAssetDecimalsResult.error?.message || "Unknown error"}`,
1338
- {
1339
- endpoint: "prepareDepositWithPermitTxData",
1340
- cause: depositAssetDecimalsResult.error
1341
- }
1342
- );
1343
- }
1344
- if (rateInQuoteResult.status === "failure") {
1345
- throw new APIError(
1346
- `Failed to get exchange rate: ${rateInQuoteResult.error?.message || "Unknown error"}`,
1347
- {
1348
- endpoint: "prepareDepositWithPermitTxData",
1349
- cause: rateInQuoteResult.error
1350
- }
1351
- );
1352
- }
1353
- const onChainDecimals = depositAssetDecimalsResult.result;
1354
- const depositAmountAsBigInt = parseUnits(depositAmount, onChainDecimals);
1355
- const totalFee = await getDepositFeeForAmount(
1356
- vault.vault.depositFeeModuleAddress,
1357
- depositAssetAddress,
1358
- depositAmountAsBigInt,
1359
- normalizedChainId
1360
- );
1361
- if (totalFee >= depositAmountAsBigInt) {
1362
- throw new APIError(
1363
- "Deposit amount is entirely consumed by fees. Increase the deposit amount.",
1364
- { endpoint: "prepareDepositWithPermitTxData" }
1365
- );
1366
- }
1367
- const depositAmountAfterFees = depositAmountAsBigInt - totalFee;
1368
- await assertDepositWithinCap(
1369
- vault,
1370
- depositAmountAfterFees,
1371
- depositAssetAddress,
1372
- normalizedChainId,
1373
- "prepareDepositWithPermitTxData"
1374
- );
1375
- const minimumMint = calculateMinimumMint(
1376
- depositAmountAfterFees,
1377
- rateInQuoteResult.result,
1378
- onChainDecimals,
1379
- slippage
1380
- );
1381
- const distributorCodeHex = stringToHex(distributorCode || "");
1382
- const policyId = vault.enterpriseConfig?.predicatePolicyId;
1383
- if (policyId === void 0) {
1384
- return {
1385
- depositType: DepositType.STANDARD,
1386
- abi: DistributorCodeDepositorAbiV0,
1387
- address: communityCodeDepositorAddress,
1388
- functionName: "depositWithPermit",
1389
- args: [
1390
- depositAssetAddress,
1391
- depositAmountAsBigInt,
1392
- minimumMint,
1393
- to,
1394
- distributorCodeHex,
1395
- deadline,
1396
- v,
1397
- r,
1398
- s
1399
- ],
1400
- chainId: normalizedChainId
1401
- };
1402
- }
1403
- if (policyId === null) {
1404
- const emptyAttestation = {
1405
- uuid: "",
1406
- expiration: 0n,
1407
- attester: zeroAddress,
1408
- signature: "0x"
1409
- };
1410
- return {
1411
- depositType: DepositType.KYT,
1412
- abi: DistributorCodeDepositorAbiV1,
1413
- address: communityCodeDepositorAddress,
1414
- functionName: "depositWithPermit",
1415
- args: [
1416
- depositAssetAddress,
1417
- depositAmountAsBigInt,
1418
- minimumMint,
1419
- to,
1420
- distributorCodeHex,
1421
- emptyAttestation,
1422
- deadline,
1423
- v,
1424
- r,
1425
- s
1426
- ],
1427
- chainId: normalizedChainId
1428
- };
1429
- }
1430
- const attestation = await fetchKytAttestation({
1431
- to: communityCodeDepositorAddress,
1432
- from: to,
1433
- chainId: normalizedChainId
1434
- });
1435
- return {
1436
- depositType: DepositType.KYT,
1437
- abi: DistributorCodeDepositorAbiV1,
1438
- address: communityCodeDepositorAddress,
1439
- functionName: "depositWithPermit",
1440
- args: [
1441
- depositAssetAddress,
1442
- depositAmountAsBigInt,
1443
- minimumMint,
1444
- to,
1445
- distributorCodeHex,
1446
- attestation,
1447
- deadline,
1448
- v,
1449
- r,
1450
- s
1451
- ],
1452
- chainId: normalizedChainId
1453
- };
1454
- } catch (error) {
1455
- if (error instanceof APIError) {
1456
- throw error;
1457
- }
1458
- throw new APIError(
1459
- `Failed to prepare deposit with permit transaction: ${error instanceof Error ? error.message : String(error)}`,
1460
- {
1461
- endpoint: "prepareDepositWithPermitTxData",
1462
- cause: error
1463
- }
1464
- );
1465
- }
1466
- }
1467
-
1468
- // src/utils/wallet.ts
1469
- async function isSmartContractWallet(address, chainId) {
1470
- const client = await getClient(chainId);
1471
- const code = await client.getCode({ address });
1472
- return !!code && code !== "0x";
1473
- }
1474
-
1475
- // src/vaults/deposit/index.ts
1476
- var DepositAuthMethod = {
1477
- PERMIT: "permit",
1478
- APPROVAL: "approval",
1479
- ALREADY_APPROVED: "already_approved"
1480
- };
1481
- function isPermitAuth(result) {
1482
- return result.method === DepositAuthMethod.PERMIT;
1483
- }
1484
- function isApprovalAuth(result) {
1485
- return result.method === DepositAuthMethod.APPROVAL;
1486
- }
1487
- function isAlreadyApprovedAuth(result) {
1488
- return result.method === DepositAuthMethod.ALREADY_APPROVED;
1489
- }
1490
- async function prepareDepositAuthorization(params) {
1491
- const {
1492
- vaultName,
1493
- depositAsset,
1494
- depositAmount,
1495
- to,
1496
- chainId,
1497
- deadline,
1498
- forceMethod
1499
- } = params;
1500
- try {
1501
- const normalizedChainId = toChainId(chainId);
1502
- const vault = await resolveVault({
1503
- vaultName,
1504
- assetAddress: depositAsset,
1505
- chainId: normalizedChainId,
1506
- callerEndpoint: "prepareDepositAuthorization"
1507
- });
1508
- if (forceMethod === "approval") {
1509
- const txData2 = await prepareApproveDepositTokenTxData({
1510
- vaultName,
1511
- depositAsset,
1512
- approvalAmount: depositAmount,
1513
- chainId: normalizedChainId
1514
- });
1515
- return {
1516
- method: DepositAuthMethod.APPROVAL,
1517
- txData: txData2
1518
- };
1519
- }
1520
- if (forceMethod === "permit") {
1521
- const tokenInfo2 = await isDepositSpendApproved({
1522
- vaultName: vault.name,
1523
- chainId: normalizedChainId,
1524
- depositAssetAddress: depositAsset,
1525
- recipientAddress: to
1526
- });
1527
- const permitData = await prepareDepositPermitSignature({
1528
- vaultName,
1529
- depositAsset,
1530
- depositAmount,
1531
- to,
1532
- chainId: normalizedChainId,
1533
- deadline,
1534
- nonce: tokenInfo2.nonce ?? void 0,
1535
- decimals: tokenInfo2.decimals,
1536
- tokenName: tokenInfo2.tokenName,
1537
- tokenVersion: tokenInfo2.tokenVersion
1538
- });
1539
- return {
1540
- method: DepositAuthMethod.PERMIT,
1541
- permitData
1542
- };
1543
- }
1544
- const smartWallet = await isSmartContractWallet(to, normalizedChainId);
1545
- if (smartWallet) {
1546
- const txData2 = await prepareApproveDepositTokenTxData({
1547
- vaultName,
1548
- depositAsset,
1549
- approvalAmount: depositAmount,
1550
- chainId: normalizedChainId
1551
- });
1552
- return {
1553
- method: DepositAuthMethod.APPROVAL,
1554
- txData: txData2
1555
- };
1556
- }
1557
- const tokenInfo = await isDepositSpendApproved({
1558
- vaultName: vault.name,
1559
- chainId: normalizedChainId,
1560
- depositAssetAddress: depositAsset,
1561
- recipientAddress: to
1562
- });
1563
- if (tokenInfo.supportsPermit) {
1564
- const permitData = await prepareDepositPermitSignature({
1565
- vaultName,
1566
- depositAsset,
1567
- depositAmount,
1568
- to,
1569
- chainId: normalizedChainId,
1570
- deadline,
1571
- nonce: tokenInfo.nonce ?? void 0,
1572
- decimals: tokenInfo.decimals,
1573
- tokenName: tokenInfo.tokenName,
1574
- tokenVersion: tokenInfo.tokenVersion
1575
- });
1576
- return {
1577
- method: DepositAuthMethod.PERMIT,
1578
- permitData
1579
- };
1580
- }
1581
- const depositAmountBigInt = parseUnits(depositAmount, tokenInfo.decimals);
1582
- const currentAllowanceBigInt = BigInt(tokenInfo.allowanceAsBigInt);
1583
- if (tokenInfo.isApproved && currentAllowanceBigInt >= depositAmountBigInt) {
1584
- return {
1585
- method: DepositAuthMethod.ALREADY_APPROVED,
1586
- allowance: tokenInfo.allowance,
1587
- allowanceAsBigInt: tokenInfo.allowanceAsBigInt
1588
- };
1589
- }
1590
- const txData = await prepareApproveDepositTokenTxData({
1591
- vaultName,
1592
- depositAsset,
1593
- approvalAmount: depositAmount,
1594
- chainId: normalizedChainId
1595
- });
1596
- return {
1597
- method: DepositAuthMethod.APPROVAL,
1598
- txData
1599
- };
1600
- } catch (error) {
1601
- if (error instanceof APIError) {
1602
- throw error;
1603
- }
1604
- throw new APIError(
1605
- `Failed to prepare deposit authorization: ${error instanceof Error ? error.message : String(error)}`,
1606
- {
1607
- endpoint: "prepareDepositAuthorization",
1608
- cause: error
1609
- }
1610
- );
1611
- }
1612
- }
1613
- async function prepareDeposit(params) {
1614
- const {
1615
- vaultName,
1616
- depositAsset,
1617
- depositAmount,
1618
- to,
1619
- chainId,
1620
- slippage,
1621
- distributorCode,
1622
- signature,
1623
- deadline,
1624
- forceMethod
1625
- } = params;
1626
- try {
1627
- if (forceMethod === "permit" && (!signature || deadline === void 0)) {
1628
- throw new APIError(
1629
- "Permit deposit requires both signature and deadline parameters when forceMethod is 'permit'",
1630
- { endpoint: "prepareDeposit" }
1631
- );
1632
- }
1633
- const usePermit = forceMethod === "permit" || forceMethod !== "approval" && signature !== void 0 && deadline !== void 0;
1634
- if (usePermit) {
1635
- if (!signature || deadline === void 0) {
1636
- throw new APIError(
1637
- "Permit deposit requires both signature and deadline parameters",
1638
- { endpoint: "prepareDeposit" }
1639
- );
1640
- }
1641
- const txData2 = await prepareDepositWithPermitTxData({
1642
- vaultName,
1643
- depositAsset,
1644
- depositAmount,
1645
- to,
1646
- chainId,
1647
- signature,
1648
- deadline,
1649
- slippage,
1650
- distributorCode
1651
- });
1652
- return {
1653
- method: DepositAuthMethod.PERMIT,
1654
- txData: txData2
1655
- };
1656
- }
1657
- const txData = await prepareDepositTxData({
1658
- vaultName,
1659
- depositAsset,
1660
- depositAmount,
1661
- to,
1662
- chainId,
1663
- slippage,
1664
- distributorCode
1665
- });
1666
- return {
1667
- method: DepositAuthMethod.APPROVAL,
1668
- txData
1669
- };
1670
- } catch (error) {
1671
- if (error instanceof APIError) {
1672
- throw error;
1673
- }
1674
- throw new APIError(
1675
- `Failed to prepare deposit: ${error instanceof Error ? error.message : String(error)}`,
1676
- {
1677
- endpoint: "prepareDeposit",
1678
- cause: error
1679
- }
1680
- );
1681
- }
1682
- }
1683
- async function prepareApproveWithdrawOrderTxData({
1684
- vaultName,
1685
- wantAssetAddress,
1686
- withdrawAmount,
1687
- chainId,
1688
- shareDecimals
1689
- }) {
1690
- try {
1691
- const normalizedChainId = toChainId(chainId);
1692
- const config = await resolveVault({
1693
- vaultName,
1694
- assetAddress: wantAssetAddress,
1695
- chainId: normalizedChainId,
1696
- callerEndpoint: "prepareApproveWithdrawOrderTxData"
1697
- });
1698
- if (!config.vault.boringVaultAddress) {
1699
- throw new APIError(
1700
- `BoringVault contract address not configured for vault ${config.id}`,
1701
- { endpoint: "prepareApproveWithdrawOrderTxData" }
1702
- );
1703
- }
1704
- if (!config.vault.withdrawQueueAddress) {
1705
- throw new APIError(
1706
- `WithdrawQueue contract address not configured for vault ${config.id}`,
1707
- { endpoint: "prepareApproveWithdrawOrderTxData" }
1708
- );
1709
- }
1710
- const boringVaultAddress = config.vault.boringVaultAddress;
1711
- const withdrawQueueAddress = config.vault.withdrawQueueAddress;
1712
- const decimals = shareDecimals ?? await getErc20Decimals({
1713
- tokenAddress: boringVaultAddress,
1714
- chainId: normalizedChainId
1715
- });
1716
- const withdrawAmountAsBigInt = withdrawAmount ? parseUnits(withdrawAmount, decimals) : DEFAULT_APPROVAL_AMOUNT;
1717
- return {
1718
- abi: BoringVaultAbi,
1719
- address: boringVaultAddress,
1720
- functionName: "approve",
1721
- args: [withdrawQueueAddress, withdrawAmountAsBigInt]
1722
- };
1723
- } catch (error) {
1724
- if (error instanceof APIError) {
1725
- throw error;
1726
- }
1727
- throw new APIError(
1728
- `Failed to prepare approval transaction: ${error instanceof Error ? error.message : String(error)}`,
1729
- {
1730
- endpoint: "prepareApproveWithdrawOrderTxData",
1731
- cause: error
1732
- }
1733
- );
1734
- }
1735
- }
1736
-
1737
- // src/vaults/withdraw/cancel-withdraw.ts
1738
- var prepareCancelWithdrawOrderTxData = async ({
1739
- vaultName,
1740
- wantAsset,
1741
- chainId,
1742
- orderIndex
1743
- }) => {
1744
- try {
1745
- const normalizedChainId = toChainId(chainId);
1746
- const config = await resolveVault({
1747
- vaultName,
1748
- assetAddress: wantAsset,
1749
- chainId: normalizedChainId,
1750
- callerEndpoint: "prepareCancelWithdrawOrderTxData"
1751
- });
1752
- if (config.chainId !== normalizedChainId) {
1753
- throw new APIError(
1754
- `Vault chain mismatch: vault is on chain ${config.chainId}, requested chain ${normalizedChainId}`,
1755
- { endpoint: "prepareCancelWithdrawOrderTxData" }
1756
- );
1757
- }
1758
- if (!config.vault.withdrawQueueAddress) {
1759
- throw new APIError(
1760
- `WithdrawQueue contract address not configured for vault ${config.id}`,
1761
- { endpoint: "prepareCancelWithdrawOrderTxData" }
1762
- );
1763
- }
1764
- return {
1765
- abi: WithdrawQueueAbi,
1766
- address: config.vault.withdrawQueueAddress,
1767
- functionName: "cancelOrder",
1768
- args: [orderIndex],
1769
- chainId: normalizedChainId
1770
- };
1771
- } catch (error) {
1772
- if (error instanceof APIError) {
1773
- throw error;
1774
- }
1775
- throw new APIError(
1776
- `Failed to prepare cancel order transaction: ${error instanceof Error ? error.message : String(error)}`,
1777
- {
1778
- endpoint: "prepareCancelWithdrawOrderTxData",
1779
- cause: error
1780
- }
1781
- );
1782
- }
1783
- };
1784
- var ApprovalMethod = {
1785
- /** Standard ERC20 approve (user has pre-approved via approve()) */
1786
- EIP20_APPROVE: 0};
1787
- var EMPTY_SIGNATURE_PARAMS = {
1788
- approvalMethod: ApprovalMethod.EIP20_APPROVE,
1789
- approvalV: 0,
1790
- approvalR: "0x0000000000000000000000000000000000000000000000000000000000000000",
1791
- approvalS: "0x0000000000000000000000000000000000000000000000000000000000000000",
1792
- submitWithSignature: false,
1793
- deadline: 0n,
1794
- eip2612Signature: "0x"
1795
- };
1796
- var prepareWithdrawOrderTxData = async ({
1797
- vaultName,
1798
- wantAsset,
1799
- userAddress,
1800
- chainId,
1801
- amountOffer
1802
- }) => {
1803
- try {
1804
- const normalizedChainId = toChainId(chainId);
1805
- const config = await resolveVault({
1806
- vaultName,
1807
- assetAddress: wantAsset,
1808
- chainId: normalizedChainId,
1809
- callerEndpoint: "prepareWithdrawOrderTxData"
1810
- });
1811
- if (config.chainId !== normalizedChainId) {
1812
- throw new APIError(
1813
- `Vault chain mismatch: vault is on chain ${config.chainId}, requested chain ${normalizedChainId}`,
1814
- { endpoint: "prepareWithdrawOrderTxData" }
1815
- );
1816
- }
1817
- if (!config.vault.withdrawQueueAddress) {
1818
- throw new APIError(
1819
- `WithdrawQueue contract address not configured for vault ${config.id}`,
1820
- { endpoint: "prepareWithdrawOrderTxData" }
1821
- );
1822
- }
1823
- if (!config.vault.boringVaultAddress) {
1824
- throw new APIError(
1825
- `BoringVault contract address not configured for vault ${config.id}`,
1826
- { endpoint: "prepareWithdrawOrderTxData" }
1827
- );
1828
- }
1829
- const sharesDecimals = await getErc20Decimals({
1830
- tokenAddress: config.vault.boringVaultAddress,
1831
- chainId: normalizedChainId
1832
- });
1833
- const formattedAmountOffer = parseUnits(amountOffer, sharesDecimals);
1834
- return {
1835
- abi: WithdrawQueueAbi,
1836
- address: config.vault.withdrawQueueAddress,
1837
- functionName: "submitOrder",
1838
- args: [
1839
- {
1840
- amountOffer: formattedAmountOffer,
1841
- wantAsset,
1842
- intendedDepositor: userAddress,
1843
- receiver: userAddress,
1844
- refundReceiver: userAddress,
1845
- signatureParams: EMPTY_SIGNATURE_PARAMS
1846
- }
1847
- ],
1848
- chainId: normalizedChainId
1849
- };
1850
- } catch (error) {
1851
- if (error instanceof APIError) {
1852
- throw error;
1853
- }
1854
- throw new APIError(
1855
- `Failed to prepare withdraw order transaction: ${error instanceof Error ? error.message : String(error)}`,
1856
- {
1857
- endpoint: "prepareWithdrawOrderTxData",
1858
- cause: error
1859
- }
1860
- );
1861
- }
1862
- };
1863
- var prepareAtomicWithdrawOrderTxData = async ({
1864
- vaultName,
1865
- wantAsset,
1866
- userAddress,
1867
- chainId,
1868
- amountOffer
1869
- }) => {
1870
- try {
1871
- const normalizedChainId = toChainId(chainId);
1872
- const config = await resolveVault({
1873
- vaultName,
1874
- assetAddress: wantAsset,
1875
- chainId: normalizedChainId,
1876
- callerEndpoint: "prepareAtomicWithdrawOrderTxData"
1877
- });
1878
- if (config.chainId !== normalizedChainId) {
1879
- throw new InvalidChainIdError(
1880
- `Vault chain mismatch: vault is on chain ${config.chainId}, requested chain ${normalizedChainId}`,
1881
- {
1882
- vaultId: config.id,
1883
- vaultChainId: config.chainId,
1884
- requestedChainId: normalizedChainId
1885
- }
1886
- );
1887
- }
1888
- if (!config.vault.withdrawQueueAddress) {
1889
- throw new TransactionDataError(
1890
- `WithdrawQueue contract address not configured for vault ${config.id}`,
1891
- { vaultId: config.id, field: "withdrawQueueAddress" }
1892
- );
1893
- }
1894
- if (!config.vault.boringVaultAddress) {
1895
- throw new TransactionDataError(
1896
- `BoringVault contract address not configured for vault ${config.id}`,
1897
- { vaultId: config.id, field: "boringVaultAddress" }
1898
- );
1899
- }
1900
- const sharesDecimals = await getErc20Decimals({
1901
- tokenAddress: config.vault.boringVaultAddress,
1902
- chainId: normalizedChainId
1903
- });
1904
- const formattedAmountOffer = parseUnits(amountOffer, sharesDecimals);
1905
- return {
1906
- abi: WithdrawQueueAbi,
1907
- address: config.vault.withdrawQueueAddress,
1908
- functionName: "submitOrderAndProcessAll",
1909
- args: [
1910
- {
1911
- amountOffer: formattedAmountOffer,
1912
- wantAsset,
1913
- intendedDepositor: userAddress,
1914
- receiver: userAddress,
1915
- refundReceiver: userAddress,
1916
- signatureParams: EMPTY_SIGNATURE_PARAMS
1917
- }
1918
- ],
1919
- chainId: normalizedChainId
1920
- };
1921
- } catch (error) {
1922
- if (error instanceof WithdrawError) {
1923
- throw error;
1924
- }
1925
- throw new TransactionDataError(
1926
- `Failed to prepare atomic withdraw order transaction: ${error instanceof Error ? error.message : String(error)}`,
1927
- {
1928
- endpoint: "prepareAtomicWithdrawOrderTxData",
1929
- cause: error
1930
- }
1931
- );
1932
- }
1933
- };
1934
-
1935
- // src/vaults/withdraw/index.ts
1936
- var WithdrawAuthMethod = {
1937
- APPROVAL: "approval",
1938
- ALREADY_APPROVED: "already_approved"
1939
- };
1940
- function isWithdrawApprovalAuth(result) {
1941
- return result.method === WithdrawAuthMethod.APPROVAL;
1942
- }
1943
- function isWithdrawAlreadyApprovedAuth(result) {
1944
- return result.method === WithdrawAuthMethod.ALREADY_APPROVED;
1945
- }
1946
- async function prepareWithdrawal(params) {
1947
- const { vaultName, wantAsset, withdrawAmount, userAddress, chainId } = params;
1948
- try {
1949
- const normalizedChainId = toChainId(chainId);
1950
- const vault = await resolveVault({
1951
- vaultName,
1952
- assetAddress: wantAsset,
1953
- chainId: normalizedChainId,
1954
- callerEndpoint: "prepareWithdrawal"
1955
- });
1956
- const builderParams = {
1957
- vaultName,
1958
- wantAsset,
1959
- userAddress,
1960
- chainId,
1961
- amountOffer: withdrawAmount
1962
- };
1963
- return vault.atomicWithdrawal ? await prepareAtomicWithdrawOrderTxData(builderParams) : await prepareWithdrawOrderTxData(builderParams);
1964
- } catch (error) {
1965
- if (error instanceof APIError) {
1966
- throw error;
1967
- }
1968
- throw new APIError(
1969
- `Failed to prepare withdrawal: ${error instanceof Error ? error.message : String(error)}`,
1970
- {
1971
- endpoint: "prepareWithdrawal",
1972
- cause: error
1973
- }
1974
- );
1975
- }
1976
- }
1977
- async function prepareWithdrawalAuthorization(params) {
1978
- const {
1979
- vaultName,
1980
- wantAsset,
1981
- withdrawAmount,
1982
- userAddress,
1983
- chainId,
1984
- forceMethod
1985
- } = params;
1986
- try {
1987
- const normalizedChainId = toChainId(chainId);
1988
- const vault = await resolveVault({
1989
- vaultName,
1990
- assetAddress: wantAsset,
1991
- chainId: normalizedChainId,
1992
- callerEndpoint: "prepareWithdrawalAuthorization"
1993
- });
1994
- if (forceMethod === "approval") {
1995
- const txData2 = await prepareApproveWithdrawOrderTxData({
1996
- vaultName,
1997
- wantAssetAddress: wantAsset,
1998
- withdrawAmount,
1999
- chainId: normalizedChainId
2000
- });
2001
- return {
2002
- method: WithdrawAuthMethod.APPROVAL,
2003
- txData: txData2
2004
- };
2005
- }
2006
- if (forceMethod !== "allowance_check") {
2007
- const smartWallet = await isSmartContractWallet(
2008
- userAddress,
2009
- normalizedChainId
2010
- );
2011
- if (smartWallet) {
2012
- const txData2 = await prepareApproveWithdrawOrderTxData({
2013
- vaultName,
2014
- wantAssetAddress: wantAsset,
2015
- withdrawAmount,
2016
- chainId: normalizedChainId
2017
- });
2018
- return {
2019
- method: WithdrawAuthMethod.APPROVAL,
2020
- txData: txData2
2021
- };
2022
- }
2023
- }
2024
- const approvalInfo = await isWithdrawalSpendApproved({
2025
- vaultName: vault.name,
2026
- chainId: normalizedChainId,
2027
- wantAssetAddress: wantAsset,
2028
- recipientAddress: userAddress
2029
- });
2030
- if (approvalInfo.error) {
2031
- throw new APIError(
2032
- `Failed to check withdrawal approval: ${approvalInfo.error}`,
2033
- { endpoint: "prepareWithdrawalAuthorization" }
2034
- );
2035
- }
2036
- const decimals = typeof approvalInfo.decimals === "string" ? Number(approvalInfo.decimals) : approvalInfo.decimals;
2037
- const withdrawAmountBigInt = parseUnits(withdrawAmount, decimals);
2038
- const currentAllowanceBigInt = BigInt(approvalInfo.allowanceAsBigInt);
2039
- if (approvalInfo.isApproved && currentAllowanceBigInt >= withdrawAmountBigInt) {
2040
- return {
2041
- method: WithdrawAuthMethod.ALREADY_APPROVED,
2042
- allowance: approvalInfo.allowance,
2043
- allowanceAsBigInt: approvalInfo.allowanceAsBigInt
2044
- };
2045
- }
2046
- const txData = await prepareApproveWithdrawOrderTxData({
2047
- vaultName,
2048
- wantAssetAddress: wantAsset,
2049
- withdrawAmount,
2050
- chainId: normalizedChainId,
2051
- shareDecimals: decimals
2052
- });
2053
- return {
2054
- method: WithdrawAuthMethod.APPROVAL,
2055
- txData
2056
- };
2057
- } catch (error) {
2058
- if (error instanceof APIError) {
2059
- throw error;
2060
- }
2061
- throw new APIError(
2062
- `Failed to prepare withdrawal authorization: ${error instanceof Error ? error.message : String(error)}`,
2063
- {
2064
- endpoint: "prepareWithdrawalAuthorization",
2065
- cause: error
2066
- }
2067
- );
2068
- }
2069
- }
2070
-
2071
- export { DepositAuthMethod, DepositType, PERMIT_TYPES, WithdrawAuthMethod, fetchKytAttestation, isAlreadyApprovedAuth, isApprovalAuth, isDepositSpendApproved, isKytDeposit, isPermitAuth, isStandardDeposit, isWithdrawAlreadyApprovedAuth, isWithdrawApprovalAuth, isWithdrawalSpendApproved, parsePermitSignature, prepareApproveDepositTokenTxData, prepareApproveWithdrawOrderTxData, prepareCancelWithdrawOrderTxData, prepareDeposit, prepareDepositAuthorization, prepareDepositPermitSignature, prepareDepositTxData, prepareDepositWithPermitTxData, prepareWithdrawOrderTxData, prepareWithdrawal, prepareWithdrawalAuthorization, toEthSignTypedDataV4 };
2072
- //# sourceMappingURL=chunk-LMNADWTH.mjs.map
2073
- //# sourceMappingURL=chunk-LMNADWTH.mjs.map