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.
- package/README.md +317 -0
- package/dist/base-01mNzZ7A.d.mts +56 -0
- package/dist/base-01mNzZ7A.d.ts +56 -0
- package/dist/base-DLLHDCZ5.d.mts +56 -0
- package/dist/base-DLLHDCZ5.d.ts +56 -0
- package/dist/chunk-ELR7YJ6L.mjs +10 -0
- package/dist/chunk-F2AHC5HC.mjs +94 -0
- package/dist/chunk-QZGD3DFS.mjs +1 -0
- package/dist/chunk-QZYDPY65.mjs +733 -0
- package/dist/chunk-X3SXEVUG.mjs +732 -0
- package/dist/chunk-XSAEU2QV.mjs +1 -0
- package/dist/chunk-YEI5UNBO.mjs +1 -0
- package/dist/index-B9tOEGVF.d.mts +192 -0
- package/dist/index-CY6ZN0n3.d.ts +192 -0
- package/dist/index-DITBfiHE.d.mts +192 -0
- package/dist/index-DhDHmxb0.d.ts +192 -0
- package/dist/index.d.mts +50 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.js +1 -0
- package/dist/index.mjs +1 -0
- package/dist/modules/index.d.mts +4 -0
- package/dist/modules/index.d.ts +4 -0
- package/dist/modules/index.js +1 -0
- package/dist/modules/index.mjs +1 -0
- package/dist/wallet-adapters/index.d.mts +38 -0
- package/dist/wallet-adapters/index.d.ts +38 -0
- package/dist/wallet-adapters/index.js +1 -0
- package/dist/wallet-adapters/index.mjs +1 -0
- package/package.json +66 -0
package/README.md
ADDED
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
# Deploy SDK
|
|
2
|
+
|
|
3
|
+
Complete DeFi interaction library for the Deploy platform with support for mint, stake, unstake, and redeem operations.
|
|
4
|
+
|
|
5
|
+
## Platform support
|
|
6
|
+
|
|
7
|
+
The SDK works in **React (web)** and **React Native**. Same API in both; you only change how you obtain the wallet provider (browser: `window.ethereum` or Privy; React Native: WalletConnect, Privy React Native, or any EIP-1193 provider passed into `ExternalWalletAdapter`).
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install deploy-sdk ethers
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
### 1. Initialize SDK with Privy
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { DeploySDK, PrivyAdapter, COLLATERAL_ASSETS, STAKE_TOKENS } from 'deploy-sdk';
|
|
21
|
+
import { usePrivy } from '@privy-io/react-auth';
|
|
22
|
+
|
|
23
|
+
function App() {
|
|
24
|
+
const privy = usePrivy();
|
|
25
|
+
|
|
26
|
+
const sdk = new DeploySDK({
|
|
27
|
+
apiUrl: 'https://your-api-url.com', // provide your backend API URL
|
|
28
|
+
chainId: 1, // Ethereum mainnet
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const connectWallet = async () => {
|
|
32
|
+
const adapter = new PrivyAdapter(privy);
|
|
33
|
+
await sdk.initialize(adapter);
|
|
34
|
+
console.log('Connected:', await sdk.getAddress());
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 2. Initialize SDK with MetaMask (React / browser)
|
|
40
|
+
|
|
41
|
+
In the browser, use `window.ethereum` with `ExternalWalletAdapter`:
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { DeploySDK, ExternalWalletAdapter } from 'deploy-sdk';
|
|
45
|
+
|
|
46
|
+
const ethereum = window.ethereum;
|
|
47
|
+
const adapter = new ExternalWalletAdapter(ethereum);
|
|
48
|
+
|
|
49
|
+
const sdk = new DeploySDK({
|
|
50
|
+
apiUrl: 'https://your-api-url.com', // provide your backend API URL
|
|
51
|
+
chainId: 1,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
await sdk.initialize(adapter);
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 3. Initialize SDK in React Native
|
|
58
|
+
|
|
59
|
+
In React Native there is no `window.ethereum`. Get an EIP-1193 provider from your wallet stack (e.g. WalletConnect, Privy React Native) and pass it to `ExternalWalletAdapter`:
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import { DeploySDK, ExternalWalletAdapter } from 'deploy-sdk';
|
|
63
|
+
|
|
64
|
+
// provider: from WalletConnect, Privy React Native, or your custom injector
|
|
65
|
+
const adapter = new ExternalWalletAdapter(provider);
|
|
66
|
+
const sdk = new DeploySDK({
|
|
67
|
+
apiUrl: 'https://your-api-url.com', // provide your backend API URL
|
|
68
|
+
chainId: 1,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
await sdk.initialize(adapter);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 4. Mint dUSD
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { COLLATERAL_ASSETS } from 'deploy-sdk';
|
|
78
|
+
|
|
79
|
+
const mintDUSD = async () => {
|
|
80
|
+
// Mint 1000 dUSD using USDC
|
|
81
|
+
const result = await sdk.mint.mint(
|
|
82
|
+
COLLATERAL_ASSETS.USDC,
|
|
83
|
+
'1000000000', // 1000 USDC (6 decimals)
|
|
84
|
+
'1000000000000000000000', // 1000 dUSD (18 decimals)
|
|
85
|
+
{ expiryMinutes: 10 }
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
console.log('Mint successful:', result.txHash);
|
|
89
|
+
};
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 5. Stake dUSD
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
import { STAKE_TOKENS } from 'deploy-sdk';
|
|
96
|
+
|
|
97
|
+
const stakeDUSD = async () => {
|
|
98
|
+
// Stake 1000 dUSD
|
|
99
|
+
const result = await sdk.stake.stake({
|
|
100
|
+
token: STAKE_TOKENS.dUSD,
|
|
101
|
+
amount: '1000000000000000000000', // 1000 dUSD
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
console.log('Staked:', result.sharesReceived, 'sDUSD shares');
|
|
105
|
+
};
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### 6. Unstake (with Cooldown)
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
const unstakeProcess = async () => {
|
|
112
|
+
// Step 1: Initiate cooldown
|
|
113
|
+
const cooldownResult = await sdk.unstake.initiateCooldown(
|
|
114
|
+
STAKE_TOKENS.dUSD,
|
|
115
|
+
'500000000000000000000' // 500 sDUSD shares
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
console.log('Cooldown initiated. Ends at:', new Date(cooldownResult.cooldownEnd!));
|
|
119
|
+
|
|
120
|
+
// Step 2: Wait for cooldown to complete
|
|
121
|
+
// ... wait 90 days ...
|
|
122
|
+
|
|
123
|
+
// Step 3: Unstake
|
|
124
|
+
const unstakeResult = await sdk.unstake.unstake({
|
|
125
|
+
token: STAKE_TOKENS.dUSD,
|
|
126
|
+
sharesAmount: '500000000000000000000',
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
console.log('Unstaked:', unstakeResult.assetsWithdrawn, 'dUSD');
|
|
130
|
+
};
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 7. Redeem dUSD for USDC
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
const redeemDUSD = async () => {
|
|
137
|
+
const result = await sdk.redeem.redeem(
|
|
138
|
+
STAKE_TOKENS.dUSD,
|
|
139
|
+
'1000000000000000000000', // 1000 dUSD
|
|
140
|
+
COLLATERAL_ASSETS.USDC.address,
|
|
141
|
+
'1000000000', // 1000 USDC
|
|
142
|
+
{ expiryMinutes: 10 }
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
console.log('Redeem successful:', result.txHash);
|
|
146
|
+
};
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## SDK Events
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
sdk.on('initialized', (data) => {
|
|
153
|
+
console.log('SDK initialized for address:', data.address);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
sdk.on('error', (error) => {
|
|
157
|
+
console.error('SDK error:', error);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
sdk.on('chainChanged', (data) => {
|
|
161
|
+
console.log('Chain changed to:', data.chainId);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
sdk.on('disconnected', () => {
|
|
165
|
+
console.log('Wallet disconnected');
|
|
166
|
+
});
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Utility Services
|
|
170
|
+
|
|
171
|
+
### Allowance Management
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
// Check allowance
|
|
175
|
+
const allowance = await sdk.allowance.getAllowance(
|
|
176
|
+
COLLATERAL_ASSETS.USDC.address,
|
|
177
|
+
COLLATERAL_ASSETS.USDC.mintingContract
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
// Approve tokens
|
|
181
|
+
await sdk.allowance.approve(
|
|
182
|
+
COLLATERAL_ASSETS.USDC.address,
|
|
183
|
+
COLLATERAL_ASSETS.USDC.mintingContract,
|
|
184
|
+
'1000000000'
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
// Approve max
|
|
188
|
+
await sdk.allowance.approveMax(
|
|
189
|
+
COLLATERAL_ASSETS.USDC.address,
|
|
190
|
+
COLLATERAL_ASSETS.USDC.mintingContract
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
// Ensure allowance (approves if needed)
|
|
194
|
+
await sdk.allowance.ensureAllowance(
|
|
195
|
+
COLLATERAL_ASSETS.USDC.address,
|
|
196
|
+
COLLATERAL_ASSETS.USDC.mintingContract,
|
|
197
|
+
'1000000000'
|
|
198
|
+
);
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Balance Management
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
// Get token balance
|
|
205
|
+
const balance = await sdk.balances.getTokenBalance(
|
|
206
|
+
STAKE_TOKENS.dUSD.address
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
// Get native ETH balance
|
|
210
|
+
const ethBalance = await sdk.balances.getNativeBalance();
|
|
211
|
+
|
|
212
|
+
// Check sufficient balance
|
|
213
|
+
const hasEnough = await sdk.balances.hasSufficientBalance(
|
|
214
|
+
STAKE_TOKENS.dUSD.address,
|
|
215
|
+
'1000000000000000000000'
|
|
216
|
+
);
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Error Handling
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
import { DeploySDKError, ErrorCode } from 'deploy-sdk';
|
|
223
|
+
|
|
224
|
+
try {
|
|
225
|
+
await sdk.mint.mint(...);
|
|
226
|
+
} catch (error) {
|
|
227
|
+
if (error instanceof DeploySDKError) {
|
|
228
|
+
console.log('Error code:', error.code);
|
|
229
|
+
console.log('Error message:', error.message);
|
|
230
|
+
|
|
231
|
+
switch (error.code) {
|
|
232
|
+
case ErrorCode.INSUFFICIENT_BALANCE:
|
|
233
|
+
// Handle insufficient balance
|
|
234
|
+
break;
|
|
235
|
+
case ErrorCode.INSUFFICIENT_ALLOWANCE:
|
|
236
|
+
// Handle insufficient allowance
|
|
237
|
+
break;
|
|
238
|
+
case ErrorCode.SIGNATURE_FAILED:
|
|
239
|
+
// Handle signature failure
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## API Reference
|
|
247
|
+
|
|
248
|
+
### DeploySDK
|
|
249
|
+
|
|
250
|
+
Main SDK class that provides access to all modules and services.
|
|
251
|
+
|
|
252
|
+
**Constructor Options:**
|
|
253
|
+
|
|
254
|
+
- `chainId`: Chain ID (default: 1)
|
|
255
|
+
- `apiUrl`: Backend API URL
|
|
256
|
+
- `rpcUrl`: Custom RPC URL
|
|
257
|
+
|
|
258
|
+
### MintModule
|
|
259
|
+
|
|
260
|
+
Handles minting dUSD using EIP-712 signed orders.
|
|
261
|
+
|
|
262
|
+
**Methods:**
|
|
263
|
+
|
|
264
|
+
- `createOrder()`: Create a mint order
|
|
265
|
+
- `signOrder()`: Sign a mint order
|
|
266
|
+
- `submitOrder()`: Submit signed order to backend
|
|
267
|
+
- `mint()`: Full mint flow (create + sign + submit)
|
|
268
|
+
- `estimateGas()`: Estimate gas for mint
|
|
269
|
+
|
|
270
|
+
### StakeModule
|
|
271
|
+
|
|
272
|
+
Handles ERC4626 vault staking operations.
|
|
273
|
+
|
|
274
|
+
**Methods:**
|
|
275
|
+
|
|
276
|
+
- `stake()`: Stake tokens into vault
|
|
277
|
+
- `getPosition()`: Get user's staking position
|
|
278
|
+
- `previewStake()`: Preview shares received for stake
|
|
279
|
+
- `getAPY()`: Calculate current APY
|
|
280
|
+
|
|
281
|
+
### UnstakeModule
|
|
282
|
+
|
|
283
|
+
Handles ERC4626 vault unstaking with cooldown.
|
|
284
|
+
|
|
285
|
+
**Methods:**
|
|
286
|
+
|
|
287
|
+
- `initiateCooldown()`: Start cooldown period
|
|
288
|
+
- `unstake()`: Unstake tokens after cooldown
|
|
289
|
+
- `getCooldownStatus()`: Check cooldown status
|
|
290
|
+
- `previewUnstake()`: Preview assets received for shares
|
|
291
|
+
|
|
292
|
+
### RedeemModule
|
|
293
|
+
|
|
294
|
+
Handles redeeming dUSD for collateral using EIP-712 signed orders.
|
|
295
|
+
|
|
296
|
+
**Methods:**
|
|
297
|
+
|
|
298
|
+
- `createOrder()`: Create a redeem order
|
|
299
|
+
- `signOrder()`: Sign a redeem order
|
|
300
|
+
- `submitOrder()`: Submit signed order to backend
|
|
301
|
+
- `redeem()`: Full redeem flow (create + sign + submit)
|
|
302
|
+
- `estimateGas()`: Estimate gas for redeem
|
|
303
|
+
|
|
304
|
+
## Supported Tokens
|
|
305
|
+
|
|
306
|
+
### Collateral Assets
|
|
307
|
+
|
|
308
|
+
- **USDC**: USD Coin (6 decimals)
|
|
309
|
+
- **USDT**: Tether USD (6 decimals)
|
|
310
|
+
|
|
311
|
+
### Stake Tokens
|
|
312
|
+
|
|
313
|
+
- **dUSD**: Deploy USD (stake to sDUSD)
|
|
314
|
+
|
|
315
|
+
## License
|
|
316
|
+
|
|
317
|
+
MIT
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
declare enum ChainId {
|
|
2
|
+
ETHEREUM = 1,
|
|
3
|
+
ARBITRUM = 42161
|
|
4
|
+
}
|
|
5
|
+
interface DeploySDKConfig {
|
|
6
|
+
chainId?: ChainId;
|
|
7
|
+
apiUrl?: string;
|
|
8
|
+
rpcUrl?: string;
|
|
9
|
+
}
|
|
10
|
+
interface SDKEvents {
|
|
11
|
+
initializing: () => void;
|
|
12
|
+
initialized: (data: {
|
|
13
|
+
address: string;
|
|
14
|
+
}) => void;
|
|
15
|
+
error: (error: any) => void;
|
|
16
|
+
chainChanged: (data: {
|
|
17
|
+
chainId: number;
|
|
18
|
+
}) => void;
|
|
19
|
+
disconnected: () => void;
|
|
20
|
+
}
|
|
21
|
+
interface CollateralAsset {
|
|
22
|
+
key: string;
|
|
23
|
+
name: string;
|
|
24
|
+
symbol: string;
|
|
25
|
+
address: string;
|
|
26
|
+
decimals: number;
|
|
27
|
+
mintingContract: string;
|
|
28
|
+
}
|
|
29
|
+
interface StakeToken {
|
|
30
|
+
key: string;
|
|
31
|
+
name: string;
|
|
32
|
+
symbol: string;
|
|
33
|
+
address: string;
|
|
34
|
+
decimals: number;
|
|
35
|
+
supportedCollateral: CollateralAsset[];
|
|
36
|
+
mintingContract: string;
|
|
37
|
+
stakingContract?: string;
|
|
38
|
+
stakingSymbol?: string;
|
|
39
|
+
cooldownPeriod?: number;
|
|
40
|
+
}
|
|
41
|
+
interface TransactionResult {
|
|
42
|
+
success: boolean;
|
|
43
|
+
txHash?: string;
|
|
44
|
+
error?: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface WalletAdapter {
|
|
48
|
+
name: string;
|
|
49
|
+
getProvider(): Promise<any>;
|
|
50
|
+
getSigner(): Promise<any>;
|
|
51
|
+
isConnected(): Promise<boolean>;
|
|
52
|
+
switchChain?(chainId: ChainId): Promise<void>;
|
|
53
|
+
disconnect?(): Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export { type CollateralAsset as C, type DeploySDKConfig as D, type StakeToken as S, type TransactionResult as T, type WalletAdapter as W, ChainId as a, type SDKEvents as b };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
declare enum ChainId {
|
|
2
|
+
ETHEREUM = 1,
|
|
3
|
+
ARBITRUM = 42161
|
|
4
|
+
}
|
|
5
|
+
interface DeploySDKConfig {
|
|
6
|
+
chainId?: ChainId;
|
|
7
|
+
apiUrl?: string;
|
|
8
|
+
rpcUrl?: string;
|
|
9
|
+
}
|
|
10
|
+
interface SDKEvents {
|
|
11
|
+
initializing: () => void;
|
|
12
|
+
initialized: (data: {
|
|
13
|
+
address: string;
|
|
14
|
+
}) => void;
|
|
15
|
+
error: (error: any) => void;
|
|
16
|
+
chainChanged: (data: {
|
|
17
|
+
chainId: number;
|
|
18
|
+
}) => void;
|
|
19
|
+
disconnected: () => void;
|
|
20
|
+
}
|
|
21
|
+
interface CollateralAsset {
|
|
22
|
+
key: string;
|
|
23
|
+
name: string;
|
|
24
|
+
symbol: string;
|
|
25
|
+
address: string;
|
|
26
|
+
decimals: number;
|
|
27
|
+
mintingContract: string;
|
|
28
|
+
}
|
|
29
|
+
interface StakeToken {
|
|
30
|
+
key: string;
|
|
31
|
+
name: string;
|
|
32
|
+
symbol: string;
|
|
33
|
+
address: string;
|
|
34
|
+
decimals: number;
|
|
35
|
+
supportedCollateral: CollateralAsset[];
|
|
36
|
+
mintingContract: string;
|
|
37
|
+
stakingContract?: string;
|
|
38
|
+
stakingSymbol?: string;
|
|
39
|
+
cooldownPeriod?: number;
|
|
40
|
+
}
|
|
41
|
+
interface TransactionResult {
|
|
42
|
+
success: boolean;
|
|
43
|
+
txHash?: string;
|
|
44
|
+
error?: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface WalletAdapter {
|
|
48
|
+
name: string;
|
|
49
|
+
getProvider(): Promise<any>;
|
|
50
|
+
getSigner(): Promise<any>;
|
|
51
|
+
isConnected(): Promise<boolean>;
|
|
52
|
+
switchChain?(chainId: ChainId): Promise<void>;
|
|
53
|
+
disconnect?(): Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export { type CollateralAsset as C, type DeploySDKConfig as D, type StakeToken as S, type TransactionResult as T, type WalletAdapter as W, ChainId as a, type SDKEvents as b };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
declare enum ChainId {
|
|
2
|
+
ETHEREUM = 1,
|
|
3
|
+
ARBITRUM = 42161
|
|
4
|
+
}
|
|
5
|
+
interface DeploySDKConfig {
|
|
6
|
+
apiUrl: string;
|
|
7
|
+
chainId?: ChainId;
|
|
8
|
+
rpcUrl?: string;
|
|
9
|
+
}
|
|
10
|
+
interface SDKEvents {
|
|
11
|
+
initializing: () => void;
|
|
12
|
+
initialized: (data: {
|
|
13
|
+
address: string;
|
|
14
|
+
}) => void;
|
|
15
|
+
error: (error: any) => void;
|
|
16
|
+
chainChanged: (data: {
|
|
17
|
+
chainId: number;
|
|
18
|
+
}) => void;
|
|
19
|
+
disconnected: () => void;
|
|
20
|
+
}
|
|
21
|
+
interface CollateralAsset {
|
|
22
|
+
key: string;
|
|
23
|
+
name: string;
|
|
24
|
+
symbol: string;
|
|
25
|
+
address: string;
|
|
26
|
+
decimals: number;
|
|
27
|
+
mintingContract: string;
|
|
28
|
+
}
|
|
29
|
+
interface StakeToken {
|
|
30
|
+
key: string;
|
|
31
|
+
name: string;
|
|
32
|
+
symbol: string;
|
|
33
|
+
address: string;
|
|
34
|
+
decimals: number;
|
|
35
|
+
supportedCollateral: CollateralAsset[];
|
|
36
|
+
mintingContract: string;
|
|
37
|
+
stakingContract?: string;
|
|
38
|
+
stakingSymbol?: string;
|
|
39
|
+
cooldownPeriod?: number;
|
|
40
|
+
}
|
|
41
|
+
interface TransactionResult {
|
|
42
|
+
success: boolean;
|
|
43
|
+
txHash?: string;
|
|
44
|
+
error?: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface WalletAdapter {
|
|
48
|
+
name: string;
|
|
49
|
+
getProvider(): Promise<any>;
|
|
50
|
+
getSigner(): Promise<any>;
|
|
51
|
+
isConnected(): Promise<boolean>;
|
|
52
|
+
switchChain?(chainId: ChainId): Promise<void>;
|
|
53
|
+
disconnect?(): Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export { type CollateralAsset as C, type DeploySDKConfig as D, type StakeToken as S, type TransactionResult as T, type WalletAdapter as W, ChainId as a, type SDKEvents as b };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
declare enum ChainId {
|
|
2
|
+
ETHEREUM = 1,
|
|
3
|
+
ARBITRUM = 42161
|
|
4
|
+
}
|
|
5
|
+
interface DeploySDKConfig {
|
|
6
|
+
apiUrl: string;
|
|
7
|
+
chainId?: ChainId;
|
|
8
|
+
rpcUrl?: string;
|
|
9
|
+
}
|
|
10
|
+
interface SDKEvents {
|
|
11
|
+
initializing: () => void;
|
|
12
|
+
initialized: (data: {
|
|
13
|
+
address: string;
|
|
14
|
+
}) => void;
|
|
15
|
+
error: (error: any) => void;
|
|
16
|
+
chainChanged: (data: {
|
|
17
|
+
chainId: number;
|
|
18
|
+
}) => void;
|
|
19
|
+
disconnected: () => void;
|
|
20
|
+
}
|
|
21
|
+
interface CollateralAsset {
|
|
22
|
+
key: string;
|
|
23
|
+
name: string;
|
|
24
|
+
symbol: string;
|
|
25
|
+
address: string;
|
|
26
|
+
decimals: number;
|
|
27
|
+
mintingContract: string;
|
|
28
|
+
}
|
|
29
|
+
interface StakeToken {
|
|
30
|
+
key: string;
|
|
31
|
+
name: string;
|
|
32
|
+
symbol: string;
|
|
33
|
+
address: string;
|
|
34
|
+
decimals: number;
|
|
35
|
+
supportedCollateral: CollateralAsset[];
|
|
36
|
+
mintingContract: string;
|
|
37
|
+
stakingContract?: string;
|
|
38
|
+
stakingSymbol?: string;
|
|
39
|
+
cooldownPeriod?: number;
|
|
40
|
+
}
|
|
41
|
+
interface TransactionResult {
|
|
42
|
+
success: boolean;
|
|
43
|
+
txHash?: string;
|
|
44
|
+
error?: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface WalletAdapter {
|
|
48
|
+
name: string;
|
|
49
|
+
getProvider(): Promise<any>;
|
|
50
|
+
getSigner(): Promise<any>;
|
|
51
|
+
isConnected(): Promise<boolean>;
|
|
52
|
+
switchChain?(chainId: ChainId): Promise<void>;
|
|
53
|
+
disconnect?(): Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export { type CollateralAsset as C, type DeploySDKConfig as D, type StakeToken as S, type TransactionResult as T, type WalletAdapter as W, ChainId as a, type SDKEvents as b };
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// src/wallet-adapters/privy-adapter.ts
|
|
2
|
+
var PrivyAdapter = class {
|
|
3
|
+
constructor(privy) {
|
|
4
|
+
this.privy = privy;
|
|
5
|
+
this.name = "Privy";
|
|
6
|
+
}
|
|
7
|
+
async getProvider() {
|
|
8
|
+
return this.privy.getEthereumProvider();
|
|
9
|
+
}
|
|
10
|
+
async getSigner() {
|
|
11
|
+
const provider = await this.getProvider();
|
|
12
|
+
return provider.getSigner();
|
|
13
|
+
}
|
|
14
|
+
async isConnected() {
|
|
15
|
+
return !!this.privy.user?.wallet?.address;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// src/wallet-adapters/external-adapter.ts
|
|
20
|
+
var ExternalWalletAdapter = class {
|
|
21
|
+
constructor(ethereum) {
|
|
22
|
+
this.ethereum = ethereum;
|
|
23
|
+
this.name = "External";
|
|
24
|
+
}
|
|
25
|
+
async getProvider() {
|
|
26
|
+
return this.ethereum;
|
|
27
|
+
}
|
|
28
|
+
async getSigner() {
|
|
29
|
+
await this.ethereum.request({ method: "eth_requestAccounts" });
|
|
30
|
+
return this.ethereum;
|
|
31
|
+
}
|
|
32
|
+
async isConnected() {
|
|
33
|
+
try {
|
|
34
|
+
const accounts = await this.ethereum.request({ method: "eth_accounts" });
|
|
35
|
+
return accounts.length > 0;
|
|
36
|
+
} catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async switchChain(chainId) {
|
|
41
|
+
const hexChainId = `0x${chainId.toString(16)}`;
|
|
42
|
+
try {
|
|
43
|
+
await this.ethereum.request({
|
|
44
|
+
method: "wallet_switchEthereumChain",
|
|
45
|
+
params: [{ chainId: hexChainId }]
|
|
46
|
+
});
|
|
47
|
+
} catch (switchError) {
|
|
48
|
+
if (switchError.code === 4902) {
|
|
49
|
+
await this.addChain(chainId);
|
|
50
|
+
} else {
|
|
51
|
+
throw switchError;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async addChain(chainId) {
|
|
56
|
+
const chainConfigs = {
|
|
57
|
+
[1 /* ETHEREUM */]: {
|
|
58
|
+
chainId: "0x1",
|
|
59
|
+
chainName: "Ethereum Mainnet",
|
|
60
|
+
nativeCurrency: {
|
|
61
|
+
name: "Ether",
|
|
62
|
+
symbol: "ETH",
|
|
63
|
+
decimals: 18
|
|
64
|
+
},
|
|
65
|
+
rpcUrls: ["https://eth.llamarpc.com"],
|
|
66
|
+
blockExplorerUrls: ["https://etherscan.io"]
|
|
67
|
+
},
|
|
68
|
+
[42161 /* ARBITRUM */]: {
|
|
69
|
+
chainId: "0xa4b1",
|
|
70
|
+
chainName: "Arbitrum One",
|
|
71
|
+
nativeCurrency: {
|
|
72
|
+
name: "Ether",
|
|
73
|
+
symbol: "ETH",
|
|
74
|
+
decimals: 18
|
|
75
|
+
},
|
|
76
|
+
rpcUrls: ["https://arb1.arbitrum.io/rpc"],
|
|
77
|
+
blockExplorerUrls: ["https://arbiscan.io"]
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
const config = chainConfigs[chainId];
|
|
81
|
+
if (!config) {
|
|
82
|
+
throw new Error(`Chain ${chainId} not supported`);
|
|
83
|
+
}
|
|
84
|
+
await this.ethereum.request({
|
|
85
|
+
method: "wallet_addEthereumChain",
|
|
86
|
+
params: [config]
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export {
|
|
92
|
+
PrivyAdapter,
|
|
93
|
+
ExternalWalletAdapter
|
|
94
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Contract as O}from"ethers";var w=(c=>(c.NOT_INITIALIZED="NOT_INITIALIZED",c.WALLET_NOT_CONNECTED="WALLET_NOT_CONNECTED",c.INVALID_CHAIN="INVALID_CHAIN",c.INSUFFICIENT_BALANCE="INSUFFICIENT_BALANCE",c.INSUFFICIENT_ALLOWANCE="INSUFFICIENT_ALLOWANCE",c.TRANSACTION_FAILED="TRANSACTION_FAILED",c.STAKE_FAILED="STAKE_FAILED",c.UNSTAKE_FAILED="UNSTAKE_FAILED",c.COOLDOWN_FAILED="COOLDOWN_FAILED",c.MINT_FAILED="MINT_FAILED",c.REDEEM_FAILED="REDEEM_FAILED",c.INVALID_ORDER="INVALID_ORDER",c.SIGNATURE_FAILED="SIGNATURE_FAILED",c.API_ERROR="API_ERROR",c.VALIDATION_ERROR="VALIDATION_ERROR",c))(w||{}),o=class g extends Error{constructor(t,r,e){super(r),this.name="DeploySDKError",this.code=t,this.originalError=e,Error.captureStackTrace&&Error.captureStackTrace(this,g)}toJSON(){return{name:this.name,code:this.code,message:this.message,originalError:this.originalError?.message||this.originalError}}};var m={1:{USDC:"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",USDT:"0xdac17f958d2ee523a2206206994597c13d831ec7",dUSD:"0xf42e0b98e32150fe02a370456e6479fcd94f5531",DUSD_MINTER:"0x1ee453Ea35f6EAbD9BFF126586322cbC906D4EB3",sDUSD_STAKING:"0x7f37B0133B1adC1D0647EE52eA38fA13caC4aA1B"},42161:{}},_={USDC:{key:"USDC",name:"USD Coin",symbol:"USDC",address:m[1].USDC,decimals:6,mintingContract:m[1].DUSD_MINTER},USDT:{key:"USDT",name:"Tether USD",symbol:"USDT",address:m[1].USDT,decimals:6,mintingContract:m[1].DUSD_MINTER}},F={dUSD:{key:"dUSD",name:"Deploy USD",symbol:"dUSD",address:m[1].dUSD,decimals:18,supportedCollateral:[_.USDC,_.USDT],mintingContract:m[1].DUSD_MINTER,stakingContract:m[1].sDUSD_STAKING,stakingSymbol:"sDUSD",cooldownPeriod:2160*60*60*1e3}},h={Order:[{name:"order_id",type:"string"},{name:"order_type",type:"uint8"},{name:"expiry",type:"uint256"},{name:"nonce",type:"uint256"},{name:"benefactor",type:"address"},{name:"beneficiary",type:"address"},{name:"collateral_asset",type:"address"},{name:"collateral_amount",type:"uint256"},{name:"dAsset_amount",type:"uint256"}]},l=["function deposit(uint256 assets, address receiver) external returns (uint256 shares)","function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares)","function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets)","function cooldownShares(uint256 shares) external","function cooldowns(address user) external view returns (uint256 cooldownEnd, uint256 underlyingAmount)","function balanceOf(address owner) external view returns (uint256)","function convertToShares(uint256 assets) external view returns (uint256)","function convertToAssets(uint256 shares) external view returns (uint256)","function totalAssets() external view returns (uint256)","function totalSupply() external view returns (uint256)","event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares)","event Withdraw(address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares)"],P=["function approve(address spender, uint256 amount) external returns (bool)","function allowance(address owner, address spender) external view returns (uint256)","function balanceOf(address account) external view returns (uint256)","function decimals() external view returns (uint8)","function symbol() external view returns (string)","function name() external view returns (string)","function transfer(address recipient, uint256 amount) external returns (bool)","function transferFrom(address sender, address recipient, uint256 amount) external returns (bool)","event Approval(address indexed owner, address indexed spender, uint256 value)","event Transfer(address indexed from, address indexed to, uint256 value)"],y=["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","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","function isWhitelistedBenefactor(address benefactor) external view returns (bool)","function addWhitelistedBenefactor(address benefactor) external","function removeWhitelistedBenefactor(address benefactor) external"];var R=class{constructor(t){this.sdk=t}async createOrder(t,r,e,n){let s=await this.sdk.getAddress(),a=crypto.randomUUID(),d=Math.floor(Date.now()/1e3)+(n?.expiryMinutes||5)*60,i=t.mintingContract;return{orderId:a,orderType:0,expiry:d,nonce:Date.now(),benefactor:n?.benefactor||s,beneficiary:n?.beneficiary||s,collateralAsset:t.address,collateralAmount:r.toString(),dAssetAmount:e.toString(),minterAddress:i}}async signOrder(t){let r=this.sdk.signer,e={name:"DeployMinting",version:"1",chainId:await this.sdk.getChainId(),verifyingContract:t.minterAddress},n={order_id:t.orderId,order_type:t.orderType,expiry:t.expiry,nonce:t.nonce,benefactor:t.benefactor,beneficiary:t.beneficiary,collateral_asset:t.collateralAsset,collateral_amount:t.collateralAmount,dAsset_amount:t.dAssetAmount};try{return await r._signTypedData(e,h,n)}catch(s){throw new o("SIGNATURE_FAILED","Failed to sign mint order",s)}}async submitOrder(t,r){try{let e=await fetch(`${this.sdk.config.apiUrl}/api/mint`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({order:{order_id:t.orderId,order_type:t.orderType,expiry:t.expiry,nonce:t.nonce,benefactor:t.benefactor,beneficiary:t.beneficiary,collateral_asset:t.collateralAsset,collateral_amount:t.collateralAmount,dAsset_amount:t.dAssetAmount},signature:{signature_type:0,signature_bytes:r}})});if(!e.ok){let s=await e.json();throw new o("API_ERROR",s.message||"Failed to submit mint order")}let n=await e.json();return{success:!0,orderId:t.orderId,txHash:n.txHash,status:n.status}}catch(e){throw e instanceof o?e:new o("API_ERROR","Failed to submit mint order",e)}}async mint(t,r,e,n){try{let s=await this.createOrder(t,r,e,n),a=await this.signOrder(s);return await this.submitOrder(s,a)}catch(s){throw s instanceof o?s:new o("MINT_FAILED","Failed to mint tokens",s)}}async estimateGas(t,r,e,n){let s=new O(t.mintingContract,y,this.sdk.provider),a={order_id:crypto.randomUUID(),order_type:0,expiry:Math.floor(Date.now()/1e3)+300,nonce:Date.now(),benefactor:await this.sdk.getAddress(),beneficiary:await this.sdk.getAddress(),collateral_asset:t.address,collateral_amount:r.toString(),dAsset_amount:e.toString()};try{return(await s.estimateGas.mint(a,{addresses:[],ratios:[]},{signature_type:0,signature_bytes:n})).toBigInt()}catch(d){throw new o("TRANSACTION_FAILED","Failed to estimate gas for mint",d)}}};import{Contract as f,BigNumber as E}from"ethers";var S=class{constructor(t){this.sdk=t}async stake(t){try{let{token:r,amount:e,receiver:n}=t;if(!r.stakingContract)throw new o("VALIDATION_ERROR",`Token ${r.symbol} does not support staking`);let s=new f(r.stakingContract,l,this.sdk.signer),a=n||await this.sdk.getAddress(),i=await(await s.deposit(e,a)).wait(),u,p=i.events?.find(A=>A.event==="Deposit");return p&&(u=p.args?.shares?.toString()),{success:!0,txHash:i.transactionHash,sharesReceived:u}}catch(r){throw r instanceof o?r:new o("STAKE_FAILED","Failed to stake tokens",r)}}async getPosition(t,r){if(!t.stakingContract)throw new o("VALIDATION_ERROR",`Token ${t.symbol} does not support staking`);let e=r||await this.sdk.getAddress(),n=new f(t.stakingContract,l,this.sdk.provider);try{let[s,a,d]=await Promise.all([n.balanceOf(e),n.convertToAssets(await n.balanceOf(e)),n.cooldowns(e).catch(()=>({cooldownEnd:E.from(0),underlyingAmount:E.from(0)}))]),i=d.cooldownEnd.toNumber()*1e3;return{tokenKey:t.key,stakedAmount:s.toString(),stakedValue:a.toString(),cooldownEnd:i>0?i:void 0,canUnstake:i===0||i<=Date.now()}}catch(s){throw new o("VALIDATION_ERROR","Failed to fetch staking position",s)}}async previewStake(t,r){if(!t.stakingContract)throw new o("VALIDATION_ERROR",`Token ${t.symbol} does not support staking`);let e=new f(t.stakingContract,l,this.sdk.provider);try{return{shares:(await e.convertToShares(r)).toString(),assets:r.toString()}}catch(n){throw new o("VALIDATION_ERROR","Failed to preview stake",n)}}async getAPY(t){if(!t.stakingContract)return 0;let r=new f(t.stakingContract,l,this.sdk.provider);try{let[e,n]=await Promise.all([r.totalAssets(),r.totalSupply()]);if(n.isZero())return 0;let s=e.mul(E.from(10).pow(18)).div(n),a=E.from(10).pow(18);return s.lte(a)?0:s.sub(a).mul(365).mul(1e4).div(a).toNumber()/100}catch{return 0}}};import{Contract as D}from"ethers";var T=class{constructor(t){this.sdk=t}async initiateCooldown(t,r){try{if(!t.stakingContract)throw new o("VALIDATION_ERROR",`Token ${t.symbol} does not support staking`);let s=await(await new D(t.stakingContract,l,this.sdk.signer).cooldownShares(r)).wait(),a=Date.now()+(t.cooldownPeriod||2160*60*60*1e3);return{success:!0,txHash:s.transactionHash,cooldownEnd:a}}catch(e){throw e instanceof o?e:new o("COOLDOWN_FAILED","Failed to initiate cooldown",e)}}async unstake(t){try{let{token:r,sharesAmount:e,receiver:n}=t;if(!r.stakingContract)throw new o("VALIDATION_ERROR",`Token ${r.symbol} does not support staking`);let s=await this.getCooldownStatus(r);if(!s.canUnstake)throw new o("VALIDATION_ERROR",`Cannot unstake. Cooldown ends at ${new Date(s.cooldownEnd).toLocaleString()}`);let a=new D(r.stakingContract,l,this.sdk.signer),d=n||await this.sdk.getAddress(),i=await this.sdk.getAddress(),p=await(await a.redeem(e,d,i)).wait(),A,I=p.events?.find(b=>b.event==="Withdraw");return I&&(A=I.args?.assets?.toString()),{success:!0,txHash:p.transactionHash,assetsWithdrawn:A}}catch(r){throw r instanceof o?r:new o("UNSTAKE_FAILED","Failed to unstake tokens",r)}}async getCooldownStatus(t,r){if(!t.stakingContract)throw new o("VALIDATION_ERROR",`Token ${t.symbol} does not support staking`);let e=r||await this.sdk.getAddress(),n=new D(t.stakingContract,l,this.sdk.provider);try{let s=await n.cooldowns(e),a=s.cooldownEnd.toNumber()*1e3;return{cooldownEnd:a,sharesInCooldown:s.underlyingAmount.toString(),canUnstake:a>0&&a<=Date.now()}}catch(s){throw new o("VALIDATION_ERROR","Failed to fetch cooldown status",s)}}async previewUnstake(t,r){if(!t.stakingContract)throw new o("VALIDATION_ERROR",`Token ${t.symbol} does not support staking`);let e=new D(t.stakingContract,l,this.sdk.provider);try{return(await e.convertToAssets(r)).toString()}catch(n){throw new o("VALIDATION_ERROR","Failed to preview unstake",n)}}};import{Contract as N}from"ethers";var k=class{constructor(t){this.sdk=t}async createOrder(t,r,e,n,s){let a=await this.sdk.getAddress(),d=crypto.randomUUID(),i=Math.floor(Date.now()/1e3)+(s?.expiryMinutes||5)*60,u=t.mintingContract;return{orderId:d,orderType:1,expiry:i,nonce:Date.now(),benefactor:s?.benefactor||a,beneficiary:s?.beneficiary||a,collateralAsset:e,collateralAmount:n.toString(),dAssetAmount:r.toString(),minterAddress:u}}async signOrder(t){let r=this.sdk.signer,e={name:"DeployMinting",version:"1",chainId:await this.sdk.getChainId(),verifyingContract:t.minterAddress},n={order_id:t.orderId,order_type:t.orderType,expiry:t.expiry,nonce:t.nonce,benefactor:t.benefactor,beneficiary:t.beneficiary,collateral_asset:t.collateralAsset,collateral_amount:t.collateralAmount,dAsset_amount:t.dAssetAmount};try{return await r._signTypedData(e,h,n)}catch(s){throw new o("SIGNATURE_FAILED","Failed to sign redeem order",s)}}async submitOrder(t,r){try{let e=await fetch(`${this.sdk.config.apiUrl}/api/redeem`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({order:{order_id:t.orderId,order_type:t.orderType,expiry:t.expiry,nonce:t.nonce,benefactor:t.benefactor,beneficiary:t.beneficiary,collateral_asset:t.collateralAsset,collateral_amount:t.collateralAmount,dAsset_amount:t.dAssetAmount},signature:{signature_type:0,signature_bytes:r}})});if(!e.ok){let s=await e.json();throw new o("API_ERROR",s.message||"Failed to submit redeem order")}let n=await e.json();return{success:!0,orderId:t.orderId,txHash:n.txHash,status:n.status}}catch(e){throw e instanceof o?e:new o("API_ERROR","Failed to submit redeem order",e)}}async redeem(t,r,e,n,s){try{let a=await this.createOrder(t,r,e,n,s),d=await this.signOrder(a);return await this.submitOrder(a,d)}catch(a){throw a instanceof o?a:new o("REDEEM_FAILED","Failed to redeem tokens",a)}}async estimateGas(t,r,e,n,s){let a=new N(t.mintingContract,y,this.sdk.provider),d={order_id:crypto.randomUUID(),order_type:1,expiry:Math.floor(Date.now()/1e3)+300,nonce:Date.now(),benefactor:await this.sdk.getAddress(),beneficiary:await this.sdk.getAddress(),collateral_asset:e,collateral_amount:n.toString(),dAsset_amount:r.toString()};try{return(await a.estimateGas.redeem(d,{signature_type:0,signature_bytes:s})).toBigInt()}catch(i){throw new o("TRANSACTION_FAILED","Failed to estimate gas for redeem",i)}}};export{w as a,o as b,m as c,_ as d,F as e,h as f,l as g,P as h,y as i,R as j,S as k,T as l,k as m};
|