deploy-sdk 0.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.
@@ -0,0 +1,732 @@
1
+ // src/modules/mint/MintModule.ts
2
+ import { Contract } from "ethers";
3
+
4
+ // src/core/errors.ts
5
+ var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
6
+ ErrorCode2["NOT_INITIALIZED"] = "NOT_INITIALIZED";
7
+ ErrorCode2["WALLET_NOT_CONNECTED"] = "WALLET_NOT_CONNECTED";
8
+ ErrorCode2["INVALID_CHAIN"] = "INVALID_CHAIN";
9
+ ErrorCode2["INSUFFICIENT_BALANCE"] = "INSUFFICIENT_BALANCE";
10
+ ErrorCode2["INSUFFICIENT_ALLOWANCE"] = "INSUFFICIENT_ALLOWANCE";
11
+ ErrorCode2["TRANSACTION_FAILED"] = "TRANSACTION_FAILED";
12
+ ErrorCode2["STAKE_FAILED"] = "STAKE_FAILED";
13
+ ErrorCode2["UNSTAKE_FAILED"] = "UNSTAKE_FAILED";
14
+ ErrorCode2["COOLDOWN_FAILED"] = "COOLDOWN_FAILED";
15
+ ErrorCode2["MINT_FAILED"] = "MINT_FAILED";
16
+ ErrorCode2["REDEEM_FAILED"] = "REDEEM_FAILED";
17
+ ErrorCode2["INVALID_ORDER"] = "INVALID_ORDER";
18
+ ErrorCode2["SIGNATURE_FAILED"] = "SIGNATURE_FAILED";
19
+ ErrorCode2["API_ERROR"] = "API_ERROR";
20
+ ErrorCode2["VALIDATION_ERROR"] = "VALIDATION_ERROR";
21
+ return ErrorCode2;
22
+ })(ErrorCode || {});
23
+ var DeploySDKError = class _DeploySDKError extends Error {
24
+ constructor(code, message, originalError) {
25
+ super(message);
26
+ this.name = "DeploySDKError";
27
+ this.code = code;
28
+ this.originalError = originalError;
29
+ if (Error.captureStackTrace) {
30
+ Error.captureStackTrace(this, _DeploySDKError);
31
+ }
32
+ }
33
+ toJSON() {
34
+ return {
35
+ name: this.name,
36
+ code: this.code,
37
+ message: this.message,
38
+ originalError: this.originalError?.message || this.originalError
39
+ };
40
+ }
41
+ };
42
+
43
+ // src/core/constants.ts
44
+ var CONTRACT_ADDRESSES = {
45
+ [1 /* ETHEREUM */]: {
46
+ USDC: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
47
+ USDT: "0xdac17f958d2ee523a2206206994597c13d831ec7",
48
+ dUSD: "0xf42e0b98e32150fe02a370456e6479fcd94f5531",
49
+ DUSD_MINTER: "0x1ee453Ea35f6EAbD9BFF126586322cbC906D4EB3",
50
+ sDUSD_STAKING: "0x7f37B0133B1adC1D0647EE52eA38fA13caC4aA1B"
51
+ },
52
+ [42161 /* ARBITRUM */]: {}
53
+ };
54
+ var COLLATERAL_ASSETS = {
55
+ USDC: {
56
+ key: "USDC",
57
+ name: "USD Coin",
58
+ symbol: "USDC",
59
+ address: CONTRACT_ADDRESSES[1 /* ETHEREUM */].USDC,
60
+ decimals: 6,
61
+ mintingContract: CONTRACT_ADDRESSES[1 /* ETHEREUM */].DUSD_MINTER
62
+ },
63
+ USDT: {
64
+ key: "USDT",
65
+ name: "Tether USD",
66
+ symbol: "USDT",
67
+ address: CONTRACT_ADDRESSES[1 /* ETHEREUM */].USDT,
68
+ decimals: 6,
69
+ mintingContract: CONTRACT_ADDRESSES[1 /* ETHEREUM */].DUSD_MINTER
70
+ }
71
+ };
72
+ var STAKE_TOKENS = {
73
+ dUSD: {
74
+ key: "dUSD",
75
+ name: "Deploy USD",
76
+ symbol: "dUSD",
77
+ address: CONTRACT_ADDRESSES[1 /* ETHEREUM */].dUSD,
78
+ decimals: 18,
79
+ supportedCollateral: [COLLATERAL_ASSETS.USDC, COLLATERAL_ASSETS.USDT],
80
+ stakingContract: CONTRACT_ADDRESSES[1 /* ETHEREUM */].sDUSD_STAKING,
81
+ stakingSymbol: "sDUSD",
82
+ cooldownPeriod: 90 * 24 * 60 * 60 * 1e3
83
+ }
84
+ };
85
+ var EIP712_TYPES_ORDER = {
86
+ Order: [
87
+ { name: "order_id", type: "string" },
88
+ { name: "order_type", type: "uint8" },
89
+ { name: "expiry", type: "uint256" },
90
+ { name: "nonce", type: "uint256" },
91
+ { name: "benefactor", type: "address" },
92
+ { name: "beneficiary", type: "address" },
93
+ { name: "collateral_asset", type: "address" },
94
+ { name: "collateral_amount", type: "uint256" },
95
+ { name: "dAsset_amount", type: "uint256" }
96
+ ]
97
+ };
98
+ var ERC4626_ABI = [
99
+ "function deposit(uint256 assets, address receiver) external returns (uint256 shares)",
100
+ "function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares)",
101
+ "function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets)",
102
+ "function cooldownShares(uint256 shares) external",
103
+ "function cooldowns(address user) external view returns (uint256 cooldownEnd, uint256 underlyingAmount)",
104
+ "function balanceOf(address owner) external view returns (uint256)",
105
+ "function convertToShares(uint256 assets) external view returns (uint256)",
106
+ "function convertToAssets(uint256 shares) external view returns (uint256)",
107
+ "function totalAssets() external view returns (uint256)",
108
+ "function totalSupply() external view returns (uint256)",
109
+ "event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares)",
110
+ "event Withdraw(address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares)"
111
+ ];
112
+ var ERC20_ABI = [
113
+ "function approve(address spender, uint256 amount) external returns (bool)",
114
+ "function allowance(address owner, address spender) external view returns (uint256)",
115
+ "function balanceOf(address account) external view returns (uint256)",
116
+ "function decimals() external view returns (uint8)",
117
+ "function symbol() external view returns (string)",
118
+ "function name() external view returns (string)",
119
+ "function transfer(address recipient, uint256 amount) external returns (bool)",
120
+ "function transferFrom(address sender, address recipient, uint256 amount) external returns (bool)",
121
+ "event Approval(address indexed owner, address indexed spender, uint256 value)",
122
+ "event Transfer(address indexed from, address indexed to, uint256 value)"
123
+ ];
124
+ var MINTER_ABI = [
125
+ "function mint(tuple(string order_id, uint8 order_type, uint256 expiry, uint256 nonce, address benefactor, address beneficiary, address collateral_asset, uint256 collateral_amount, uint256 dAsset_amount) order, tuple(address[] addresses, uint256[] ratios) route, tuple(uint8 signature_type, bytes signature_bytes) signature) external",
126
+ "function redeem(tuple(string order_id, uint8 order_type, uint256 expiry, uint256 nonce, address benefactor, address beneficiary, address collateral_asset, uint256 collateral_amount, uint256 dAsset_amount) order, tuple(uint8 signature_type, bytes signature_bytes) signature) external",
127
+ "function isWhitelistedBenefactor(address benefactor) external view returns (bool)",
128
+ "function addWhitelistedBenefactor(address benefactor) external",
129
+ "function removeWhitelistedBenefactor(address benefactor) external"
130
+ ];
131
+
132
+ // src/modules/mint/MintModule.ts
133
+ import { v4 as uuidv4 } from "uuid";
134
+ var MintModule = class {
135
+ constructor(sdk) {
136
+ this.sdk = sdk;
137
+ }
138
+ async createOrder(collateralAsset, collateralAmount, dAssetAmount, options) {
139
+ const address = await this.sdk.getAddress();
140
+ const orderId = uuidv4();
141
+ const expiry = Math.floor(Date.now() / 1e3) + (options?.expiryMinutes || 5) * 60;
142
+ const minterAddress = collateralAsset.mintingContract;
143
+ const order = {
144
+ orderId,
145
+ orderType: 0,
146
+ expiry,
147
+ nonce: Date.now(),
148
+ benefactor: options?.benefactor || address,
149
+ beneficiary: options?.beneficiary || address,
150
+ collateralAsset: collateralAsset.address,
151
+ collateralAmount: collateralAmount.toString(),
152
+ dAssetAmount: dAssetAmount.toString(),
153
+ minterAddress
154
+ };
155
+ return order;
156
+ }
157
+ async signOrder(order) {
158
+ const signer = this.sdk.signer;
159
+ const domain = {
160
+ name: "DeployMinting",
161
+ version: "1",
162
+ chainId: await this.sdk.getChainId(),
163
+ verifyingContract: order.minterAddress
164
+ };
165
+ const value = {
166
+ order_id: order.orderId,
167
+ order_type: order.orderType,
168
+ expiry: order.expiry,
169
+ nonce: order.nonce,
170
+ benefactor: order.benefactor,
171
+ beneficiary: order.beneficiary,
172
+ collateral_asset: order.collateralAsset,
173
+ collateral_amount: order.collateralAmount,
174
+ dAsset_amount: order.dAssetAmount
175
+ };
176
+ try {
177
+ const signature = await signer._signTypedData(domain, EIP712_TYPES_ORDER, value);
178
+ return signature;
179
+ } catch (error) {
180
+ throw new DeploySDKError(
181
+ "SIGNATURE_FAILED" /* SIGNATURE_FAILED */,
182
+ "Failed to sign mint order",
183
+ error
184
+ );
185
+ }
186
+ }
187
+ async submitOrder(order, signature) {
188
+ try {
189
+ const response = await fetch(`${this.sdk.config.apiUrl}/api/mint`, {
190
+ method: "POST",
191
+ headers: {
192
+ "Content-Type": "application/json"
193
+ },
194
+ body: JSON.stringify({
195
+ order: {
196
+ order_id: order.orderId,
197
+ order_type: order.orderType,
198
+ expiry: order.expiry,
199
+ nonce: order.nonce,
200
+ benefactor: order.benefactor,
201
+ beneficiary: order.beneficiary,
202
+ collateral_asset: order.collateralAsset,
203
+ collateral_amount: order.collateralAmount,
204
+ dAsset_amount: order.dAssetAmount
205
+ },
206
+ signature: {
207
+ signature_type: 0,
208
+ signature_bytes: signature
209
+ }
210
+ })
211
+ });
212
+ if (!response.ok) {
213
+ const error = await response.json();
214
+ throw new DeploySDKError(
215
+ "API_ERROR" /* API_ERROR */,
216
+ error.message || "Failed to submit mint order"
217
+ );
218
+ }
219
+ const result = await response.json();
220
+ return {
221
+ success: true,
222
+ orderId: order.orderId,
223
+ txHash: result.txHash,
224
+ status: result.status
225
+ };
226
+ } catch (error) {
227
+ if (error instanceof DeploySDKError) throw error;
228
+ throw new DeploySDKError(
229
+ "API_ERROR" /* API_ERROR */,
230
+ "Failed to submit mint order",
231
+ error
232
+ );
233
+ }
234
+ }
235
+ async mint(collateralAsset, collateralAmount, dAssetAmount, options) {
236
+ try {
237
+ const order = await this.createOrder(
238
+ collateralAsset,
239
+ collateralAmount,
240
+ dAssetAmount,
241
+ options
242
+ );
243
+ const signature = await this.signOrder(order);
244
+ return await this.submitOrder(order, signature);
245
+ } catch (error) {
246
+ if (error instanceof DeploySDKError) throw error;
247
+ throw new DeploySDKError(
248
+ "MINT_FAILED" /* MINT_FAILED */,
249
+ "Failed to mint tokens",
250
+ error
251
+ );
252
+ }
253
+ }
254
+ async estimateGas(collateralAsset, collateralAmount, dAssetAmount, signature) {
255
+ const minterContract = new Contract(
256
+ collateralAsset.mintingContract,
257
+ MINTER_ABI,
258
+ this.sdk.provider
259
+ );
260
+ const order = {
261
+ order_id: uuidv4(),
262
+ order_type: 0,
263
+ expiry: Math.floor(Date.now() / 1e3) + 300,
264
+ nonce: Date.now(),
265
+ benefactor: await this.sdk.getAddress(),
266
+ beneficiary: await this.sdk.getAddress(),
267
+ collateral_asset: collateralAsset.address,
268
+ collateral_amount: collateralAmount.toString(),
269
+ dAsset_amount: dAssetAmount.toString()
270
+ };
271
+ try {
272
+ const gasEstimate = await minterContract.estimateGas.mint(
273
+ order,
274
+ { addresses: [], ratios: [] },
275
+ { signature_type: 0, signature_bytes: signature }
276
+ );
277
+ return gasEstimate.toBigInt();
278
+ } catch (error) {
279
+ throw new DeploySDKError(
280
+ "TRANSACTION_FAILED" /* TRANSACTION_FAILED */,
281
+ "Failed to estimate gas for mint",
282
+ error
283
+ );
284
+ }
285
+ }
286
+ };
287
+
288
+ // src/modules/stake/StakeModule.ts
289
+ import { Contract as Contract2, BigNumber } from "ethers";
290
+ var StakeModule = class {
291
+ constructor(sdk) {
292
+ this.sdk = sdk;
293
+ }
294
+ async stake(params) {
295
+ try {
296
+ const { token, amount, receiver } = params;
297
+ if (!token.stakingContract) {
298
+ throw new DeploySDKError(
299
+ "VALIDATION_ERROR" /* VALIDATION_ERROR */,
300
+ `Token ${token.symbol} does not support staking`
301
+ );
302
+ }
303
+ const vaultContract = new Contract2(
304
+ token.stakingContract,
305
+ ERC4626_ABI,
306
+ this.sdk.signer
307
+ );
308
+ const receiverAddress = receiver || await this.sdk.getAddress();
309
+ const tx = await vaultContract.deposit(amount, receiverAddress);
310
+ const receipt = await tx.wait();
311
+ let sharesReceived;
312
+ const depositEvent = receipt.events?.find(
313
+ (e) => e.event === "Deposit"
314
+ );
315
+ if (depositEvent) {
316
+ sharesReceived = depositEvent.args?.shares?.toString();
317
+ }
318
+ return {
319
+ success: true,
320
+ txHash: receipt.transactionHash,
321
+ sharesReceived
322
+ };
323
+ } catch (error) {
324
+ if (error instanceof DeploySDKError) throw error;
325
+ throw new DeploySDKError(
326
+ "STAKE_FAILED" /* STAKE_FAILED */,
327
+ "Failed to stake tokens",
328
+ error
329
+ );
330
+ }
331
+ }
332
+ async getPosition(token, userAddress) {
333
+ if (!token.stakingContract) {
334
+ throw new DeploySDKError(
335
+ "VALIDATION_ERROR" /* VALIDATION_ERROR */,
336
+ `Token ${token.symbol} does not support staking`
337
+ );
338
+ }
339
+ const address = userAddress || await this.sdk.getAddress();
340
+ const vaultContract = new Contract2(
341
+ token.stakingContract,
342
+ ERC4626_ABI,
343
+ this.sdk.provider
344
+ );
345
+ try {
346
+ const [shares, assets, cooldown] = await Promise.all([
347
+ vaultContract.balanceOf(address),
348
+ vaultContract.convertToAssets(await vaultContract.balanceOf(address)),
349
+ vaultContract.cooldowns(address).catch(() => ({ cooldownEnd: BigNumber.from(0), underlyingAmount: BigNumber.from(0) }))
350
+ ]);
351
+ const cooldownEnd = cooldown.cooldownEnd.toNumber() * 1e3;
352
+ return {
353
+ tokenKey: token.key,
354
+ stakedAmount: shares.toString(),
355
+ stakedValue: assets.toString(),
356
+ cooldownEnd: cooldownEnd > 0 ? cooldownEnd : void 0,
357
+ canUnstake: cooldownEnd === 0 || cooldownEnd <= Date.now()
358
+ };
359
+ } catch (error) {
360
+ throw new DeploySDKError(
361
+ "VALIDATION_ERROR" /* VALIDATION_ERROR */,
362
+ "Failed to fetch staking position",
363
+ error
364
+ );
365
+ }
366
+ }
367
+ async previewStake(token, amount) {
368
+ if (!token.stakingContract) {
369
+ throw new DeploySDKError(
370
+ "VALIDATION_ERROR" /* VALIDATION_ERROR */,
371
+ `Token ${token.symbol} does not support staking`
372
+ );
373
+ }
374
+ const vaultContract = new Contract2(
375
+ token.stakingContract,
376
+ ERC4626_ABI,
377
+ this.sdk.provider
378
+ );
379
+ try {
380
+ const shares = await vaultContract.convertToShares(amount);
381
+ return {
382
+ shares: shares.toString(),
383
+ assets: amount.toString()
384
+ };
385
+ } catch (error) {
386
+ throw new DeploySDKError(
387
+ "VALIDATION_ERROR" /* VALIDATION_ERROR */,
388
+ "Failed to preview stake",
389
+ error
390
+ );
391
+ }
392
+ }
393
+ async getAPY(token) {
394
+ if (!token.stakingContract) {
395
+ return 0;
396
+ }
397
+ const vaultContract = new Contract2(
398
+ token.stakingContract,
399
+ ERC4626_ABI,
400
+ this.sdk.provider
401
+ );
402
+ try {
403
+ const [totalAssets, totalSupply] = await Promise.all([
404
+ vaultContract.totalAssets(),
405
+ vaultContract.totalSupply()
406
+ ]);
407
+ if (totalSupply.isZero()) {
408
+ return 0;
409
+ }
410
+ const sharePrice = totalAssets.mul(BigNumber.from(10).pow(18)).div(totalSupply);
411
+ const basePrice = BigNumber.from(10).pow(18);
412
+ if (sharePrice.lte(basePrice)) {
413
+ return 0;
414
+ }
415
+ const yieldPerShare = sharePrice.sub(basePrice);
416
+ const dailyYield = yieldPerShare.mul(365);
417
+ const apy = dailyYield.mul(1e4).div(basePrice).toNumber() / 100;
418
+ return apy;
419
+ } catch (error) {
420
+ return 0;
421
+ }
422
+ }
423
+ };
424
+
425
+ // src/modules/unstake/UnstakeModule.ts
426
+ import { Contract as Contract3 } from "ethers";
427
+ var UnstakeModule = class {
428
+ constructor(sdk) {
429
+ this.sdk = sdk;
430
+ }
431
+ async initiateCooldown(token, sharesAmount) {
432
+ try {
433
+ if (!token.stakingContract) {
434
+ throw new DeploySDKError(
435
+ "VALIDATION_ERROR" /* VALIDATION_ERROR */,
436
+ `Token ${token.symbol} does not support staking`
437
+ );
438
+ }
439
+ const vaultContract = new Contract3(
440
+ token.stakingContract,
441
+ ERC4626_ABI,
442
+ this.sdk.signer
443
+ );
444
+ const tx = await vaultContract.cooldownShares(sharesAmount);
445
+ const receipt = await tx.wait();
446
+ const cooldownEnd = Date.now() + (token.cooldownPeriod || 90 * 24 * 60 * 60 * 1e3);
447
+ return {
448
+ success: true,
449
+ txHash: receipt.transactionHash,
450
+ cooldownEnd
451
+ };
452
+ } catch (error) {
453
+ if (error instanceof DeploySDKError) throw error;
454
+ throw new DeploySDKError(
455
+ "COOLDOWN_FAILED" /* COOLDOWN_FAILED */,
456
+ "Failed to initiate cooldown",
457
+ error
458
+ );
459
+ }
460
+ }
461
+ async unstake(params) {
462
+ try {
463
+ const { token, sharesAmount, receiver } = params;
464
+ if (!token.stakingContract) {
465
+ throw new DeploySDKError(
466
+ "VALIDATION_ERROR" /* VALIDATION_ERROR */,
467
+ `Token ${token.symbol} does not support staking`
468
+ );
469
+ }
470
+ const cooldownStatus = await this.getCooldownStatus(token);
471
+ if (!cooldownStatus.canUnstake) {
472
+ throw new DeploySDKError(
473
+ "VALIDATION_ERROR" /* VALIDATION_ERROR */,
474
+ `Cannot unstake. Cooldown ends at ${new Date(cooldownStatus.cooldownEnd).toLocaleString()}`
475
+ );
476
+ }
477
+ const vaultContract = new Contract3(
478
+ token.stakingContract,
479
+ ERC4626_ABI,
480
+ this.sdk.signer
481
+ );
482
+ const receiverAddress = receiver || await this.sdk.getAddress();
483
+ const owner = await this.sdk.getAddress();
484
+ const tx = await vaultContract.redeem(sharesAmount, receiverAddress, owner);
485
+ const receipt = await tx.wait();
486
+ let assetsWithdrawn;
487
+ const withdrawEvent = receipt.events?.find(
488
+ (e) => e.event === "Withdraw"
489
+ );
490
+ if (withdrawEvent) {
491
+ assetsWithdrawn = withdrawEvent.args?.assets?.toString();
492
+ }
493
+ return {
494
+ success: true,
495
+ txHash: receipt.transactionHash,
496
+ assetsWithdrawn
497
+ };
498
+ } catch (error) {
499
+ if (error instanceof DeploySDKError) throw error;
500
+ throw new DeploySDKError(
501
+ "UNSTAKE_FAILED" /* UNSTAKE_FAILED */,
502
+ "Failed to unstake tokens",
503
+ error
504
+ );
505
+ }
506
+ }
507
+ async getCooldownStatus(token, userAddress) {
508
+ if (!token.stakingContract) {
509
+ throw new DeploySDKError(
510
+ "VALIDATION_ERROR" /* VALIDATION_ERROR */,
511
+ `Token ${token.symbol} does not support staking`
512
+ );
513
+ }
514
+ const address = userAddress || await this.sdk.getAddress();
515
+ const vaultContract = new Contract3(
516
+ token.stakingContract,
517
+ ERC4626_ABI,
518
+ this.sdk.provider
519
+ );
520
+ try {
521
+ const cooldown = await vaultContract.cooldowns(address);
522
+ const cooldownEnd = cooldown.cooldownEnd.toNumber() * 1e3;
523
+ return {
524
+ cooldownEnd,
525
+ sharesInCooldown: cooldown.underlyingAmount.toString(),
526
+ canUnstake: cooldownEnd > 0 && cooldownEnd <= Date.now()
527
+ };
528
+ } catch (error) {
529
+ throw new DeploySDKError(
530
+ "VALIDATION_ERROR" /* VALIDATION_ERROR */,
531
+ "Failed to fetch cooldown status",
532
+ error
533
+ );
534
+ }
535
+ }
536
+ async previewUnstake(token, sharesAmount) {
537
+ if (!token.stakingContract) {
538
+ throw new DeploySDKError(
539
+ "VALIDATION_ERROR" /* VALIDATION_ERROR */,
540
+ `Token ${token.symbol} does not support staking`
541
+ );
542
+ }
543
+ const vaultContract = new Contract3(
544
+ token.stakingContract,
545
+ ERC4626_ABI,
546
+ this.sdk.provider
547
+ );
548
+ try {
549
+ const assets = await vaultContract.convertToAssets(sharesAmount);
550
+ return assets.toString();
551
+ } catch (error) {
552
+ throw new DeploySDKError(
553
+ "VALIDATION_ERROR" /* VALIDATION_ERROR */,
554
+ "Failed to preview unstake",
555
+ error
556
+ );
557
+ }
558
+ }
559
+ };
560
+
561
+ // src/modules/redeem/RedeemModule.ts
562
+ import { Contract as Contract4 } from "ethers";
563
+ import { v4 as uuidv42 } from "uuid";
564
+ var RedeemModule = class {
565
+ constructor(sdk) {
566
+ this.sdk = sdk;
567
+ }
568
+ async createOrder(token, redeemAmount, collateralAsset, collateralAmount, options) {
569
+ const address = await this.sdk.getAddress();
570
+ const orderId = uuidv42();
571
+ const expiry = Math.floor(Date.now() / 1e3) + (options?.expiryMinutes || 5) * 60;
572
+ const minterAddress = token.mintingContract;
573
+ const order = {
574
+ orderId,
575
+ orderType: 1,
576
+ expiry,
577
+ nonce: Date.now(),
578
+ benefactor: options?.benefactor || address,
579
+ beneficiary: options?.beneficiary || address,
580
+ collateralAsset,
581
+ collateralAmount: collateralAmount.toString(),
582
+ dAssetAmount: redeemAmount.toString(),
583
+ minterAddress
584
+ };
585
+ return order;
586
+ }
587
+ async signOrder(order) {
588
+ const signer = this.sdk.signer;
589
+ const domain = {
590
+ name: "DeployMinting",
591
+ version: "1",
592
+ chainId: await this.sdk.getChainId(),
593
+ verifyingContract: order.minterAddress
594
+ };
595
+ const value = {
596
+ order_id: order.orderId,
597
+ order_type: order.orderType,
598
+ expiry: order.expiry,
599
+ nonce: order.nonce,
600
+ benefactor: order.benefactor,
601
+ beneficiary: order.beneficiary,
602
+ collateral_asset: order.collateralAsset,
603
+ collateral_amount: order.collateralAmount,
604
+ dAsset_amount: order.dAssetAmount
605
+ };
606
+ try {
607
+ const signature = await signer._signTypedData(domain, EIP712_TYPES_ORDER, value);
608
+ return signature;
609
+ } catch (error) {
610
+ throw new DeploySDKError(
611
+ "SIGNATURE_FAILED" /* SIGNATURE_FAILED */,
612
+ "Failed to sign redeem order",
613
+ error
614
+ );
615
+ }
616
+ }
617
+ async submitOrder(order, signature) {
618
+ try {
619
+ const response = await fetch(`${this.sdk.config.apiUrl}/api/redeem`, {
620
+ method: "POST",
621
+ headers: {
622
+ "Content-Type": "application/json"
623
+ },
624
+ body: JSON.stringify({
625
+ order: {
626
+ order_id: order.orderId,
627
+ order_type: order.orderType,
628
+ expiry: order.expiry,
629
+ nonce: order.nonce,
630
+ benefactor: order.benefactor,
631
+ beneficiary: order.beneficiary,
632
+ collateral_asset: order.collateralAsset,
633
+ collateral_amount: order.collateralAmount,
634
+ dAsset_amount: order.dAssetAmount
635
+ },
636
+ signature: {
637
+ signature_type: 0,
638
+ signature_bytes: signature
639
+ }
640
+ })
641
+ });
642
+ if (!response.ok) {
643
+ const error = await response.json();
644
+ throw new DeploySDKError(
645
+ "API_ERROR" /* API_ERROR */,
646
+ error.message || "Failed to submit redeem order"
647
+ );
648
+ }
649
+ const result = await response.json();
650
+ return {
651
+ success: true,
652
+ orderId: order.orderId,
653
+ txHash: result.txHash,
654
+ status: result.status
655
+ };
656
+ } catch (error) {
657
+ if (error instanceof DeploySDKError) throw error;
658
+ throw new DeploySDKError(
659
+ "API_ERROR" /* API_ERROR */,
660
+ "Failed to submit redeem order",
661
+ error
662
+ );
663
+ }
664
+ }
665
+ async redeem(token, redeemAmount, collateralAsset, collateralAmount, options) {
666
+ try {
667
+ const order = await this.createOrder(
668
+ token,
669
+ redeemAmount,
670
+ collateralAsset,
671
+ collateralAmount,
672
+ options
673
+ );
674
+ const signature = await this.signOrder(order);
675
+ return await this.submitOrder(order, signature);
676
+ } catch (error) {
677
+ if (error instanceof DeploySDKError) throw error;
678
+ throw new DeploySDKError(
679
+ "REDEEM_FAILED" /* REDEEM_FAILED */,
680
+ "Failed to redeem tokens",
681
+ error
682
+ );
683
+ }
684
+ }
685
+ async estimateGas(token, redeemAmount, collateralAsset, collateralAmount, signature) {
686
+ const minterContract = new Contract4(
687
+ token.mintingContract,
688
+ MINTER_ABI,
689
+ this.sdk.provider
690
+ );
691
+ const order = {
692
+ order_id: uuidv42(),
693
+ order_type: 1,
694
+ expiry: Math.floor(Date.now() / 1e3) + 300,
695
+ nonce: Date.now(),
696
+ benefactor: await this.sdk.getAddress(),
697
+ beneficiary: await this.sdk.getAddress(),
698
+ collateral_asset: collateralAsset,
699
+ collateral_amount: collateralAmount.toString(),
700
+ dAsset_amount: redeemAmount.toString()
701
+ };
702
+ try {
703
+ const gasEstimate = await minterContract.estimateGas.redeem(
704
+ order,
705
+ { signature_type: 0, signature_bytes: signature }
706
+ );
707
+ return gasEstimate.toBigInt();
708
+ } catch (error) {
709
+ throw new DeploySDKError(
710
+ "TRANSACTION_FAILED" /* TRANSACTION_FAILED */,
711
+ "Failed to estimate gas for redeem",
712
+ error
713
+ );
714
+ }
715
+ }
716
+ };
717
+
718
+ export {
719
+ ErrorCode,
720
+ DeploySDKError,
721
+ CONTRACT_ADDRESSES,
722
+ COLLATERAL_ASSETS,
723
+ STAKE_TOKENS,
724
+ EIP712_TYPES_ORDER,
725
+ ERC4626_ABI,
726
+ ERC20_ABI,
727
+ MINTER_ABI,
728
+ MintModule,
729
+ StakeModule,
730
+ UnstakeModule,
731
+ RedeemModule
732
+ };