@txnlab/deflex 1.1.0 → 1.3.0
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 +86 -30
- package/dist/index.d.ts +334 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +164 -86
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Deflex SDK
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@txnlab/deflex)
|
|
4
|
+
[](https://bundlejs.com/?q=%40txnlab%2Fdeflex%40latest&treeshake=%5B*%5D)
|
|
5
|
+
[](https://github.com/TxnLab/deflex-js/actions/workflows/ci.yml)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
|
|
3
9
|
TypeScript/JavaScript SDK for [Deflex Order Router](https://txnlab.gitbook.io/deflex-api) - smart order routing and DEX aggregation on Algorand.
|
|
4
10
|
|
|
5
11
|
## Prerequisites
|
|
@@ -174,6 +180,7 @@ await swap.execute()
|
|
|
174
180
|
```
|
|
175
181
|
|
|
176
182
|
The signer function supports two return patterns:
|
|
183
|
+
|
|
177
184
|
- **Pattern 1** (Pera, Defly, algosdk): Returns only the signed transactions as `Uint8Array[]`
|
|
178
185
|
- **Pattern 2** (Lute, ARC-1 compliant): Returns an array matching the transaction group length with `null` for unsigned transactions as `(Uint8Array | null)[]`
|
|
179
186
|
|
|
@@ -181,17 +188,25 @@ Both patterns are automatically handled by the SDK.
|
|
|
181
188
|
|
|
182
189
|
### Advanced Transaction Composition
|
|
183
190
|
|
|
184
|
-
Build the transaction group by adding custom transactions before or after the swap using the [`SwapComposer`](#swapcomposer) instance:
|
|
191
|
+
Build the transaction group by adding custom transactions and ABI method calls before or after the swap using the [`SwapComposer`](#swapcomposer) instance:
|
|
185
192
|
|
|
186
193
|
```typescript
|
|
187
|
-
import { Transaction } from 'algosdk'
|
|
194
|
+
import { ABIMethod, Transaction } from 'algosdk'
|
|
188
195
|
import { useWallet } from '@txnlab/use-wallet-*' // react, vue, solid, or svelte
|
|
189
196
|
|
|
190
197
|
const { activeAddress, transactionSigner } = useWallet()
|
|
191
198
|
|
|
192
199
|
// Create your custom transactions
|
|
193
|
-
const
|
|
194
|
-
|
|
200
|
+
const customTxn = new Transaction({...})
|
|
201
|
+
|
|
202
|
+
// Define an ABI method call
|
|
203
|
+
const methodCall = {
|
|
204
|
+
appID: 123456,
|
|
205
|
+
method: new ABIMethod({...}),
|
|
206
|
+
methodArgs: [...],
|
|
207
|
+
sender: activeAddress,
|
|
208
|
+
suggestedParams: await algodClient.getTransactionParams().do(),
|
|
209
|
+
}
|
|
195
210
|
|
|
196
211
|
// Build and execute the transaction group
|
|
197
212
|
const swap = await deflex.newSwap({
|
|
@@ -202,12 +217,50 @@ const swap = await deflex.newSwap({
|
|
|
202
217
|
})
|
|
203
218
|
|
|
204
219
|
const result = await swap
|
|
205
|
-
.addTransaction(
|
|
220
|
+
.addTransaction(customTxn) // Add transaction before swap
|
|
206
221
|
.addSwapTransactions() // Add swap transactions
|
|
207
|
-
.
|
|
222
|
+
.addMethodCall(methodCall) // Add ABI method call after swap
|
|
208
223
|
.execute() // Sign and execute entire group
|
|
209
224
|
```
|
|
210
225
|
|
|
226
|
+
### Middleware for Custom Asset Requirements
|
|
227
|
+
|
|
228
|
+
Some Algorand assets require additional transactions to be added to swap groups (e.g., assets with transfer restrictions, taxes, or custom smart contract logic). The Deflex SDK supports a middleware system that allows these special requirements to be handled by external packages without modifying the core SDK.
|
|
229
|
+
|
|
230
|
+
Middleware can:
|
|
231
|
+
- Adjust quote parameters (e.g., reduce `maxGroupSize` to account for extra transactions)
|
|
232
|
+
- Add transactions before the swap (e.g., unfreeze account, setup calls)
|
|
233
|
+
- Add transactions after the swap (e.g., tax payments, cleanup calls)
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
import { DeflexClient } from '@txnlab/deflex'
|
|
237
|
+
import { FirstStageMiddleware } from '@firststage/deflex-middleware' // Example external package
|
|
238
|
+
|
|
239
|
+
// Initialize middleware
|
|
240
|
+
const firstStage = new FirstStageMiddleware({
|
|
241
|
+
contractAppId: 123456,
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
// Pass middleware to DeflexClient
|
|
245
|
+
const deflex = new DeflexClient({
|
|
246
|
+
apiKey: 'your-api-key',
|
|
247
|
+
middleware: [firstStage], // Middleware is applied automatically
|
|
248
|
+
})
|
|
249
|
+
|
|
250
|
+
// Use normally - middleware handles everything
|
|
251
|
+
const quote = await deflex.newQuote({
|
|
252
|
+
fromASAID: 0, // ALGO
|
|
253
|
+
toASAID: 789012, // Custom asset (e.g., MOOJ, DEAL)
|
|
254
|
+
amount: 1_000_000,
|
|
255
|
+
address: userAddress,
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
const swap = await deflex.newSwap({ quote, address, signer, slippage: 1 })
|
|
259
|
+
await swap.execute() // Middleware transactions are automatically included
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
For details on creating your own middleware, see [MIDDLEWARE.md](MIDDLEWARE.md).
|
|
263
|
+
|
|
211
264
|
### Manual Asset Opt-In Detection
|
|
212
265
|
|
|
213
266
|
If you're not using `autoOptIn: true`, you can manually check if opt-in is needed:
|
|
@@ -269,16 +322,17 @@ The main client for interacting with the Deflex API.
|
|
|
269
322
|
new DeflexClient(config: DeflexConfigParams)
|
|
270
323
|
```
|
|
271
324
|
|
|
272
|
-
| Option | Description | Type
|
|
273
|
-
| ----------------- | ------------------------------------------------------------ |
|
|
274
|
-
| `apiKey` | Your Deflex API key | `string`
|
|
275
|
-
| `apiBaseUrl` | Base URL for the Deflex API | `string`
|
|
276
|
-
| `algodUri` | Algod node URI | `string`
|
|
277
|
-
| `algodToken` | Algod node token | `string`
|
|
278
|
-
| `algodPort` | Algod node port | `string \| number`
|
|
279
|
-
| `referrerAddress` | Referrer address for fee sharing (receives 25% of swap fees) | `string`
|
|
280
|
-
| `feeBps` | Fee in basis points (0.15%, max: 300 = 3.00%) | `number`
|
|
281
|
-
| `autoOptIn` | Auto-detect and add required opt-in transactions | `boolean`
|
|
325
|
+
| Option | Description | Type | Default |
|
|
326
|
+
| ----------------- | ------------------------------------------------------------ | --------------------- | -------------------------------------- |
|
|
327
|
+
| `apiKey` | Your Deflex API key | `string` | **required** |
|
|
328
|
+
| `apiBaseUrl` | Base URL for the Deflex API | `string` | `https://deflex.txnlab.dev` |
|
|
329
|
+
| `algodUri` | Algod node URI | `string` | `https://mainnet-api.4160.nodely.dev/` |
|
|
330
|
+
| `algodToken` | Algod node token | `string` | `''` |
|
|
331
|
+
| `algodPort` | Algod node port | `string \| number` | `443` |
|
|
332
|
+
| `referrerAddress` | Referrer address for fee sharing (receives 25% of swap fees) | `string` | `undefined` |
|
|
333
|
+
| `feeBps` | Fee in basis points (0.15%, max: 300 = 3.00%) | `number` | `15` |
|
|
334
|
+
| `autoOptIn` | Auto-detect and add required opt-in transactions | `boolean` | `false` |
|
|
335
|
+
| `middleware` | Array of middleware for custom asset requirements | `SwapMiddleware[]` | `[]` |
|
|
282
336
|
|
|
283
337
|
> **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).
|
|
284
338
|
|
|
@@ -310,11 +364,11 @@ Returns a [`SwapComposer`](#swapcomposer) instance for building and executing sw
|
|
|
310
364
|
async newSwap(config: SwapComposerConfig): Promise<SwapComposer>
|
|
311
365
|
```
|
|
312
366
|
|
|
313
|
-
| Parameter | Description | Type
|
|
314
|
-
| ---------- | ------------------------------------------------- |
|
|
315
|
-
| `quote` | Quote result or raw API response | `DeflexQuote \| FetchQuoteResponse`
|
|
316
|
-
| `address` | Signer address | `string`
|
|
317
|
-
| `slippage` | Slippage tolerance as percentage (e.g., 1 for 1%) | `number`
|
|
367
|
+
| Parameter | Description | Type |
|
|
368
|
+
| ---------- | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
|
369
|
+
| `quote` | Quote result or raw API response | `DeflexQuote \| FetchQuoteResponse` |
|
|
370
|
+
| `address` | Signer address | `string` |
|
|
371
|
+
| `slippage` | Slippage tolerance as percentage (e.g., 1 for 1%) | `number` |
|
|
318
372
|
| `signer` | Transaction signer function | `algosdk.TransactionSigner \| ((txnGroup: Transaction[], indexesToSign: number[]) => Promise<(Uint8Array \| null)[]>)` |
|
|
319
373
|
|
|
320
374
|
#### DeflexClient.needsAssetOptIn()
|
|
@@ -368,15 +422,17 @@ Plain object returned by [`newQuote()`](#deflexclientnewquote). Extends the raw
|
|
|
368
422
|
|
|
369
423
|
Builder for constructing and executing atomic swap transaction groups, returned by [`newSwap()`](#deflexclientnewswap).
|
|
370
424
|
|
|
371
|
-
| Method
|
|
372
|
-
|
|
|
373
|
-
| `addTransaction(transaction)` | Add a transaction to the atomic group | `transaction: algosdk.Transaction` | `SwapComposer`
|
|
374
|
-
| `
|
|
375
|
-
| `
|
|
376
|
-
| `
|
|
377
|
-
| `
|
|
378
|
-
| `
|
|
379
|
-
| `
|
|
425
|
+
| Method | Description | Parameters | Returns |
|
|
426
|
+
| -------------------------------------- | ------------------------------------------------------------------------------ | -------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
|
|
427
|
+
| `addTransaction(transaction, signer?)` | Add a transaction to the atomic group | `transaction: algosdk.Transaction, signer?: TransactionSigner` | `SwapComposer` |
|
|
428
|
+
| `addMethodCall(methodCall, signer?)` | Add an ABI method call to the atomic group | `methodCall: MethodCall, signer?: TransactionSigner` | `SwapComposer` |
|
|
429
|
+
| `addSwapTransactions()` | Add swap transactions to the group (includes required app opt-ins) | None | `Promise<SwapComposer>` |
|
|
430
|
+
| `buildGroup()` | Build the transaction group and assign group IDs | None | `TransactionWithSigner[]` |
|
|
431
|
+
| `sign()` | Sign the transaction group | None | `Promise<Uint8Array[]>` |
|
|
432
|
+
| `submit()` | Sign and submit the transaction group | None | `Promise<string[]>` (transaction IDs) |
|
|
433
|
+
| `execute(waitRounds?)` | Sign, submit, and wait for confirmation | `waitRounds?: number` (default: 4) | `Promise<{ confirmedRound: bigint, txIds: string[], methodResults: ABIResult[] }>` |
|
|
434
|
+
| `getStatus()` | Get current status: `BUILDING`, `BUILT`, `SIGNED`, `SUBMITTED`, or `COMMITTED` | None | `SwapComposerStatus` |
|
|
435
|
+
| `count()` | Get the number of transactions in the group | None | `number` |
|
|
380
436
|
|
|
381
437
|
## Documentation
|
|
382
438
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ABIArgument, ABIMethod, ABIResult, Address, Algodv2, BoxReference, OnApplicationComplete, ResourceReference, SuggestedParams, Transaction, TransactionSigner, TransactionWithSigner } from "algosdk";
|
|
2
2
|
|
|
3
3
|
//#region src/constants.d.ts
|
|
4
4
|
/**
|
|
@@ -281,14 +281,270 @@ interface FetchSwapTxnsResponse {
|
|
|
281
281
|
/**
|
|
282
282
|
* Processed transaction with optional pre-signature
|
|
283
283
|
*
|
|
284
|
+
* @deprecated This type is no longer used internally. Use algosdk.TransactionWithSigner instead.
|
|
284
285
|
* @internal
|
|
285
286
|
*/
|
|
286
287
|
interface SwapTransaction {
|
|
287
288
|
/** The Algorand transaction */
|
|
288
|
-
readonly txn:
|
|
289
|
+
readonly txn: Transaction;
|
|
289
290
|
/** Pre-signature from Deflex (if applicable) */
|
|
290
291
|
readonly deflexSignature?: DeflexSignature;
|
|
291
292
|
}
|
|
293
|
+
/**
|
|
294
|
+
* Method call to be executed as part of the swap
|
|
295
|
+
*/
|
|
296
|
+
interface MethodCall {
|
|
297
|
+
/** The ID of the smart contract to call. Set this to 0 to indicate an application creation call. */
|
|
298
|
+
appID: number | bigint;
|
|
299
|
+
/** The method to call on the smart contract */
|
|
300
|
+
method: ABIMethod;
|
|
301
|
+
/** The arguments to include in the method call. If omitted, no arguments will be passed to the method. */
|
|
302
|
+
methodArgs?: ABIArgument[];
|
|
303
|
+
/** The address of the sender of this application call */
|
|
304
|
+
sender: string | Address;
|
|
305
|
+
/** Transactions params to use for this application call */
|
|
306
|
+
suggestedParams: SuggestedParams;
|
|
307
|
+
/** The OnComplete action to take for this application call. If omitted, OnApplicationComplete.NoOpOC will be used. */
|
|
308
|
+
onComplete?: OnApplicationComplete;
|
|
309
|
+
/** The approval program for this application call. Only set this if this is an application creation call, or if onComplete is OnApplicationComplete.UpdateApplicationOC */
|
|
310
|
+
approvalProgram?: Uint8Array;
|
|
311
|
+
/** The clear program for this application call. Only set this if this is an application creation call, or if onComplete is OnApplicationComplete.UpdateApplicationOC */
|
|
312
|
+
clearProgram?: Uint8Array;
|
|
313
|
+
/** The global integer schema size. Only set this if this is an application creation call. */
|
|
314
|
+
numGlobalInts?: number;
|
|
315
|
+
/** The global byte slice schema size. Only set this if this is an application creation call. */
|
|
316
|
+
numGlobalByteSlices?: number;
|
|
317
|
+
/** The local integer schema size. Only set this if this is an application creation call. */
|
|
318
|
+
numLocalInts?: number;
|
|
319
|
+
/** The local byte slice schema size. Only set this if this is an application creation call. */
|
|
320
|
+
numLocalByteSlices?: number;
|
|
321
|
+
/** The number of extra pages to allocate for the application's programs. Only set this if this is an application creation call. If omitted, defaults to 0. */
|
|
322
|
+
extraPages?: number;
|
|
323
|
+
/** Array of Address strings that represent external accounts supplied to this application. If accounts are provided here, the accounts specified in the method args will appear after these. */
|
|
324
|
+
appAccounts?: Array<string | Address>;
|
|
325
|
+
/** Array of App ID numbers that represent external apps supplied to this application. If apps are provided here, the apps specified in the method args will appear after these. */
|
|
326
|
+
appForeignApps?: Array<number | bigint>;
|
|
327
|
+
/** Array of Asset ID numbers that represent external assets supplied to this application. If assets are provided here, the assets specified in the method args will appear after these. */
|
|
328
|
+
appForeignAssets?: Array<number | bigint>;
|
|
329
|
+
/** The box references for this application call */
|
|
330
|
+
boxes?: BoxReference[];
|
|
331
|
+
/** The resource references for this application call */
|
|
332
|
+
access?: ResourceReference[];
|
|
333
|
+
/** The note value for this application call */
|
|
334
|
+
note?: Uint8Array;
|
|
335
|
+
/** The lease value for this application call */
|
|
336
|
+
lease?: Uint8Array;
|
|
337
|
+
/** If provided, the address that the sender will be rekeyed to at the conclusion of this application call */
|
|
338
|
+
rekeyTo?: string | Address;
|
|
339
|
+
/** The lowest application version for which this transaction should immediately fail. 0 indicates that no version check should be performed. */
|
|
340
|
+
rejectVersion?: number | bigint;
|
|
341
|
+
/** A transaction signer that can authorize this application call from sender */
|
|
342
|
+
signer?: TransactionSigner;
|
|
343
|
+
}
|
|
344
|
+
//#endregion
|
|
345
|
+
//#region src/middleware.d.ts
|
|
346
|
+
/**
|
|
347
|
+
* Context provided to middleware hooks during swap composition
|
|
348
|
+
*/
|
|
349
|
+
interface SwapContext {
|
|
350
|
+
/** The quote result from newQuote() */
|
|
351
|
+
readonly quote: DeflexQuote;
|
|
352
|
+
/** The address of the account performing the swap */
|
|
353
|
+
readonly address: string;
|
|
354
|
+
/** Algodv2 client instance for making additional queries/transactions */
|
|
355
|
+
readonly algodClient: Algodv2;
|
|
356
|
+
/** Suggested transaction parameters from the network */
|
|
357
|
+
readonly suggestedParams: SuggestedParams;
|
|
358
|
+
/** Input asset ID (always bigint for precision and future-proofing) */
|
|
359
|
+
readonly fromASAID: bigint;
|
|
360
|
+
/** Output asset ID (always bigint for precision and future-proofing) */
|
|
361
|
+
readonly toASAID: bigint;
|
|
362
|
+
/** Transaction signer for transactions that need to be signed by the user */
|
|
363
|
+
readonly signer: TransactionSigner;
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Middleware interface for extending Deflex swap functionality
|
|
367
|
+
*
|
|
368
|
+
* Middleware allows you to modify quote parameters and inject additional transactions
|
|
369
|
+
* into the atomic swap group. This is useful for assets that require special handling,
|
|
370
|
+
* such as those with transfer restrictions, taxes, or custom smart contract logic.
|
|
371
|
+
*
|
|
372
|
+
* @example
|
|
373
|
+
* ```typescript
|
|
374
|
+
* class CustomAssetMiddleware implements SwapMiddleware {
|
|
375
|
+
* readonly name = 'CustomAsset'
|
|
376
|
+
* readonly version = '1.0.0'
|
|
377
|
+
*
|
|
378
|
+
* async shouldApply(params) {
|
|
379
|
+
* return params.fromASAID === CUSTOM_ASSET_ID || params.toASAID === CUSTOM_ASSET_ID
|
|
380
|
+
* }
|
|
381
|
+
*
|
|
382
|
+
* async adjustQuoteParams(params) {
|
|
383
|
+
* // Reduce maxGroupSize to account for extra transactions
|
|
384
|
+
* return { ...params, maxGroupSize: params.maxGroupSize - 3 }
|
|
385
|
+
* }
|
|
386
|
+
*
|
|
387
|
+
* async beforeSwap(context) {
|
|
388
|
+
* // Return transactions to add before the swap
|
|
389
|
+
* return [unfreezeTransaction]
|
|
390
|
+
* }
|
|
391
|
+
*
|
|
392
|
+
* async afterSwap(context) {
|
|
393
|
+
* // Return transactions to add after the swap
|
|
394
|
+
* return [taxTransaction, refreezeTransaction]
|
|
395
|
+
* }
|
|
396
|
+
* }
|
|
397
|
+
* ```
|
|
398
|
+
*/
|
|
399
|
+
interface SwapMiddleware {
|
|
400
|
+
/** Unique identifier for the middleware */
|
|
401
|
+
readonly name: string;
|
|
402
|
+
/** Semantic version of the middleware */
|
|
403
|
+
readonly version: string;
|
|
404
|
+
/**
|
|
405
|
+
* Determines if this middleware should be applied to the given swap
|
|
406
|
+
*
|
|
407
|
+
* Called during both quote and swap phases. Use this to check if either
|
|
408
|
+
* the input or output asset requires special handling.
|
|
409
|
+
*
|
|
410
|
+
* @param params - Asset IDs being swapped
|
|
411
|
+
* @returns True if middleware should be applied
|
|
412
|
+
*
|
|
413
|
+
* @example
|
|
414
|
+
* ```typescript
|
|
415
|
+
* async shouldApply(params) {
|
|
416
|
+
* // Check if asset is registered in our smart contract
|
|
417
|
+
* const assetInfo = await this.getAssetInfo(params.fromASAID)
|
|
418
|
+
* return assetInfo !== null
|
|
419
|
+
* }
|
|
420
|
+
* ```
|
|
421
|
+
*/
|
|
422
|
+
shouldApply(params: {
|
|
423
|
+
fromASAID: bigint;
|
|
424
|
+
toASAID: bigint;
|
|
425
|
+
}): Promise<boolean>;
|
|
426
|
+
/**
|
|
427
|
+
* Modify quote parameters before fetching the quote
|
|
428
|
+
*
|
|
429
|
+
* **IMPORTANT**: If your middleware adds transactions via `beforeSwap` or `afterSwap`,
|
|
430
|
+
* you MUST reduce `maxGroupSize` accordingly to prevent failures. The Deflex API may
|
|
431
|
+
* return routes that use all 16 available transaction slots.
|
|
432
|
+
*
|
|
433
|
+
* Use this to adjust the quote request based on your asset's requirements.
|
|
434
|
+
* Common adjustments include:
|
|
435
|
+
* - Reducing `maxGroupSize` to account for additional transactions (REQUIRED if adding txns)
|
|
436
|
+
* - Adjusting `amount` to account for fees/taxes
|
|
437
|
+
* - Modifying `disabledProtocols` if certain DEXs are incompatible
|
|
438
|
+
*
|
|
439
|
+
* @param params - Original quote parameters
|
|
440
|
+
* @returns Modified quote parameters
|
|
441
|
+
*
|
|
442
|
+
* @example
|
|
443
|
+
* ```typescript
|
|
444
|
+
* async adjustQuoteParams(params) {
|
|
445
|
+
* const [fromTaxed, toTaxed] = await Promise.all([
|
|
446
|
+
* this.isAssetTaxed(params.fromASAID),
|
|
447
|
+
* this.isAssetTaxed(params.toASAID),
|
|
448
|
+
* ])
|
|
449
|
+
*
|
|
450
|
+
* // 3 extra transactions per taxed asset
|
|
451
|
+
* let maxGroupSize = params.maxGroupSize ?? 16
|
|
452
|
+
* if (fromTaxed) maxGroupSize -= 3
|
|
453
|
+
* if (toTaxed) maxGroupSize -= 3
|
|
454
|
+
*
|
|
455
|
+
* // Adjust amount for input tax
|
|
456
|
+
* let amount = params.amount
|
|
457
|
+
* if (fromTaxed) {
|
|
458
|
+
* const taxRate = await this.getTaxRate(params.fromASAID)
|
|
459
|
+
* amount = this.applyTax(amount, taxRate)
|
|
460
|
+
* }
|
|
461
|
+
*
|
|
462
|
+
* return { ...params, maxGroupSize, amount }
|
|
463
|
+
* }
|
|
464
|
+
* ```
|
|
465
|
+
*/
|
|
466
|
+
adjustQuoteParams?(params: FetchQuoteParams): Promise<FetchQuoteParams>;
|
|
467
|
+
/**
|
|
468
|
+
* Add transactions before the swap transactions
|
|
469
|
+
*
|
|
470
|
+
* Called when building the swap transaction group. Transactions are added
|
|
471
|
+
* to the group in the order they appear in the returned array.
|
|
472
|
+
*
|
|
473
|
+
* Transaction order in final group: [beforeSwap] → [swap txns] → [afterSwap]
|
|
474
|
+
*
|
|
475
|
+
* @param context - Swap context with quote, address, and algod client
|
|
476
|
+
* @returns Array of transactions with signers to add before swap
|
|
477
|
+
*
|
|
478
|
+
* @example
|
|
479
|
+
* ```typescript
|
|
480
|
+
* async beforeSwap(context) {
|
|
481
|
+
* const txns: TransactionWithSigner[] = []
|
|
482
|
+
*
|
|
483
|
+
* // Unfreeze user account before swap
|
|
484
|
+
* if (await this.needsUnfreeze(context.fromASAID)) {
|
|
485
|
+
* const unfreezeCall = makeApplicationNoOpTxn(
|
|
486
|
+
* context.address,
|
|
487
|
+
* this.appId,
|
|
488
|
+
* ...,
|
|
489
|
+
* context.suggestedParams
|
|
490
|
+
* )
|
|
491
|
+
*
|
|
492
|
+
* txns.push({
|
|
493
|
+
* txn: unfreezeCall,
|
|
494
|
+
* signer: context.signer, // Use the signer from context
|
|
495
|
+
* })
|
|
496
|
+
* }
|
|
497
|
+
*
|
|
498
|
+
* return txns
|
|
499
|
+
* }
|
|
500
|
+
* ```
|
|
501
|
+
*/
|
|
502
|
+
beforeSwap?(context: SwapContext): Promise<TransactionWithSigner[]>;
|
|
503
|
+
/**
|
|
504
|
+
* Add transactions after the swap transactions
|
|
505
|
+
*
|
|
506
|
+
* Called when building the swap transaction group. Transactions are added
|
|
507
|
+
* to the group in the order they appear in the returned array.
|
|
508
|
+
*
|
|
509
|
+
* Transaction order in final group: [beforeSwap] → [swap txns] → [afterSwap]
|
|
510
|
+
*
|
|
511
|
+
* @param context - Swap context with quote, address, and algod client
|
|
512
|
+
* @returns Array of transactions with signers to add after swap
|
|
513
|
+
*
|
|
514
|
+
* @example
|
|
515
|
+
* ```typescript
|
|
516
|
+
* async afterSwap(context) {
|
|
517
|
+
* const txns: TransactionWithSigner[] = []
|
|
518
|
+
*
|
|
519
|
+
* // Pay tax and refreeze account
|
|
520
|
+
* if (await this.isTaxed(context.fromASAID)) {
|
|
521
|
+
* const taxAmount = await this.calculateTax(context)
|
|
522
|
+
* const taxPayment = makeAssetTransferTxn(
|
|
523
|
+
* context.address,
|
|
524
|
+
* this.taxReceiver,
|
|
525
|
+
* taxAmount,
|
|
526
|
+
* context.fromASAID,
|
|
527
|
+
* context.suggestedParams
|
|
528
|
+
* )
|
|
529
|
+
* const refreezeCall = makeApplicationNoOpTxn(
|
|
530
|
+
* context.address,
|
|
531
|
+
* this.appId,
|
|
532
|
+
* ...,
|
|
533
|
+
* context.suggestedParams
|
|
534
|
+
* )
|
|
535
|
+
*
|
|
536
|
+
* txns.push(
|
|
537
|
+
* { txn: taxPayment, signer: context.signer },
|
|
538
|
+
* { txn: refreezeCall, signer: context.signer },
|
|
539
|
+
* )
|
|
540
|
+
* }
|
|
541
|
+
*
|
|
542
|
+
* return txns
|
|
543
|
+
* }
|
|
544
|
+
* ```
|
|
545
|
+
*/
|
|
546
|
+
afterSwap?(context: SwapContext): Promise<TransactionWithSigner[]>;
|
|
547
|
+
}
|
|
292
548
|
//#endregion
|
|
293
549
|
//#region src/composer.d.ts
|
|
294
550
|
/**
|
|
@@ -329,6 +585,8 @@ interface SwapComposerConfig {
|
|
|
329
585
|
readonly address: string;
|
|
330
586
|
/** Transaction signer function */
|
|
331
587
|
readonly signer: TransactionSigner | SignerFunction;
|
|
588
|
+
/** Middleware to apply during swap composition */
|
|
589
|
+
readonly middleware?: SwapMiddleware[];
|
|
332
590
|
}
|
|
333
591
|
/**
|
|
334
592
|
* Composer for building and executing atomic swap transaction groups
|
|
@@ -340,27 +598,28 @@ interface SwapComposerConfig {
|
|
|
340
598
|
* @example
|
|
341
599
|
* ```typescript
|
|
342
600
|
* const quote = await deflex.fetchQuote({ ... })
|
|
343
|
-
* const composer = await deflex.newSwap({ quote, address, slippage })
|
|
601
|
+
* const composer = await deflex.newSwap({ quote, address, slippage, signer })
|
|
344
602
|
*
|
|
345
603
|
* await composer
|
|
346
604
|
* .addTransaction(customTxn)
|
|
347
605
|
* .addSwapTransactions()
|
|
348
|
-
* .execute(
|
|
606
|
+
* .execute()
|
|
349
607
|
* ```
|
|
350
608
|
*/
|
|
351
609
|
declare class SwapComposer {
|
|
610
|
+
/** The ATC used to compose the group */
|
|
611
|
+
private atc;
|
|
352
612
|
/** The maximum size of an atomic transaction group. */
|
|
353
613
|
static MAX_GROUP_SIZE: number;
|
|
354
|
-
|
|
355
|
-
private transactions;
|
|
614
|
+
/** Whether the swap transactions have been added to the atomic group. */
|
|
356
615
|
private swapTransactionsAdded;
|
|
357
|
-
private
|
|
358
|
-
private txIds;
|
|
616
|
+
private readonly quote;
|
|
359
617
|
private readonly requiredAppOptIns;
|
|
360
618
|
private readonly deflexTxns;
|
|
361
619
|
private readonly algodClient;
|
|
362
620
|
private readonly address;
|
|
363
621
|
private readonly signer;
|
|
622
|
+
private readonly middleware;
|
|
364
623
|
/**
|
|
365
624
|
* Create a new SwapComposer instance
|
|
366
625
|
*
|
|
@@ -368,11 +627,12 @@ declare class SwapComposer {
|
|
|
368
627
|
* this directly, as the factory method handles fetching swap transactions automatically.
|
|
369
628
|
*
|
|
370
629
|
* @param config - Configuration for the composer
|
|
371
|
-
* @param config.
|
|
630
|
+
* @param config.quote - The quote response from fetchQuote()
|
|
372
631
|
* @param config.deflexTxns - The swap transactions from fetchSwapTransactions()
|
|
373
632
|
* @param config.algodClient - Algodv2 client instance
|
|
374
633
|
* @param config.address - The address of the account that will sign transactions
|
|
375
634
|
* @param config.signer - Transaction signer function
|
|
635
|
+
* @param config.middleware - Middleware to apply during swap composition
|
|
376
636
|
*/
|
|
377
637
|
constructor(config: SwapComposerConfig);
|
|
378
638
|
/**
|
|
@@ -403,12 +663,29 @@ declare class SwapComposer {
|
|
|
403
663
|
* @throws Error if the composer is not in the BUILDING status
|
|
404
664
|
* @throws Error if the maximum group size is exceeded
|
|
405
665
|
*/
|
|
406
|
-
addTransaction(transaction: Transaction): this;
|
|
666
|
+
addTransaction(transaction: Transaction, signer?: TransactionSigner): this;
|
|
667
|
+
/**
|
|
668
|
+
* Add a method call to the atomic group
|
|
669
|
+
*
|
|
670
|
+
* The `signer` property in the `methodCall` parameter is optional. If not provided,
|
|
671
|
+
* the signer will default to the one passed as the second parameter, or the
|
|
672
|
+
* configured signer from the constructor if no second parameter is provided.
|
|
673
|
+
*
|
|
674
|
+
* @param methodCall - The method call to add
|
|
675
|
+
* @param signer - The signer to use for the method call (defaults to constructor signer)
|
|
676
|
+
* @returns This composer instance for chaining
|
|
677
|
+
*/
|
|
678
|
+
addMethodCall(methodCall: MethodCall, signer?: TransactionSigner): this;
|
|
407
679
|
/**
|
|
408
680
|
* Add swap transactions to the atomic group
|
|
409
681
|
*
|
|
410
|
-
* This method automatically processes required app opt-ins
|
|
411
|
-
* transactions from the quote. Can only be called once per composer instance.
|
|
682
|
+
* This method automatically processes required app opt-ins, executes middleware hooks,
|
|
683
|
+
* and adds all swap transactions from the quote. Can only be called once per composer instance.
|
|
684
|
+
*
|
|
685
|
+
* Middleware hooks are executed in this order:
|
|
686
|
+
* 1. beforeSwap() - Add transactions before swap transactions
|
|
687
|
+
* 2. Swap transactions (from API)
|
|
688
|
+
* 3. afterSwap() - Add transactions after swap transactions
|
|
412
689
|
*
|
|
413
690
|
* @returns This composer instance for chaining
|
|
414
691
|
* @throws Error if the swap transactions have already been added
|
|
@@ -416,6 +693,30 @@ declare class SwapComposer {
|
|
|
416
693
|
* @throws Error if the maximum group size is exceeded
|
|
417
694
|
*/
|
|
418
695
|
addSwapTransactions(): Promise<this>;
|
|
696
|
+
/**
|
|
697
|
+
* Finalize the transaction group by assigning group IDs
|
|
698
|
+
*
|
|
699
|
+
* This method builds the atomic transaction group, assigning group IDs to all transactions
|
|
700
|
+
* if there is more than one transaction. After calling this method, the composer's status
|
|
701
|
+
* will be at least BUILT.
|
|
702
|
+
*
|
|
703
|
+
* @returns Array of transactions with their associated signers
|
|
704
|
+
*
|
|
705
|
+
* @throws Error if the group contains 0 transactions
|
|
706
|
+
*
|
|
707
|
+
* @example
|
|
708
|
+
* ```typescript
|
|
709
|
+
* const composer = await deflex.newSwap({ quote, address, slippage, signer })
|
|
710
|
+
* composer.addTransaction(customTxn)
|
|
711
|
+
*
|
|
712
|
+
* // Build the group to inspect transactions before signing
|
|
713
|
+
* const txnsWithSigners = composer.buildGroup()
|
|
714
|
+
* console.log('Group ID:', txnsWithSigners[0].txn.group)
|
|
715
|
+
* console.log('Group length:', txnsWithSigners.length)
|
|
716
|
+
* console.log('Status:', composer.getStatus()) // BUILT
|
|
717
|
+
* ```
|
|
718
|
+
*/
|
|
719
|
+
buildGroup(): TransactionWithSigner[];
|
|
419
720
|
/**
|
|
420
721
|
* Sign the transaction group
|
|
421
722
|
*
|
|
@@ -467,6 +768,7 @@ declare class SwapComposer {
|
|
|
467
768
|
execute(waitRounds?: number): Promise<{
|
|
468
769
|
confirmedRound: bigint;
|
|
469
770
|
txIds: string[];
|
|
771
|
+
methodResults: ABIResult[];
|
|
470
772
|
}>;
|
|
471
773
|
/**
|
|
472
774
|
* Validates an Algorand address
|
|
@@ -481,15 +783,25 @@ declare class SwapComposer {
|
|
|
481
783
|
*/
|
|
482
784
|
private processRequiredAppOptIns;
|
|
483
785
|
/**
|
|
484
|
-
*
|
|
485
|
-
*
|
|
486
|
-
* The composer's status will be at least BUILT after executing this method.
|
|
786
|
+
* The default signer function that uses the configured signer
|
|
487
787
|
*/
|
|
488
|
-
private
|
|
788
|
+
private defaultSigner;
|
|
789
|
+
/**
|
|
790
|
+
* Creates a TransactionSigner function for Deflex pre-signed transactions
|
|
791
|
+
*/
|
|
792
|
+
private createDeflexSigner;
|
|
489
793
|
/**
|
|
490
794
|
* Re-signs a Deflex transaction using the provided logic signature or secret key
|
|
491
795
|
*/
|
|
492
796
|
private signDeflexTransaction;
|
|
797
|
+
/**
|
|
798
|
+
* Execute middleware hooks (beforeSwap or afterSwap)
|
|
799
|
+
*/
|
|
800
|
+
private executeMiddlewareHooks;
|
|
801
|
+
/**
|
|
802
|
+
* Create SwapContext for middleware hooks
|
|
803
|
+
*/
|
|
804
|
+
private createSwapContext;
|
|
493
805
|
}
|
|
494
806
|
//#endregion
|
|
495
807
|
//#region src/client.d.ts
|
|
@@ -524,6 +836,7 @@ declare class SwapComposer {
|
|
|
524
836
|
declare class DeflexClient {
|
|
525
837
|
private readonly config;
|
|
526
838
|
private readonly algodClient;
|
|
839
|
+
private readonly middleware;
|
|
527
840
|
/**
|
|
528
841
|
* Create a new DeflexClient instance
|
|
529
842
|
*
|
|
@@ -536,8 +849,11 @@ declare class DeflexClient {
|
|
|
536
849
|
* @param config.referrerAddress - Referrer address for fee sharing (receives 25% of swap fees)
|
|
537
850
|
* @param config.feeBps - Fee in basis points (default: 15 = 0.15%, max: 300 = 3.00%)
|
|
538
851
|
* @param config.autoOptIn - Automatically detect and add required opt-in transactions (default: false)
|
|
852
|
+
* @param config.middleware - Array of middleware to apply to swaps (default: [])
|
|
539
853
|
*/
|
|
540
|
-
constructor(config: DeflexConfigParams
|
|
854
|
+
constructor(config: DeflexConfigParams & {
|
|
855
|
+
middleware?: SwapMiddleware[];
|
|
856
|
+
});
|
|
541
857
|
/**
|
|
542
858
|
* Fetch a swap quote from the Deflex API
|
|
543
859
|
*
|
|
@@ -737,5 +1053,5 @@ declare class HTTPError extends Error {
|
|
|
737
1053
|
*/
|
|
738
1054
|
declare function request<T>(url: string, options?: RequestInit): Promise<T>;
|
|
739
1055
|
//#endregion
|
|
740
|
-
export { Asset, DEFAULT_ALGOD_PORT, DEFAULT_ALGOD_TOKEN, DEFAULT_ALGOD_URI, DEFAULT_API_BASE_URL, DEFAULT_AUTO_OPT_IN, DEFAULT_CONFIRMATION_ROUNDS, DEFAULT_FEE_BPS, DEFAULT_MAX_DEPTH, DEFAULT_MAX_GROUP_SIZE, DEPRECATED_PROTOCOLS, DeflexClient, DeflexConfig, DeflexConfigParams, DeflexQuote, DeflexSignature, DeflexTransaction, DexQuote, FetchQuoteParams, FetchQuoteResponse, FetchSwapTxnsBody, FetchSwapTxnsParams, FetchSwapTxnsResponse, HTTPError, MAX_FEE_BPS, PathElement, Profit, Protocol, QuoteType, Route, SignerFunction, SwapComposer, SwapComposerConfig, SwapComposerStatus, SwapTransaction, TxnPayload, request };
|
|
1056
|
+
export { Asset, DEFAULT_ALGOD_PORT, DEFAULT_ALGOD_TOKEN, DEFAULT_ALGOD_URI, DEFAULT_API_BASE_URL, DEFAULT_AUTO_OPT_IN, DEFAULT_CONFIRMATION_ROUNDS, DEFAULT_FEE_BPS, DEFAULT_MAX_DEPTH, DEFAULT_MAX_GROUP_SIZE, DEPRECATED_PROTOCOLS, DeflexClient, DeflexConfig, DeflexConfigParams, DeflexQuote, DeflexSignature, DeflexTransaction, DexQuote, FetchQuoteParams, FetchQuoteResponse, FetchSwapTxnsBody, FetchSwapTxnsParams, FetchSwapTxnsResponse, HTTPError, MAX_FEE_BPS, MethodCall, PathElement, Profit, Protocol, QuoteType, Route, SignerFunction, SwapComposer, SwapComposerConfig, SwapComposerStatus, SwapContext, SwapMiddleware, SwapTransaction, TxnPayload, request };
|
|
741
1057
|
//# sourceMappingURL=index.d.ts.map
|