@aspan/sdk 0.1.4 → 0.1.8

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 CHANGED
@@ -23,10 +23,12 @@ pnpm add @aspan/sdk
23
23
 
24
24
  ## Quick Start
25
25
 
26
+ ### Read-Only Client (Query Data)
27
+
26
28
  ```typescript
27
29
  import { createAspanReadClient, formatAmount, formatCR } from "@aspan/sdk";
28
30
 
29
- const DIAMOND = "0xa67e91ebbb709516c563bcf1d9dae355aaf6d2ef";
31
+ const DIAMOND = "0x10d25Ae0690533e0BA9E64EC7ae77dbD4fE8A46f";
30
32
  const client = createAspanReadClient(DIAMOND, "https://bsc-dataseed.binance.org/");
31
33
 
32
34
  const stats = await client.getProtocolStats();
@@ -34,6 +36,53 @@ console.log("TVL:", formatAmount(stats.tvlInUSD), "USD");
34
36
  console.log("CR:", formatCR(stats.collateralRatio));
35
37
  ```
36
38
 
39
+ ### Write Client - Browser (React/wagmi)
40
+
41
+ ```typescript
42
+ import { AspanClient } from "@aspan/sdk";
43
+ import { useWalletClient } from "wagmi";
44
+
45
+ const DIAMOND = "0x10d25Ae0690533e0BA9E64EC7ae77dbD4fE8A46f";
46
+
47
+ function MyComponent() {
48
+ const { data: walletClient } = useWalletClient();
49
+
50
+ const getClient = () => {
51
+ if (!walletClient) return null;
52
+ return new AspanClient({
53
+ diamondAddress: DIAMOND,
54
+ walletClient: walletClient, // Pass wagmi's walletClient
55
+ });
56
+ };
57
+
58
+ const handleMint = async () => {
59
+ const client = getClient();
60
+ if (!client) return;
61
+
62
+ const hash = await client.mintApUSD({
63
+ lstToken: "0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B",
64
+ lstAmount: parseAmount("1"),
65
+ });
66
+ console.log("Tx hash:", hash);
67
+ };
68
+ }
69
+ ```
70
+
71
+ ### Write Client - Node.js / Server
72
+
73
+ ```typescript
74
+ import { createAspanClient, parseAmount } from "@aspan/sdk";
75
+ import { privateKeyToAccount } from "viem/accounts";
76
+
77
+ const account = privateKeyToAccount("0x...");
78
+ const client = createAspanClient(DIAMOND, account);
79
+
80
+ const hash = await client.mintApUSD({
81
+ lstToken: "0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B",
82
+ lstAmount: parseAmount("1"),
83
+ });
84
+ ```
85
+
37
86
  ---
38
87
 
39
88
  ## User Flows
@@ -42,10 +91,56 @@ console.log("CR:", formatCR(stats.collateralRatio));
42
91
 
43
92
  User deposits LST (e.g., slisBNB) to mint apUSD stablecoin.
44
93
 
94
+ #### Browser (React/wagmi)
95
+
96
+ ```typescript
97
+ import { AspanClient, parseAmount } from "@aspan/sdk";
98
+ import { useWalletClient } from "wagmi";
99
+
100
+ const DIAMOND = "0x10d25Ae0690533e0BA9E64EC7ae77dbD4fE8A46f";
101
+ const SLISBNB = "0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B";
102
+
103
+ function MintComponent() {
104
+ const { data: walletClient } = useWalletClient();
105
+
106
+ const handleMint = async () => {
107
+ if (!walletClient) return;
108
+
109
+ const client = new AspanClient({
110
+ diamondAddress: DIAMOND,
111
+ walletClient,
112
+ });
113
+
114
+ const lstAmount = parseAmount("10"); // 10 slisBNB
115
+
116
+ // Step 1: Check LST is supported
117
+ const isSupported = await client.isLSTSupported(SLISBNB);
118
+ if (!isSupported) throw new Error("LST not supported");
119
+
120
+ // Step 2: Check current fees
121
+ const fees = await client.getCurrentFees();
122
+ if (fees.apUSDMintDisabled) throw new Error("Minting disabled");
123
+
124
+ // Step 3: Approve LST (use wagmi's useWriteContract or viem)
125
+ // ...
126
+
127
+ // Step 4: Calculate minOut for slippage protection (e.g., 0.5% slippage)
128
+ const expectedApUSD = lstAmount; // Simplified, use actual calculation
129
+ const minOut = expectedApUSD * 995n / 1000n; // 0.5% slippage
130
+
131
+ // Step 5: Mint apUSD
132
+ const hash = await client.mintApUSD({ lstToken: SLISBNB, lstAmount, minOut });
133
+ const receipt = await client.waitForTransaction(hash);
134
+ console.log("Minted apUSD:", receipt.status);
135
+ };
136
+ }
137
+ ```
138
+
139
+ #### Node.js / Server
140
+
45
141
  ```typescript
46
142
  import { createAspanClient, parseAmount } from "@aspan/sdk";
47
143
  import { privateKeyToAccount } from "viem/accounts";
48
- import { erc20Abi } from "viem";
49
144
 
50
145
  const account = privateKeyToAccount("0x...");
51
146
  const client = createAspanClient(DIAMOND, account);
@@ -70,8 +165,9 @@ if (fees.apUSDMintDisabled) throw new Error("Minting disabled in current CR");
70
165
  // args: [DIAMOND, lstAmount],
71
166
  // });
72
167
 
73
- // Step 4: Mint apUSD
74
- const hash = await client.mintApUSD({ lstToken: SLISBNB, lstAmount });
168
+ // Step 4: Mint apUSD with slippage protection
169
+ const minOut = lstAmount * 995n / 1000n; // 0.5% slippage tolerance
170
+ const hash = await client.mintApUSD({ lstToken: SLISBNB, lstAmount, minOut });
75
171
  const receipt = await client.waitForTransaction(hash);
76
172
  console.log("Minted apUSD:", receipt.status);
77
173
  ```
@@ -90,8 +186,13 @@ const maxRedeemable = (collateral * lstPrice) / parseAmount("1");
90
186
  console.log("Max redeemable:", formatAmount(maxRedeemable), "USD");
91
187
 
92
188
  // Step 2: Approve apUSD spending (use viem directly)
93
- // Step 3: Redeem
94
- const hash = await client.redeemApUSD({ lstToken: SLISBNB, apUSDAmount });
189
+
190
+ // Step 3: Calculate expected LST output and set minOut
191
+ const expectedLST = (apUSDAmount * parseAmount("1")) / lstPrice;
192
+ const minOut = expectedLST * 995n / 1000n; // 0.5% slippage
193
+
194
+ // Step 4: Redeem with slippage protection
195
+ const hash = await client.redeemApUSD({ lstToken: SLISBNB, apUSDAmount, minOut });
95
196
  await client.waitForTransaction(hash);
96
197
  ```
97
198
 
@@ -111,12 +212,46 @@ if (xBNBPrice === 0n) {
111
212
  throw new Error("xBNB underwater - cannot mint");
112
213
  }
113
214
 
114
- // Step 3: Approve LST, then mint xBNB
115
- const hash = await client.mintXBNB({ lstToken: SLISBNB, lstAmount });
215
+ // Step 3: Approve LST, then mint xBNB with slippage protection
216
+ const minOut = 0n; // Set appropriate minOut based on expected xBNB output
217
+ const hash = await client.mintXBNB({ lstToken: SLISBNB, lstAmount, minOut });
218
+ await client.waitForTransaction(hash);
219
+ ```
220
+
221
+ ### Flow 4: Redeem xBNB for LST
222
+
223
+ User burns xBNB to get back LST.
224
+
225
+ ```typescript
226
+ const xBNBAmount = parseAmount("100"); // 100 xBNB
227
+
228
+ // Step 1: Check xBNB price (ensure not underwater)
229
+ const xBNBPrice = await client.getXBNBPriceBNB();
230
+ if (xBNBPrice === 0n) {
231
+ throw new Error("xBNB is underwater - redemption may result in 0 LST");
232
+ }
233
+
234
+ // Step 2: Check current fees
235
+ const fees = await client.getCurrentFees();
236
+ console.log("xBNB Redeem fee:", fees.xBNBRedeemFee / 100, "%");
237
+
238
+ // Step 3: Check available LST liquidity
239
+ const collateral = await client.getLSTCollateral(SLISBNB);
240
+ console.log("Available collateral:", formatAmount(collateral));
241
+
242
+ // Step 4: Approve xBNB spending (use viem directly)
243
+ // ...
244
+
245
+ // Step 5: Calculate expected LST and set minOut for slippage protection
246
+ const expectedLST = (xBNBAmount * xBNBPrice) / parseAmount("1");
247
+ const minOut = expectedLST * 995n / 1000n; // 0.5% slippage
248
+
249
+ // Step 6: Redeem xBNB
250
+ const hash = await client.redeemXBNB({ lstToken: SLISBNB, xBNBAmount, minOut });
116
251
  await client.waitForTransaction(hash);
117
252
  ```
118
253
 
119
- ### Flow 4: Stake apUSD to Earn Yield (sApUSD)
254
+ ### Flow 5: Stake apUSD to Earn Yield (sApUSD)
120
255
 
121
256
  User deposits apUSD to stability pool to earn LST yield.
122
257
 
@@ -141,7 +276,7 @@ console.log("Shares:", formatAmount(position.shares));
141
276
  console.log("Balance (incl. yield):", formatAmount(position.balance));
142
277
  ```
143
278
 
144
- ### Flow 5: Withdraw from Stability Pool
279
+ ### Flow 6: Withdraw from Stability Pool
145
280
 
146
281
  User withdraws their staked apUSD plus accumulated yield.
147
282
 
@@ -164,7 +299,7 @@ await client.waitForTransaction(hash);
164
299
  // const hash = await client.withdrawAssets({ assets: parseAmount("500") });
165
300
  ```
166
301
 
167
- ### Flow 6: Manual Yield Harvest
302
+ ### Flow 7: Manual Yield Harvest
168
303
 
169
304
  Anyone can trigger yield harvest to distribute pending LST yield.
170
305
 
@@ -394,6 +529,18 @@ displayDashboard();
394
529
 
395
530
  ## API Reference
396
531
 
532
+ ### Client Configuration
533
+
534
+ | Option | Type | Required | Description |
535
+ |--------|------|----------|-------------|
536
+ | `diamondAddress` | `Address` | ✅ | Diamond contract address |
537
+ | `chain` | `Chain` | ❌ | Chain config (default: BSC Mainnet) |
538
+ | `rpcUrl` | `string` | ❌ | RPC URL (default: BSC public RPC) |
539
+ | `walletClient` | `WalletClient` | ⚠️ | For browser/wagmi (required if no account) |
540
+ | `account` | `Account` | ⚠️ | For Node.js (required if no walletClient) |
541
+
542
+ > ⚠️ Write client requires either `walletClient` (browser) or `account` (Node.js)
543
+
397
544
  ### View Functions
398
545
 
399
546
  | Category | Methods |
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as viem from 'viem';
2
- import { Address, Hash, PublicClient, Chain, Account } from 'viem';
2
+ import { Address, Hash, PublicClient, Chain, Account, WalletClient, Transport } from 'viem';
3
3
 
4
4
  /**
5
5
  * Aspan SDK Type Definitions
@@ -71,21 +71,29 @@ interface StabilityMode2Info {
71
71
  interface MintApUSDParams {
72
72
  lstToken: Address;
73
73
  lstAmount: bigint;
74
+ /** Minimum apUSD output for slippage protection (default: 0n) */
75
+ minOut?: bigint;
74
76
  }
75
77
  /** Parameters for redeeming apUSD */
76
78
  interface RedeemApUSDParams {
77
79
  lstToken: Address;
78
80
  apUSDAmount: bigint;
81
+ /** Minimum LST output for slippage protection (default: 0n) */
82
+ minOut?: bigint;
79
83
  }
80
84
  /** Parameters for minting xBNB */
81
85
  interface MintXBNBParams {
82
86
  lstToken: Address;
83
87
  lstAmount: bigint;
88
+ /** Minimum xBNB output for slippage protection (default: 0n) */
89
+ minOut?: bigint;
84
90
  }
85
91
  /** Parameters for redeeming xBNB */
86
92
  interface RedeemXBNBParams {
87
93
  lstToken: Address;
88
94
  xBNBAmount: bigint;
95
+ /** Minimum LST output for slippage protection (default: 0n) */
96
+ minOut?: bigint;
89
97
  }
90
98
  /** Parameters for depositing to stability pool */
91
99
  interface DepositParams {
@@ -199,8 +207,10 @@ interface AspanClientConfig {
199
207
  rpcUrl?: string;
200
208
  }
201
209
  interface AspanWriteClientConfig extends AspanClientConfig {
202
- /** Account for signing transactions */
203
- account: Account;
210
+ /** Account for signing transactions (required if walletClient not provided) */
211
+ account?: Account;
212
+ /** External wallet client (for browser environments with wagmi/rainbowkit) */
213
+ walletClient?: WalletClient<Transport, Chain, Account>;
204
214
  }
205
215
  /**
206
216
  * Read-only client for querying Aspan Protocol state
@@ -240,7 +250,7 @@ declare class AspanReadClient {
240
250
  getBNBPriceUSD(): Promise<bigint>;
241
251
  getLSTPriceUSD(lstToken: Address): Promise<bigint>;
242
252
  getLSTInfo(lstToken: Address): Promise<LSTInfo>;
243
- getSupportedLSTs(): Promise<readonly Address[]>;
253
+ getSupportedLSTs(): Promise<Address[]>;
244
254
  isLSTSupported(lstToken: Address): Promise<boolean>;
245
255
  getBNBPriceFeed(): Promise<Address>;
246
256
  getOracleBounds(priceFeed: Address): Promise<OracleBounds>;
@@ -363,6 +373,10 @@ declare const DiamondABI: readonly [{
363
373
  readonly name: "_lstAmount";
364
374
  readonly type: "uint256";
365
375
  readonly internalType: "uint256";
376
+ }, {
377
+ readonly name: "_minOut";
378
+ readonly type: "uint256";
379
+ readonly internalType: "uint256";
366
380
  }];
367
381
  readonly outputs: readonly [{
368
382
  readonly name: "apUSDAmount";
@@ -381,6 +395,10 @@ declare const DiamondABI: readonly [{
381
395
  readonly name: "_apUSDAmount";
382
396
  readonly type: "uint256";
383
397
  readonly internalType: "uint256";
398
+ }, {
399
+ readonly name: "_minOut";
400
+ readonly type: "uint256";
401
+ readonly internalType: "uint256";
384
402
  }];
385
403
  readonly outputs: readonly [{
386
404
  readonly name: "lstAmount";
@@ -399,6 +417,10 @@ declare const DiamondABI: readonly [{
399
417
  readonly name: "_lstAmount";
400
418
  readonly type: "uint256";
401
419
  readonly internalType: "uint256";
420
+ }, {
421
+ readonly name: "_minOut";
422
+ readonly type: "uint256";
423
+ readonly internalType: "uint256";
402
424
  }];
403
425
  readonly outputs: readonly [{
404
426
  readonly name: "xBNBAmount";
@@ -417,6 +439,10 @@ declare const DiamondABI: readonly [{
417
439
  readonly name: "_xBNBAmount";
418
440
  readonly type: "uint256";
419
441
  readonly internalType: "uint256";
442
+ }, {
443
+ readonly name: "_minOut";
444
+ readonly type: "uint256";
445
+ readonly internalType: "uint256";
420
446
  }];
421
447
  readonly outputs: readonly [{
422
448
  readonly name: "lstAmount";
@@ -1302,8 +1328,8 @@ declare function parseAmount(amount: string): bigint;
1302
1328
  declare function formatFeeBPS(bps: number): string;
1303
1329
  /**
1304
1330
  * Format collateral ratio to percentage string
1305
- * @param cr Collateral ratio (18 decimals, 1e18 = 100%)
1306
- * @returns Percentage string (e.g., "150%")
1331
+ * @param cr Collateral ratio in BPS (10000 = 100%, contract format)
1332
+ * @returns Percentage string (e.g., "150.00%")
1307
1333
  */
1308
1334
  declare function formatCR(cr: bigint): string;
1309
1335
  /**
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as viem from 'viem';
2
- import { Address, Hash, PublicClient, Chain, Account } from 'viem';
2
+ import { Address, Hash, PublicClient, Chain, Account, WalletClient, Transport } from 'viem';
3
3
 
4
4
  /**
5
5
  * Aspan SDK Type Definitions
@@ -71,21 +71,29 @@ interface StabilityMode2Info {
71
71
  interface MintApUSDParams {
72
72
  lstToken: Address;
73
73
  lstAmount: bigint;
74
+ /** Minimum apUSD output for slippage protection (default: 0n) */
75
+ minOut?: bigint;
74
76
  }
75
77
  /** Parameters for redeeming apUSD */
76
78
  interface RedeemApUSDParams {
77
79
  lstToken: Address;
78
80
  apUSDAmount: bigint;
81
+ /** Minimum LST output for slippage protection (default: 0n) */
82
+ minOut?: bigint;
79
83
  }
80
84
  /** Parameters for minting xBNB */
81
85
  interface MintXBNBParams {
82
86
  lstToken: Address;
83
87
  lstAmount: bigint;
88
+ /** Minimum xBNB output for slippage protection (default: 0n) */
89
+ minOut?: bigint;
84
90
  }
85
91
  /** Parameters for redeeming xBNB */
86
92
  interface RedeemXBNBParams {
87
93
  lstToken: Address;
88
94
  xBNBAmount: bigint;
95
+ /** Minimum LST output for slippage protection (default: 0n) */
96
+ minOut?: bigint;
89
97
  }
90
98
  /** Parameters for depositing to stability pool */
91
99
  interface DepositParams {
@@ -199,8 +207,10 @@ interface AspanClientConfig {
199
207
  rpcUrl?: string;
200
208
  }
201
209
  interface AspanWriteClientConfig extends AspanClientConfig {
202
- /** Account for signing transactions */
203
- account: Account;
210
+ /** Account for signing transactions (required if walletClient not provided) */
211
+ account?: Account;
212
+ /** External wallet client (for browser environments with wagmi/rainbowkit) */
213
+ walletClient?: WalletClient<Transport, Chain, Account>;
204
214
  }
205
215
  /**
206
216
  * Read-only client for querying Aspan Protocol state
@@ -240,7 +250,7 @@ declare class AspanReadClient {
240
250
  getBNBPriceUSD(): Promise<bigint>;
241
251
  getLSTPriceUSD(lstToken: Address): Promise<bigint>;
242
252
  getLSTInfo(lstToken: Address): Promise<LSTInfo>;
243
- getSupportedLSTs(): Promise<readonly Address[]>;
253
+ getSupportedLSTs(): Promise<Address[]>;
244
254
  isLSTSupported(lstToken: Address): Promise<boolean>;
245
255
  getBNBPriceFeed(): Promise<Address>;
246
256
  getOracleBounds(priceFeed: Address): Promise<OracleBounds>;
@@ -363,6 +373,10 @@ declare const DiamondABI: readonly [{
363
373
  readonly name: "_lstAmount";
364
374
  readonly type: "uint256";
365
375
  readonly internalType: "uint256";
376
+ }, {
377
+ readonly name: "_minOut";
378
+ readonly type: "uint256";
379
+ readonly internalType: "uint256";
366
380
  }];
367
381
  readonly outputs: readonly [{
368
382
  readonly name: "apUSDAmount";
@@ -381,6 +395,10 @@ declare const DiamondABI: readonly [{
381
395
  readonly name: "_apUSDAmount";
382
396
  readonly type: "uint256";
383
397
  readonly internalType: "uint256";
398
+ }, {
399
+ readonly name: "_minOut";
400
+ readonly type: "uint256";
401
+ readonly internalType: "uint256";
384
402
  }];
385
403
  readonly outputs: readonly [{
386
404
  readonly name: "lstAmount";
@@ -399,6 +417,10 @@ declare const DiamondABI: readonly [{
399
417
  readonly name: "_lstAmount";
400
418
  readonly type: "uint256";
401
419
  readonly internalType: "uint256";
420
+ }, {
421
+ readonly name: "_minOut";
422
+ readonly type: "uint256";
423
+ readonly internalType: "uint256";
402
424
  }];
403
425
  readonly outputs: readonly [{
404
426
  readonly name: "xBNBAmount";
@@ -417,6 +439,10 @@ declare const DiamondABI: readonly [{
417
439
  readonly name: "_xBNBAmount";
418
440
  readonly type: "uint256";
419
441
  readonly internalType: "uint256";
442
+ }, {
443
+ readonly name: "_minOut";
444
+ readonly type: "uint256";
445
+ readonly internalType: "uint256";
420
446
  }];
421
447
  readonly outputs: readonly [{
422
448
  readonly name: "lstAmount";
@@ -1302,8 +1328,8 @@ declare function parseAmount(amount: string): bigint;
1302
1328
  declare function formatFeeBPS(bps: number): string;
1303
1329
  /**
1304
1330
  * Format collateral ratio to percentage string
1305
- * @param cr Collateral ratio (18 decimals, 1e18 = 100%)
1306
- * @returns Percentage string (e.g., "150%")
1331
+ * @param cr Collateral ratio in BPS (10000 = 100%, contract format)
1332
+ * @returns Percentage string (e.g., "150.00%")
1307
1333
  */
1308
1334
  declare function formatCR(cr: bigint): string;
1309
1335
  /**