@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.
Files changed (22) hide show
  1. package/lib/x402-fetch.ts +3 -10
  2. package/openclaw.plugin.json +4 -2
  3. package/package.json +1 -1
  4. package/skills/algorand-interaction/SKILL.md +12 -6
  5. package/skills/algorand-interaction/references/algorand-mcp.md +81 -7
  6. package/skills/algorand-interaction/references/examples-algorand-mcp.md +77 -2
  7. package/skills/haystack-router-development/SKILL.md +85 -0
  8. package/skills/haystack-router-development/references/api-reference.md +381 -0
  9. package/skills/haystack-router-development/references/configuration.md +184 -0
  10. package/skills/haystack-router-development/references/fees-and-referrals.md +91 -0
  11. package/skills/haystack-router-development/references/getting-started.md +93 -0
  12. package/skills/haystack-router-development/references/migration.md +53 -0
  13. package/skills/haystack-router-development/references/node-automation.md +113 -0
  14. package/skills/haystack-router-development/references/quotes.md +155 -0
  15. package/skills/haystack-router-development/references/react-integration.md +260 -0
  16. package/skills/haystack-router-development/references/swaps.md +161 -0
  17. package/skills/haystack-router-interaction/SKILL.md +146 -0
  18. package/skills/haystack-router-interaction/references/configuration.md +53 -0
  19. package/skills/haystack-router-interaction/references/getting-started.md +48 -0
  20. package/skills/haystack-router-interaction/references/node-automation.md +51 -0
  21. package/skills/haystack-router-interaction/references/quotes.md +80 -0
  22. 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.