@goplausible/openclaw-algorand-plugin 1.1.0 → 1.2.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/openclaw.plugin.json +4 -2
- package/package.json +1 -1
- package/skills/algorand-interaction/SKILL.md +4 -2
- package/skills/algorand-interaction/references/algorand-mcp.md +49 -2
- package/skills/algorand-interaction/references/examples-algorand-mcp.md +49 -0
- package/skills/haystack-router-development/SKILL.md +85 -0
- package/skills/haystack-router-development/references/api-reference.md +381 -0
- package/skills/haystack-router-development/references/configuration.md +184 -0
- package/skills/haystack-router-development/references/fees-and-referrals.md +91 -0
- package/skills/haystack-router-development/references/getting-started.md +93 -0
- package/skills/haystack-router-development/references/migration.md +53 -0
- package/skills/haystack-router-development/references/node-automation.md +113 -0
- package/skills/haystack-router-development/references/quotes.md +155 -0
- package/skills/haystack-router-development/references/react-integration.md +260 -0
- package/skills/haystack-router-development/references/swaps.md +161 -0
- package/skills/haystack-router-interaction/SKILL.md +146 -0
- package/skills/haystack-router-interaction/references/configuration.md +53 -0
- package/skills/haystack-router-interaction/references/getting-started.md +48 -0
- package/skills/haystack-router-interaction/references/node-automation.md +51 -0
- package/skills/haystack-router-interaction/references/quotes.md +80 -0
- package/skills/haystack-router-interaction/references/swaps.md +84 -0
package/openclaw.plugin.json
CHANGED
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
"id": "openclaw-algorand-plugin",
|
|
3
3
|
"name": "Algorand Integration",
|
|
4
4
|
"description": "Algorand blockchain integration with MCP and skills — by GoPlausible",
|
|
5
|
-
"version": "1.0
|
|
5
|
+
"version": "1.2.0",
|
|
6
6
|
"skills": [
|
|
7
7
|
"skills/algorand-development",
|
|
8
8
|
"skills/algorand-typescript",
|
|
9
9
|
"skills/algorand-python",
|
|
10
10
|
"skills/algorand-interaction",
|
|
11
11
|
"skills/algorand-x402-typescript",
|
|
12
|
-
"skills/algorand-x402-python"
|
|
12
|
+
"skills/algorand-x402-python",
|
|
13
|
+
"skills/haystack-router-development",
|
|
14
|
+
"skills/haystack-router-interaction"
|
|
13
15
|
],
|
|
14
16
|
"configSchema": {
|
|
15
17
|
"type": "object",
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: algorand-interaction
|
|
3
|
-
description: Interact with Algorand blockchain via the Algorand MCP server — wallet operations, ALGO/ASA transactions, smart contracts, account info, NFD lookups, atomic groups, Tinyman swaps, TEAL compilation, knowledge base. Use when user asks about Algorand wallet, balances, sending ALGO or tokens, asset opt-in, transactions, NFD names, DEX swaps, smart contracts, or account details.
|
|
3
|
+
description: Interact with Algorand blockchain via the Algorand MCP server — wallet operations, ALGO/ASA transactions, smart contracts, account info, NFD lookups, atomic groups, Tinyman swaps, Haystack Router DEX-aggregated swaps, TEAL compilation, knowledge base. Use when user asks about Algorand wallet, balances, sending ALGO or tokens, asset opt-in, transactions, NFD names, DEX swaps, smart contracts, or account details.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Algorand MCP Interaction
|
|
7
7
|
|
|
8
|
-
Interact with Algorand blockchain through the Algorand MCP server (
|
|
8
|
+
Interact with Algorand blockchain through the Algorand MCP server (101+ tools across 12 categories).
|
|
9
9
|
|
|
10
10
|
## Key Characteristics
|
|
11
11
|
|
|
@@ -160,6 +160,8 @@ For atomic (all-or-nothing) multi-transaction groups:
|
|
|
160
160
|
|
|
161
161
|
**Tinyman DEX** (9): `api_tinyman_get_pool`, `api_tinyman_get_pool_analytics`, `api_tinyman_get_pool_creation_quote`, `api_tinyman_get_liquidity_quote`, `api_tinyman_get_remove_liquidity_quote`, `api_tinyman_get_swap_quote`, `api_tinyman_get_asset_optin_quote`, `api_tinyman_get_validator_optin_quote`, `api_tinyman_get_validator_optout_quote`
|
|
162
162
|
|
|
163
|
+
**Haystack Router** (3): `api_haystack_get_swap_quote`, `api_haystack_execute_swap`, `api_haystack_needs_optin` — DEX-aggregated swaps across Tinyman V2, Pact, Folks with optimal routing. See the **haystack-router-interaction** skill for detailed workflows and reference docs.
|
|
164
|
+
|
|
163
165
|
**ARC-26 URI** (1): `generate_algorand_uri`
|
|
164
166
|
|
|
165
167
|
**Knowledge Base** (1): `get_knowledge_doc`
|
|
@@ -14,8 +14,9 @@
|
|
|
14
14
|
7. [Indexer API Tools](#indexer-api-tools)
|
|
15
15
|
8. [NFDomains API Tools](#nfdomains-api-tools)
|
|
16
16
|
9. [Tinyman DEX API Tools](#tinyman-dex-api-tools)
|
|
17
|
-
10. [
|
|
18
|
-
11. [
|
|
17
|
+
10. [Haystack Router Tools](#haystack-router-tools)
|
|
18
|
+
11. [ARC-26 URI Tools](#arc-26-uri-tools)
|
|
19
|
+
12. [Knowledge Base Tools](#knowledge-base-tools)
|
|
19
20
|
|
|
20
21
|
---
|
|
21
22
|
|
|
@@ -691,6 +692,52 @@ Decentralized exchange operations on Tinyman AMM.
|
|
|
691
692
|
|
|
692
693
|
---
|
|
693
694
|
|
|
695
|
+
## Haystack Router Tools
|
|
696
|
+
|
|
697
|
+
DEX-aggregated swaps across Tinyman V2, Pact, and Folks with smart order routing. For detailed workflows and the full SDK guide, see the **haystack-router-interaction** and **haystack-router-development** skills.
|
|
698
|
+
|
|
699
|
+
### api_haystack_get_swap_quote
|
|
700
|
+
- **Purpose**: Get an optimized swap quote across multiple DEXes without executing
|
|
701
|
+
- **Parameters**:
|
|
702
|
+
```json
|
|
703
|
+
{
|
|
704
|
+
"fromASAID": 0,
|
|
705
|
+
"toASAID": 31566704,
|
|
706
|
+
"amount": 1000000,
|
|
707
|
+
"type": "fixed-input",
|
|
708
|
+
"address": "optional — enables opt-in detection",
|
|
709
|
+
"maxGroupSize": 16,
|
|
710
|
+
"maxDepth": 4,
|
|
711
|
+
"network": "mainnet"
|
|
712
|
+
}
|
|
713
|
+
```
|
|
714
|
+
- **Returns**: `expectedOutput`, `inputAmount`, `usdIn`, `usdOut`, `userPriceImpact`, `route`, `flattenedRoute`, `requiredAppOptIns`, `protocolFees`
|
|
715
|
+
|
|
716
|
+
### api_haystack_execute_swap
|
|
717
|
+
- **Purpose**: All-in-one swap: quote → sign (via wallet) → submit → confirm. Enforces wallet spending limits.
|
|
718
|
+
- **Parameters**:
|
|
719
|
+
```json
|
|
720
|
+
{
|
|
721
|
+
"fromASAID": 0,
|
|
722
|
+
"toASAID": 31566704,
|
|
723
|
+
"amount": 1000000,
|
|
724
|
+
"slippage": 1,
|
|
725
|
+
"type": "fixed-input",
|
|
726
|
+
"note": "optional text note",
|
|
727
|
+
"maxGroupSize": 16,
|
|
728
|
+
"maxDepth": 4,
|
|
729
|
+
"network": "mainnet"
|
|
730
|
+
}
|
|
731
|
+
```
|
|
732
|
+
- **Returns**: `status`, `confirmedRound`, `txIds`, `signer`, `nickname`, quote details, `summary` (inputAmount, outputAmount, totalFees, transactionCount)
|
|
733
|
+
|
|
734
|
+
### api_haystack_needs_optin
|
|
735
|
+
- **Purpose**: Check if an address needs to opt into an asset before swapping
|
|
736
|
+
- **Parameters**: `{ "address": "ALGO_ADDRESS", "assetId": 31566704, "network": "mainnet" }`
|
|
737
|
+
- **Returns**: `{ address, assetId, needsOptIn: true/false, network }`
|
|
738
|
+
|
|
739
|
+
---
|
|
740
|
+
|
|
694
741
|
## ARC-26 URI Tools
|
|
695
742
|
|
|
696
743
|
### generate_algorand_uri
|
|
@@ -398,6 +398,55 @@ api_tinyman_get_pool {
|
|
|
398
398
|
|
|
399
399
|
---
|
|
400
400
|
|
|
401
|
+
## Haystack Router Swap (DEX-Aggregated)
|
|
402
|
+
|
|
403
|
+
Best-price swap across multiple DEXes (Tinyman V2, Pact, Folks). For detailed reference, see the **haystack-router-interaction** skill.
|
|
404
|
+
|
|
405
|
+
### Step 1: Check wallet
|
|
406
|
+
```
|
|
407
|
+
wallet_get_info { "network": "mainnet" }
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### Step 2: Check opt-in (if swapping to an ASA)
|
|
411
|
+
```
|
|
412
|
+
api_haystack_needs_optin {
|
|
413
|
+
"address": "[wallet_address]",
|
|
414
|
+
"assetId": 31566704,
|
|
415
|
+
"network": "mainnet"
|
|
416
|
+
}
|
|
417
|
+
```
|
|
418
|
+
If `needsOptIn: true`:
|
|
419
|
+
```
|
|
420
|
+
wallet_optin_asset { "assetId": 31566704, "network": "mainnet" }
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
### Step 3: Get a quote (show user before executing)
|
|
424
|
+
```
|
|
425
|
+
api_haystack_get_swap_quote {
|
|
426
|
+
"fromASAID": 0,
|
|
427
|
+
"toASAID": 31566704,
|
|
428
|
+
"amount": 1000000,
|
|
429
|
+
"type": "fixed-input",
|
|
430
|
+
"address": "[wallet_address]",
|
|
431
|
+
"network": "mainnet"
|
|
432
|
+
}
|
|
433
|
+
```
|
|
434
|
+
> Present to user: expected output, USD values, route, price impact.
|
|
435
|
+
|
|
436
|
+
### Step 4: Execute swap (after user confirms)
|
|
437
|
+
```
|
|
438
|
+
api_haystack_execute_swap {
|
|
439
|
+
"fromASAID": 0,
|
|
440
|
+
"toASAID": 31566704,
|
|
441
|
+
"amount": 1000000,
|
|
442
|
+
"slippage": 1,
|
|
443
|
+
"network": "mainnet"
|
|
444
|
+
}
|
|
445
|
+
```
|
|
446
|
+
> Signs via wallet, submits, and confirms atomically. Returns confirmed round and tx IDs.
|
|
447
|
+
|
|
448
|
+
---
|
|
449
|
+
|
|
401
450
|
## Using the Knowledge Base
|
|
402
451
|
|
|
403
452
|
### Get a specific document
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: haystack-router-development
|
|
3
|
+
description: Comprehensive guide for building applications with Haystack Router SDK (@txnlab/haystack-router) — a DEX aggregator and smart order routing protocol on Algorand. Use when developing swap UIs with React and use-wallet, writing Node.js automation scripts, integrating RouterClient for quotes and swaps, or working with the SDK API surface, middleware, fees, and referral program. Strong triggers include haystack router, @txnlab/haystack-router, RouterClient, DEX aggregator, swap UI, swap React, newQuote, newSwap, deflex migration, haystack SDK, swap routing, best price swap.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Haystack Router (Development)
|
|
7
|
+
|
|
8
|
+
This is the parent skill for building applications that integrate the `@txnlab/haystack-router` SDK — React swap UIs, Node.js automation scripts, custom signing flows, middleware, and direct RouterClient usage. No Algorand MCP tools are involved.
|
|
9
|
+
|
|
10
|
+
> **Want to execute swaps** through the Algorand MCP server instead of building an app? Use the **haystack-router-interaction** skill — it provides Algorand MCP tools for quoting, swapping, and opt-in checking with wallet-based signing.
|
|
11
|
+
> **Need Algorand blockchain interaction guidance?** See the **algorand-interaction** skill for wallet setup, transaction workflows, and MCP tool reference.
|
|
12
|
+
|
|
13
|
+
Haystack Router is a DEX aggregator and smart order routing protocol on Algorand. It finds optimal swap routes across multiple DEXes (Tinyman V2, Pact, Folks) and LST protocols (tALGO, xALGO), then executes them atomically through on-chain smart contracts.
|
|
14
|
+
|
|
15
|
+
## Package
|
|
16
|
+
|
|
17
|
+
`@txnlab/haystack-router` — TypeScript SDK for DEX-aggregated swaps. Requires `algosdk` (v3+) as a peer dependency.
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @txnlab/haystack-router algosdk
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**API key required.** A free tier key is available for immediate use — see [configuration.md](references/configuration.md) for details.
|
|
24
|
+
|
|
25
|
+
## SDK Core Flow
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { RouterClient } from '@txnlab/haystack-router'
|
|
29
|
+
|
|
30
|
+
// 1. Initialize
|
|
31
|
+
const router = new RouterClient({
|
|
32
|
+
apiKey: '1b72df7e-1131-4449-8ce1-29b79dd3f51e', // Free tier (60 requests/min)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
// 2. Get a quote
|
|
36
|
+
const quote = await router.newQuote({
|
|
37
|
+
fromASAID: 0, // ALGO
|
|
38
|
+
toASAID: 31566704, // USDC
|
|
39
|
+
amount: 1_000_000, // 1 ALGO (base units)
|
|
40
|
+
address: activeAddress,
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
// 3. Execute the swap (use-wallet signer for browser, custom signer for Node.js)
|
|
44
|
+
const swap = await router.newSwap({
|
|
45
|
+
quote,
|
|
46
|
+
address: activeAddress,
|
|
47
|
+
signer: transactionSigner,
|
|
48
|
+
slippage: 1, // 1%
|
|
49
|
+
})
|
|
50
|
+
const result = await swap.execute()
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The SDK is the **only** supported integration path. Do not call the API directly.
|
|
54
|
+
|
|
55
|
+
## Key Concepts
|
|
56
|
+
|
|
57
|
+
- **Amounts** are always in base units (microAlgos for ALGO, smallest unit for ASAs)
|
|
58
|
+
- **ASA IDs**: 0 = ALGO, 31566704 = USDC, etc.
|
|
59
|
+
- **Quote types**: `fixed-input` (default) — specify input amount; `fixed-output` — specify desired output
|
|
60
|
+
- **Slippage**: Percentage tolerance on output (e.g., 1 = 1%). Applied to the final output, not individual hops
|
|
61
|
+
- **Routing**: Supports multi-hop and parallel (combo) swaps for optimal pricing
|
|
62
|
+
- **Middleware**: Plugin system for custom pre/post-swap transactions (e.g., auto opt-out)
|
|
63
|
+
|
|
64
|
+
## Reference Files
|
|
65
|
+
|
|
66
|
+
Read the appropriate file based on the task:
|
|
67
|
+
|
|
68
|
+
| Task | Reference |
|
|
69
|
+
| --------------------------------------- | ------------------------------------------------------- |
|
|
70
|
+
| Install SDK, initialize RouterClient | [getting-started.md](references/getting-started.md) |
|
|
71
|
+
| Get swap quotes, display pricing | [quotes.md](references/quotes.md) |
|
|
72
|
+
| Execute swaps with SDK signing | [swaps.md](references/swaps.md) |
|
|
73
|
+
| Build React swap UI with use-wallet | [react-integration.md](references/react-integration.md) |
|
|
74
|
+
| Automate swaps via Node.js scripts | [node-automation.md](references/node-automation.md) |
|
|
75
|
+
| RouterClient config, middleware, debug | [configuration.md](references/configuration.md) |
|
|
76
|
+
| Fee structure, referral program | [fees-and-referrals.md](references/fees-and-referrals.md) |
|
|
77
|
+
| Full API surface and types | [api-reference.md](references/api-reference.md) |
|
|
78
|
+
| Migrate from @txnlab/deflex | [migration.md](references/migration.md) |
|
|
79
|
+
|
|
80
|
+
## How to Use This Skill
|
|
81
|
+
|
|
82
|
+
1. **Start here** to understand which reference you need
|
|
83
|
+
2. **Read the topic `.md`** file for step-by-step guidance
|
|
84
|
+
3. **For MCP-based swaps** (no SDK), see the `haystack-router-interaction` skill
|
|
85
|
+
4. **For general Algorand development**, see `algorand-development`, `algorand-typescript`, or `algorand-python` skills
|
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
# API Reference
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
- [RouterClient](#routerclient)
|
|
6
|
+
- [SwapComposer](#swapcomposer)
|
|
7
|
+
- [SwapMiddleware](#swapmiddleware)
|
|
8
|
+
- [Types](#types)
|
|
9
|
+
|
|
10
|
+
## RouterClient
|
|
11
|
+
|
|
12
|
+
### Constructor
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
new RouterClient(config: ConfigParams & { middleware?: SwapMiddleware[] })
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**ConfigParams:**
|
|
19
|
+
|
|
20
|
+
| Property | Type | Default | Description |
|
|
21
|
+
| ----------------- | ------------------ | -------------- | ---------------------------------------- |
|
|
22
|
+
| `apiKey` | `string` | — | **Required.** API key |
|
|
23
|
+
| `apiBaseUrl` | `string` | SDK default | API endpoint override |
|
|
24
|
+
| `algodUri` | `string` | MainNet Nodely | Algod node URI |
|
|
25
|
+
| `algodToken` | `string` | `''` | Algod node token |
|
|
26
|
+
| `algodPort` | `string \| number` | `443` | Algod node port |
|
|
27
|
+
| `referrerAddress` | `string` | — | Earn 25% of swap fees |
|
|
28
|
+
| `feeBps` | `number` | `10` | Fee in basis points (10–300) |
|
|
29
|
+
| `autoOptIn` | `boolean` | `false` | Auto-detect asset opt-in |
|
|
30
|
+
| `debugLevel` | `string` | `'none'` | `'none' \| 'info' \| 'debug' \| 'trace'` |
|
|
31
|
+
|
|
32
|
+
### newQuote()
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
async newQuote(params: FetchQuoteParams): Promise<SwapQuote>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Get an optimized swap quote with enhanced types (bigint coercion, timestamps).
|
|
39
|
+
|
|
40
|
+
### fetchQuote()
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
async fetchQuote(params: FetchQuoteParams): Promise<FetchQuoteResponse>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Get a raw swap quote without SwapQuote enhancements.
|
|
47
|
+
|
|
48
|
+
### newSwap()
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
async newSwap(config: {
|
|
52
|
+
quote: SwapQuote | FetchQuoteResponse
|
|
53
|
+
address: string
|
|
54
|
+
signer: TransactionSigner | SignerFunction
|
|
55
|
+
slippage: number
|
|
56
|
+
note?: Uint8Array
|
|
57
|
+
}): Promise<SwapComposer>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Create a swap composer for building and executing the swap transaction group.
|
|
61
|
+
|
|
62
|
+
### needsAssetOptIn()
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
async needsAssetOptIn(address: string, assetId: number | bigint): Promise<boolean>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Check if an address needs to opt into an asset. Always returns `false` for ALGO (ASA 0).
|
|
69
|
+
|
|
70
|
+
### fetchSwapTransactions()
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
async fetchSwapTransactions(params: FetchSwapTxnsParams): Promise<FetchSwapTxnsResponse>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Low-level: fetch executable swap transactions. Typically called internally by `newSwap()`.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## SwapComposer
|
|
81
|
+
|
|
82
|
+
Returned by `router.newSwap()`. Builder pattern for transaction groups.
|
|
83
|
+
|
|
84
|
+
### execute()
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
async execute(waitRounds?: number): Promise<{
|
|
88
|
+
confirmedRound: bigint
|
|
89
|
+
txIds: string[]
|
|
90
|
+
methodResults: ABIResult[]
|
|
91
|
+
}>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Sign, submit, and wait for confirmation. `waitRounds` defaults to 10.
|
|
95
|
+
|
|
96
|
+
### buildGroup()
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
buildGroup(): TransactionWithSigner[]
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Finalize the transaction group and assign group IDs.
|
|
103
|
+
|
|
104
|
+
### sign()
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
async sign(): Promise<Uint8Array[]>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Sign all transactions. Auto-adds swap transactions if not already added.
|
|
111
|
+
|
|
112
|
+
### submit()
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
async submit(): Promise<string[]>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Sign and submit without waiting for confirmation. Returns transaction IDs.
|
|
119
|
+
|
|
120
|
+
### addTransaction()
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
addTransaction(transaction: Transaction, signer?: TransactionSigner): this
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Add a custom transaction to the group. Chainable. Must be called before `buildGroup()`.
|
|
127
|
+
|
|
128
|
+
### addMethodCall()
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
addMethodCall(methodCall: MethodCall, signer?: TransactionSigner): this
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Add an ABI method call to the group. Chainable.
|
|
135
|
+
|
|
136
|
+
### addSwapTransactions()
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
async addSwapTransactions(): Promise<this>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Manually add swap transactions (including middleware hooks and app opt-ins). Called automatically by `execute()` if not called explicitly.
|
|
143
|
+
|
|
144
|
+
### getSummary()
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
getSummary(): SwapSummary | undefined
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Get exact swap amounts after execution. Only available after `execute()`.
|
|
151
|
+
|
|
152
|
+
### getInputTransactionId()
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
getInputTransactionId(): string | undefined
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Get the user-signed input transaction ID. Available after `buildGroup()`.
|
|
159
|
+
|
|
160
|
+
### getStatus()
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
getStatus(): SwapComposerStatus
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Returns: `BUILDING` (0) → `BUILT` (1) → `SIGNED` (2) → `SUBMITTED` (3) → `COMMITTED` (4)
|
|
167
|
+
|
|
168
|
+
### count()
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
count(): number
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Number of transactions in the group.
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## SwapMiddleware
|
|
179
|
+
|
|
180
|
+
Interface for plugins that hook into the quote and swap lifecycle.
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
interface SwapMiddleware {
|
|
184
|
+
readonly name: string
|
|
185
|
+
readonly version: string
|
|
186
|
+
|
|
187
|
+
shouldApply(context: QuoteContext): Promise<boolean>
|
|
188
|
+
adjustQuoteParams?(params: FetchQuoteParams): Promise<FetchQuoteParams>
|
|
189
|
+
beforeSwap?(context: SwapContext): Promise<TransactionWithSigner[]>
|
|
190
|
+
afterSwap?(context: SwapContext): Promise<TransactionWithSigner[]>
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Built-in: AutoOptOutMiddleware
|
|
195
|
+
|
|
196
|
+
Automatically opts out of assets when swapping full balance.
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
import { AutoOptOutMiddleware } from '@txnlab/haystack-router'
|
|
200
|
+
|
|
201
|
+
const middleware = new AutoOptOutMiddleware({
|
|
202
|
+
excludedAssets?: readonly (number | bigint)[] // Assets to never auto-opt-out
|
|
203
|
+
})
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### QuoteContext
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
interface QuoteContext {
|
|
210
|
+
fromASAID: bigint
|
|
211
|
+
toASAID: bigint
|
|
212
|
+
amount: bigint
|
|
213
|
+
type: QuoteType
|
|
214
|
+
address?: string
|
|
215
|
+
algodClient: Algodv2
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### SwapContext
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
interface SwapContext {
|
|
223
|
+
quote: SwapQuote
|
|
224
|
+
address: string
|
|
225
|
+
algodClient: Algodv2
|
|
226
|
+
suggestedParams: SuggestedParams
|
|
227
|
+
fromASAID: bigint
|
|
228
|
+
toASAID: bigint
|
|
229
|
+
signer: TransactionSigner
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## Types
|
|
236
|
+
|
|
237
|
+
### FetchQuoteParams
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
interface FetchQuoteParams {
|
|
241
|
+
fromASAID: bigint | number
|
|
242
|
+
toASAID: bigint | number
|
|
243
|
+
amount: bigint | number
|
|
244
|
+
type?: 'fixed-input' | 'fixed-output' // Default: 'fixed-input'
|
|
245
|
+
address?: string | null
|
|
246
|
+
disabledProtocols?: readonly Protocol[]
|
|
247
|
+
maxGroupSize?: number // Default: 16
|
|
248
|
+
maxDepth?: number // Default: 4
|
|
249
|
+
optIn?: boolean
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### FetchQuoteResponse
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
interface FetchQuoteResponse {
|
|
257
|
+
quote: string | number
|
|
258
|
+
profit: Profit // { amount: number, asa: Asset }
|
|
259
|
+
priceBaseline: number
|
|
260
|
+
userPriceImpact?: number
|
|
261
|
+
marketPriceImpact?: number
|
|
262
|
+
usdIn: number
|
|
263
|
+
usdOut: number
|
|
264
|
+
route: Route[]
|
|
265
|
+
flattenedRoute: Record<string, number>
|
|
266
|
+
quotes: DexQuote[]
|
|
267
|
+
requiredAppOptIns: number[]
|
|
268
|
+
txnPayload: TxnPayload | null
|
|
269
|
+
protocolFees: Record<string, number>
|
|
270
|
+
fromASAID: number
|
|
271
|
+
toASAID: number
|
|
272
|
+
type: string
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### SwapQuote
|
|
277
|
+
|
|
278
|
+
```typescript
|
|
279
|
+
type SwapQuote = FetchQuoteResponse & {
|
|
280
|
+
quote: bigint // Coerced to bigint
|
|
281
|
+
amount: bigint // Original request amount
|
|
282
|
+
address?: string
|
|
283
|
+
createdAt: number // Timestamp (ms)
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### SwapSummary
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
interface SwapSummary {
|
|
291
|
+
inputAssetId: bigint
|
|
292
|
+
outputAssetId: bigint
|
|
293
|
+
inputAmount: bigint
|
|
294
|
+
outputAmount: bigint
|
|
295
|
+
type: QuoteType
|
|
296
|
+
totalFees: bigint // microAlgos
|
|
297
|
+
transactionCount: number
|
|
298
|
+
inputTxnId: string
|
|
299
|
+
outputTxnId: string
|
|
300
|
+
inputSender: string
|
|
301
|
+
outputSender: string
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### SwapTransaction
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
interface SwapTransaction {
|
|
309
|
+
data: string // Base64-encoded transaction
|
|
310
|
+
group: string // Group ID
|
|
311
|
+
logicSigBlob: unknown | false
|
|
312
|
+
signature: Signature | false
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### SignerFunction
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
type SignerFunction = (
|
|
320
|
+
txnGroup: Transaction[],
|
|
321
|
+
indexesToSign: number[],
|
|
322
|
+
) => Promise<(Uint8Array | null)[]>
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
Supports two return patterns:
|
|
326
|
+
|
|
327
|
+
- `Uint8Array[]` matching `indexesToSign` length (Pera/Defly)
|
|
328
|
+
- `(Uint8Array | null)[]` matching full group length (Lute/ARC-1)
|
|
329
|
+
|
|
330
|
+
### Route and PathElement
|
|
331
|
+
|
|
332
|
+
```typescript
|
|
333
|
+
interface Route {
|
|
334
|
+
percentage: number
|
|
335
|
+
path: PathElement[]
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
interface PathElement {
|
|
339
|
+
name: string // Protocol name + fee tier
|
|
340
|
+
class: string[][]
|
|
341
|
+
in: Asset
|
|
342
|
+
out: Asset
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### Asset
|
|
347
|
+
|
|
348
|
+
```typescript
|
|
349
|
+
interface Asset {
|
|
350
|
+
id: number
|
|
351
|
+
decimals: number
|
|
352
|
+
unit_name: string
|
|
353
|
+
name: string
|
|
354
|
+
price_algo: number
|
|
355
|
+
price_usd: number
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Protocol
|
|
360
|
+
|
|
361
|
+
```typescript
|
|
362
|
+
enum Protocol {
|
|
363
|
+
TinymanV2 = 'TinymanV2'
|
|
364
|
+
Algofi = 'Algofi'
|
|
365
|
+
Algomint = 'Algomint'
|
|
366
|
+
Pact = 'Pact'
|
|
367
|
+
Folks = 'Folks'
|
|
368
|
+
TAlgo = 'TAlgo'
|
|
369
|
+
}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### Constants
|
|
373
|
+
|
|
374
|
+
```typescript
|
|
375
|
+
const DEFAULT_FEE_BPS = 10 // 0.10%
|
|
376
|
+
const MAX_FEE_BPS = 300 // 3.00%
|
|
377
|
+
const DEFAULT_MAX_GROUP_SIZE = 16
|
|
378
|
+
const DEFAULT_MAX_DEPTH = 4
|
|
379
|
+
const DEFAULT_AUTO_OPT_IN = false
|
|
380
|
+
const DEFAULT_CONFIRMATION_ROUNDS = 10
|
|
381
|
+
```
|