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 +38 -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,487 @@
|
|
|
1
|
+
# Migrating TEALScript to Algorand TypeScript 1.0
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
- [Migration Checklist](#migration-checklist)
|
|
6
|
+
- [Type Migration Table](#type-migration-table)
|
|
7
|
+
- [Migrations](#migrations)
|
|
8
|
+
- [Add explicit imports](#add-explicit-imports)
|
|
9
|
+
- [EventLogger → emit](#replace-eventlogger-with-emit)
|
|
10
|
+
- [Box creation syntax](#update-box-creation-syntax)
|
|
11
|
+
- [Inner transactions](#refactor-inner-transactions)
|
|
12
|
+
- [sendMethodCall → arc4.abiCall](#replace-sendmethodcall-with-arc4abicall)
|
|
13
|
+
- [App creation with compileArc4](#use-arc4compilearc4-for-app-creation)
|
|
14
|
+
- [Static methods → compileArc4](#replace-static-methods-with-compilearc4)
|
|
15
|
+
- [Logic sigs](#update-logic-sigs)
|
|
16
|
+
- [Template variables](#move-template-variables)
|
|
17
|
+
- [Numeric type annotations](#add-explicit-type-annotations)
|
|
18
|
+
- [Typed literals → arc4.Uint](#replace-typed-literals-with-arc4uint)
|
|
19
|
+
- [Type casting](#replace-as-type-casts)
|
|
20
|
+
- [Array/object references](#use-clone-for-copies)
|
|
21
|
+
|
|
22
|
+
## Migration Checklist
|
|
23
|
+
|
|
24
|
+
Work through these changes when migrating from TEALScript to Algorand TypeScript 1.0:
|
|
25
|
+
|
|
26
|
+
- [ ] **Explicit imports**: Replace global namespace with imports from `@algorandfoundation/algorand-typescript`
|
|
27
|
+
- [ ] **Event logging**: Replace `EventLogger` with `emit()`
|
|
28
|
+
- [ ] **Box creation**: Change `box.create(size)` to `box.create({ size })`
|
|
29
|
+
- [ ] **Inner transactions**: Update to use `itxn` namespace methods
|
|
30
|
+
- [ ] **Typed method calls**: Replace `sendMethodCall` with `arc4.abiCall`
|
|
31
|
+
- [ ] **App creation**: Use `arc4.compileArc4()` before creating apps
|
|
32
|
+
- [ ] **Compiled contract access**: Replace static methods with `arc4.compileArc4()` result
|
|
33
|
+
- [ ] **Logic sigs**: Rename `logic()` to `program()`, add return statement
|
|
34
|
+
- [ ] **Template variables**: Move outside class properties, use `TemplateVar<uint64>('NAME')`
|
|
35
|
+
- [ ] **Type annotations**: Add `:uint64` to all arithmetic operations
|
|
36
|
+
- [ ] **Numeric types**: Replace `uint256` literals with `arc4.Uint<256>` constructors
|
|
37
|
+
- [ ] **Type casting**: Replace `as type` with constructor calls
|
|
38
|
+
- [ ] **Array/object copies**: Use `clone()` function
|
|
39
|
+
|
|
40
|
+
## Type Migration Table
|
|
41
|
+
|
|
42
|
+
| TEALScript | Algorand TypeScript 1.0 |
|
|
43
|
+
|------------|------------------------|
|
|
44
|
+
| `EventLogger` | `emit` function |
|
|
45
|
+
| `BoxKey` | `Box` |
|
|
46
|
+
| `Txn` | `Transaction` |
|
|
47
|
+
| `PayTxn` | `PaymentTxn` |
|
|
48
|
+
| `AppCallTxn` | `ApplicationCallTxn` |
|
|
49
|
+
| `KeyRegTxn` | `KeyRegistrationTxn` |
|
|
50
|
+
| `OnCompletion` | `OnCompleteAction` |
|
|
51
|
+
| `ecAdd`, `ecMultiply`, etc. | `ElipticCurve.add`, `ElipticCurve.multiply` |
|
|
52
|
+
| `GlobalStateKey` | `GlobalState` |
|
|
53
|
+
| `LocalStateKey` | `LocalState` |
|
|
54
|
+
| `GlobalStateMap` | Not yet supported |
|
|
55
|
+
| `LocalStateMap` | Not yet supported |
|
|
56
|
+
| `isOptedInToApp`, `isOptedInToAsset` | `isOptedIn` |
|
|
57
|
+
| `this.txn` | `Txn` |
|
|
58
|
+
| `this.app` | `Global.currentApplicationAddress` |
|
|
59
|
+
| `verify...Txn` | `assertMatch` |
|
|
60
|
+
| `globals` | `Global` |
|
|
61
|
+
| `StaticArray` | `FixedArray` |
|
|
62
|
+
| `AppID` | `Application` |
|
|
63
|
+
| `AssetID` | `Asset` |
|
|
64
|
+
| `Address` | `Account` |
|
|
65
|
+
| `throw Error('msg')` | `err('msg')` |
|
|
66
|
+
|
|
67
|
+
## Migrations
|
|
68
|
+
|
|
69
|
+
### Add explicit imports
|
|
70
|
+
|
|
71
|
+
TEALScript injects types into global namespace. Algorand TypeScript requires explicit imports.
|
|
72
|
+
|
|
73
|
+
**BEFORE - TEALScript**
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
import { LogicSig } from '@algorandfoundation/tealscript';
|
|
77
|
+
|
|
78
|
+
class AppCaller extends LogicSig {
|
|
79
|
+
logic(): void {
|
|
80
|
+
assert(this.txn.applicationID === 1234); // No import needed
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**AFTER - Algorand TypeScript 1.0**
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
import {
|
|
89
|
+
LogicSig,
|
|
90
|
+
Txn,
|
|
91
|
+
assert,
|
|
92
|
+
uint64,
|
|
93
|
+
TemplateVar,
|
|
94
|
+
} from '@algorandfoundation/algorand-typescript';
|
|
95
|
+
|
|
96
|
+
class AppCaller extends LogicSig {
|
|
97
|
+
program(): boolean {
|
|
98
|
+
assert(Txn.applicationId.id === 1234);
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Replace `EventLogger` with `emit()`
|
|
105
|
+
|
|
106
|
+
**BEFORE - TEALScript**
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
class Swapper {
|
|
110
|
+
swap = new EventLogger<{
|
|
111
|
+
assetA: AssetID;
|
|
112
|
+
assetB: AssetID;
|
|
113
|
+
}>();
|
|
114
|
+
|
|
115
|
+
doSwap(a: AssetID, b: AssetID) {
|
|
116
|
+
this.swap.log({ assetA: a, assetB: b });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**AFTER - Algorand TypeScript 1.0**
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
import { uint64, emit, Contract } from '@algorandfoundation/algorand-typescript';
|
|
125
|
+
|
|
126
|
+
type Swap = { assetA: uint64; assetB: uint64 };
|
|
127
|
+
|
|
128
|
+
class Swapper extends Contract {
|
|
129
|
+
doSwap(a: uint64, b: uint64): void {
|
|
130
|
+
emit('swap', { assetA: a, assetB: b } as Swap);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Alternative: infer event name from type
|
|
135
|
+
type swap = { assetA: uint64; assetB: uint64 };
|
|
136
|
+
|
|
137
|
+
class Swapper2 extends Contract {
|
|
138
|
+
doSwap(a: uint64, b: uint64) {
|
|
139
|
+
emit<swap>({ assetA: a, assetB: b });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Update box creation syntax
|
|
145
|
+
|
|
146
|
+
**TEALScript**: `box.create(size)` or `box.create(size?)`
|
|
147
|
+
|
|
148
|
+
**Algorand TypeScript**: `box.create({ size })` or `box.create(options?: { size?: uint64 })`
|
|
149
|
+
|
|
150
|
+
Size is auto-determined for fixed-length types in both.
|
|
151
|
+
|
|
152
|
+
### Refactor inner transactions
|
|
153
|
+
|
|
154
|
+
#### Sending a single transaction
|
|
155
|
+
|
|
156
|
+
**BEFORE - TEALScript**
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
sendAssetConfig({
|
|
160
|
+
total: 1000,
|
|
161
|
+
assetName: 'AST1',
|
|
162
|
+
unitName: 'unit',
|
|
163
|
+
decimals: 3,
|
|
164
|
+
manager: this.app.address,
|
|
165
|
+
reserve: this.app.address,
|
|
166
|
+
});
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**AFTER - Algorand TypeScript 1.0**
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
import { itxn, Global, log } from '@algorandfoundation/algorand-typescript';
|
|
173
|
+
|
|
174
|
+
const assetParams = itxn.assetConfig({
|
|
175
|
+
total: 1000,
|
|
176
|
+
assetName: 'AST1',
|
|
177
|
+
unitName: 'unit',
|
|
178
|
+
decimals: 3,
|
|
179
|
+
manager: Global.currentApplicationAddress,
|
|
180
|
+
reserve: Global.currentApplicationAddress,
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
const asset_txn = assetParams.submit();
|
|
184
|
+
log(asset_txn.createdAsset.id);
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
#### Sending a transaction group
|
|
188
|
+
|
|
189
|
+
**BEFORE - TEALScript**
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
this.pendingGroup.addAssetCreation({
|
|
193
|
+
configAssetTotal: 1000,
|
|
194
|
+
configAssetName: 'AST3',
|
|
195
|
+
configAssetUnitName: 'unit',
|
|
196
|
+
configAssetDecimals: 3,
|
|
197
|
+
configAssetManager: this.app.address,
|
|
198
|
+
configAssetReserve: this.app.address,
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
this.pendingGroup.addAppCall({
|
|
202
|
+
approvalProgram: APPROVE,
|
|
203
|
+
clearStateProgram: APPROVE,
|
|
204
|
+
fee: 0,
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
const appCreateTxn = this.lastInnerGroup[0];
|
|
208
|
+
const asset3_txn = this.lastInnerGroup[1];
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**AFTER - Algorand TypeScript 1.0**
|
|
212
|
+
|
|
213
|
+
```ts
|
|
214
|
+
import { itxn, Global, assert, Bytes } from '@algorandfoundation/algorand-typescript';
|
|
215
|
+
|
|
216
|
+
const assetParams = itxn.assetConfig({
|
|
217
|
+
total: 1000,
|
|
218
|
+
assetName: 'AST3',
|
|
219
|
+
unitName: 'unit',
|
|
220
|
+
decimals: 3,
|
|
221
|
+
manager: Global.currentApplicationAddress,
|
|
222
|
+
reserve: Global.currentApplicationAddress,
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
const appCreateParams = itxn.applicationCall({
|
|
226
|
+
approvalProgram: APPROVAL_PROGRAM,
|
|
227
|
+
clearStateProgram: CLEAR_STATE_PROGRAM,
|
|
228
|
+
fee: 0,
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
const [appCreateTxn, asset3_txn] = itxn.submitGroup(appCreateParams, assetParams);
|
|
232
|
+
|
|
233
|
+
assert(appCreateTxn.createdApp, 'app is created');
|
|
234
|
+
assert(asset3_txn.assetName === Bytes('AST3'));
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Replace `sendMethodCall` with `arc4.abiCall`
|
|
238
|
+
|
|
239
|
+
**BEFORE - TEALScript**
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
const result = sendMethodCall<typeof Hello.prototype.greet>({
|
|
243
|
+
applicationID: app,
|
|
244
|
+
methodArgs: ['algo dev'],
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
assert(result === 'hello algo dev');
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
**AFTER - Algorand TypeScript 1.0**
|
|
251
|
+
|
|
252
|
+
```ts
|
|
253
|
+
import { arc4, assert } from '@algorandfoundation/algorand-typescript';
|
|
254
|
+
import type { HelloStubbed } from './HelloWorld.algo';
|
|
255
|
+
|
|
256
|
+
// Option 1: type argument (supports type-only imports)
|
|
257
|
+
const result = arc4.abiCall<typeof HelloStubbed.prototype.greet>({
|
|
258
|
+
appId: 1234,
|
|
259
|
+
args: ['algo dev'],
|
|
260
|
+
}).returnValue;
|
|
261
|
+
|
|
262
|
+
assert(result === 'hello algo dev');
|
|
263
|
+
|
|
264
|
+
// Option 2: method property
|
|
265
|
+
const result2 = arc4.abiCall({
|
|
266
|
+
method: Hello.prototype.greet,
|
|
267
|
+
appId: 1234,
|
|
268
|
+
args: ['algo dev'],
|
|
269
|
+
}).returnValue;
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Use `arc4.compileArc4()` for app creation
|
|
273
|
+
|
|
274
|
+
**BEFORE - TEALScript**
|
|
275
|
+
|
|
276
|
+
```ts
|
|
277
|
+
sendMethodCall<typeof Greeter.prototype.createApplication>({
|
|
278
|
+
clearStateProgram: Greeter.clearProgram(),
|
|
279
|
+
approvalProgram: Greeter.approvalProgram(),
|
|
280
|
+
globalNumUint: Greeter.schema.global.numUint,
|
|
281
|
+
methodArgs: ['hello'],
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
const app = this.itxn.createdApplicationId;
|
|
285
|
+
|
|
286
|
+
const result = sendMethodCall<typeof Greeter.prototype.greet>({
|
|
287
|
+
applicationID: app,
|
|
288
|
+
methodArgs: ['world'],
|
|
289
|
+
});
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
**AFTER - Algorand TypeScript 1.0**
|
|
293
|
+
|
|
294
|
+
```ts
|
|
295
|
+
import { Contract, arc4, assert } from '@algorandfoundation/algorand-typescript';
|
|
296
|
+
import Greeter from './Greeter.algo';
|
|
297
|
+
|
|
298
|
+
// First compile the contract
|
|
299
|
+
const compiled = arc4.compileArc4(Greeter);
|
|
300
|
+
|
|
301
|
+
const app = arc4.abiCall({
|
|
302
|
+
method: compiled.call.createApplication,
|
|
303
|
+
args: ['hello'],
|
|
304
|
+
globalNumUint: compiled.globalUints,
|
|
305
|
+
}).itxn.createdApp;
|
|
306
|
+
|
|
307
|
+
const result = arc4.abiCall({
|
|
308
|
+
method: compiled.call.greet,
|
|
309
|
+
args: ['world'],
|
|
310
|
+
appId: app,
|
|
311
|
+
}).returnValue;
|
|
312
|
+
|
|
313
|
+
assert(result === 'hello world');
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Replace static methods with `compileArc4()`
|
|
317
|
+
|
|
318
|
+
**BEFORE - TEALScript**
|
|
319
|
+
|
|
320
|
+
```ts
|
|
321
|
+
// Direct static method access
|
|
322
|
+
Greeter.clearProgram();
|
|
323
|
+
Greeter.approvalProgram();
|
|
324
|
+
Greeter.schema.global.numUint;
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
**AFTER - Algorand TypeScript 1.0**
|
|
328
|
+
|
|
329
|
+
```ts
|
|
330
|
+
// Use compiled object
|
|
331
|
+
const compiled = arc4.compileArc4(Greeter);
|
|
332
|
+
compiled.clearStateProgram;
|
|
333
|
+
compiled.approvalProgram;
|
|
334
|
+
compiled.globalUints;
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Update logic sigs
|
|
338
|
+
|
|
339
|
+
**BEFORE - TEALScript**
|
|
340
|
+
|
|
341
|
+
```ts
|
|
342
|
+
class DangerousPaymentLsig extends LogicSig {
|
|
343
|
+
logic(amt: uint64) {
|
|
344
|
+
assert(this.txn.amount === amt);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
**AFTER - Algorand TypeScript 1.0**
|
|
350
|
+
|
|
351
|
+
```ts
|
|
352
|
+
import { op, LogicSig, Txn } from '@algorandfoundation/algorand-typescript';
|
|
353
|
+
|
|
354
|
+
class DangerousPaymentLsig extends LogicSig {
|
|
355
|
+
program() {
|
|
356
|
+
const amt = op.btoi(op.arg(0)); // Use op.arg() for arguments
|
|
357
|
+
return Txn.amount === amt; // Must return boolean or uint64
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### Move template variables
|
|
363
|
+
|
|
364
|
+
**BEFORE - TEALScript**
|
|
365
|
+
|
|
366
|
+
```ts
|
|
367
|
+
class AppCaller extends LogicSig {
|
|
368
|
+
APP_ID = TemplateVar<AppID>();
|
|
369
|
+
|
|
370
|
+
logic(): void {
|
|
371
|
+
assert(this.txn.applicationID === this.APP_ID);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
**AFTER - Algorand TypeScript 1.0**
|
|
377
|
+
|
|
378
|
+
```ts
|
|
379
|
+
import { LogicSig, Txn, TemplateVar, assert, uint64 } from '@algorandfoundation/algorand-typescript';
|
|
380
|
+
|
|
381
|
+
// Template vars can be outside class
|
|
382
|
+
const APP_ID = TemplateVar<uint64>('APP_ID');
|
|
383
|
+
|
|
384
|
+
class AppCaller extends LogicSig {
|
|
385
|
+
program(): boolean {
|
|
386
|
+
assert(Txn.applicationId.id === APP_ID);
|
|
387
|
+
return true;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### Add explicit type annotations
|
|
393
|
+
|
|
394
|
+
TEALScript allows implicit `number` types. Algorand TypeScript requires explicit `uint64`.
|
|
395
|
+
|
|
396
|
+
**BEFORE - TEALScript**
|
|
397
|
+
|
|
398
|
+
```ts
|
|
399
|
+
add(a: uint64, b: uint64): uint64 {
|
|
400
|
+
const sum = a + b; // Type inferred
|
|
401
|
+
return sum;
|
|
402
|
+
}
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
**AFTER - Algorand TypeScript 1.0**
|
|
406
|
+
|
|
407
|
+
```ts
|
|
408
|
+
import { uint64 } from '@algorandfoundation/algorand-typescript';
|
|
409
|
+
|
|
410
|
+
add(a: uint64, b: uint64): uint64 {
|
|
411
|
+
const sum: uint64 = a + b; // Type required
|
|
412
|
+
return sum;
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Replace typed literals with `arc4.Uint` constructors
|
|
417
|
+
|
|
418
|
+
**BEFORE - TEALScript**
|
|
419
|
+
|
|
420
|
+
```ts
|
|
421
|
+
addOne(n: uint256): uint256 {
|
|
422
|
+
const one: uint256 = 1;
|
|
423
|
+
const sum = n + one;
|
|
424
|
+
return sum;
|
|
425
|
+
}
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
**AFTER - Algorand TypeScript 1.0**
|
|
429
|
+
|
|
430
|
+
```ts
|
|
431
|
+
import { arc4, biguint } from '@algorandfoundation/algorand-typescript';
|
|
432
|
+
|
|
433
|
+
addOne(n: arc4.Uint<256>): arc4.Uint<256> {
|
|
434
|
+
// Use biguint for intermediate arithmetic to avoid overflow checks
|
|
435
|
+
const one = 1n;
|
|
436
|
+
const sum: biguint = n.asBigUint() + one;
|
|
437
|
+
return new arc4.Uint<256>(sum);
|
|
438
|
+
}
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
**Best practice**: Use `biguint` for intermediate values, convert to `arc4.Uint` only when encoding.
|
|
442
|
+
|
|
443
|
+
### Replace `as` type casts
|
|
444
|
+
|
|
445
|
+
**BEFORE - TEALScript**
|
|
446
|
+
|
|
447
|
+
```ts
|
|
448
|
+
convertNumber(n: uint64): uint8 {
|
|
449
|
+
return n as uint8;
|
|
450
|
+
}
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
**AFTER - Algorand TypeScript 1.0**
|
|
454
|
+
|
|
455
|
+
```ts
|
|
456
|
+
import { uint64, arc4 } from '@algorandfoundation/algorand-typescript';
|
|
457
|
+
|
|
458
|
+
convertNumber(n: uint64): arc4.Uint<8> {
|
|
459
|
+
return new arc4.Uint<8>(n); // Use constructor
|
|
460
|
+
}
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### Use `clone()` for array and object copies
|
|
464
|
+
|
|
465
|
+
TEALScript allows mutable references. Algorand TypeScript requires explicit copies.
|
|
466
|
+
|
|
467
|
+
**BEFORE - TEALScript**
|
|
468
|
+
|
|
469
|
+
```ts
|
|
470
|
+
const a: uint64[] = [1, 2, 3];
|
|
471
|
+
const b = a;
|
|
472
|
+
b.push(4);
|
|
473
|
+
assert(a === b); // Same reference
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
**AFTER - Algorand TypeScript 1.0**
|
|
477
|
+
|
|
478
|
+
```ts
|
|
479
|
+
import { uint64, clone, assertMatch } from '@algorandfoundation/algorand-typescript';
|
|
480
|
+
|
|
481
|
+
const a: uint64[] = [1, 2, 3];
|
|
482
|
+
const b = clone(a); // Explicit copy
|
|
483
|
+
b.push(4);
|
|
484
|
+
|
|
485
|
+
assertMatch(a, [1, 2, 3]);
|
|
486
|
+
assertMatch(b, [1, 2, 3, 4]); // Different arrays
|
|
487
|
+
```
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
|
|
2
|
+
# Algorand TypeScript Migration
|
|
3
|
+
|
|
4
|
+
Migrate smart contracts to Algorand TypeScript 1.0 from TEALScript or Algorand TypeScript Beta.
|
|
5
|
+
|
|
6
|
+
## Migration Workflow
|
|
7
|
+
|
|
8
|
+
### 1. Identify Source Language
|
|
9
|
+
|
|
10
|
+
Determine whether the code is **TEALScript** or **Algorand TypeScript Beta**:
|
|
11
|
+
|
|
12
|
+
| Indicator | TEALScript | Algorand TypeScript Beta |
|
|
13
|
+
|-----------|------------|--------------------------|
|
|
14
|
+
| Import source | `@algorandfoundation/tealscript` | `@algorandfoundation/algorand-typescript` |
|
|
15
|
+
| Global types | Uses `assert`, `uint64` without imports | Requires explicit imports |
|
|
16
|
+
| Event logging | `new EventLogger<...>()` | N/A |
|
|
17
|
+
| Inner transactions | `sendAssetConfig({...})` | `itxn.assetConfig({...})` |
|
|
18
|
+
| Logic sig method | `logic()` | `program()` |
|
|
19
|
+
| Type syntax | `uint256`, `uint8` literals | `arc4.UintN<256>`, `arc4.UintN8` |
|
|
20
|
+
|
|
21
|
+
### 2. Load Migration Guide
|
|
22
|
+
|
|
23
|
+
Based on the source language, read the appropriate reference:
|
|
24
|
+
|
|
25
|
+
- **From TEALScript**: Read [algorand-ts-migration-from-tealscript.md](./algorand-ts-migration-from-tealscript.md)
|
|
26
|
+
- **From Algorand TypeScript Beta**: Read [algorand-ts-migration-from-beta.md](./algorand-ts-migration-from-beta.md)
|
|
27
|
+
|
|
28
|
+
### 3. Execute Migration
|
|
29
|
+
|
|
30
|
+
Follow the checklist in the loaded reference file. Apply transformations systematically:
|
|
31
|
+
|
|
32
|
+
1. Start with imports and type renames (mechanical changes)
|
|
33
|
+
2. Update syntax patterns (inner transactions, method calls)
|
|
34
|
+
3. Add explicit type annotations where required
|
|
35
|
+
4. Handle semantic changes (mutability, resource encoding)
|
|
36
|
+
5. Rename test files if applicable
|
|
37
|
+
|
|
38
|
+
### 4. Verify Migration
|
|
39
|
+
|
|
40
|
+
After migration:
|
|
41
|
+
- Ensure all imports resolve from `@algorandfoundation/algorand-typescript`
|
|
42
|
+
- Verify no TypeScript errors remain
|
|
43
|
+
- Run the Algorand TypeScript compiler to validate
|
|
44
|
+
|
|
45
|
+
## Quick Reference
|
|
46
|
+
|
|
47
|
+
### Common Import Pattern (1.0)
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import {
|
|
51
|
+
Contract,
|
|
52
|
+
GlobalState,
|
|
53
|
+
LocalState,
|
|
54
|
+
Box,
|
|
55
|
+
BoxMap,
|
|
56
|
+
arc4,
|
|
57
|
+
uint64,
|
|
58
|
+
bytes,
|
|
59
|
+
Bytes,
|
|
60
|
+
Uint64,
|
|
61
|
+
assert,
|
|
62
|
+
err,
|
|
63
|
+
emit,
|
|
64
|
+
clone,
|
|
65
|
+
itxn,
|
|
66
|
+
gtxn,
|
|
67
|
+
Txn,
|
|
68
|
+
Global,
|
|
69
|
+
op,
|
|
70
|
+
} from '@algorandfoundation/algorand-typescript';
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Key Type Changes
|
|
74
|
+
|
|
75
|
+
| Old | New (1.0) |
|
|
76
|
+
|-----|-----------|
|
|
77
|
+
| `uint8`, `uint16`, `uint256` | `arc4.Uint<8>`, `arc4.Uint<16>`, `arc4.Uint<256>` |
|
|
78
|
+
| `arc4.UintN64`, `arc4.UintN<N>` | `arc4.Uint64`, `arc4.Uint<N>` |
|
|
79
|
+
| `arc4.UFixedNxM<N,M>` | `arc4.UFixed<N,M>` |
|
|
80
|
+
| `MutableArray` | `ReferenceArray` |
|
|
81
|
+
| `BoxRef` | `Box<bytes>` |
|
|
82
|
+
| `Address` (TEALScript) | `Account` |
|
|
83
|
+
| `AppID` (TEALScript) | `Application` |
|
|
84
|
+
| `AssetID` (TEALScript) | `Asset` |
|
|
85
|
+
|
|
86
|
+
### Key Function Changes
|
|
87
|
+
|
|
88
|
+
| Old | New (1.0) |
|
|
89
|
+
|-----|-----------|
|
|
90
|
+
| `x.copy()` | `clone(x)` |
|
|
91
|
+
| `arc4EncodedLength<T>()` | `sizeOf<T>()` |
|
|
92
|
+
| `arc4.interpretAsArc4<T>(b)` | `arc4.convertBytes<T>(b, { strategy: 'validate' })` |
|
|
93
|
+
| `x.native` | `x.asUint64()` or `x.asBigUint()` |
|
|
94
|
+
| `sendMethodCall<T>({...})` | `arc4.abiCall({ method: T, ... })` |
|
|
95
|
+
|
|
96
|
+
## Resources
|
|
97
|
+
|
|
98
|
+
### references/
|
|
99
|
+
|
|
100
|
+
- **[algorand-ts-migration-from-beta.md](./algorand-ts-migration-from-beta.md)**: Complete migration guide from Algorand TypeScript Beta to 1.0. Includes checklist of 13 breaking changes with before/after examples.
|
|
101
|
+
|
|
102
|
+
- **[algorand-ts-migration-from-tealscript.md](./algorand-ts-migration-from-tealscript.md)**: Complete migration guide from TEALScript to Algorand TypeScript 1.0. Includes type migration table and 13 migration patterns with examples.
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Methods, ABI, and Lifecycle
|
|
2
|
+
|
|
3
|
+
## Method Visibility
|
|
4
|
+
|
|
5
|
+
By default, `@abimethod` decorators are NOT necessary. Visibility determines ABI exposure:
|
|
6
|
+
|
|
7
|
+
| Visibility | Behavior |
|
|
8
|
+
|------------|----------|
|
|
9
|
+
| `public` | Automatically exposed as ABI method |
|
|
10
|
+
| `private` | Becomes subroutine (internal only) |
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
// Public = ABI method automatically
|
|
14
|
+
public addTodo(text: string): uint64 { }
|
|
15
|
+
|
|
16
|
+
// Private = subroutine
|
|
17
|
+
private getTodoKey(account: bytes, todoId: uint64): string { }
|
|
18
|
+
|
|
19
|
+
// Decorator only when needed for config
|
|
20
|
+
@abimethod({ readonly: true })
|
|
21
|
+
public getData(): [uint64, uint64, uint64] { }
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**When to use `@abimethod()`**: Only when you need configuration like `{ readonly: true }`, `{ allowActions: 'OptIn' }`, etc.
|
|
25
|
+
|
|
26
|
+
## Decorator Syntax
|
|
27
|
+
|
|
28
|
+
ARC4 decorators MUST be called as functions with parentheses:
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
// CORRECT
|
|
32
|
+
@abimethod()
|
|
33
|
+
public update(): string { }
|
|
34
|
+
|
|
35
|
+
// INCORRECT - "Decorator function return type mismatch"
|
|
36
|
+
@arc4.abimethod
|
|
37
|
+
public update(): string { }
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Application Lifecycle Methods
|
|
41
|
+
|
|
42
|
+
**PREFER convention-based methods** for lifecycle events. They are automatically routed based on OnCompletion action.
|
|
43
|
+
|
|
44
|
+
| Method Name | When Called |
|
|
45
|
+
|-------------|-------------|
|
|
46
|
+
| `createApplication()` | Application creation |
|
|
47
|
+
| `optInToApplication()` | OnCompletion is OptIn |
|
|
48
|
+
| `closeOutOfApplication()` | OnCompletion is CloseOut |
|
|
49
|
+
| `updateApplication()` | OnCompletion is UpdateApplication |
|
|
50
|
+
| `deleteApplication()` | OnCompletion is DeleteApplication |
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
export class TodoList extends Contract {
|
|
54
|
+
todos = LocalState<TodoListData>({ key: 'todos' })
|
|
55
|
+
|
|
56
|
+
// Convention-based: automatically routed on OptIn
|
|
57
|
+
public optInToApplication(): void {
|
|
58
|
+
const initialList = {
|
|
59
|
+
todos: [] as Todo[],
|
|
60
|
+
nextId: Uint64(1),
|
|
61
|
+
}
|
|
62
|
+
this.todos(Txn.sender).value = clone(initialList)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Regular ABI methods for business logic
|
|
66
|
+
public addTodo(text: string): uint64 {
|
|
67
|
+
// ...
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## ABI Return Types
|
|
73
|
+
|
|
74
|
+
Struct objects can be returned directly. Puya converts to ABI tuples automatically:
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
// CORRECT: Return struct directly
|
|
78
|
+
@abimethod({ readonly: true })
|
|
79
|
+
public getData(): MyData {
|
|
80
|
+
const state = clone(this.appState.value)
|
|
81
|
+
return state // Compiler converts to ABI tuple
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// ALSO CORRECT: Return tuple explicitly
|
|
85
|
+
@abimethod({ readonly: true })
|
|
86
|
+
public getData(): [uint64, uint64, uint64] {
|
|
87
|
+
const state = clone(this.appState.value)
|
|
88
|
+
return [state.field1, state.field2, state.field3]
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Type Definitions
|
|
93
|
+
|
|
94
|
+
Use plain TypeScript types for storage, not ARC4 decorators:
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
// CORRECT
|
|
98
|
+
type MyData = { field1: uint64; field2: uint64 }
|
|
99
|
+
|
|
100
|
+
// INCORRECT
|
|
101
|
+
@arc4.abiTuple class MyData { }
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Generated Client Method Names
|
|
105
|
+
|
|
106
|
+
### Convention-based Lifecycle Methods
|
|
107
|
+
|
|
108
|
+
Convention-based methods like `optInToApplication()` are nested under their action type in generated clients:
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
// Contract
|
|
112
|
+
public optInToApplication(): void { }
|
|
113
|
+
|
|
114
|
+
// Client call
|
|
115
|
+
await client.send.optIn.optInToApplication({ args: [] })
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Decorator-based Opt-in Methods
|
|
119
|
+
|
|
120
|
+
Methods with `@abimethod({ allowActions: 'OptIn' })` are also nested:
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
// Contract
|
|
124
|
+
@abimethod({ allowActions: 'OptIn' })
|
|
125
|
+
public optIn(): void { }
|
|
126
|
+
|
|
127
|
+
// CORRECT - nested under optIn
|
|
128
|
+
await client.send.optIn.optIn({ args: [] })
|
|
129
|
+
|
|
130
|
+
// INCORRECT
|
|
131
|
+
await client.send.optIn({ args: [] })
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Recommendation**: Use convention-based `optInToApplication()` for better readability. Always check the generated client file to confirm exact method names.
|