Skip to content

Commit fb8915c

Browse files
rahxephon89claude
andcommitted
[sdk] Add support for public struct/enum transaction arguments
Implement complete support for passing public copy structs and enums as transaction arguments in JSON format, mirroring functionality in the Rust CLI (aptos-core#18591). Features: - Automatic type inference from function ABI - Nested structs/enums support (up to 7 levels deep) - Generic type parameter substitution (T0, T1, etc.) - Support for all Move primitive types (bool, u8-u256, i8-i256, address) - Special framework types (String, Object<T>, Option<T>) - Option<T> dual format support (vector and enum formats) - Module ABI caching for performance - Comprehensive validation and error messages Implementation: - MoveStructArgument and MoveEnumArgument BCS-serializable classes - StructEnumArgumentParser with full encoding logic: * Fetches module ABI from REST API for struct/enum definitions * Encodes struct fields in declaration order * Encodes enum variants with ULEB128 indices * Recursive encoding for nested types * Generic type parameter substitution with bounds checking - Integration into transaction builder: * Made argument conversion functions async (convertArgument, parseArg) * Added struct/enum detection logic in parseArg * Updated transaction builder to handle async conversions - Complete type support: * All primitives (bool, u8-u256, i8-i256, address) * Vectors with recursive element encoding * Special framework types (String, Object<T>, Option<T>) Testing: - 70+ comprehensive unit tests with mocked module ABIs - Tests cover: struct/enum encoding, generics, nested types, depth limits, error cases, Option formats, framework types, caching Documentation: - JSDoc with 5 usage examples in StructEnumArgumentParser class - README section with 6 practical examples - CHANGELOG entry with breaking changes and feature list - Complete design document (STRUCT_ENUM_SUPPORT.md) Breaking Changes: - Argument conversion functions are now async to support fetching module ABIs - Impact is minimal since top-level APIs like generateTransactionPayload were already async Files: - src/transactions/transactionBuilder/structEnumParser.ts: Complete parser implementation - src/transactions/transactionBuilder/remoteAbi.ts: Async conversion with struct/enum support - src/transactions/transactionBuilder/transactionBuilder.ts: Async transaction building - src/transactions/types.ts: Added MoveStructArgument and MoveEnumArgument to type system - src/internal/digitalAsset.ts: Async property value encoding - tests/unit/structEnumParser.test.ts: Comprehensive test suite (70+ tests) - tests/e2e/transaction/transactionArguments.test.ts: Updated for async - tests/unit/remoteAbi.test.ts: Updated for async - README.md: Usage examples section - CHANGELOG.md: Breaking changes and features - STRUCT_ENUM_SUPPORT.md: Complete design and status document Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent d10017e commit fb8915c

File tree

13 files changed

+2695
-497
lines changed

13 files changed

+2695
-497
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,25 @@ All notable changes to the Aptos TypeScript SDK will be captured in this file. T
44

55
# Unreleased
66

7+
## Breaking Changes
8+
9+
- [Transactions] Argument conversion functions (`convertArgument`, `checkOrConvertArgument`, `parseArg`) are now async to support fetching module ABIs for struct/enum argument encoding. This change has minimal impact since top-level transaction building functions (`generateTransactionPayload`, etc.) were already async.
10+
711
## Added
812

913
- Add JWK caching for keyless authentication with 5-minute TTL to improve performance
1014
- Add `clearMemoizeCache()` utility function for clearing the memoization cache
1115
- Add Bun runtime detection with `isBun()` utility function
1216
- Add warning at `AptosConfig` construction time when running in Bun without explicitly disabling HTTP/2 (Bun does not fully support HTTP/2, which is enabled by default)
17+
- [Transactions] Add support for public copy structs and enums as transaction arguments via `MoveStructArgument`, `MoveEnumArgument`, and `StructEnumArgumentParser` classes
18+
- Automatic type inference from function ABI
19+
- Nested structs/enums support (up to 7 levels deep)
20+
- Generic type parameter substitution (T0, T1, etc.)
21+
- Support for all Move primitive types (bool, u8-u256, i8-i256, address)
22+
- Special framework types (String, Object<T>, Option<T>)
23+
- Option<T> dual format support (vector and enum formats)
24+
- Module ABI caching for performance
25+
- Comprehensive validation and error messages
1326

1427
## Changed
1528

README.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,92 @@ async function example() {
222222
example();
223223
```
224224

225+
### Using Struct and Enum Arguments
226+
227+
---
228+
229+
The SDK supports passing public copy structs and enums as transaction arguments in natural JSON format:
230+
231+
```ts
232+
// Example 1: Simple struct argument
233+
const transaction = await aptos.transaction.build.simple({
234+
sender: alice.accountAddress,
235+
data: {
236+
function: "0x1::shapes::draw_point",
237+
functionArguments: [
238+
{ x: "10", y: "20" } // Point struct
239+
],
240+
},
241+
});
242+
243+
// Example 2: Nested structs
244+
const transaction = await aptos.transaction.build.simple({
245+
sender: alice.accountAddress,
246+
data: {
247+
function: "0x1::shapes::draw_line",
248+
functionArguments: [
249+
{
250+
start: { x: "0", y: "0" },
251+
end: { x: "10", y: "10" }
252+
} // Line struct with nested Point structs
253+
],
254+
},
255+
});
256+
257+
// Example 3: Enum variants
258+
const transaction = await aptos.transaction.build.simple({
259+
sender: alice.accountAddress,
260+
data: {
261+
function: "0x1::game::set_color",
262+
functionArguments: [
263+
{ Red: {} } // Color enum, Red variant (no fields)
264+
],
265+
},
266+
});
267+
268+
// Example 4: Enum with fields
269+
const transaction = await aptos.transaction.build.simple({
270+
sender: alice.accountAddress,
271+
data: {
272+
function: "0x1::game::create_player",
273+
functionArguments: [
274+
{ Premium: { "0": "100" } } // AccountType enum, Premium variant with u64 field
275+
],
276+
},
277+
});
278+
279+
// Example 5: Generic structs
280+
const transaction = await aptos.transaction.build.simple({
281+
sender: alice.accountAddress,
282+
data: {
283+
function: "0x1::container::store",
284+
functionArguments: [
285+
{ value: "42" } // Box<u64> struct - type parameter automatically substituted
286+
],
287+
},
288+
});
289+
290+
// Example 6: Option type (dual format support)
291+
// Vector format (backward compatible):
292+
functionArguments: [[]]; // None
293+
functionArguments: [[42]]; // Some(42)
294+
295+
// Enum format (new standard):
296+
functionArguments: [{ None: {} }];
297+
functionArguments: [{ Some: { "0": "42" } }];
298+
```
299+
300+
**Features:**
301+
- Automatic type inference from function ABI
302+
- Support for nested structs/enums (up to 7 levels deep)
303+
- Generic type parameter substitution (T0, T1, etc.)
304+
- All Move primitive types (bool, u8-u256, i8-i256, address)
305+
- Special framework types (String, Object<T>, Option<T>)
306+
- Module ABI caching for performance
307+
308+
**Breaking Change Note:**
309+
Argument conversion functions are now async to support fetching module ABIs. This is a low-impact change since top-level transaction building functions were already async.
310+
225311
## Troubleshooting
226312

227313
If you see an import error when you do this:

0 commit comments

Comments
 (0)