@txnlab/deflex 1.0.0-beta.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/LICENSE +21 -0
- package/README.md +384 -0
- package/dist/index.d.ts +973 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +994 -0
- package/dist/index.js.map +1 -0
- package/package.json +78 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 TxnLab Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
# Deflex SDK
|
|
2
|
+
|
|
3
|
+
TypeScript/JavaScript SDK for [Deflex Order Router](https://txnlab.gitbook.io/deflex-api) - smart order routing and DEX aggregation on Algorand.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @txnlab/deflex
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { DeflexClient } from '@txnlab/deflex'
|
|
15
|
+
import { useWallet } from '@txnlab/use-wallet-*' // react, vue, solid, or svelte
|
|
16
|
+
|
|
17
|
+
const { activeAddress, transactionSigner } = useWallet()
|
|
18
|
+
|
|
19
|
+
// Initialize the client
|
|
20
|
+
const deflex = new DeflexClient({
|
|
21
|
+
apiKey: 'your-api-key',
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
// Get a quote
|
|
25
|
+
const quote = await deflex.newQuote({
|
|
26
|
+
address: activeAddress,
|
|
27
|
+
fromAssetId: 0, // ALGO
|
|
28
|
+
toAssetId: 31566704, // USDC
|
|
29
|
+
amount: 1_000_000, // 1 ALGO (in microAlgos)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
// Execute the swap
|
|
33
|
+
const swap = await deflex.newSwap({
|
|
34
|
+
quote,
|
|
35
|
+
address: activeAddress,
|
|
36
|
+
signer: transactionSigner,
|
|
37
|
+
slippage: 1, // 1% slippage tolerance
|
|
38
|
+
})
|
|
39
|
+
const result = await swap.execute()
|
|
40
|
+
|
|
41
|
+
console.log(`Swap completed in round ${result.confirmedRound}`)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Usage
|
|
45
|
+
|
|
46
|
+
### Initialize the Client
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import { DeflexClient } from '@txnlab/deflex'
|
|
50
|
+
|
|
51
|
+
// Basic initialization
|
|
52
|
+
const deflex = new DeflexClient({
|
|
53
|
+
apiKey: 'your-api-key',
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
// Advanced configuration
|
|
57
|
+
const deflex = new DeflexClient({
|
|
58
|
+
apiKey: 'your-api-key',
|
|
59
|
+
algodUri: 'https://mainnet-api.4160.nodely.dev/',
|
|
60
|
+
algodToken: '',
|
|
61
|
+
algodPort: 443,
|
|
62
|
+
referrerAddress: '<referrer_address>', // Earns 25% of swap fees
|
|
63
|
+
feeBps: 15, // 0.15% fee (max: 300 = 3%)
|
|
64
|
+
autoOptIn: true, // Automatically handle asset opt-ins
|
|
65
|
+
})
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Get a Swap Quote
|
|
69
|
+
|
|
70
|
+
The [`newQuote()`](#deflexclientnewquote) method returns a [`DeflexQuote`](#deflexquote) instance:
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
// Basic quote
|
|
74
|
+
const quote = await deflex.newQuote({
|
|
75
|
+
fromAssetId: 0, // ALGO
|
|
76
|
+
toAssetId: 31566704, // USDC
|
|
77
|
+
amount: 1_000_000, // 1 ALGO
|
|
78
|
+
address: userAddress, // Required for auto opt-in detection
|
|
79
|
+
})
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Execute a Swap
|
|
83
|
+
|
|
84
|
+
The [`newSwap()`](#deflexclientnewswap) method returns a [`SwapComposer`](#swapcomposer) instance:
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
import { useWallet } from '@txnlab/use-wallet-*' // react, vue, solid, or svelte
|
|
88
|
+
|
|
89
|
+
const { activeAddress, transactionSigner } = useWallet()
|
|
90
|
+
|
|
91
|
+
const swap = await deflex.newSwap({
|
|
92
|
+
quote,
|
|
93
|
+
address: activeAddress,
|
|
94
|
+
signer: transactionSigner,
|
|
95
|
+
slippage: 1, // 1% slippage tolerance
|
|
96
|
+
})
|
|
97
|
+
const result = await swap.execute()
|
|
98
|
+
|
|
99
|
+
console.log(`Confirmed in round ${result.confirmedRound}`)
|
|
100
|
+
console.log('Transaction IDs:', result.txIds)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Transaction Signing
|
|
104
|
+
|
|
105
|
+
The SDK supports two types of transaction signers that must be passed to `newSwap()`:
|
|
106
|
+
|
|
107
|
+
#### 1. use-wallet Signer (Recommended)
|
|
108
|
+
|
|
109
|
+
Use the `@txnlab/use-wallet` library for wallet management in your dApp:
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
import { useWallet } from '@txnlab/use-wallet-*' // react, vue, solid, or svelte
|
|
113
|
+
|
|
114
|
+
const { activeAddress, transactionSigner } = useWallet()
|
|
115
|
+
|
|
116
|
+
const swap = await deflex.newSwap({
|
|
117
|
+
quote,
|
|
118
|
+
address: activeAddress,
|
|
119
|
+
signer: transactionSigner,
|
|
120
|
+
slippage: 1,
|
|
121
|
+
})
|
|
122
|
+
await swap.execute()
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
> **Tip**: The [`@txnlab/use-wallet`](https://github.com/TxnLab/use-wallet) library supports multiple wallet providers (Pera, Defly, Lute, WalletConnect, etc.) and provides a unified interface. Choose the framework-specific adapter for your project: `@txnlab/use-wallet-react`, `@txnlab/use-wallet-vue`, `@txnlab/use-wallet-solid`, or `@txnlab/use-wallet-svelte`.
|
|
126
|
+
|
|
127
|
+
#### 2. Custom Signer Function
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
// Custom signer function signature:
|
|
131
|
+
// (txns: Transaction[]) => Promise<Uint8Array[]>
|
|
132
|
+
|
|
133
|
+
const customSigner = async (txns) => {
|
|
134
|
+
// Your custom signing logic here
|
|
135
|
+
const signedTxns = await yourWalletProvider.signTransactions(txns)
|
|
136
|
+
|
|
137
|
+
return signedTxns
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const swap = await deflex.newSwap({
|
|
141
|
+
quote,
|
|
142
|
+
address: activeAddress,
|
|
143
|
+
signer: customSigner,
|
|
144
|
+
slippage: 1,
|
|
145
|
+
})
|
|
146
|
+
await swap.execute()
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
> **Note**: The custom signer function must return an array of `Uint8Array` where each element is a signed transaction.
|
|
150
|
+
|
|
151
|
+
### Advanced Transaction Composition
|
|
152
|
+
|
|
153
|
+
Build the transaction group by adding custom transactions before or after the swap using the [`SwapComposer`](#swapcomposer) instance:
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
import { Transaction } from 'algosdk'
|
|
157
|
+
import { useWallet } from '@txnlab/use-wallet-*' // react, vue, solid, or svelte
|
|
158
|
+
|
|
159
|
+
const { activeAddress, transactionSigner } = useWallet()
|
|
160
|
+
|
|
161
|
+
// Create your custom transactions
|
|
162
|
+
const customTxn1 = new Transaction({...})
|
|
163
|
+
const customTxn2 = new Transaction({...})
|
|
164
|
+
|
|
165
|
+
// Build and execute the transaction group
|
|
166
|
+
const swap = await deflex.newSwap({
|
|
167
|
+
quote,
|
|
168
|
+
address: activeAddress,
|
|
169
|
+
signer: transactionSigner,
|
|
170
|
+
slippage: 1,
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
const result = await swap
|
|
174
|
+
.addTransaction(customTxn1) // Add transaction before swap
|
|
175
|
+
.addSwapTransactions() // Add swap transactions
|
|
176
|
+
.addTransaction(customTxn2) // Add transaction after swap
|
|
177
|
+
.execute() // Sign and execute entire group
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Manual Asset Opt-In Detection
|
|
181
|
+
|
|
182
|
+
If you're not using `autoOptIn: true`, you can manually check if opt-in is needed:
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
const deflex = new DeflexClient({
|
|
186
|
+
apiKey: 'your-api-key',
|
|
187
|
+
autoOptIn: false, // Default if not provided
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
// Check if user needs to opt into the output asset
|
|
191
|
+
const needsOptIn = await deflex.needsAssetOptIn(userAddress, toAssetId)
|
|
192
|
+
|
|
193
|
+
// Include opt-in in quote if needed
|
|
194
|
+
const quote = await deflex.newQuote({
|
|
195
|
+
fromAssetId,
|
|
196
|
+
toAssetId,
|
|
197
|
+
amount,
|
|
198
|
+
optIn: needsOptIn,
|
|
199
|
+
})
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Error Handling
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
import { useWallet } from '@txnlab/use-wallet-*' // react, vue, solid, or svelte
|
|
206
|
+
|
|
207
|
+
const { activeAddress, transactionSigner } = useWallet()
|
|
208
|
+
|
|
209
|
+
try {
|
|
210
|
+
const quote = await deflex.newQuote({
|
|
211
|
+
fromAssetId: 0,
|
|
212
|
+
toAssetId: 31566704,
|
|
213
|
+
amount: 1_000_000,
|
|
214
|
+
address: activeAddress,
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
const swap = await deflex.newSwap({
|
|
218
|
+
quote,
|
|
219
|
+
address: activeAddress,
|
|
220
|
+
signer: transactionSigner,
|
|
221
|
+
slippage: 1,
|
|
222
|
+
})
|
|
223
|
+
const result = await swap.execute()
|
|
224
|
+
|
|
225
|
+
console.log('Swap successful:', result)
|
|
226
|
+
} catch (error) {
|
|
227
|
+
console.error('Swap failed:', error.message)
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## API Reference
|
|
232
|
+
|
|
233
|
+
### DeflexClient
|
|
234
|
+
|
|
235
|
+
The main client for interacting with the Deflex API.
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
new DeflexClient(config: DeflexConfigParams)
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
| Option | Description | Type | Default |
|
|
242
|
+
| ----------------- | ------------------------------------------------------------ | ------------------ | -------------------------------------- |
|
|
243
|
+
| `apiKey` | Your Deflex API key | `string` | **required** |
|
|
244
|
+
| `algodUri` | Algod node URI | `string` | `https://mainnet-api.4160.nodely.dev/` |
|
|
245
|
+
| `algodToken` | Algod node token | `string` | `''` |
|
|
246
|
+
| `algodPort` | Algod node port | `string \| number` | `443` |
|
|
247
|
+
| `referrerAddress` | Referrer address for fee sharing (receives 25% of swap fees) | `string` | `undefined` |
|
|
248
|
+
| `feeBps` | Fee in basis points (0.15%, max: 300 = 3.00%) | `number` | `15` |
|
|
249
|
+
| `autoOptIn` | Auto-detect and add required opt-in transactions | `boolean` | `false` |
|
|
250
|
+
|
|
251
|
+
> **Referral Program**: By providing a `referrerAddress`, you can earn 25% of the swap fees generated through your integration. The `feeBps` parameter sets the total fee charged (default: 0.15%). Learn more about the [Deflex Referral Program](https://txnlab.gitbook.io/deflex-api/referral-treasury/referral-program).
|
|
252
|
+
|
|
253
|
+
#### DeflexClient.newQuote()
|
|
254
|
+
|
|
255
|
+
Fetch a swap quote and return a [`DeflexQuote`](#deflexquote) instance.
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
async newQuote(params: QuoteParams): Promise<DeflexQuote>
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
| Parameter | Description | Type | Default |
|
|
262
|
+
| ------------------- | ------------------------------------------ | --------------------------------- | --------------- |
|
|
263
|
+
| `fromAssetId` | Input asset ID | `bigint \| number` | **required** |
|
|
264
|
+
| `toAssetId` | Output asset ID | `bigint \| number` | **required** |
|
|
265
|
+
| `amount` | Amount to swap in base units | `bigint \| number` | **required** |
|
|
266
|
+
| `type` | Quote type | `'fixed-input' \| 'fixed-output'` | `'fixed-input'` |
|
|
267
|
+
| `address` | User address (recommended for auto opt-in) | `string` | `undefined` |
|
|
268
|
+
| `disabledProtocols` | Array of protocols to exclude | `Protocol[]` | `[]` |
|
|
269
|
+
| `maxGroupSize` | Maximum transactions in atomic group | `number` | `16` |
|
|
270
|
+
| `maxDepth` | Maximum swap hops | `number` | `4` |
|
|
271
|
+
| `optIn` | Override auto opt-in behavior | `boolean` | `undefined` |
|
|
272
|
+
|
|
273
|
+
#### DeflexClient.newSwap()
|
|
274
|
+
|
|
275
|
+
Returns a [`SwapComposer`](#swapcomposer) instance for building and executing swaps.
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
async newSwap(config: SwapComposerConfig): Promise<SwapComposer>
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
| Parameter | Description | Type |
|
|
282
|
+
| ---------- | ------------------------------------------------- | --------------------------------------------------------------------------------------- |
|
|
283
|
+
| `quote` | Quote instance or response object | `DeflexQuote \| FetchQuoteResponse` |
|
|
284
|
+
| `address` | Signer address | `string` |
|
|
285
|
+
| `slippage` | Slippage tolerance as percentage (e.g., 1 for 1%) | `number` |
|
|
286
|
+
| `signer` | Transaction signer function | `algosdk.TransactionSigner \| ((txns: algosdk.Transaction[]) => Promise<Uint8Array[]>)` |
|
|
287
|
+
|
|
288
|
+
#### DeflexClient.needsAssetOptIn()
|
|
289
|
+
|
|
290
|
+
Checks if an address needs to opt into an asset.
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
async needsAssetOptIn(address: string, assetId: bigint | number): Promise<boolean>
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
| Parameter | Description | Type |
|
|
297
|
+
| --------- | ------------------------- | ------------------ |
|
|
298
|
+
| `address` | Algorand address to check | `string` |
|
|
299
|
+
| `assetId` | Asset ID to check | `bigint \| number` |
|
|
300
|
+
|
|
301
|
+
### DeflexQuote
|
|
302
|
+
|
|
303
|
+
Wrapper class for quote responses returned by [`newQuote()`](#deflexclientnewquote).
|
|
304
|
+
|
|
305
|
+
| Property | Description | Type |
|
|
306
|
+
| ------------------- | ------------------------------------------------ | ------------------------ |
|
|
307
|
+
| `quote` | Quoted amount | `bigint` |
|
|
308
|
+
| `amount` | Original request amount | `bigint` |
|
|
309
|
+
| `address` | User address (if provided) | `string \| undefined` |
|
|
310
|
+
| `createdAt` | Timestamp when quote was created | `number` |
|
|
311
|
+
| `fromAssetId` | Input asset ID | `number` |
|
|
312
|
+
| `toAssetId` | Output asset ID | `number` |
|
|
313
|
+
| `type` | Quote type (`'fixed-input'` or `'fixed-output'`) | `string` |
|
|
314
|
+
| `profit` | Profit information | `Profit` |
|
|
315
|
+
| `priceBaseline` | Baseline price without fees | `number` |
|
|
316
|
+
| `userPriceImpact` | Price impact for the user | `number \| undefined` |
|
|
317
|
+
| `marketPriceImpact` | Overall market price impact | `number \| undefined` |
|
|
318
|
+
| `usdIn` | USD value of input | `number` |
|
|
319
|
+
| `usdOut` | USD value of output | `number` |
|
|
320
|
+
| `route` | Routing path information | `Route[]` |
|
|
321
|
+
| `flattenedRoute` | Flattened routing percentages | `Record<string, number>` |
|
|
322
|
+
| `quotes` | Individual DEX quotes | `DexQuote[]` |
|
|
323
|
+
| `requiredAppOptIns` | Required app opt-ins | `number[]` |
|
|
324
|
+
| `txnPayload` | Encrypted transaction payload | `TxnPayload \| null` |
|
|
325
|
+
| `protocolFees` | Fees by protocol | `Record<string, number>` |
|
|
326
|
+
| `response` | Raw API response | `FetchQuoteResponse` |
|
|
327
|
+
|
|
328
|
+
#### DeflexQuote.getSlippageAmount()
|
|
329
|
+
|
|
330
|
+
Calculates the slippage-adjusted amount.
|
|
331
|
+
|
|
332
|
+
- For **fixed-input** swaps: Returns minimum output amount
|
|
333
|
+
- For **fixed-output** swaps: Returns maximum input amount
|
|
334
|
+
|
|
335
|
+
```typescript
|
|
336
|
+
getSlippageAmount(slippage: number): bigint
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
| Parameter | Description | Type |
|
|
340
|
+
| ---------- | ------------------------------------------------- | -------- |
|
|
341
|
+
| `slippage` | Slippage tolerance as percentage (e.g., 1 for 1%) | `number` |
|
|
342
|
+
|
|
343
|
+
**Example:**
|
|
344
|
+
|
|
345
|
+
```typescript
|
|
346
|
+
const quote = await deflex.newQuote({
|
|
347
|
+
fromAssetId: 0,
|
|
348
|
+
toAssetId: 31566704,
|
|
349
|
+
amount: 1_000_000,
|
|
350
|
+
type: 'fixed-input',
|
|
351
|
+
})
|
|
352
|
+
|
|
353
|
+
// Get minimum output with 1% slippage
|
|
354
|
+
const minOutput = quote.getSlippageAmount(1)
|
|
355
|
+
console.log(`Minimum you'll receive: ${minOutput}`)
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### SwapComposer
|
|
359
|
+
|
|
360
|
+
Builder for constructing and executing atomic swap transaction groups, returned by [`newSwap()`](#deflexclientnewswap).
|
|
361
|
+
|
|
362
|
+
| Method | Description | Parameters | Returns |
|
|
363
|
+
| ----------------------------- | ------------------------------------------------------------------------------ | ---------------------------------- | ------------------------------------- |
|
|
364
|
+
| `addTransaction(transaction)` | Add a transaction to the atomic group | `transaction: algosdk.Transaction` | `SwapComposer` |
|
|
365
|
+
| `addSwapTransactions()` | Add swap transactions to the group (includes required app opt-ins) | None | `Promise<SwapComposer>` |
|
|
366
|
+
| `sign()` | Sign the transaction group | None | `Promise<Uint8Array[]>` |
|
|
367
|
+
| `submit()` | Sign and submit the transaction group | None | `Promise<string[]>` |
|
|
368
|
+
| `execute(waitRounds?)` | Sign, submit, and wait for confirmation | `waitRounds?: number` (default: 4) | `Promise<PendingTransactionResponse>` |
|
|
369
|
+
| `getStatus()` | Get current status: `BUILDING`, `BUILT`, `SIGNED`, `SUBMITTED`, or `COMMITTED` | None | `ComposerStatus` |
|
|
370
|
+
| `count()` | Get the number of transactions in the group | None | `number` |
|
|
371
|
+
|
|
372
|
+
## Documentation
|
|
373
|
+
|
|
374
|
+
For more information about the Deflex Order Router protocol, visit the [official documentation](https://txnlab.gitbook.io/deflex-api).
|
|
375
|
+
|
|
376
|
+
## License
|
|
377
|
+
|
|
378
|
+
MIT
|
|
379
|
+
|
|
380
|
+
## Support
|
|
381
|
+
|
|
382
|
+
- [GitHub Issues](https://github.com/TxnLab/deflex-js/issues)
|
|
383
|
+
- [Discord](https://discord.gg/Ek3dNyzG)
|
|
384
|
+
- [TxnLab](https://txnlab.dev)
|