@goplausible/openclaw-algorand-plugin 0.5.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/LICENSE +21 -0
- package/README.md +112 -0
- package/index.ts +361 -0
- package/lib/mcp-servers.ts +14 -0
- package/lib/x402-fetch.ts +213 -0
- package/memory/algorand-plugin.md +82 -0
- package/openclaw.plugin.json +30 -0
- package/package.json +41 -0
- package/setup.ts +80 -0
- package/skills/algorand-development/SKILL.md +90 -0
- package/skills/algorand-development/references/build-smart-contracts-reference.md +79 -0
- package/skills/algorand-development/references/build-smart-contracts.md +52 -0
- package/skills/algorand-development/references/create-project-reference.md +86 -0
- package/skills/algorand-development/references/create-project.md +89 -0
- package/skills/algorand-development/references/implement-arc-standards-arc32-arc56.md +396 -0
- package/skills/algorand-development/references/implement-arc-standards-arc4.md +265 -0
- package/skills/algorand-development/references/implement-arc-standards.md +92 -0
- package/skills/algorand-development/references/search-algorand-examples-reference.md +119 -0
- package/skills/algorand-development/references/search-algorand-examples.md +89 -0
- package/skills/algorand-development/references/troubleshoot-errors-contract.md +373 -0
- package/skills/algorand-development/references/troubleshoot-errors-transaction.md +599 -0
- package/skills/algorand-development/references/troubleshoot-errors.md +105 -0
- package/skills/algorand-development/references/use-algokit-cli-reference.md +228 -0
- package/skills/algorand-development/references/use-algokit-cli.md +64 -0
- package/skills/algorand-interaction/SKILL.md +223 -0
- package/skills/algorand-interaction/references/algorand-mcp.md +743 -0
- package/skills/algorand-interaction/references/examples-algorand-mcp.md +647 -0
- package/skills/algorand-python/SKILL.md +95 -0
- package/skills/algorand-python/references/build-smart-contracts-decorators.md +413 -0
- package/skills/algorand-python/references/build-smart-contracts-reference.md +55 -0
- package/skills/algorand-python/references/build-smart-contracts-storage.md +452 -0
- package/skills/algorand-python/references/build-smart-contracts-transactions.md +445 -0
- package/skills/algorand-python/references/build-smart-contracts-types.md +438 -0
- package/skills/algorand-python/references/build-smart-contracts.md +82 -0
- package/skills/algorand-python/references/create-project-reference.md +55 -0
- package/skills/algorand-python/references/create-project.md +75 -0
- package/skills/algorand-python/references/implement-arc-standards-arc32-arc56.md +101 -0
- package/skills/algorand-python/references/implement-arc-standards-arc4.md +154 -0
- package/skills/algorand-python/references/implement-arc-standards.md +39 -0
- package/skills/algorand-python/references/troubleshoot-errors-contract.md +355 -0
- package/skills/algorand-python/references/troubleshoot-errors-transaction.md +430 -0
- package/skills/algorand-python/references/troubleshoot-errors.md +46 -0
- package/skills/algorand-python/references/use-algokit-utils-reference.md +350 -0
- package/skills/algorand-python/references/use-algokit-utils.md +76 -0
- package/skills/algorand-typescript/SKILL.md +131 -0
- package/skills/algorand-typescript/references/algorand-ts-migration-from-beta.md +448 -0
- package/skills/algorand-typescript/references/algorand-ts-migration-from-tealscript.md +487 -0
- package/skills/algorand-typescript/references/algorand-ts-migration.md +102 -0
- package/skills/algorand-typescript/references/algorand-typescript-syntax-methods-and-abi.md +134 -0
- package/skills/algorand-typescript/references/algorand-typescript-syntax-reference.md +58 -0
- package/skills/algorand-typescript/references/algorand-typescript-syntax-storage.md +154 -0
- package/skills/algorand-typescript/references/algorand-typescript-syntax-transactions.md +187 -0
- package/skills/algorand-typescript/references/algorand-typescript-syntax-types-and-values.md +150 -0
- package/skills/algorand-typescript/references/algorand-typescript-syntax.md +84 -0
- package/skills/algorand-typescript/references/build-smart-contracts-reference.md +52 -0
- package/skills/algorand-typescript/references/build-smart-contracts.md +74 -0
- package/skills/algorand-typescript/references/call-smart-contracts-reference.md +237 -0
- package/skills/algorand-typescript/references/call-smart-contracts.md +183 -0
- package/skills/algorand-typescript/references/create-project-reference.md +53 -0
- package/skills/algorand-typescript/references/create-project.md +86 -0
- package/skills/algorand-typescript/references/deploy-react-frontend-examples.md +527 -0
- package/skills/algorand-typescript/references/deploy-react-frontend-reference.md +412 -0
- package/skills/algorand-typescript/references/deploy-react-frontend.md +239 -0
- package/skills/algorand-typescript/references/implement-arc-standards-arc32-arc56.md +73 -0
- package/skills/algorand-typescript/references/implement-arc-standards-arc4.md +126 -0
- package/skills/algorand-typescript/references/implement-arc-standards.md +44 -0
- package/skills/algorand-typescript/references/test-smart-contracts-examples.md +245 -0
- package/skills/algorand-typescript/references/test-smart-contracts-unit-tests.md +147 -0
- package/skills/algorand-typescript/references/test-smart-contracts.md +127 -0
- package/skills/algorand-typescript/references/troubleshoot-errors-contract.md +296 -0
- package/skills/algorand-typescript/references/troubleshoot-errors-transaction.md +438 -0
- package/skills/algorand-typescript/references/troubleshoot-errors.md +56 -0
- package/skills/algorand-typescript/references/use-algokit-utils-reference.md +342 -0
- package/skills/algorand-typescript/references/use-algokit-utils.md +74 -0
- package/skills/algorand-x402-python/SKILL.md +113 -0
- package/skills/algorand-x402-python/references/create-python-x402-client-examples.md +469 -0
- package/skills/algorand-x402-python/references/create-python-x402-client-reference.md +313 -0
- package/skills/algorand-x402-python/references/create-python-x402-client.md +207 -0
- package/skills/algorand-x402-python/references/create-python-x402-facilitator-examples.md +924 -0
- package/skills/algorand-x402-python/references/create-python-x402-facilitator-reference.md +629 -0
- package/skills/algorand-x402-python/references/create-python-x402-facilitator.md +408 -0
- package/skills/algorand-x402-python/references/create-python-x402-server-examples.md +703 -0
- package/skills/algorand-x402-python/references/create-python-x402-server-reference.md +303 -0
- package/skills/algorand-x402-python/references/create-python-x402-server.md +221 -0
- package/skills/algorand-x402-python/references/explain-algorand-x402-python-examples.md +605 -0
- package/skills/algorand-x402-python/references/explain-algorand-x402-python-reference.md +315 -0
- package/skills/algorand-x402-python/references/explain-algorand-x402-python.md +167 -0
- package/skills/algorand-x402-python/references/use-python-x402-core-avm-examples.md +554 -0
- package/skills/algorand-x402-python/references/use-python-x402-core-avm-reference.md +278 -0
- package/skills/algorand-x402-python/references/use-python-x402-core-avm.md +166 -0
- package/skills/algorand-x402-typescript/SKILL.md +129 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-client-examples.md +879 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-client-reference.md +371 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-client.md +236 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-facilitator-examples.md +875 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-facilitator-reference.md +461 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-facilitator.md +270 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-nextjs-examples.md +1181 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-nextjs-reference.md +360 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-nextjs.md +251 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-paywall-examples.md +870 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-paywall-reference.md +323 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-paywall.md +281 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-server-examples.md +1135 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-server-reference.md +382 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-server.md +216 -0
- package/skills/algorand-x402-typescript/references/explain-algorand-x402-typescript-examples.md +616 -0
- package/skills/algorand-x402-typescript/references/explain-algorand-x402-typescript-reference.md +323 -0
- package/skills/algorand-x402-typescript/references/explain-algorand-x402-typescript.md +232 -0
- package/skills/algorand-x402-typescript/references/use-typescript-x402-core-avm-examples.md +1417 -0
- package/skills/algorand-x402-typescript/references/use-typescript-x402-core-avm-reference.md +504 -0
- package/skills/algorand-x402-typescript/references/use-typescript-x402-core-avm.md +158 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
# Smart Contract Errors (TypeScript)
|
|
2
|
+
|
|
3
|
+
TypeScript-focused fixes for common Algorand smart contract errors.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Logic Eval Errors](#logic-eval-errors)
|
|
8
|
+
- [Assert Failed](#assert-failed)
|
|
9
|
+
- [Opcode Budget Exceeded](#opcode-budget-exceeded)
|
|
10
|
+
- [Invalid Program](#invalid-program)
|
|
11
|
+
- [Stack Underflow](#stack-underflow)
|
|
12
|
+
- [Byte/Int Type Mismatch](#byteint-type-mismatch)
|
|
13
|
+
- [ABI Errors](#abi-errors)
|
|
14
|
+
- [Method Not Found](#method-not-found)
|
|
15
|
+
- [ABI Encoding Error](#abi-encoding-error)
|
|
16
|
+
- [Return Value Decoding Error](#return-value-decoding-error)
|
|
17
|
+
- [State Errors](#state-errors)
|
|
18
|
+
- [Global State Full](#global-state-full)
|
|
19
|
+
- [Local State Not Opted In](#local-state-not-opted-in)
|
|
20
|
+
- [Box Not Found](#box-not-found)
|
|
21
|
+
- [Box MBR Not Met](#box-mbr-not-met)
|
|
22
|
+
- [Inner Transaction Errors](#inner-transaction-errors)
|
|
23
|
+
- [Debugging Tips](#debugging-tips)
|
|
24
|
+
|
|
25
|
+
## Logic Eval Errors
|
|
26
|
+
|
|
27
|
+
### Assert Failed
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
logic eval error: assert failed pc=123
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Cause:** An `assert` statement evaluated to false.
|
|
34
|
+
|
|
35
|
+
**Debug with source maps:**
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
// Errors include source location automatically with AlgoKit Utils
|
|
39
|
+
try {
|
|
40
|
+
await appClient.send.myMethod({ args: { value: 0 } })
|
|
41
|
+
} catch (e) {
|
|
42
|
+
// Error includes: "assert failed at contracts/my_contract.py:45"
|
|
43
|
+
console.error(e)
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Common causes:**
|
|
48
|
+
- Input validation failed (e.g., `assert amount > 0`)
|
|
49
|
+
- Authorization check failed (e.g., `assert Txn.sender == self.owner`)
|
|
50
|
+
- State precondition not met (e.g., `assert self.is_initialized`)
|
|
51
|
+
|
|
52
|
+
**Fix:** Check the assertion condition and ensure inputs satisfy it.
|
|
53
|
+
|
|
54
|
+
### Opcode Budget Exceeded
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
logic eval error: dynamic cost budget exceeded
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Cause:** Contract exceeded the 700 opcode budget per app call.
|
|
61
|
+
|
|
62
|
+
**Budget limits:**
|
|
63
|
+
| Context | Budget |
|
|
64
|
+
|---------|--------|
|
|
65
|
+
| Single app call | 700 opcodes |
|
|
66
|
+
| Max pooled (16 app calls) | 11,200 opcodes |
|
|
67
|
+
| Logic signature | 20,000 opcodes |
|
|
68
|
+
|
|
69
|
+
**Fix - Pool budget with extra app calls:**
|
|
70
|
+
```typescript
|
|
71
|
+
await algorand.newGroup()
|
|
72
|
+
.addAppCallMethodCall(actualCallParams)
|
|
73
|
+
.addAppCall({
|
|
74
|
+
sender: sender,
|
|
75
|
+
appId: appId,
|
|
76
|
+
onComplete: OnComplete.NoOp,
|
|
77
|
+
args: [new Uint8Array(Buffer.from('noop'))], // Dummy call for budget
|
|
78
|
+
})
|
|
79
|
+
.send()
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Invalid Program
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
logic eval error: invalid program
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Cause:** The TEAL program is malformed or uses unsupported opcodes.
|
|
89
|
+
|
|
90
|
+
**Common causes:**
|
|
91
|
+
- Compiling for wrong AVM version
|
|
92
|
+
- Using opcodes not supported on target network
|
|
93
|
+
- Corrupted approval/clear program bytes
|
|
94
|
+
|
|
95
|
+
**Fix:** Ensure compilation targets the correct AVM version.
|
|
96
|
+
|
|
97
|
+
### Stack Underflow
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
logic eval error: stack underflow
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Cause:** Operation tried to pop from empty stack. Usually indicates a bug in low-level operations.
|
|
104
|
+
|
|
105
|
+
### Byte/Int Type Mismatch
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
logic eval error: assert failed: wanted type uint64 but got []byte
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Cause:** Wrong type passed to an operation. Ensure correct types in contract code.
|
|
112
|
+
|
|
113
|
+
## ABI Errors
|
|
114
|
+
|
|
115
|
+
### Method Not Found
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
error: method "foo(uint64)void" not found
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**Cause:** Calling a method that doesn't exist in the contract ABI.
|
|
122
|
+
|
|
123
|
+
**Fix:**
|
|
124
|
+
```typescript
|
|
125
|
+
// 1. Regenerate typed client after contract changes
|
|
126
|
+
// 2. Check method signature matches exactly
|
|
127
|
+
// 3. Verify contract was deployed with latest code
|
|
128
|
+
|
|
129
|
+
// Regenerate typed client
|
|
130
|
+
// algokit generate client -a ./artifacts -o ./client.ts
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### ABI Encoding Error
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
ABIEncodingError: value out of range for uint64
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**Cause:** Value doesn't fit the ABI type. Check value ranges for the target type.
|
|
140
|
+
|
|
141
|
+
### Return Value Decoding Error
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
error: could not decode return value
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Cause:** Method returned unexpected data format.
|
|
148
|
+
|
|
149
|
+
**Common causes:**
|
|
150
|
+
- Contract didn't log the return value properly
|
|
151
|
+
- Wrong return type in client
|
|
152
|
+
- Transaction failed before return
|
|
153
|
+
|
|
154
|
+
**Fix:** Check contract method has correct return annotation.
|
|
155
|
+
|
|
156
|
+
## State Errors
|
|
157
|
+
|
|
158
|
+
### Global State Full
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
logic eval error: store global state: failed
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Cause:** Exceeded declared global state schema.
|
|
165
|
+
|
|
166
|
+
**Fix:** Increase schema in contract deployment configuration.
|
|
167
|
+
|
|
168
|
+
### Local State Not Opted In
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
logic eval error: application APPID not opted in
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**Cause:** Account hasn't opted into the application.
|
|
175
|
+
|
|
176
|
+
**Fix:**
|
|
177
|
+
```typescript
|
|
178
|
+
await algorand.send.appCall({
|
|
179
|
+
sender: userAddress,
|
|
180
|
+
appId: appId,
|
|
181
|
+
onComplete: OnComplete.OptIn,
|
|
182
|
+
})
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Box Not Found
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
logic eval error: box not found
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**Cause:** Accessing a box that doesn't exist. Create box before access or check existence in contract code.
|
|
192
|
+
|
|
193
|
+
### Box MBR Not Met
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
logic eval error: box create with insufficient funds
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
**Cause:** App account lacks funds for box minimum balance requirement.
|
|
200
|
+
|
|
201
|
+
**MBR formula:** `2500 + (400 * (key_length + value_length))` microAlgos per box
|
|
202
|
+
|
|
203
|
+
**Fix:** Fund the app account:
|
|
204
|
+
```typescript
|
|
205
|
+
await algorand.send.payment({
|
|
206
|
+
sender: funder.address,
|
|
207
|
+
receiver: appClient.appAddress,
|
|
208
|
+
amount: algo(1), // Cover box MBR
|
|
209
|
+
})
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Inner Transaction Errors
|
|
213
|
+
|
|
214
|
+
### Insufficient Balance for Inner Txn
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
logic eval error: insufficient balance
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**Cause:** App account lacks funds for inner transaction amount.
|
|
221
|
+
|
|
222
|
+
**Fix:** Fund the app account before calling methods with inner transactions:
|
|
223
|
+
```typescript
|
|
224
|
+
await algorand.send.payment({
|
|
225
|
+
sender: deployer.address,
|
|
226
|
+
receiver: appClient.appAddress,
|
|
227
|
+
amount: algo(5),
|
|
228
|
+
})
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Inner Transaction Limit
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
logic eval error: too many inner transactions
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**Cause:** Exceeded 256 inner transactions per group.
|
|
238
|
+
|
|
239
|
+
**Fix:** Split operations across multiple outer transactions.
|
|
240
|
+
|
|
241
|
+
### App Not Opted Into Asset
|
|
242
|
+
|
|
243
|
+
```
|
|
244
|
+
logic eval error: asset ASSET_ID not opted in
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**Cause:** Contract account isn't opted into the asset. The contract must have an opt-in method that sends a 0-amount inner asset transfer.
|
|
248
|
+
|
|
249
|
+
## Debugging Tips
|
|
250
|
+
|
|
251
|
+
### Enable Debug Logging
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
import { Config } from '@algorandfoundation/algokit-utils'
|
|
255
|
+
Config.configure({ debug: true })
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Get Transaction Trace
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
// Simulate to get execution trace
|
|
262
|
+
const result = await algorand.newGroup()
|
|
263
|
+
.addAppCallMethodCall(params)
|
|
264
|
+
.simulate({ execTraceConfig: { enable: true } })
|
|
265
|
+
|
|
266
|
+
console.log(result.simulateResponse.txnGroups[0].txnResults[0].execTrace)
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Simulate Before Sending
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
const result = await algorand
|
|
273
|
+
.newGroup()
|
|
274
|
+
.addPayment({ sender, receiver, amount: algo(1) })
|
|
275
|
+
.simulate()
|
|
276
|
+
|
|
277
|
+
if (result.simulateResponse.txnGroups[0].failureMessage) {
|
|
278
|
+
console.error('Would fail:', result.simulateResponse.txnGroups[0].failureMessage)
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Check Program Counter Location
|
|
283
|
+
|
|
284
|
+
When you see `pc=123`, use algokit to find the source:
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
algokit compile contracts/my_contract.py --output-sourcemap
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
Then map the PC to source using the generated `.map` file.
|
|
291
|
+
|
|
292
|
+
## References
|
|
293
|
+
|
|
294
|
+
- [Debugging Smart Contracts](https://dev.algorand.co/concepts/smart-contracts/debugging/)
|
|
295
|
+
- [AVM Opcodes Reference](https://dev.algorand.co/reference/teal/opcodes/)
|
|
296
|
+
- [Error Handling in AlgoKit Utils TS](https://dev.algorand.co/algokit/utils/typescript/debugging/)
|
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
# Transaction & Account Errors (TypeScript)
|
|
2
|
+
|
|
3
|
+
TypeScript-focused fixes for common Algorand transaction and account errors.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Transaction Errors](#transaction-errors)
|
|
8
|
+
- [Overspend](#overspend)
|
|
9
|
+
- [Transaction Already in Ledger](#transaction-already-in-ledger)
|
|
10
|
+
- [Transaction Pool Full](#transaction-pool-full)
|
|
11
|
+
- [Fee Too Low](#fee-too-low)
|
|
12
|
+
- [Round Out of Range](#round-out-of-range)
|
|
13
|
+
- [Invalid Group](#invalid-group)
|
|
14
|
+
- [Group Size Limit](#group-size-limit)
|
|
15
|
+
- [Asset Errors](#asset-errors)
|
|
16
|
+
- [Asset Not Found](#asset-not-found)
|
|
17
|
+
- [Asset Not Opted In](#asset-not-opted-in)
|
|
18
|
+
- [Asset Frozen](#asset-frozen)
|
|
19
|
+
- [Clawback Not Authorized](#clawback-not-authorized)
|
|
20
|
+
- [Cannot Close Asset](#cannot-close-asset)
|
|
21
|
+
- [Account Errors](#account-errors)
|
|
22
|
+
- [Account Not Found](#account-not-found)
|
|
23
|
+
- [Invalid Address](#invalid-address)
|
|
24
|
+
- [Wrong Network](#wrong-network)
|
|
25
|
+
- [SDK Errors](#sdk-errors)
|
|
26
|
+
- [Application Errors](#application-errors)
|
|
27
|
+
- [Debugging Tips](#debugging-tips)
|
|
28
|
+
|
|
29
|
+
## Transaction Errors
|
|
30
|
+
|
|
31
|
+
### Overspend
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
TransactionPool.Remember: transaction TXID: overspend (account ADDRESS, data {_struct:{} Status:Offline MicroAlgos:{Raw:1000} ...})
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Cause:** Sender account has insufficient balance for amount + fee + minimum balance.
|
|
38
|
+
|
|
39
|
+
**Minimum balance requirements:**
|
|
40
|
+
| Item | MBR |
|
|
41
|
+
|------|-----|
|
|
42
|
+
| Base account | 100,000 microAlgo |
|
|
43
|
+
| Each opted-in asset | +100,000 microAlgo |
|
|
44
|
+
| Each created asset | +100,000 microAlgo |
|
|
45
|
+
| Each opted-in app | +100,000 microAlgo |
|
|
46
|
+
| Each created app | +100,000 microAlgo |
|
|
47
|
+
| App local state per schema | Varies |
|
|
48
|
+
| Box storage | 2,500 + 400 * size |
|
|
49
|
+
|
|
50
|
+
**Fix:**
|
|
51
|
+
```typescript
|
|
52
|
+
// Calculate available balance
|
|
53
|
+
const accountInfo = await algorand.account.getInformation(address)
|
|
54
|
+
const available = accountInfo.amount - accountInfo.minBalance
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Transaction Already in Ledger
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
TransactionPool.Remember: transaction already in ledger: TXID
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Cause:** Duplicate transaction submitted (same txn ID).
|
|
64
|
+
|
|
65
|
+
**Fix:** Check if transaction exists before retrying:
|
|
66
|
+
```typescript
|
|
67
|
+
try {
|
|
68
|
+
const result = await algorand.client.algod.pendingTransactionInformation(txId).do()
|
|
69
|
+
// Transaction exists
|
|
70
|
+
} catch {
|
|
71
|
+
// Safe to retry
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Transaction Pool Full
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
TransactionPool.Remember: transaction pool is full
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Cause:** Node's transaction pool at capacity.
|
|
82
|
+
|
|
83
|
+
**Fix:**
|
|
84
|
+
1. Wait and retry with exponential backoff
|
|
85
|
+
2. Increase fee to prioritize transaction
|
|
86
|
+
3. Try a different node
|
|
87
|
+
|
|
88
|
+
### Fee Too Low
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
TransactionPool.Remember: transaction TXID: fee X below threshold Y
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Cause:** Transaction fee below minimum (usually 1000 microAlgo).
|
|
95
|
+
|
|
96
|
+
**Fix:**
|
|
97
|
+
```typescript
|
|
98
|
+
await algorand.send.payment({
|
|
99
|
+
sender: sender,
|
|
100
|
+
receiver: receiver,
|
|
101
|
+
amount: algo(1),
|
|
102
|
+
staticFee: microAlgo(1000), // Minimum fee
|
|
103
|
+
})
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Round Out of Range
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
TransactionPool.Remember: transaction TXID: round X outside of Y-Z range
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Cause:** Transaction's validity window expired or is in the future.
|
|
113
|
+
|
|
114
|
+
**Fix:**
|
|
115
|
+
```typescript
|
|
116
|
+
await algorand.send.payment({
|
|
117
|
+
sender: sender,
|
|
118
|
+
receiver: receiver,
|
|
119
|
+
amount: algo(1),
|
|
120
|
+
validityWindow: 1000, // Valid for 1000 rounds (~1 hour)
|
|
121
|
+
})
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Invalid Group
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
TransactionPool.Remember: transaction TXID: bad group assignment
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Cause:** Transaction claims to be part of a group but has wrong group ID.
|
|
131
|
+
|
|
132
|
+
**Fix:** Use AlgoKit Utils for proper grouping:
|
|
133
|
+
```typescript
|
|
134
|
+
await algorand
|
|
135
|
+
.newGroup()
|
|
136
|
+
.addPayment({ sender, receiver, amount: algo(1) })
|
|
137
|
+
.addAssetOptIn({ sender, assetId: 12345n })
|
|
138
|
+
.send()
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Group Size Limit
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
cannot send transaction group with more than 16 transactions
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Cause:** Transaction group exceeds 16 transaction limit.
|
|
148
|
+
|
|
149
|
+
**Fix:** Split into multiple groups or optimize to fewer transactions.
|
|
150
|
+
|
|
151
|
+
## Asset Errors
|
|
152
|
+
|
|
153
|
+
### Asset Not Found
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
asset ASSET_ID does not exist
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Cause:** Asset ID doesn't exist on the network.
|
|
160
|
+
|
|
161
|
+
**Common causes:**
|
|
162
|
+
- Wrong network (TestNet vs MainNet)
|
|
163
|
+
- Asset was deleted
|
|
164
|
+
- Typo in asset ID
|
|
165
|
+
|
|
166
|
+
**Fix:** Verify asset exists:
|
|
167
|
+
```typescript
|
|
168
|
+
const assetInfo = await algorand.client.algod.getAssetByID(assetId).do()
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Asset Not Opted In
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
asset ASSET_ID missing from ACCOUNT_ADDRESS
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**Cause:** Receiving account hasn't opted into the asset.
|
|
178
|
+
|
|
179
|
+
**Fix:**
|
|
180
|
+
```typescript
|
|
181
|
+
await algorand.send.assetOptIn({
|
|
182
|
+
sender: receiverAddress,
|
|
183
|
+
assetId: assetId,
|
|
184
|
+
})
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Asset Frozen
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
asset ASSET_ID frozen in ACCOUNT_ADDRESS
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Cause:** Account's holding of this asset is frozen.
|
|
194
|
+
|
|
195
|
+
**Fix:** Asset freeze manager must unfreeze the account.
|
|
196
|
+
|
|
197
|
+
### Clawback Not Authorized
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
only clawback address can clawback
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**Cause:** Attempting clawback without being the clawback address.
|
|
204
|
+
|
|
205
|
+
**Fix:** Only the designated clawback address can perform clawbacks.
|
|
206
|
+
|
|
207
|
+
### Cannot Close Asset
|
|
208
|
+
|
|
209
|
+
```
|
|
210
|
+
cannot close asset: ACCOUNT_ADDRESS still has X units
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Cause:** Trying to opt out while still holding units.
|
|
214
|
+
|
|
215
|
+
**Fix:** Transfer all units before opting out:
|
|
216
|
+
```typescript
|
|
217
|
+
// First transfer all units
|
|
218
|
+
await algorand.send.assetTransfer({
|
|
219
|
+
sender: account,
|
|
220
|
+
receiver: creatorOrOther,
|
|
221
|
+
assetId: assetId,
|
|
222
|
+
amount: balance, // All remaining
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
// Then opt out
|
|
226
|
+
await algorand.send.assetOptOut({
|
|
227
|
+
sender: account,
|
|
228
|
+
assetId: assetId,
|
|
229
|
+
creator: creatorAddress,
|
|
230
|
+
})
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Account Errors
|
|
234
|
+
|
|
235
|
+
### Account Not Found
|
|
236
|
+
|
|
237
|
+
```
|
|
238
|
+
account ADDRESS not found
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
**Cause:** Account doesn't exist (never funded).
|
|
242
|
+
|
|
243
|
+
**Note:** Algorand accounts must receive at least minimum balance to exist.
|
|
244
|
+
|
|
245
|
+
**Fix:**
|
|
246
|
+
```typescript
|
|
247
|
+
await algorand.send.payment({
|
|
248
|
+
sender: funder.address,
|
|
249
|
+
receiver: newAccount.address,
|
|
250
|
+
amount: microAlgo(100_000), // Minimum
|
|
251
|
+
})
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Invalid Address
|
|
255
|
+
|
|
256
|
+
```
|
|
257
|
+
invalid address: ADDRESS
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
**Cause:** Malformed Algorand address.
|
|
261
|
+
|
|
262
|
+
**Valid address format:**
|
|
263
|
+
- 58 characters
|
|
264
|
+
- Base32 encoded
|
|
265
|
+
- Includes checksum
|
|
266
|
+
|
|
267
|
+
**Verify address:**
|
|
268
|
+
```typescript
|
|
269
|
+
import { isValidAddress } from 'algosdk'
|
|
270
|
+
if (!isValidAddress(address)) {
|
|
271
|
+
throw new Error('Invalid address')
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Wrong Network
|
|
276
|
+
|
|
277
|
+
```
|
|
278
|
+
genesis hash mismatch
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
**Cause:** Transaction built for different network than target.
|
|
282
|
+
|
|
283
|
+
**Fix:**
|
|
284
|
+
```typescript
|
|
285
|
+
// For TestNet
|
|
286
|
+
const algorand = AlgorandClient.testNet()
|
|
287
|
+
|
|
288
|
+
// For MainNet
|
|
289
|
+
const algorand = AlgorandClient.mainNet()
|
|
290
|
+
|
|
291
|
+
// Check network
|
|
292
|
+
const params = await algorand.client.algod.getTransactionParams().do()
|
|
293
|
+
console.log('Network:', params.genesisID) // testnet-v1.0, mainnet-v1.0
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## SDK Errors
|
|
297
|
+
|
|
298
|
+
### AlgodHTTPError
|
|
299
|
+
|
|
300
|
+
```
|
|
301
|
+
AlgodHTTPError: Network request error. Received status 401
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
**Common status codes:**
|
|
305
|
+
| Status | Meaning | Fix |
|
|
306
|
+
|--------|---------|-----|
|
|
307
|
+
| 401 | Unauthorized | Check API token |
|
|
308
|
+
| 404 | Not found | Check server URL |
|
|
309
|
+
| 500 | Server error | Node issue, retry |
|
|
310
|
+
| 503 | Unavailable | Node overloaded, retry |
|
|
311
|
+
|
|
312
|
+
**Fix for 401:**
|
|
313
|
+
```typescript
|
|
314
|
+
const algorand = AlgorandClient.fromConfig({
|
|
315
|
+
algodConfig: {
|
|
316
|
+
server: 'https://testnet-api.algonode.cloud',
|
|
317
|
+
port: '443',
|
|
318
|
+
token: '', // AlgoNode doesn't require token
|
|
319
|
+
}
|
|
320
|
+
})
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Timeout Waiting for Confirmation
|
|
324
|
+
|
|
325
|
+
```
|
|
326
|
+
Timeout waiting for transaction TXID to be confirmed
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
**Cause:** Transaction not confirmed within wait rounds.
|
|
330
|
+
|
|
331
|
+
**Fix:**
|
|
332
|
+
```typescript
|
|
333
|
+
const result = await algorand.send.payment(
|
|
334
|
+
{ sender, receiver, amount: algo(1) },
|
|
335
|
+
{ maxRoundsToWaitForConfirmation: 10 } // Wait longer
|
|
336
|
+
)
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### Connection Refused
|
|
340
|
+
|
|
341
|
+
```
|
|
342
|
+
fetch failed: ECONNREFUSED
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
**Cause:** Cannot connect to Algorand node.
|
|
346
|
+
|
|
347
|
+
**Fix:**
|
|
348
|
+
1. For LocalNet: Ensure AlgoKit LocalNet is running (`algokit localnet start`)
|
|
349
|
+
2. For public networks: Check internet connection
|
|
350
|
+
3. Verify server URL is correct
|
|
351
|
+
|
|
352
|
+
## Application Errors
|
|
353
|
+
|
|
354
|
+
### Application Not Found
|
|
355
|
+
|
|
356
|
+
```
|
|
357
|
+
application APPID does not exist
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
**Cause:** App ID doesn't exist on the network.
|
|
361
|
+
|
|
362
|
+
**Fix:**
|
|
363
|
+
```typescript
|
|
364
|
+
const appInfo = await algorand.client.algod.getApplicationByID(appId).do()
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
### Not Opted Into Application
|
|
368
|
+
|
|
369
|
+
```
|
|
370
|
+
address ADDRESS has not opted in to application APPID
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
**Cause:** Account trying to access local state without opt-in.
|
|
374
|
+
|
|
375
|
+
**Fix:**
|
|
376
|
+
```typescript
|
|
377
|
+
await algorand.send.appCall({
|
|
378
|
+
sender: userAddress,
|
|
379
|
+
appId: appId,
|
|
380
|
+
onComplete: OnComplete.OptIn,
|
|
381
|
+
})
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### Application Creator Only
|
|
385
|
+
|
|
386
|
+
```
|
|
387
|
+
cannot update or delete application: only creator can modify
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
**Cause:** Attempting to modify app without being creator.
|
|
391
|
+
|
|
392
|
+
**Fix:**
|
|
393
|
+
```typescript
|
|
394
|
+
const appInfo = await algorand.app.getById(appId)
|
|
395
|
+
if (sender !== appInfo.creator) {
|
|
396
|
+
throw new Error('Only creator can modify')
|
|
397
|
+
}
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
## Debugging Tips
|
|
401
|
+
|
|
402
|
+
### Enable Verbose Logging
|
|
403
|
+
|
|
404
|
+
```typescript
|
|
405
|
+
import { Config } from '@algorandfoundation/algokit-utils'
|
|
406
|
+
Config.configure({ debug: true })
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### Check Transaction Status
|
|
410
|
+
|
|
411
|
+
```typescript
|
|
412
|
+
// Check pending transaction
|
|
413
|
+
const pending = await algorand.client.algod.pendingTransactionInformation(txId).do()
|
|
414
|
+
console.log('Pool error:', pending.poolError)
|
|
415
|
+
|
|
416
|
+
// Check confirmed transaction
|
|
417
|
+
const confirmed = await algorand.client.indexer.lookupTransactionByID(txId).do()
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### Simulate Before Sending
|
|
421
|
+
|
|
422
|
+
```typescript
|
|
423
|
+
const result = await algorand
|
|
424
|
+
.newGroup()
|
|
425
|
+
.addPayment({ sender, receiver, amount: algo(1) })
|
|
426
|
+
.simulate()
|
|
427
|
+
|
|
428
|
+
if (result.simulateResponse.txnGroups[0].failureMessage) {
|
|
429
|
+
console.error('Would fail:', result.simulateResponse.txnGroups[0].failureMessage)
|
|
430
|
+
}
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
## References
|
|
434
|
+
|
|
435
|
+
- [Transaction Structure](https://dev.algorand.co/concepts/transactions/structure/)
|
|
436
|
+
- [Account Management](https://dev.algorand.co/concepts/accounts/)
|
|
437
|
+
- [Asset Overview](https://dev.algorand.co/concepts/assets/)
|
|
438
|
+
- [AlgoKit Utils TS Debugging](https://dev.algorand.co/algokit/utils/typescript/debugging/)
|