@goplausible/openclaw-algorand-plugin 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/lib/x402-fetch.ts +3 -10
- package/openclaw.plugin.json +4 -2
- package/package.json +1 -1
- package/skills/algorand-interaction/SKILL.md +12 -6
- package/skills/algorand-interaction/references/algorand-mcp.md +81 -7
- package/skills/algorand-interaction/references/examples-algorand-mcp.md +77 -2
- 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
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Swaps
|
|
2
|
+
|
|
3
|
+
## Executing a Swap
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
import { RouterClient } from '@txnlab/haystack-router'
|
|
7
|
+
|
|
8
|
+
const router = new RouterClient({
|
|
9
|
+
apiKey: '1b72df7e-1131-4449-8ce1-29b79dd3f51e', // Free tier (60 requests/min)
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
// 1. Get a quote
|
|
13
|
+
const quote = await router.newQuote({
|
|
14
|
+
fromASAID: 0,
|
|
15
|
+
toASAID: 31566704,
|
|
16
|
+
amount: 1_000_000,
|
|
17
|
+
address: activeAddress,
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
// 2. Create and execute swap
|
|
21
|
+
const swap = await router.newSwap({
|
|
22
|
+
quote,
|
|
23
|
+
address: activeAddress,
|
|
24
|
+
signer: transactionSigner,
|
|
25
|
+
slippage: 1, // 1%
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
const result = await swap.execute()
|
|
29
|
+
console.log(`Confirmed in round ${result.confirmedRound}`)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## newSwap() Parameters
|
|
33
|
+
|
|
34
|
+
| Parameter | Type | Required | Description |
|
|
35
|
+
| ---------- | ------------------------------------- | -------- | ----------------------------------------- |
|
|
36
|
+
| `quote` | `SwapQuote \| FetchQuoteResponse` | Yes | Quote from `newQuote()` or `fetchQuote()` |
|
|
37
|
+
| `address` | `string` | Yes | Signer's Algorand address |
|
|
38
|
+
| `signer` | `TransactionSigner \| SignerFunction` | Yes | Transaction signing function |
|
|
39
|
+
| `slippage` | `number` | Yes | Slippage tolerance (e.g., `1` = 1%) |
|
|
40
|
+
| `note` | `Uint8Array` | No | Note attached to input transaction |
|
|
41
|
+
|
|
42
|
+
## Signer Patterns
|
|
43
|
+
|
|
44
|
+
### Browser: use-wallet
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import { useWallet } from '@txnlab/use-wallet-react'
|
|
48
|
+
|
|
49
|
+
const { activeAddress, transactionSigner } = useWallet()
|
|
50
|
+
|
|
51
|
+
const swap = await router.newSwap({
|
|
52
|
+
quote,
|
|
53
|
+
address: activeAddress,
|
|
54
|
+
signer: transactionSigner,
|
|
55
|
+
slippage: 1,
|
|
56
|
+
})
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The SDK supports two signer return patterns:
|
|
60
|
+
|
|
61
|
+
- **Pera/Defly style**: Returns `Uint8Array[]` matching `indexesToSign` length
|
|
62
|
+
- **Lute/ARC-1 style**: Returns `(Uint8Array | null)[]` matching full group length, `null` for unsigned
|
|
63
|
+
|
|
64
|
+
Both are detected and handled automatically.
|
|
65
|
+
|
|
66
|
+
## Slippage Guidance
|
|
67
|
+
|
|
68
|
+
| Pair Type | Recommended Slippage |
|
|
69
|
+
| ----------------- | -------------------- |
|
|
70
|
+
| Stable pairs | 0.5–1% |
|
|
71
|
+
| Volatile pairs | 1–3% |
|
|
72
|
+
| Low liquidity | 3–5% |
|
|
73
|
+
|
|
74
|
+
Slippage is verified on the **final output** of the swap, not individual hops. This means intermediate steps can have higher variance as long as the final result is within tolerance.
|
|
75
|
+
|
|
76
|
+
## Execution Result
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
const result = await swap.execute()
|
|
80
|
+
|
|
81
|
+
result.confirmedRound // bigint — block where swap confirmed
|
|
82
|
+
result.txIds // string[] — all transaction IDs
|
|
83
|
+
result.methodResults // ABIResult[] — ABI method call results
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Swap Summary
|
|
87
|
+
|
|
88
|
+
After execution, get exact amounts (may differ from quote due to slippage):
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
const result = await swap.execute()
|
|
92
|
+
const summary = swap.getSummary()
|
|
93
|
+
|
|
94
|
+
if (summary) {
|
|
95
|
+
summary.inputAssetId // bigint
|
|
96
|
+
summary.outputAssetId // bigint
|
|
97
|
+
summary.inputAmount // bigint — exact input sent
|
|
98
|
+
summary.outputAmount // bigint — exact output received
|
|
99
|
+
summary.totalFees // bigint — total ALGO fees (microAlgos)
|
|
100
|
+
summary.transactionCount // number
|
|
101
|
+
summary.inputTxnId // string — user-signed input txn ID
|
|
102
|
+
summary.outputTxnId // string — app call containing output
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Advanced: Custom Transaction Composition
|
|
107
|
+
|
|
108
|
+
Add custom transactions before/after the swap in the same atomic group:
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
const swap = await router.newSwap({
|
|
112
|
+
quote,
|
|
113
|
+
address: activeAddress,
|
|
114
|
+
signer: transactionSigner,
|
|
115
|
+
slippage: 1,
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
const result = await swap
|
|
119
|
+
.addTransaction(customTxn) // Add before swap
|
|
120
|
+
.addSwapTransactions() // Add swap txns + middleware
|
|
121
|
+
.addMethodCall(abiCall) // Add ABI call after swap
|
|
122
|
+
.execute()
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Constraints:
|
|
126
|
+
|
|
127
|
+
- Max 16 transactions per group
|
|
128
|
+
- Non-composable swaps (Tinyman v1) cannot add custom transactions
|
|
129
|
+
- Call `addSwapTransactions()` to manually control ordering
|
|
130
|
+
|
|
131
|
+
## Advanced: Step-by-Step Execution
|
|
132
|
+
|
|
133
|
+
For more control over the signing and submission flow:
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
const swap = await router.newSwap({ quote, address, signer, slippage: 1 })
|
|
137
|
+
|
|
138
|
+
// Build (assigns group IDs)
|
|
139
|
+
const txnsWithSigners = swap.buildGroup()
|
|
140
|
+
|
|
141
|
+
// Sign
|
|
142
|
+
const signedTxns = await swap.sign()
|
|
143
|
+
|
|
144
|
+
// Submit (doesn't wait)
|
|
145
|
+
const txIds = await swap.submit()
|
|
146
|
+
|
|
147
|
+
// Check status
|
|
148
|
+
swap.getStatus() // BUILDING → BUILT → SIGNED → SUBMITTED → COMMITTED
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Error Handling
|
|
152
|
+
|
|
153
|
+
Common errors:
|
|
154
|
+
|
|
155
|
+
- **Slippage exceeded** — price moved beyond tolerance, refetch quote
|
|
156
|
+
- **Insufficient balance** — check account balance
|
|
157
|
+
- **Asset not opted in** — include opt-in in quote or opt in manually
|
|
158
|
+
- **Transaction rejected** — user declined or signing failed
|
|
159
|
+
- **Network timeout** — retry after brief delay
|
|
160
|
+
|
|
161
|
+
Quotes are time-sensitive. If a quote is stale (prices moved significantly), refetch before executing.
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: haystack-router-interaction
|
|
3
|
+
description: Route and execute optimal token swaps on Algorand using Haystack Router via Algorand MCP tools. Use when getting best-price quotes across multiple Algorand DEXes and LST protocols, executing atomic swaps, and checking asset opt-in — all through the Algorand MCP server. Strong triggers include haystack swap, best price swap, DEX aggregator swap, swap ALGO to USDC, api_haystack, haystack quote, execute swap, swap routing, optimal swap, multi-DEX swap.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Haystack Router (Interaction)
|
|
7
|
+
|
|
8
|
+
This is the parent skill for interacting with Haystack Router through Algorand MCP tools — getting quotes, executing swaps, and checking opt-in status. All operations use the Algorand MCP wallet for signing; no SDK installation or API keys needed.
|
|
9
|
+
|
|
10
|
+
> **Building an application** that integrates Haystack Router directly? Use the **haystack-router-development** skill instead — it covers the `@txnlab/haystack-router` SDK, React integration, Node.js automation, middleware, and the full API surface.
|
|
11
|
+
> **Need general wallet/transaction guidance?** See the **algorand-interaction** skill for wallet setup, session start checklist, network selection, and pre-transaction validation.
|
|
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
|
+
## mcporter Syntax (OpenClaw CLI)
|
|
16
|
+
|
|
17
|
+
When calling Haystack Router MCP tools via mcporter in OpenClaw CLI:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
mcporter call algorand-mcp.api_haystack_get_swap_quote --args '{"fromASAID": 0, "toASAID": 31566704, "amount": 1000000, "network": "mainnet"}'
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Key: use `server.tool` (dot notation) with `--args '{"json"}'`. See `algorand-interaction` skill for full mcporter reference.
|
|
24
|
+
|
|
25
|
+
## Network Selection
|
|
26
|
+
|
|
27
|
+
Every Haystack Router tool accepts a `network` parameter:
|
|
28
|
+
|
|
29
|
+
| Value | Description |
|
|
30
|
+
|-------|-------------|
|
|
31
|
+
| `mainnet` | Algorand mainnet (default) — **real value, exercise caution** |
|
|
32
|
+
| `testnet` | Algorand testnet — safe for development |
|
|
33
|
+
|
|
34
|
+
Default to `testnet` during development. Always confirm with the user before mainnet swaps.
|
|
35
|
+
|
|
36
|
+
## Algorand MCP Haystack Router Tools
|
|
37
|
+
|
|
38
|
+
Three dedicated Algorand MCP tools provide full Haystack Router functionality. These handle quoting, execution (with wallet signing), and opt-in checking — no raw mnemonics or secret keys needed.
|
|
39
|
+
|
|
40
|
+
### `api_haystack_get_swap_quote`
|
|
41
|
+
|
|
42
|
+
Get an optimized swap quote without executing. Use to preview pricing, route, and price impact before confirming with user.
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
→ api_haystack_get_swap_quote {
|
|
46
|
+
fromASAID: 0, // Input asset (0 = ALGO)
|
|
47
|
+
toASAID: 31566704, // Output asset (USDC)
|
|
48
|
+
amount: 1000000, // 1 ALGO in base units
|
|
49
|
+
type: "fixed-input", // or "fixed-output"
|
|
50
|
+
address: "<address>", // optional, for opt-in detection
|
|
51
|
+
maxGroupSize: 16, // optional
|
|
52
|
+
maxDepth: 4, // optional
|
|
53
|
+
network: "mainnet"
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
Returns: expectedOutput, inputAmount, usdIn, usdOut, userPriceImpact,
|
|
57
|
+
route, flattenedRoute, requiredAppOptIns, protocolFees
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### `api_haystack_execute_swap`
|
|
61
|
+
|
|
62
|
+
All-in-one swap: quote → sign (via wallet) → submit → confirm. Uses the active wallet account for signing. Enforces wallet spending limits.
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
→ api_haystack_execute_swap {
|
|
66
|
+
fromASAID: 0, // Input asset
|
|
67
|
+
toASAID: 31566704, // Output asset
|
|
68
|
+
amount: 1000000, // Amount in base units
|
|
69
|
+
slippage: 1, // 1% slippage tolerance
|
|
70
|
+
type: "fixed-input", // optional
|
|
71
|
+
note: "my swap", // optional text note
|
|
72
|
+
maxGroupSize: 16, // optional
|
|
73
|
+
maxDepth: 4, // optional
|
|
74
|
+
network: "mainnet"
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
Returns: status, confirmedRound, txIds, signer, nickname, quote details,
|
|
78
|
+
summary (inputAmount, outputAmount, totalFees, transactionCount)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### `api_haystack_needs_optin`
|
|
82
|
+
|
|
83
|
+
Check if an address needs to opt into an asset before swapping.
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
→ api_haystack_needs_optin {
|
|
87
|
+
address: "<address>",
|
|
88
|
+
assetId: 31566704,
|
|
89
|
+
network: "mainnet"
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
Returns: { address, assetId, needsOptIn: true/false, network }
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Algorand MCP Agent Swap Workflow
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
Step 1: Check wallet
|
|
99
|
+
→ wallet_get_info { network }
|
|
100
|
+
|
|
101
|
+
Step 2: Check opt-in (if swapping to an ASA)
|
|
102
|
+
→ api_haystack_needs_optin { address, assetId, network }
|
|
103
|
+
→ If needed: wallet_optin_asset { assetId, network }
|
|
104
|
+
|
|
105
|
+
Step 3: Preview quote (recommended — show user before executing)
|
|
106
|
+
→ api_haystack_get_swap_quote { fromASAID, toASAID, amount, address, network }
|
|
107
|
+
→ Present to user: expected output, USD values, route, price impact
|
|
108
|
+
|
|
109
|
+
Step 4: User confirms → Execute
|
|
110
|
+
→ api_haystack_execute_swap { fromASAID, toASAID, amount, slippage, network }
|
|
111
|
+
→ Returns confirmed result with summary
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Key rules:**
|
|
115
|
+
- Always check wallet with `wallet_get_info` before any swap
|
|
116
|
+
- Always confirm with the user before executing (show quote details)
|
|
117
|
+
- The execute tool handles signing via the active wallet — no manual signing needed
|
|
118
|
+
- Default to testnet during development; confirm before mainnet
|
|
119
|
+
- Quotes are time-sensitive — execute promptly after user confirms
|
|
120
|
+
|
|
121
|
+
## Key Concepts
|
|
122
|
+
|
|
123
|
+
- **Amounts** are always in base units (microAlgos for ALGO, smallest unit for ASAs)
|
|
124
|
+
- **ASA IDs**: 0 = ALGO, 31566704 = USDC, etc.
|
|
125
|
+
- **Quote types**: `fixed-input` (default) — specify input amount; `fixed-output` — specify desired output
|
|
126
|
+
- **Slippage**: Percentage tolerance on output (e.g., 1 = 1%). Applied to the final output, not individual hops
|
|
127
|
+
- **Routing**: Supports multi-hop and parallel (combo) swaps for optimal pricing
|
|
128
|
+
|
|
129
|
+
## Reference Files
|
|
130
|
+
|
|
131
|
+
Read the appropriate file based on the task:
|
|
132
|
+
|
|
133
|
+
| Task | Reference |
|
|
134
|
+
| ------------------------------------------- | ----------------------------------------------------- |
|
|
135
|
+
| Quick start and Algorand MCP tool reference | [getting-started.md](references/getting-started.md) |
|
|
136
|
+
| Get swap quotes, display pricing | [quotes.md](references/quotes.md) |
|
|
137
|
+
| Execute swaps via Algorand MCP tools | [swaps.md](references/swaps.md) |
|
|
138
|
+
| Automate swaps via Algorand MCP tools | [node-automation.md](references/node-automation.md) |
|
|
139
|
+
| Network, slippage, rate limits, ASA IDs | [configuration.md](references/configuration.md) |
|
|
140
|
+
|
|
141
|
+
## How to Use This Skill
|
|
142
|
+
|
|
143
|
+
1. **Start here** to understand the three Haystack Router MCP tools and the swap workflow
|
|
144
|
+
2. **Read the topic `.md`** file for detailed guidance on quotes, swaps, or automation
|
|
145
|
+
3. **For SDK-based development** (React UIs, Node.js apps), see the `haystack-router-development` skill
|
|
146
|
+
4. **For wallet setup and general blockchain interaction**, see the `algorand-interaction` skill
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Configuration (Algorand MCP)
|
|
2
|
+
|
|
3
|
+
## Network
|
|
4
|
+
|
|
5
|
+
All Algorand MCP Haystack Router tools accept a `network` parameter:
|
|
6
|
+
|
|
7
|
+
- `"mainnet"` — MainNet (default)
|
|
8
|
+
- `"testnet"` — TestNet
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
→ api_haystack_get_swap_quote {
|
|
12
|
+
fromASAID: 0, toASAID: 31566704, amount: 1000000,
|
|
13
|
+
network: "testnet"
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Default to **testnet** during development; confirm with user before using mainnet.
|
|
18
|
+
|
|
19
|
+
## Slippage
|
|
20
|
+
|
|
21
|
+
Set slippage (percentage tolerance on output) when executing swaps:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
→ api_haystack_execute_swap {
|
|
25
|
+
fromASAID: 0, toASAID: 31566704, amount: 1000000,
|
|
26
|
+
slippage: 1, // 1% — receive at least 99% of quoted output
|
|
27
|
+
network: "testnet"
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Recommendations:**
|
|
32
|
+
|
|
33
|
+
- **Stable pairs** (ALGO/USDC): 0.5–1%
|
|
34
|
+
- **Volatile pairs**: 1–3%
|
|
35
|
+
- **Low liquidity**: 3–5%
|
|
36
|
+
|
|
37
|
+
Slippage is verified on the **final output** of the swap, not on individual hops.
|
|
38
|
+
|
|
39
|
+
## Rate Limits
|
|
40
|
+
|
|
41
|
+
The Algorand MCP server uses a free tier API key (60 requests/min). This applies to all Haystack Router tool calls. Override via `HAYSTACK_API_KEY` environment variable.
|
|
42
|
+
|
|
43
|
+
## Common ASA IDs
|
|
44
|
+
|
|
45
|
+
| Asset | ASA ID |
|
|
46
|
+
| ----- | --------- |
|
|
47
|
+
| ALGO | 0 |
|
|
48
|
+
| USDC | 31566704 |
|
|
49
|
+
| USDt | 312769 |
|
|
50
|
+
| goBTC | 386192725 |
|
|
51
|
+
| goETH | 386195940 |
|
|
52
|
+
|
|
53
|
+
Look up ASA IDs on [Allo.info](https://allo.info) or [Pera Explorer](https://explorer.perawallet.app/).
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Getting Started
|
|
2
|
+
|
|
3
|
+
When operating as an Algorand MCP agent, use Algorand MCP tools directly. No SDK installation or API key management needed — the Algorand MCP server handles this internally.
|
|
4
|
+
|
|
5
|
+
## Quick Swap (2 steps)
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
1. wallet_get_info { network: "testnet" }
|
|
9
|
+
→ Get wallet address and balance
|
|
10
|
+
|
|
11
|
+
2. api_haystack_execute_swap {
|
|
12
|
+
fromASAID: 0, toASAID: 31566704, amount: 1000000,
|
|
13
|
+
slippage: 1, network: "testnet"
|
|
14
|
+
}
|
|
15
|
+
→ Quotes, signs via wallet, submits, confirms — all in one call
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## With Preview (recommended for user-facing swaps)
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
1. wallet_get_info { network: "testnet" }
|
|
22
|
+
2. api_haystack_needs_optin { address, assetId: 31566704, network: "testnet" }
|
|
23
|
+
→ If needed: wallet_optin_asset { assetId: 31566704, network: "testnet" }
|
|
24
|
+
3. api_haystack_get_swap_quote { fromASAID: 0, toASAID: 31566704, amount: 1000000, network: "testnet" }
|
|
25
|
+
→ Show user the quote → get confirmation
|
|
26
|
+
4. api_haystack_execute_swap { fromASAID: 0, toASAID: 31566704, amount: 1000000, slippage: 1, network: "testnet" }
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Algorand MCP Tool Reference
|
|
30
|
+
|
|
31
|
+
| Tool | Purpose |
|
|
32
|
+
| ------------------------------- | ------------------------------------------------ |
|
|
33
|
+
| `api_haystack_get_swap_quote` | Preview swap quote with routing and pricing |
|
|
34
|
+
| `api_haystack_execute_swap` | Execute swap: quote + sign + submit + confirm |
|
|
35
|
+
| `api_haystack_needs_optin` | Check if address needs asset opt-in |
|
|
36
|
+
| `wallet_get_info` | Get wallet address and ALGO balance |
|
|
37
|
+
| `wallet_optin_asset` | Opt into an ASA (one-step build+sign+submit) |
|
|
38
|
+
|
|
39
|
+
See [swaps.md](swaps.md) for detailed workflow and [quotes.md](quotes.md) for quote parameters.
|
|
40
|
+
|
|
41
|
+
## Amounts and Units
|
|
42
|
+
|
|
43
|
+
All amounts are in **base units** (smallest denomination):
|
|
44
|
+
|
|
45
|
+
| Asset | Decimals | 1 unit in base | Example |
|
|
46
|
+
| ------------------- | -------- | -------------- | -------------------- |
|
|
47
|
+
| ALGO (ASA 0) | 6 | 1,000,000 | `1_000_000` = 1 ALGO |
|
|
48
|
+
| USDC (ASA 31566704) | 6 | 1,000,000 | `5_000_000` = 5 USDC |
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Node.js Automation (Algorand MCP)
|
|
2
|
+
|
|
3
|
+
Automate swaps using Algorand MCP tools. The `api_haystack_execute_swap` tool handles quoting, signing, and submission in one call.
|
|
4
|
+
|
|
5
|
+
## Single Swap
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
1. wallet_get_info { network: "testnet" }
|
|
9
|
+
→ Get address and confirm ALGO balance is sufficient
|
|
10
|
+
|
|
11
|
+
2. api_haystack_needs_optin { address, assetId: 31566704, network: "testnet" }
|
|
12
|
+
→ Check if output asset needs opt-in
|
|
13
|
+
|
|
14
|
+
3. (If needsOptIn) wallet_optin_asset { assetId: 31566704, network: "testnet" }
|
|
15
|
+
→ Opt into output asset
|
|
16
|
+
|
|
17
|
+
4. api_haystack_get_swap_quote {
|
|
18
|
+
fromASAID: 0, toASAID: 31566704, amount: 1000000,
|
|
19
|
+
address: "<wallet_address>", network: "testnet"
|
|
20
|
+
}
|
|
21
|
+
→ Preview quote → confirm with user
|
|
22
|
+
|
|
23
|
+
5. api_haystack_execute_swap {
|
|
24
|
+
fromASAID: 0, toASAID: 31566704, amount: 1000000,
|
|
25
|
+
slippage: 1, note: "order-123", network: "testnet"
|
|
26
|
+
}
|
|
27
|
+
→ Signs via wallet, submits, waits for confirmation
|
|
28
|
+
→ Returns: confirmedRound, txIds, summary with exact amounts
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Batch Swaps
|
|
32
|
+
|
|
33
|
+
For multiple sequential swaps, repeat steps 4–5 for each pair:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
Swap pairs example:
|
|
37
|
+
- 0 → 31566704, amount: 1000000 (1 ALGO → USDC)
|
|
38
|
+
- 0 → 312769, amount: 2000000 (2 ALGO → USDt)
|
|
39
|
+
|
|
40
|
+
For each pair:
|
|
41
|
+
→ api_haystack_get_swap_quote { ... } → show user
|
|
42
|
+
→ api_haystack_execute_swap { ... } → execute after confirmation
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Key Rules
|
|
46
|
+
|
|
47
|
+
- **Use `api_haystack_execute_swap`** — it handles signing via the active wallet
|
|
48
|
+
- **Always confirm each swap with the user** before executing
|
|
49
|
+
- **Each execute call gets a fresh quote** — no stale quote issues
|
|
50
|
+
- **Check opt-in** before first swap to a new ASA using `api_haystack_needs_optin`
|
|
51
|
+
- **Default to testnet** unless user explicitly requests mainnet
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Quotes
|
|
2
|
+
|
|
3
|
+
## Getting a Quote
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
→ api_haystack_get_swap_quote {
|
|
7
|
+
fromASAID: 0, // ALGO
|
|
8
|
+
toASAID: 31566704, // USDC
|
|
9
|
+
amount: 1000000, // 1 ALGO in base units
|
|
10
|
+
type: "fixed-input", // or "fixed-output"
|
|
11
|
+
address: "<wallet_address>", // optional, for opt-in detection
|
|
12
|
+
network: "mainnet"
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
Response includes:
|
|
16
|
+
- expectedOutput: output amount in base units
|
|
17
|
+
- inputAmount: original input amount
|
|
18
|
+
- usdIn / usdOut: USD values
|
|
19
|
+
- userPriceImpact: price impact percentage
|
|
20
|
+
- route: detailed routing path
|
|
21
|
+
- flattenedRoute: protocol split percentages (e.g., "TinymanV2: 60%", "Pact: 40%")
|
|
22
|
+
- requiredAppOptIns: app IDs needing opt-in
|
|
23
|
+
- protocolFees: fee breakdown
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Parameters
|
|
27
|
+
|
|
28
|
+
| Parameter | Type | Required | Description |
|
|
29
|
+
| -------------- | -------- | -------- | ----------------------------------------------- |
|
|
30
|
+
| `fromASAID` | `number` | Yes | Input asset ID (0 = ALGO) |
|
|
31
|
+
| `toASAID` | `number` | Yes | Output asset ID |
|
|
32
|
+
| `amount` | `number` | Yes | Amount in base units |
|
|
33
|
+
| `type` | `string` | No | `"fixed-input"` (default) or `"fixed-output"` |
|
|
34
|
+
| `address` | `string` | No | User address (for opt-in detection) |
|
|
35
|
+
| `maxGroupSize` | `number` | No | Max transactions in group (default: 16) |
|
|
36
|
+
| `maxDepth` | `number` | No | Max routing hops (default: 4) |
|
|
37
|
+
| `network` | `string` | No | `"mainnet"` (default) or `"testnet"` |
|
|
38
|
+
|
|
39
|
+
## Quote Types
|
|
40
|
+
|
|
41
|
+
**Fixed-input** (default): Specify exact input amount, receive variable output.
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
→ api_haystack_get_swap_quote {
|
|
45
|
+
fromASAID: 0, toASAID: 31566704,
|
|
46
|
+
amount: 1000000, // Exact: send 1 ALGO
|
|
47
|
+
type: "fixed-input", network: "mainnet"
|
|
48
|
+
}
|
|
49
|
+
// expectedOutput = USDC to receive
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Fixed-output**: Specify desired output, send variable input.
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
→ api_haystack_get_swap_quote {
|
|
56
|
+
fromASAID: 0, toASAID: 31566704,
|
|
57
|
+
amount: 1000000, // Exact: receive 1 USDC
|
|
58
|
+
type: "fixed-output", network: "mainnet"
|
|
59
|
+
}
|
|
60
|
+
// inputAmount = ALGO required to send
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Asset Opt-In Detection
|
|
64
|
+
|
|
65
|
+
Use the dedicated `api_haystack_needs_optin` tool to check:
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
1. api_haystack_needs_optin { address: "<address>", assetId: <toASAID>, network }
|
|
69
|
+
→ Returns { needsOptIn: true/false }
|
|
70
|
+
|
|
71
|
+
2. If needsOptIn is true:
|
|
72
|
+
→ wallet_optin_asset { assetId: <toASAID>, network }
|
|
73
|
+
→ This handles build, sign, and submit in one step
|
|
74
|
+
|
|
75
|
+
3. Then proceed with quote or execute:
|
|
76
|
+
→ api_haystack_get_swap_quote { fromASAID, toASAID, amount, address, network }
|
|
77
|
+
→ api_haystack_execute_swap { fromASAID, toASAID, amount, slippage, network }
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Note: `api_haystack_execute_swap` automatically handles opt-in detection when the RouterClient is configured with `autoOptIn: true` (default for Algorand MCP tools).
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Swaps
|
|
2
|
+
|
|
3
|
+
The `api_haystack_execute_swap` tool handles the entire swap lifecycle: quoting, signing (via active wallet), submission, and confirmation — all in one call. **No manual signing or transaction assembly needed.**
|
|
4
|
+
|
|
5
|
+
## Quick Swap (Single Tool)
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
→ api_haystack_execute_swap {
|
|
9
|
+
fromASAID: 0, // ALGO
|
|
10
|
+
toASAID: 31566704, // USDC
|
|
11
|
+
amount: 1000000, // 1 ALGO in base units
|
|
12
|
+
slippage: 1, // 1% tolerance
|
|
13
|
+
network: "mainnet"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
status: "confirmed"
|
|
18
|
+
confirmedRound: "12345678"
|
|
19
|
+
txIds: ["TXID1...", "TXID2...", ...]
|
|
20
|
+
signer: "<wallet_address>"
|
|
21
|
+
nickname: "<account_nickname>"
|
|
22
|
+
quote: { expectedOutput, usdIn, usdOut, userPriceImpact, route }
|
|
23
|
+
summary: { inputAmount, outputAmount, totalFees, transactionCount }
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Complete Workflow (with preview)
|
|
27
|
+
|
|
28
|
+
For best UX, preview the quote before executing:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
1. Check wallet state
|
|
32
|
+
→ wallet_get_info { network: "mainnet" }
|
|
33
|
+
→ Note the address and ALGO balance
|
|
34
|
+
|
|
35
|
+
2. Check output asset opt-in (skip for ALGO)
|
|
36
|
+
→ api_haystack_needs_optin { address, assetId: 31566704, network: "mainnet" }
|
|
37
|
+
→ If needsOptIn is true:
|
|
38
|
+
→ wallet_optin_asset { assetId: 31566704, network: "mainnet" }
|
|
39
|
+
|
|
40
|
+
3. Preview quote (show user before executing)
|
|
41
|
+
→ api_haystack_get_swap_quote {
|
|
42
|
+
fromASAID: 0, toASAID: 31566704, amount: 1000000,
|
|
43
|
+
address: "<wallet_address>", network: "mainnet"
|
|
44
|
+
}
|
|
45
|
+
→ Present to user: expected output, USD values, route, price impact
|
|
46
|
+
|
|
47
|
+
4. User confirms → Execute (all-in-one)
|
|
48
|
+
→ api_haystack_execute_swap {
|
|
49
|
+
fromASAID: 0, toASAID: 31566704, amount: 1000000,
|
|
50
|
+
slippage: 1, network: "mainnet"
|
|
51
|
+
}
|
|
52
|
+
→ Returns confirmed result with exact summary
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Important Rules
|
|
56
|
+
|
|
57
|
+
- **Always check wallet first** — Use `wallet_get_info` to confirm address, balance, and network
|
|
58
|
+
- **Always confirm with user** — Show quote details and ask for confirmation before executing
|
|
59
|
+
- **Use `api_haystack_execute_swap`** — It handles signing via the active wallet account
|
|
60
|
+
- **Check opt-in for ASAs** — Use `api_haystack_needs_optin` + `wallet_optin_asset` if needed
|
|
61
|
+
- **Default to testnet** — Unless user explicitly requests mainnet
|
|
62
|
+
- **Handle quote staleness** — Quotes are time-sensitive; execute promptly after user confirms
|
|
63
|
+
|
|
64
|
+
## Slippage Guidance
|
|
65
|
+
|
|
66
|
+
| Pair Type | Recommended Slippage |
|
|
67
|
+
| ----------------- | -------------------- |
|
|
68
|
+
| Stable pairs | 0.5–1% |
|
|
69
|
+
| Volatile pairs | 1–3% |
|
|
70
|
+
| Low liquidity | 3–5% |
|
|
71
|
+
|
|
72
|
+
Slippage is verified on the **final output** of the swap, not individual hops.
|
|
73
|
+
|
|
74
|
+
## Error Handling
|
|
75
|
+
|
|
76
|
+
Common errors:
|
|
77
|
+
|
|
78
|
+
- **Slippage exceeded** — price moved beyond tolerance, refetch quote
|
|
79
|
+
- **Insufficient balance** — check with `wallet_get_info`
|
|
80
|
+
- **Asset not opted in** — use `wallet_optin_asset`
|
|
81
|
+
- **Transaction rejected** — user declined or signing failed
|
|
82
|
+
- **Network timeout** — retry after brief delay
|
|
83
|
+
|
|
84
|
+
Quotes are time-sensitive. If a quote is stale (prices moved significantly), refetch before executing.
|