aptos-tsgen
uses json output from jsongen
to generate TypeScript interface for Move modules.
Steps:
- clone and build the
jsongen
branch of move-jsongen - Find the
move
binary built undertarget/debug/
- From inside your move project's directory (where
Move.toml
exists), run this command:path/to/target/debug/move package build --json
- This step generates json interface descriptors for your Move modules
- From one of your typescript projects:
yarn add @manahippo/aptos-tsgen
yarn aptos-tsgen src/generated path/to/generated/json/dir
- Note that path to generated json dir is usually, in the move project,
build/MODULE_NAME/json
I'll add a full demo with the required steps in a bit...
Move source code:
address 0x1234 {
module TestModule {
use Std::Signer;
use Std::ASCII;
use Std::FixedPoint32;
const SOME_ERROR:u64 = 1;
struct AccountInfo has key {
name: String,
age: u8,
balance: u64,
some_index: FixedPoint32,
}
public(script) fun register(account: &signer, name: vector<u8>, age: u8, balance: u64, some_index: u64) {
let account_info = AccountInfo{
name: name,
age: age,
balance: balance,
some_index: FixedPoint32 {value: some_index},
};
let signer_addr = Signer::address_of(account);
assert!(!exists<AccountInfo>(signer_addr), SOME_ERROR);
move_to(account, account_info);
}
}
}
Output from jsongen
:
{
"address": "0x1234",
"module": "TestModule",
"constants": [
{ "name": "SOME_ERROR", "type": "u64", "value": "1" }
],
"structs": [
{
"name": "AccountInfo",
"abilities": ["key"],
"type_params": [],
"fields": [
{ "name": "name", "type": "0x1::ASCII::String" },
{ "name": "age", "type": "u8" },
{ "name": "balance", "type": "u64" },
{ "name": "some_index", "type": "0x1::FixedPoint32::FixedPoint32" }
]
}
],
"script_functions": [
{
"name": "register",
"type_params": [],
"params": [
{ "name": "account", "type": "&signer" },
{ "name": "name", "type": "vector<u8>" },
{ "name": "age", "type": "u8" },
{ "name": "balance", "type": "u64" },
{ "name": "some_index", "type": "u64" }
]
}
]
}
Output from aptos-tsgen
:
import HexString from "aptos";
import bigInt from "big-integer";
import TypeParamDeclType from "@hippospace/aptos-tsgen";
import FieldDeclType from "@hippospace/aptos-tsgen";
import parseTypeTag from "@hippospace/aptos-tsgen";
import TypeTag from "@hippospace/aptos-tsgen";
import AptosParserRepo from "@hippospace/aptos-tsgen";
import parseStructProto from "@hippospace/aptos-tsgen";
import AptosClient from "aptos";
import AptosAccount from "aptos";
import * as X0x1 from "../../X0x1";
export const moduleAddress = new HexString("0x1234");
export const moduleName = "TestModule";
export const SOME_ERROR: bigInt.BigInteger = bigInt("1");
export class AccountInfo {
static moduleAddress = moduleAddress;
static moduleName = moduleName;
static structName: string = "AccountInfo";
static typeParameters: TypeParamDeclType[] = [
];
static fields: FieldDeclType[] = [
{name: name, typeTag: parseTypeTag("0x1::ASCII::String")},
{name: age, typeTag: parseTypeTag("u8")},
{name: balance, typeTag: parseTypeTag("u64")},
{name: some_index, typeTag: parseTypeTag("0x1::FixedPoint32::FixedPoint32")}
];
name: string;
age: number;
balance: bigInt.BigInteger;
some_index: X0x1.FixedPoint32.FixedPoint32;
constructor(proto: any, public typeTag: TypeTag) {
this.name = proto['name'] as string;
this.age = proto['age'] as number;
this.balance = proto['balance'] as bigInt.BigInteger;
this.some_index = proto['some_index'] as X0x1.FixedPoint32.FixedPoint32;
}
static AccountInfoParser(data:any, typeTag: TypeTag, repo: AptosParserRepo) : AccountInfo {
const proto = parseStructProto(data, typeTag, repo, AccountInfo);
return new AccountInfo(proto, typeTag);
}
}
export async function register(
client: AptosClient,
account: AptosAccount,
name: number[],
age: number,
balance: bigInt.BigInteger,
some_index: bigInt.BigInteger,
typeParams: TypeTag[],
) {
const typeParamStrings = typeParams.map(t=>getTypeTagFullname(t));
return sendAndWait(
client,
account,
"0x1234::TestModule::register",
typeParamStrings,
[
HexString.fromUintArray(new Uint8Array(name)).hex(),
age,
balance.toString(),
some_index.toString(),
]
);
}
Here's how we map Aptos' native types to TypeScript types:
bool
toboolean
u8
tonumber
u64
toBigInteger
u128
toBigInteger
address
toHexString
Std::ASCII::String
tostring
Std::FixedPoint32::FixedPoint32
toDecimal
vector<u8>
tonumber[]
vector<T>
toT[]
struct
toclass
struct A<T1,T2>
toclass A
We only support named constants of type bool
, u8
, u64
, u128
, address
at the module-level.