@typemove/sui 2.0.0 → 2.0.1

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 (68) hide show
  1. package/dist/esm/builtin/0x1.d.ts +1030 -0
  2. package/dist/esm/builtin/0x1.d.ts.map +1 -0
  3. package/dist/esm/builtin/0x1.js +7799 -0
  4. package/dist/esm/builtin/0x1.js.map +1 -0
  5. package/dist/esm/builtin/0x2.d.ts +4766 -0
  6. package/dist/esm/builtin/0x2.d.ts.map +1 -0
  7. package/dist/esm/builtin/0x2.js +23180 -0
  8. package/dist/esm/builtin/0x2.js.map +1 -0
  9. package/dist/esm/builtin/0x3.d.ts +1964 -0
  10. package/dist/esm/builtin/0x3.d.ts.map +1 -0
  11. package/dist/esm/builtin/0x3.js +7606 -0
  12. package/dist/esm/builtin/0x3.js.map +1 -0
  13. package/dist/esm/builtin/index.d.ts +4 -0
  14. package/dist/esm/builtin/index.d.ts.map +1 -0
  15. package/dist/esm/builtin/index.js +7 -0
  16. package/dist/esm/builtin/index.js.map +1 -0
  17. package/dist/esm/codegen/codegen.d.ts +20 -0
  18. package/dist/esm/codegen/codegen.d.ts.map +1 -0
  19. package/dist/esm/codegen/codegen.js +247 -0
  20. package/dist/esm/codegen/codegen.js.map +1 -0
  21. package/dist/esm/codegen/index.d.ts +2 -0
  22. package/dist/esm/codegen/index.d.ts.map +1 -0
  23. package/dist/esm/codegen/index.js +2 -0
  24. package/dist/esm/codegen/index.js.map +1 -0
  25. package/dist/esm/codegen/run.d.ts +3 -0
  26. package/dist/esm/codegen/run.d.ts.map +1 -0
  27. package/dist/esm/codegen/run.js.map +1 -0
  28. package/dist/esm/index.d.ts +5 -0
  29. package/dist/esm/index.d.ts.map +1 -0
  30. package/dist/esm/index.js +5 -0
  31. package/dist/esm/index.js.map +1 -0
  32. package/dist/esm/models.d.ts +21 -0
  33. package/dist/esm/models.d.ts.map +1 -0
  34. package/dist/esm/models.js +2 -0
  35. package/dist/esm/models.js.map +1 -0
  36. package/dist/esm/move-coder.d.ts +28 -0
  37. package/dist/esm/move-coder.d.ts.map +1 -0
  38. package/dist/esm/move-coder.js +311 -0
  39. package/dist/esm/move-coder.js.map +1 -0
  40. package/dist/esm/sui-chain-adapter.d.ts +28 -0
  41. package/dist/esm/sui-chain-adapter.d.ts.map +1 -0
  42. package/dist/esm/sui-chain-adapter.js +109 -0
  43. package/dist/esm/sui-chain-adapter.js.map +1 -0
  44. package/dist/esm/to-internal.d.ts +6 -0
  45. package/dist/esm/to-internal.d.ts.map +1 -0
  46. package/dist/esm/to-internal.js +170 -0
  47. package/dist/esm/to-internal.js.map +1 -0
  48. package/dist/esm/transaction.d.ts +15 -0
  49. package/dist/esm/transaction.d.ts.map +1 -0
  50. package/dist/esm/transaction.js +83 -0
  51. package/dist/esm/transaction.js.map +1 -0
  52. package/package.json +6 -6
  53. package/src/abis/0x1.json +9096 -0
  54. package/src/abis/0x2.json +38512 -0
  55. package/src/abis/0x3.json +14755 -0
  56. package/src/builtin/0x1.ts +10657 -0
  57. package/src/builtin/0x2.ts +33567 -0
  58. package/src/builtin/0x3.ts +11437 -0
  59. package/src/builtin/index.ts +6 -0
  60. package/src/codegen/codegen.ts +292 -0
  61. package/src/codegen/index.ts +1 -0
  62. package/src/codegen/run.ts +57 -0
  63. package/src/index.ts +13 -0
  64. package/src/models.ts +32 -0
  65. package/src/move-coder.ts +364 -0
  66. package/src/sui-chain-adapter.ts +142 -0
  67. package/src/to-internal.ts +201 -0
  68. package/src/transaction.ts +127 -0
@@ -0,0 +1,6 @@
1
+ /* Autogenerated file. Do not edit manually. */
2
+ /* tslint:disable */
3
+ /* eslint-disable */
4
+ export * as _0x1 from './0x1.js'
5
+ export * as _0x2 from './0x2.js'
6
+ export * as _0x3 from './0x3.js'
@@ -0,0 +1,292 @@
1
+ import * as fs from 'fs'
2
+ import chalk from 'chalk'
3
+ import {
4
+ InternalMoveModule,
5
+ InternalMoveStruct,
6
+ structQname,
7
+ InternalMoveFunction,
8
+ InternalMoveFunctionVisibility,
9
+ normalizeToJSName,
10
+ camel
11
+ } from '@typemove/move'
12
+ import { AbstractCodegen } from '@typemove/move/codegen'
13
+ import { join } from 'path'
14
+ import {
15
+ SuiChainAdapter,
16
+ ModuleWithAddress,
17
+ getGrpcClient,
18
+ SuiEventInput,
19
+ SuiMoveObjectInput
20
+ } from '../sui-chain-adapter.js'
21
+
22
+ export async function codegen(
23
+ abisDir: string,
24
+ outDir = join('src', 'types', 'sui'),
25
+ endpoint: string,
26
+ genExample = false,
27
+ builtin = false
28
+ ) {
29
+ if (!fs.existsSync(abisDir)) {
30
+ console.error(chalk.red(`ABIs directory ${abisDir} does not exist`))
31
+ return 0
32
+ }
33
+ try {
34
+ const gen = new SuiCodegen(endpoint)
35
+ const numFiles = await gen.generate(abisDir, outDir, builtin)
36
+ if (numFiles > 0) {
37
+ console.log(chalk.green(`Generated for ${numFiles} accounts for Sui to ${outDir}`))
38
+ } else {
39
+ console.error(chalk.red(`No account found`))
40
+ }
41
+ return numFiles
42
+ } catch (e) {
43
+ console.error(chalk.red(`Failed to generate for ${abisDir}, please check if ABI json files are valid`))
44
+ console.log(e)
45
+ return 0
46
+ }
47
+ }
48
+
49
+ export class SuiCodegen extends AbstractCodegen<ModuleWithAddress, SuiEventInput | SuiMoveObjectInput> {
50
+ ADDRESS_TYPE = 'string'
51
+ SYSTEM_PACKAGE = '@typemove/sui'
52
+ PREFIX = 'Sui'
53
+ PAYLOAD_OPTIONAL = true
54
+
55
+ constructor(endpoint: string) {
56
+ super(new SuiChainAdapter(getGrpcClient(endpoint)))
57
+ }
58
+
59
+ readModulesFile(fullPath: string) {
60
+ // Cached ABI is now an array of { address, module } produced by
61
+ // SuiChainAdapter.fetchModules / codegen run.ts. Just pass it through.
62
+ return super.readModulesFile(fullPath)
63
+ }
64
+
65
+ generateStructs(module: InternalMoveModule, struct: InternalMoveStruct, events: Set<string>): string {
66
+ let content = ''
67
+ switch (structQname(module, struct)) {
68
+ // TODO they should still have module code generated
69
+ case '0x1::ascii::Char':
70
+ case '0x1::ascii::String':
71
+ case '0x2::object::ID':
72
+ content += `export type ${struct.name} = string`
73
+ break
74
+ case '0x2::coin::Coin':
75
+ content += `export type ${struct.name}<T> = string`
76
+ break
77
+ case '0x2::balance::Balance':
78
+ content += `export type ${struct.name}<T> = bigint`
79
+ break
80
+ case '0x1::option::Option':
81
+ content += `export type Option<T> = T | undefined`
82
+ break
83
+ }
84
+ return content + super.generateStructs(module, struct, events, content !== '')
85
+ }
86
+
87
+ generateForEvents(module: InternalMoveModule, struct: InternalMoveStruct): string {
88
+ switch (structQname(module, struct)) {
89
+ case '0x1::ascii::Char':
90
+ case '0x1::ascii::String':
91
+ case '0x2::object::ID':
92
+ case '0x2::coin::Coin':
93
+ case '0x1::option::Option':
94
+ case '0x2::balance::Balance':
95
+ return ''
96
+ }
97
+ return super.generateForEvents(module, struct)
98
+ }
99
+
100
+ protected generateExtra(address: string | undefined, module: InternalMoveModule): string {
101
+ const funcs = module.exposedFunctions.map((f) =>
102
+ this.generateBuilderForFunction(address || module.address, module, f)
103
+ )
104
+
105
+ const viewFuncs = module.exposedFunctions.map((f) => this.generateViewFunction(module, f))
106
+
107
+ return `
108
+ export namespace builder {
109
+ ${funcs.join('\n')}
110
+ }
111
+ export namespace view {
112
+ ${viewFuncs.join('\n')}
113
+ }
114
+ `
115
+ }
116
+
117
+ private generateArgs(module: InternalMoveModule, func: InternalMoveFunction, isView: boolean) {
118
+ const args = []
119
+ const argsLen = func.params.length
120
+ for (const [idx, arg] of func.params.entries()) {
121
+ if (idx === argsLen - 1 && arg.qname === '0x2::tx_context::TxContext') {
122
+ // no op
123
+ } else if (arg.reference) {
124
+ args.push({
125
+ paramType: isView ? this.ADDRESS_TYPE : `${this.ADDRESS_TYPE} | TransactionObjectArgument`,
126
+ callValue: `_args.push(transactionArgumentOrObject(args[${idx}], tx))`
127
+ })
128
+ } else if (arg.isVector()) {
129
+ // TODO fix pure vector
130
+ args.push({
131
+ paramType: isView
132
+ ? `${this.ADDRESS_TYPE}[]`
133
+ : `(${this.ADDRESS_TYPE} | TransactionObjectArgument)[] | TransactionArgument`,
134
+ callValue: `_args.push(transactionArgumentOrVec(args[${idx}], tx))`
135
+ })
136
+ } else {
137
+ // Handle pure type
138
+ let pureFunction = ''
139
+ const paramType = isView
140
+ ? this.generateTypeForDescriptor(arg, module.address)
141
+ : `${this.generateTypeForDescriptor(arg, module.address)} | TransactionArgument`
142
+
143
+ switch (arg.qname.toLowerCase()) {
144
+ case 'u8':
145
+ pureFunction = `transactionArgumentOrPureU8`
146
+ break
147
+ case 'u16':
148
+ pureFunction = `transactionArgumentOrPureU16`
149
+ break
150
+ case 'u32':
151
+ pureFunction = `transactionArgumentOrPureU32`
152
+ break
153
+ case 'u64':
154
+ pureFunction = `transactionArgumentOrPureU64`
155
+ break
156
+ case 'u128':
157
+ pureFunction = `transactionArgumentOrPureU128`
158
+ break
159
+ case 'u256':
160
+ pureFunction = `transactionArgumentOrPureU256`
161
+ break
162
+ case 'bool':
163
+ pureFunction = `transactionArgumentOrPureBool`
164
+ break
165
+ case 'string':
166
+ pureFunction = `transactionArgumentOrPureString`
167
+ break
168
+ case 'address':
169
+ pureFunction = `transactionArgumentOrPureAddress`
170
+ break
171
+ // case 'vector':
172
+ // case 'option':
173
+ default:
174
+ pureFunction = `transactionArgumentOrPure`
175
+ // paramType = 'TransactionArgument'
176
+ }
177
+ const callValue = pureFunction ? `_args.push(${pureFunction}(args[${idx}], tx))` : `_args.push(args[${idx}])`
178
+
179
+ args.push({
180
+ paramType,
181
+ callValue
182
+ })
183
+ }
184
+ }
185
+ return args
186
+ }
187
+
188
+ protected generateViewFunction(module: InternalMoveModule, func: InternalMoveFunction): string {
189
+ if (func.visibility === InternalMoveFunctionVisibility.PRIVATE) {
190
+ return ''
191
+ }
192
+ const genericString = this.generateFunctionTypeParameters(func)
193
+
194
+ const typeParamArg = func.typeParams
195
+ .map((v, idx) => {
196
+ return `TypeDescriptor<T${idx}> | string`
197
+ })
198
+ .join(',')
199
+
200
+ const args = this.generateArgs(module, func, true)
201
+ const returnType = `${this.generateFunctionReturnTypeParameters(func, module.address)}`
202
+
203
+ // gRPC simulateTransaction's CommandOutput only carries BCS bytes (no type
204
+ // string the way devInspectTransactionBlock did), so we capture the
205
+ // declared Move return-type signatures at codegen time and pass them
206
+ // through to the decoder at runtime.
207
+ const returnSignaturesLiteral = JSON.stringify(func.return.map((t) => t.getSignature()))
208
+
209
+ return `export async function ${camel(normalizeToJSName(func.name))}${genericString}(
210
+ client: SuiGrpcClient,
211
+ args: [${args.map((a) => a.paramType).join(',')}],
212
+ ${
213
+ typeParamArg.length > 0 ? `typeArguments: [${typeParamArg}]` : ``
214
+ } ): Promise<TypedSimulateResults<${returnType}>> {
215
+ const tx = new Transaction()
216
+ builder.${camel(normalizeToJSName(func.name))}(tx, args ${typeParamArg.length > 0 ? `, typeArguments` : ''})
217
+ // checksEnabled: false matches the old devInspectTransactionBlock
218
+ // semantics — allow simulating view calls without validating object
219
+ // ownership or signer, which view callers obviously can't satisfy.
220
+ const simulateRes = await client.simulateTransaction({
221
+ transaction: tx,
222
+ sender: ZERO_ADDRESS,
223
+ include: { commandResults: true },
224
+ checksEnabled: false
225
+ } as any)
226
+
227
+ return (await getMoveCoder(client)).decodeSimulateResult<${returnType}>(simulateRes, ${returnSignaturesLiteral}${typeParamArg.length > 0 ? `, typeArguments` : ''})
228
+ }`
229
+ }
230
+
231
+ protected generateBuilderForFunction(
232
+ address: string,
233
+ module: InternalMoveModule,
234
+ func: InternalMoveFunction
235
+ ): string {
236
+ if (func.visibility === InternalMoveFunctionVisibility.PRIVATE && func.isEntry !== true) {
237
+ return ''
238
+ }
239
+
240
+ const args = this.generateArgs(module, func, false)
241
+
242
+ const genericString = this.generateFunctionTypeParameters(func)
243
+
244
+ const typeParamArg = func.typeParams
245
+ .map((v, idx) => {
246
+ return `TypeDescriptor<T${idx}> | string`
247
+ })
248
+ .join(',')
249
+ const typeParamToString = func.typeParams
250
+ .map((v, idx) => {
251
+ return `typeof typeArguments[${idx}] === 'string' ? typeArguments[${idx}] : typeArguments[${idx}].getSignature()`
252
+ })
253
+ .join(',')
254
+
255
+ return `export function ${camel(normalizeToJSName(func.name))}${genericString}(tx: Transaction,
256
+ args: [${args.map((a) => a.paramType).join(',')}],
257
+ ${typeParamArg.length > 0 ? `typeArguments: [${typeParamArg}]` : ``} ):
258
+ TransactionArgument & [ ${'TransactionArgument,'.repeat(args.length)} ] {
259
+ const _args: any[] = []
260
+ ${args.map((a) => a.callValue).join('\n')}
261
+
262
+ // @ts-ignore
263
+ return tx.moveCall({
264
+ target: "${address}::${module.name}::${func.name}",
265
+ arguments: _args,
266
+ ${typeParamArg.length > 0 ? `typeArguments: [${typeParamToString}]` : ``}
267
+ })
268
+ }`
269
+ }
270
+
271
+ generateImports(): string {
272
+ return `
273
+ ${super.generateImports()}
274
+ import { ZERO_ADDRESS, TypedSimulateResults, getMoveCoder } from '@typemove/sui'
275
+ import { Transaction, TransactionArgument, TransactionObjectArgument } from '@mysten/sui/transactions'
276
+ import { SuiGrpcClient } from '@mysten/sui/grpc'
277
+ import { transactionArgumentOrObject,
278
+ transactionArgumentOrVec,
279
+ transactionArgumentOrPure,
280
+ transactionArgumentOrPureU8,
281
+ transactionArgumentOrPureU16,
282
+ transactionArgumentOrPureU32,
283
+ transactionArgumentOrPureU64,
284
+ transactionArgumentOrPureU128,
285
+ transactionArgumentOrPureU256,
286
+ transactionArgumentOrPureBool,
287
+ transactionArgumentOrPureString,
288
+ transactionArgumentOrPureAddress,
289
+ } from '@typemove/sui'
290
+ `
291
+ }
292
+ }
@@ -0,0 +1 @@
1
+ export * from './codegen.js'
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { codegen } from './codegen.js'
4
+ import { Command } from 'commander'
5
+ import { createRequire } from 'module'
6
+ import fs from 'fs'
7
+ import path from 'path'
8
+ import { getGrpcClient, getGrpcFullnodeUrl, SuiChainAdapter } from '../sui-chain-adapter.js'
9
+ const require = createRequire(import.meta.url)
10
+ let pkg = undefined
11
+ try {
12
+ pkg = require('../../package.json')
13
+ } catch (e) {
14
+ pkg = require('../../../package.json')
15
+ }
16
+
17
+ const program = new Command()
18
+ program
19
+ .name('typemove-sui')
20
+ .description('CLI to generate typescript types from SUI ABIs')
21
+ .showHelpAfterError()
22
+ .version(pkg.version)
23
+ .argument('<location>', 'Directory of ABI json files or address of account to generate types for')
24
+ .option('-a, --abi-dir <dir>', 'Directory to store downloaded ABI. Only useful if <location> is address', './abis')
25
+ .option('-t, --target-dir <dir>', 'Directory to output generated files', './types')
26
+ .option(
27
+ '-n, --network <mainnet|testnet|$url>',
28
+ 'Network to use, could be either "mainnet", "testnet" or any node URL',
29
+ 'mainnet'
30
+ )
31
+ .action(async (location, options) => {
32
+ let endpoint = options.network
33
+ if (endpoint === 'mainnet' || endpoint === 'testnet' || endpoint === 'devnet' || endpoint === 'localnet') {
34
+ endpoint = getGrpcFullnodeUrl(endpoint)
35
+ }
36
+
37
+ const suiClient = getGrpcClient(endpoint)
38
+
39
+ let abisDir = location
40
+ if (location.startsWith('0x')) {
41
+ const abiAddress = abisDir
42
+ // Fetch via adapter so the on-disk shape matches what codegen reads back.
43
+ // ABI is serialized as { address, module }[] — the address is included
44
+ // because the proto Module doesn't carry the package id per entry.
45
+ const abi = await new SuiChainAdapter(suiClient).fetchModules(abiAddress)
46
+ abisDir = options.abiDir
47
+ if (!fs.existsSync(abisDir)) {
48
+ fs.mkdirSync(abisDir, { recursive: true })
49
+ }
50
+ fs.writeFileSync(path.join(abisDir, abiAddress + '.json'), JSON.stringify(abi, null, 2))
51
+ }
52
+
53
+ const num = await codegen(abisDir, options.targetDir, endpoint, true)
54
+ process.exit(num == 0 ? 1 : 0)
55
+ })
56
+
57
+ program.parse()
package/src/index.ts ADDED
@@ -0,0 +1,13 @@
1
+ export * from './models.js'
2
+ export * from './transaction.js'
3
+
4
+ export { MoveCoder, defaultMoveCoder, getMoveCoder } from './move-coder.js'
5
+ export {
6
+ SuiChainAdapter,
7
+ type ModuleWithAddress,
8
+ type SuiEventInput,
9
+ type SuiMoveObjectInput,
10
+ inferNetworkFromUrl,
11
+ getGrpcClient,
12
+ getGrpcFullnodeUrl
13
+ } from './sui-chain-adapter.js'
package/src/models.ts ADDED
@@ -0,0 +1,32 @@
1
+ import type { SuiClientTypes } from '@mysten/sui/client'
2
+ import type { GrpcTypes } from '@mysten/sui/grpc'
3
+ import { DecodedStruct } from '@typemove/move'
4
+
5
+ export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000000000000000000000000000'
6
+
7
+ // Decoder input/output types are now keyed on @mysten/sui/client's unified
8
+ // SuiClientTypes shapes (which both jsonRpc and gRPC clients implement) plus
9
+ // gRPC proto types for the transaction-side shapes that don't have a
10
+ // transport-agnostic equivalent. No `@mysten/sui/jsonRpc` import remains.
11
+ export type TypedEventInstance<T> = DecodedStruct<SuiClientTypes.Event, T>
12
+ export type TypedSuiMoveObject<T> = DecodedStruct<SuiClientTypes.Object<{ json: true }>, T>
13
+
14
+ export type TypedFunctionPayload<T extends Array<any>> = GrpcTypes.MoveCall & {
15
+ /**
16
+ * decoded argument data using ABI, undefined if there is decoding error, usually because the ABI/data mismatch
17
+ */
18
+ arguments_decoded: T
19
+ }
20
+
21
+ // Result wrapper for SuiGrpcClient.simulateTransaction return values. Replaces
22
+ // the old TypedDevInspectResults that was tied to JSON-RPC's DevInspectResults.
23
+ // The raw simulate response shape is intentionally widened to `any` here
24
+ // because the underlying SDK types are heavily generic and we only need the
25
+ // `commandResults` slice; we pass the original result through unchanged plus a
26
+ // `results_decoded` field populated by `MoveCoder.decodeSimulateResult`.
27
+ export type TypedSimulateResults<T extends Array<any>> = {
28
+ /**
29
+ * Decoded return values using ABI, undefined if there is decoding error, usually because the ABI/data mismatch
30
+ */
31
+ results_decoded?: T
32
+ } & Record<string, any>