@sentio/sdk 2.4.0 → 2.5.0-rc.2

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 (170) hide show
  1. package/lib/aptos/aptos-processor.d.ts +1 -1
  2. package/lib/aptos/aptos-processor.js +1 -1
  3. package/lib/aptos/aptos-processor.js.map +1 -1
  4. package/lib/aptos/builtin/0x1.d.ts +16 -177
  5. package/lib/aptos/builtin/0x1.js +56 -538
  6. package/lib/aptos/builtin/0x1.js.map +1 -1
  7. package/lib/aptos/builtin/0x3.d.ts +2 -13
  8. package/lib/aptos/builtin/0x3.js +20 -48
  9. package/lib/aptos/builtin/0x3.js.map +1 -1
  10. package/lib/aptos/codegen/codegen.d.ts +0 -20
  11. package/lib/aptos/codegen/codegen.js +37 -357
  12. package/lib/aptos/codegen/codegen.js.map +1 -1
  13. package/lib/aptos/{types.test.d.ts → codegen/types.test.d.ts} +0 -0
  14. package/lib/aptos/codegen/types.test.js.map +1 -0
  15. package/lib/aptos/models.d.ts +0 -8
  16. package/lib/aptos/models.js.map +1 -1
  17. package/lib/aptos/move-coder.d.ts +4 -13
  18. package/lib/aptos/move-coder.js +13 -124
  19. package/lib/aptos/move-coder.js.map +1 -1
  20. package/lib/aptos/move-types.d.ts +6 -0
  21. package/lib/aptos/move-types.js +52 -1
  22. package/lib/aptos/move-types.js.map +1 -1
  23. package/lib/aptos/tests/souffl3.js +1 -1
  24. package/lib/aptos/tests/souffl3.js.map +1 -1
  25. package/lib/aptos/tests/types/reserved.d.ts +2 -8
  26. package/lib/aptos/tests/types/reserved.js +11 -24
  27. package/lib/aptos/tests/types/reserved.js.map +1 -1
  28. package/lib/aptos/tests/types/soffl3.d.ts +2 -14
  29. package/lib/aptos/tests/types/soffl3.js +15 -48
  30. package/lib/aptos/tests/types/soffl3.js.map +1 -1
  31. package/lib/aptos/tests/types/souffle.d.ts +2 -8
  32. package/lib/aptos/tests/types/souffle.js +11 -24
  33. package/lib/aptos/tests/types/souffle.js.map +1 -1
  34. package/lib/aptos/utils.d.ts +2 -7
  35. package/lib/aptos/utils.js +2 -15
  36. package/lib/aptos/utils.js.map +1 -1
  37. package/lib/eth/bind-options.js +6 -0
  38. package/lib/eth/bind-options.js.map +1 -1
  39. package/lib/eth/tests/codegen.test.js.map +1 -1
  40. package/lib/eth/tests/erc20.js +1 -1
  41. package/lib/eth/tests/erc20.js.map +1 -1
  42. package/lib/eth/tests/logger.test.js.map +1 -1
  43. package/lib/move/abstract-codegen.d.ts +44 -0
  44. package/lib/move/abstract-codegen.js +341 -0
  45. package/lib/move/abstract-codegen.js.map +1 -0
  46. package/lib/move/abstract-move-coder.d.ts +24 -0
  47. package/lib/move/abstract-move-coder.js +141 -0
  48. package/lib/move/abstract-move-coder.js.map +1 -0
  49. package/lib/move/account.d.ts +18 -0
  50. package/lib/{aptos/codegen/typegen.js → move/account.js} +20 -82
  51. package/lib/move/account.js.map +1 -0
  52. package/lib/move/filter.d.ts +25 -0
  53. package/lib/move/filter.js +11 -0
  54. package/lib/move/filter.js.map +1 -0
  55. package/lib/move/index.d.ts +5 -25
  56. package/lib/move/index.js +5 -10
  57. package/lib/move/index.js.map +1 -1
  58. package/lib/move/neutral-models.d.ts +34 -0
  59. package/lib/move/neutral-models.js +7 -0
  60. package/lib/move/neutral-models.js.map +1 -0
  61. package/lib/move/ts-type.d.ts +2 -0
  62. package/lib/move/ts-type.js +77 -0
  63. package/lib/move/ts-type.js.map +1 -0
  64. package/lib/{aptos/codegen/typegen.test.d.ts → move/ts-type.test.d.ts} +0 -0
  65. package/lib/move/ts-type.test.js.map +1 -0
  66. package/lib/{aptos → move}/types.d.ts +1 -0
  67. package/lib/{aptos → move}/types.js +26 -3
  68. package/lib/move/types.js.map +1 -0
  69. package/lib/move/utils.d.ts +9 -0
  70. package/lib/move/utils.js +20 -0
  71. package/lib/move/utils.js.map +1 -0
  72. package/lib/sui/builtin/0x1.d.ts +114 -0
  73. package/lib/sui/builtin/0x1.js +174 -0
  74. package/lib/sui/builtin/0x1.js.map +1 -0
  75. package/lib/sui/builtin/0x2.d.ts +1047 -0
  76. package/lib/sui/builtin/0x2.js +1295 -0
  77. package/lib/sui/builtin/0x2.js.map +1 -0
  78. package/lib/sui/builtin/index.d.ts +2 -0
  79. package/lib/sui/builtin/index.js +6 -0
  80. package/lib/sui/builtin/index.js.map +1 -0
  81. package/lib/sui/codegen/codegen.d.ts +1 -0
  82. package/lib/sui/codegen/codegen.js +61 -0
  83. package/lib/sui/codegen/codegen.js.map +1 -0
  84. package/lib/sui/codegen/index.d.ts +1 -0
  85. package/lib/sui/codegen/index.js +2 -0
  86. package/lib/sui/codegen/index.js.map +1 -0
  87. package/lib/sui/codegen/run.d.ts +1 -0
  88. package/lib/sui/codegen/run.js +12 -0
  89. package/lib/sui/codegen/run.js.map +1 -0
  90. package/lib/sui/index.d.ts +2 -0
  91. package/lib/sui/index.js +1 -0
  92. package/lib/sui/index.js.map +1 -1
  93. package/lib/sui/models.d.ts +7 -1
  94. package/lib/sui/models.js +0 -23
  95. package/lib/sui/models.js.map +1 -1
  96. package/lib/sui/move-coder.d.ts +11 -0
  97. package/lib/sui/move-coder.js +53 -0
  98. package/lib/sui/move-coder.js.map +1 -0
  99. package/lib/sui/move-types.d.ts +9 -0
  100. package/lib/sui/move-types.js +81 -0
  101. package/lib/sui/move-types.js.map +1 -0
  102. package/lib/sui/sui-processor.js +3 -3
  103. package/lib/sui/sui-processor.js.map +1 -1
  104. package/lib/sui/tests/sui.test.js.map +1 -1
  105. package/lib/sui/tests/types/index.d.ts +1 -0
  106. package/lib/sui/tests/types/index.js +5 -0
  107. package/lib/sui/tests/types/index.js.map +1 -0
  108. package/lib/sui/tests/types/testnet/index.d.ts +1 -0
  109. package/lib/sui/tests/types/testnet/index.js +5 -0
  110. package/lib/sui/tests/types/testnet/index.js.map +1 -0
  111. package/lib/sui/tests/types/testnet/swap.d.ts +249 -0
  112. package/lib/sui/tests/types/testnet/swap.js +310 -0
  113. package/lib/sui/tests/types/testnet/swap.js.map +1 -0
  114. package/lib/testing/aptos-facet.js +1 -1
  115. package/lib/testing/aptos-facet.js.map +1 -1
  116. package/lib/testing/sui-facet.js +3 -2
  117. package/lib/testing/sui-facet.js.map +1 -1
  118. package/package.json +8 -5
  119. package/src/aptos/aptos-processor.ts +1 -1
  120. package/src/aptos/builtin/0x1.ts +70 -652
  121. package/src/aptos/builtin/0x3.ts +24 -59
  122. package/src/aptos/codegen/codegen.ts +35 -421
  123. package/src/aptos/models.ts +0 -10
  124. package/src/aptos/move-coder.ts +16 -150
  125. package/src/aptos/move-types.ts +62 -0
  126. package/src/aptos/tests/souffl3.ts +1 -1
  127. package/src/aptos/tests/types/reserved.ts +15 -30
  128. package/src/aptos/tests/types/soffl3.ts +19 -58
  129. package/src/aptos/tests/types/souffle.ts +15 -30
  130. package/src/aptos/utils.ts +3 -21
  131. package/src/eth/bind-options.ts +6 -0
  132. package/src/eth/tests/erc20.ts +1 -1
  133. package/src/move/abstract-codegen.ts +426 -0
  134. package/src/move/abstract-move-coder.ts +170 -0
  135. package/src/move/account.ts +96 -0
  136. package/src/move/filter.ts +33 -0
  137. package/src/move/index.ts +5 -33
  138. package/src/move/neutral-models.ts +45 -0
  139. package/src/move/ts-type.ts +86 -0
  140. package/src/{aptos → move}/types.ts +28 -3
  141. package/src/move/utils.ts +25 -0
  142. package/src/sui/abis/0x1.json +1729 -1733
  143. package/src/sui/abis/0x2.json +13279 -13283
  144. package/src/sui/builtin/0x1.ts +307 -0
  145. package/src/sui/builtin/0x2.ts +2578 -0
  146. package/src/sui/builtin/index.ts +5 -0
  147. package/src/sui/codegen/codegen.ts +71 -0
  148. package/src/sui/codegen/index.ts +1 -0
  149. package/src/sui/codegen/run.ts +13 -0
  150. package/src/sui/index.ts +4 -0
  151. package/src/sui/models.ts +7 -28
  152. package/src/sui/move-coder.ts +63 -0
  153. package/src/sui/move-types.ts +109 -0
  154. package/src/sui/sui-processor.ts +3 -3
  155. package/src/sui/tests/abis/testnet/swap.json +1752 -0
  156. package/src/sui/tests/types/index.ts +3 -0
  157. package/src/sui/tests/types/testnet/index.ts +4 -0
  158. package/src/sui/tests/types/testnet/swap.ts +698 -0
  159. package/src/testing/aptos-facet.ts +1 -1
  160. package/src/testing/sui-facet.ts +3 -2
  161. package/lib/aptos/codegen/typegen.d.ts +0 -18
  162. package/lib/aptos/codegen/typegen.js.map +0 -1
  163. package/lib/aptos/codegen/typegen.test.js.map +0 -1
  164. package/lib/aptos/types.js.map +0 -1
  165. package/lib/aptos/types.test.js.map +0 -1
  166. package/lib/jest.config.d.ts +0 -9
  167. package/lib/jest.config.js +0 -9
  168. package/lib/jest.config.js.map +0 -1
  169. package/src/aptos/codegen/typegen.ts +0 -165
  170. package/src/jest.config.ts +0 -8
@@ -1,21 +1,20 @@
1
1
  import * as fs from 'fs'
2
- import * as path from 'path'
3
- import { format } from 'prettier'
4
- import { MoveFunction, MoveModule, MoveModuleBytecode, MoveStruct } from '../move-types.js'
5
- import { AccountModulesImportInfo, AccountRegister, generateType, normalizeToJSName } from './typegen.js'
6
- import { getMeaningfulFunctionParams, isFrameworkAccount, moduleQname, SPLITTER } from '../utils.js'
2
+ import { MoveModuleBytecode, toNeutralModule } from '../move-types.js'
3
+ import { moduleQname, SPLITTER, TypeDescriptor } from '../../move/index.js'
7
4
  import chalk from 'chalk'
8
- import { AptosNetwork, getAptosChainName } from '../network.js'
9
- import { parseMoveType } from '../types.js'
5
+ import { AptosNetwork } from '../network.js'
10
6
  import { AptosClient } from 'aptos-sdk'
11
- import { camelCase } from 'lodash-es'
7
+ import { getMeaningfulFunctionParams } from '../utils.js'
8
+ import { NeutralMoveModule, NeutralMoveStruct } from '../../move/neutral-models.js'
9
+ import { AbstractCodegen } from '../../move/abstract-codegen.js'
12
10
 
13
11
  export async function codegen(abisDir: string, outDir = 'src/types/aptos') {
14
12
  if (!fs.existsSync(abisDir)) {
15
13
  return
16
14
  }
17
15
  console.log(chalk.green('Generated Types for Aptos'))
18
- await generate(abisDir, outDir)
16
+ const gen = new AptosCodegen()
17
+ await gen.generate(abisDir, outDir)
19
18
  }
20
19
 
21
20
  function getRpcEndpoint(network: AptosNetwork): string {
@@ -30,432 +29,47 @@ function getRpcClient(network: AptosNetwork): AptosClient {
30
29
  return new AptosClient(getRpcEndpoint(network))
31
30
  }
32
31
 
33
- async function generate(srcDir: string, outputDir: string) {
34
- await generateForNetwork(srcDir, outputDir, AptosNetwork.MAIN_NET)
35
- await generateForNetwork(path.join(srcDir, 'testnet'), path.join(outputDir, 'testnet'), AptosNetwork.TEST_NET)
36
- }
37
-
38
- async function generateForNetwork(srcDir: string, outputDir: string, network: AptosNetwork) {
39
- if (!fs.existsSync(srcDir)) {
40
- return
41
- }
42
- if (network === AptosNetwork.TEST_NET) {
43
- console.log('Found testnet directory, generate code for testnet modules')
44
- }
45
- const files = fs.readdirSync(srcDir)
46
- outputDir = path.resolve(outputDir)
47
- const outputs: OutputFile[] = []
48
-
49
- fs.mkdirSync(outputDir, { recursive: true })
50
-
51
- const loader = new AccountRegister()
52
-
53
- // when generating user code, don't need to generate framework account
54
- loader.accountImports.set('0x1', new AccountModulesImportInfo('0x1', '0x1'))
55
- loader.accountImports.set('0x2', new AccountModulesImportInfo('0x2', '0x2'))
56
- loader.accountImports.set('0x3', new AccountModulesImportInfo('0x3', '0x3'))
57
- const client = getRpcClient(network)
58
-
59
- for (const file of files) {
60
- if (!file.endsWith('.json')) {
61
- continue
62
- }
63
- const fullPath = path.resolve(srcDir, file)
64
- const modules = JSON.parse(fs.readFileSync(fullPath, 'utf-8'))
65
-
66
- for (const module of modules) {
67
- if (module.abi) {
68
- loader.register(module.abi, path.basename(file, '.json'))
69
- }
70
- }
71
- const codeGen = new AccountCodegen(loader, modules, {
72
- fileName: path.basename(file, '.json'),
73
- outputDir: outputDir,
74
- network,
75
- })
76
-
77
- outputs.push(...codeGen.generate())
78
- }
79
-
80
- while (loader.pendingAccounts.size > 0) {
81
- for (const account of loader.pendingAccounts) {
82
- console.log(`download dependent module for account ${account} at ${getAptosChainName(network)}`)
83
-
84
- try {
85
- const modules = await client.getAccountModules(account)
86
- fs.writeFileSync(path.resolve(srcDir, account + '.json'), JSON.stringify(modules, null, '\t'))
87
-
88
- for (const module of modules) {
89
- if (module.abi) {
90
- loader.register(module.abi, account)
91
- }
92
- }
93
- const codeGen = new AccountCodegen(loader, modules, {
94
- fileName: account,
95
- outputDir: outputDir,
96
- network,
97
- })
98
-
99
- outputs.push(...codeGen.generate())
100
- } catch (e) {
101
- console.error(
102
- chalk.red(
103
- 'Error downloading account module, check if you choose the right network,or download account modules manually into your director'
104
- )
105
- )
106
- console.error(e)
107
- process.exit(1)
108
- }
109
- }
110
- }
32
+ class AptosCodegen extends AbstractCodegen<MoveModuleBytecode[], AptosNetwork> {
33
+ ADDRESS_TYPE = 'Address'
34
+ MAIN_NET = AptosNetwork.MAIN_NET
35
+ TEST_NET = AptosNetwork.TEST_NET
36
+ PREFIX = 'Aptos'
111
37
 
112
- for (const output of outputs) {
113
- const content = format(output.fileContent, { parser: 'typescript' })
114
- fs.writeFileSync(path.join(outputDir, output.fileName), content)
38
+ async fetchModules(account: string, network: AptosNetwork): Promise<MoveModuleBytecode[]> {
39
+ const client = getRpcClient(network)
40
+ return await client.getAccountModules(account)
115
41
  }
116
42
 
117
- const rootFile = path.join(outputDir, 'index.ts')
118
- fs.writeFileSync(
119
- rootFile,
120
- `/* Autogenerated file. Do not edit manually. */
121
- /* tslint:disable */
122
- /* eslint-disable */
123
- `
124
- )
125
- for (const output of outputs) {
126
- const parsed = path.parse(output.fileName)
127
- const content = `export * as _${parsed.name} from './${parsed.name}.js'\n`
128
- fs.appendFileSync(rootFile, content)
43
+ toNeutral(modules: MoveModuleBytecode[]): NeutralMoveModule[] {
44
+ return modules.flatMap((m) => (m.abi ? [toNeutralModule(m)] : []))
129
45
  }
130
- }
131
-
132
- interface OutputFile {
133
- fileName: string
134
- fileContent: string
135
- }
136
-
137
- interface Config {
138
- fileName: string
139
- outputDir: string
140
- network: AptosNetwork
141
- }
142
-
143
- export class AccountCodegen {
144
- modules: MoveModuleBytecode[]
145
- config: Config
146
- loader: AccountRegister
147
46
 
148
- constructor(loader: AccountRegister, modules: MoveModuleBytecode[], config: Config) {
149
- // const json = fs.readFileSync(config.srcFile, 'utf-8')
150
- this.modules = modules
151
- this.config = config
152
- this.loader = loader
47
+ getMeaningfulFunctionParams(params: TypeDescriptor[]): TypeDescriptor[] {
48
+ return getMeaningfulFunctionParams(params)
153
49
  }
154
50
 
155
- generate(): OutputFile[] {
156
- if (!this.modules) {
157
- return []
158
- }
159
- // const baseName = path.basename(this.config.fileName, '.json')
160
-
161
- let address: string | undefined
162
- for (const module of this.modules) {
163
- if (module.abi && module.abi.address) {
164
- address = module.abi.address
165
- }
166
- }
167
- if (!address) {
168
- return []
169
- }
170
-
171
- const imports = `
172
- import { CallFilter } from "@sentio/sdk/move"
173
- import {
174
- MoveCoder, AptosBindOptions, AptosBaseProcessor,
175
- TypedEventInstance, AptosNetwork, TypedEntryFunctionPayload,
176
- AptosContext } from "@sentio/sdk/aptos"
177
- import { MoveFetchConfig } from "@sentio/protos"
178
- import { Address, MoveModule } from "@sentio/sdk/aptos"
179
- `
180
-
181
- const dependedAccounts: string[] = []
182
-
183
- const moduleImports: string[] = []
184
-
185
- const info = this.loader.accountImports.get(address)
51
+ getEventStructs(module: NeutralMoveModule) {
52
+ const qname = moduleQname(module)
53
+ const structMap = new Map<string, NeutralMoveStruct>()
54
+ const eventMap = new Map<string, NeutralMoveStruct>()
186
55
 
187
- if (info) {
188
- for (const [account] of info.imports.entries()) {
189
- // Remap to user's filename if possible, TODO codepath not well tested
190
- const tsAccountModule = './' + (this.loader.accountImports.get(account)?.moduleName || account)
191
- if (isFrameworkAccount(account) && !isFrameworkAccount(address)) {
192
- // Decide where to find runtime library
193
- moduleImports.push(`import { _${account} } from "@sentio/sdk/aptos/builtin"`)
194
- } else {
195
- moduleImports.push(`import * as _${account} from "${tsAccountModule}.js"`)
196
- }
197
-
198
- dependedAccounts.push(account)
199
- }
56
+ for (const struct of module.structs) {
57
+ structMap.set(qname + SPLITTER + struct.name, struct)
200
58
  }
201
59
 
202
- const source = `
203
- /* Autogenerated file. Do not edit manually. */
204
- /* tslint:disable */
205
- /* eslint-disable */
206
-
207
- /* Generated modules for account ${address} */
208
-
209
- ${imports}
210
-
211
- ${moduleImports.join('\n')}
212
-
213
- ${this.modules.map((m) => generateModule(m, this.config.network)).join('\n')}
214
-
215
- export function loadAllTypes(_r: MoveCoder) {
216
- ${dependedAccounts.map((a) => `_${a}.loadAllTypes(_r)`).join('\n')}
217
-
218
- ${this.modules
219
- .map((m) => {
220
- if (m.abi) {
221
- return `_r.load(${normalizeToJSName(m.abi.name)}.ABI)`
60
+ for (const struct of module.structs) {
61
+ for (const field of struct.fields) {
62
+ const t = field.type
63
+ if (t.qname === '0x1::event::EventHandle') {
64
+ const event = t.typeArgs[0].qname
65
+ const eventStruct = structMap.get(event)
66
+ if (eventStruct) {
67
+ eventMap.set(event, eventStruct)
222
68
  }
223
- console.error('Find Module with empty ABI')
224
- return ''
225
- })
226
- .join('\n')}
227
- }
228
- ` // source
229
-
230
- return [
231
- {
232
- fileName: this.config.fileName + '.ts',
233
- fileContent: source,
234
- },
235
- ]
236
- }
237
- }
238
-
239
- function generateNetworkOption(network: AptosNetwork) {
240
- switch (network) {
241
- case AptosNetwork.TEST_NET:
242
- return 'TEST_NET'
243
- }
244
- return 'MAIN_NET'
245
- }
246
-
247
- function generateModule(moduleByteCode: MoveModuleBytecode, network: AptosNetwork) {
248
- if (!moduleByteCode.abi) {
249
- return ''
250
- }
251
- const module = moduleByteCode.abi
252
-
253
- const functions = module.exposed_functions.map((f) => generateOnEntryFunctions(module, f)).filter((s) => s !== '')
254
-
255
- const eventStructs = getEventStructs(module)
256
- const eventTypes = new Set(eventStructs.keys())
257
- const events = Array.from(eventStructs.values())
258
- .map((e) => generateOnEvents(module, e))
259
- .filter((s) => s !== '')
260
- const structs = module.structs.map((s) => generateStructs(module, s, eventTypes))
261
- const callArgs = module.exposed_functions.map((f) => generateCallArgsStructs(module, f))
262
-
263
- const moduleName = normalizeToJSName(module.name)
264
- let processor = ''
265
- if (functions.length > 0 || events.length > 0) {
266
- processor = `export class ${moduleName} extends AptosBaseProcessor {
267
-
268
- constructor(options: AptosBindOptions) {
269
- super("${module.name}", options)
270
- }
271
- static DEFAULT_OPTIONS: AptosBindOptions = {
272
- address: "${module.address}",
273
- network: AptosNetwork.${generateNetworkOption(network)}
274
- }
275
-
276
- static bind(options: Partial<AptosBindOptions> = {}): ${moduleName} {
277
- return new ${moduleName}({ ...${moduleName}.DEFAULT_OPTIONS, ...options })
278
- }
279
-
280
- ${functions.join('\n')}
281
-
282
- ${events.join('\n')}
283
-
284
- loadTypesInternal(registry: MoveCoder) {
285
- loadAllTypes(registry)
286
- }
287
- }
288
- `
289
- }
290
-
291
- return `
292
- ${processor}
293
-
294
- export namespace ${moduleName} {
295
- ${structs.join('\n')}
296
-
297
- ${callArgs.join('\n')}
298
-
299
- export function loadTypes(_r: MoveCoder) {
300
- loadAllTypes(_r)
301
- }
302
- export const ABI: MoveModule = JSON.parse('${JSON.stringify(module)}')
303
- }
304
- `
305
- }
306
-
307
- function generateStructs(module: MoveModule, struct: MoveStruct, events: Set<string>) {
308
- const genericString = generateStructTypeParameters(struct)
309
- const genericStringAny = generateStructTypeParameters(struct, true)
310
-
311
- const structName = normalizeToJSName(struct.name)
312
-
313
- const fields = struct.fields.map((field) => {
314
- return `${field.name}: ${generateType(field.type, module.address)}`
315
- })
316
-
317
- let eventPayload = ''
318
- if (events.has(moduleQname(module) + SPLITTER + struct.name)) {
319
- eventPayload = `
320
- export interface ${structName}Instance extends
321
- TypedEventInstance<${structName}${genericStringAny}> {
322
- data_decoded: ${structName}${genericStringAny}
323
- type_arguments: [${struct.generic_type_params.map((_) => 'string').join(', ')}]
324
- }
325
- `
326
- }
327
-
328
- return `
329
- export class ${structName}${genericString} {
330
- static TYPE_QNAME = '${module.address}::${module.name}::${struct.name}'
331
- ${fields.join('\n')}
332
- }
333
-
334
- ${eventPayload}
335
- `
336
- }
337
-
338
- function generateFunctionTypeParameters(func: MoveFunction) {
339
- let genericString = ''
340
- if (func.generic_type_params && func.generic_type_params.length > 0) {
341
- const params = func.generic_type_params
342
- .map((v, idx) => {
343
- return `T${idx}=any`
344
- })
345
- .join(',')
346
- genericString = `<${params}>`
347
- }
348
- return genericString
349
- }
350
-
351
- function generateStructTypeParameters(struct: MoveStruct, useAny = false) {
352
- let genericString = ''
353
-
354
- if (struct.generic_type_params && struct.generic_type_params.length > 0) {
355
- const params = struct.generic_type_params
356
- .map((v, idx) => {
357
- return useAny ? 'any' : 'T' + idx
358
- })
359
- .join(',')
360
- genericString = `<${params}>`
361
- }
362
- return genericString
363
- }
364
-
365
- function generateCallArgsStructs(module: MoveModule, func: MoveFunction) {
366
- if (!func.is_entry) {
367
- return
368
- }
369
-
370
- const fields = getMeaningfulFunctionParams(func).map((param) => {
371
- return `${generateType(param, module.address)}`
372
- })
373
-
374
- const camelFuncName = capitalizeFirstChar(camelCase(func.name))
375
-
376
- const genericString = generateFunctionTypeParameters(func)
377
- return `
378
- export interface ${camelFuncName}Payload${genericString}
379
- extends TypedEntryFunctionPayload<[${fields.join(',')}]> {
380
- arguments_decoded: [${fields.join(',')}],
381
- type_arguments: [${func.generic_type_params.map((_) => 'string').join(', ')}]
382
- }
383
- `
384
- }
385
-
386
- function generateOnEntryFunctions(module: MoveModule, func: MoveFunction) {
387
- if (!func.is_entry) {
388
- return ''
389
- }
390
-
391
- // const genericString = generateFunctionTypeParameters(func)
392
- const moduleName = normalizeToJSName(module.name)
393
-
394
- const camelFuncName = capitalizeFirstChar(camelCase(func.name))
395
- const source = `
396
- onEntry${camelFuncName}(func: (call: ${moduleName}.${camelFuncName}Payload, ctx: AptosContext) => void, filter?: CallFilter, fetchConfig?: MoveFetchConfig): ${moduleName} {
397
- this.onEntryFunctionCall(func, {
398
- ...filter,
399
- function: '${module.name}::${func.name}'
400
- },
401
- fetchConfig)
402
- return this
403
- }`
404
-
405
- return source
406
- }
407
-
408
- function getEventStructs(module: MoveModule) {
409
- const qname = moduleQname(module)
410
- const structMap = new Map<string, MoveStruct>()
411
- const eventMap = new Map<string, MoveStruct>()
412
-
413
- for (const struct of module.structs) {
414
- structMap.set(qname + SPLITTER + struct.name, struct)
415
- }
416
-
417
- for (const struct of module.structs) {
418
- for (const field of struct.fields) {
419
- const t = parseMoveType(field.type)
420
- if (t.qname === '0x1::event::EventHandle') {
421
- const event = t.typeArgs[0].qname
422
- const eventStruct = structMap.get(event)
423
- if (eventStruct) {
424
- eventMap.set(event, eventStruct)
425
69
  }
426
70
  }
427
71
  }
428
- }
429
-
430
- return eventMap
431
- }
432
-
433
- function generateOnEvents(module: MoveModule, struct: MoveStruct): string {
434
- // for struct that has drop + store
435
- // if (!isEvent(struct, module)) {
436
- // return ''
437
- // }
438
-
439
- // const genericString = generateStructTypeParameters(struct)
440
-
441
- const moduleName = normalizeToJSName(module.name)
442
- const source = `
443
- onEvent${struct.name}(func: (event: ${moduleName}.${normalizeToJSName(
444
- struct.name
445
- )}Instance, ctx: AptosContext) => void, fetchConfig?: MoveFetchConfig): ${moduleName} {
446
- this.onEvent(func, {
447
- type: '${module.name}::${struct.name}'
448
- },
449
- fetchConfig)
450
- return this
451
- }
452
- `
453
- return source
454
- }
455
72
 
456
- function capitalizeFirstChar(input: string): string {
457
- if (!input) {
458
- return input
73
+ return eventMap
459
74
  }
460
- return input[0].toUpperCase() + (input.length > 1 ? input.substring(1) : '')
461
75
  }
@@ -25,13 +25,3 @@ export type TypedMoveResource<T> = MoveResource & {
25
25
  data_decoded: T
26
26
  type_arguments: string[]
27
27
  }
28
-
29
- export interface StructWithTag {
30
- type: string
31
- data: any
32
- }
33
-
34
- export interface StructWithType<T> extends StructWithTag {
35
- data_decoded: T
36
- type_arguments: string[]
37
- }
@@ -1,118 +1,25 @@
1
1
  import {
2
2
  Event,
3
- MoveFunction,
4
3
  MoveModule,
4
+ MoveModuleBytecode,
5
5
  MoveResource,
6
- MoveStruct,
6
+ toNeutralModule,
7
7
  TransactionPayload_EntryFunctionPayload,
8
8
  } from './move-types.js'
9
9
 
10
- import { getMeaningfulFunctionParams, moduleQname, SPLITTER, VECTOR_STR } from './utils.js'
11
- import { parseMoveType, TypeDescriptor } from './types.js'
12
- import {
13
- TypedEventInstance,
14
- TypedMoveResource,
15
- StructWithTag,
16
- StructWithType,
17
- TypedEntryFunctionPayload,
18
- } from './models.js'
19
-
20
- export class MoveCoder {
21
- private moduleMapping = new Map<string, MoveModule>()
22
- private typeMapping = new Map<string, MoveStruct>()
23
- private funcMapping = new Map<string, MoveFunction>()
24
-
25
- contains(account: string, name: string) {
26
- return this.moduleMapping.has(account + '::' + name)
27
- }
28
-
29
- load(module: MoveModule) {
30
- if (this.contains(module.address, module.name)) {
31
- return
32
- }
33
- this.moduleMapping.set(moduleQname(module), module)
34
-
35
- for (const struct of module.structs) {
36
- // TODO move to util
37
- const key = [module.address, module.name, struct.name].join(SPLITTER)
38
- this.typeMapping.set(key, struct)
39
- }
10
+ import { TypedEventInstance, TypedMoveResource, TypedEntryFunctionPayload } from './models.js'
11
+ import { getMeaningfulFunctionParams } from './utils.js'
12
+ import { AbstractMoveCoder } from '../move/abstract-move-coder.js'
40
13
 
41
- for (const func of module.exposed_functions) {
42
- if (!func.is_entry) {
43
- continue
44
- }
45
- const key = [module.address, module.name, func.name].join(SPLITTER)
46
- this.funcMapping.set(key, func)
14
+ export class MoveCoder extends AbstractMoveCoder<Event | MoveResource> {
15
+ load(module: MoveModuleBytecode) {
16
+ if (!module.abi) {
17
+ throw Error('Module without abi')
47
18
  }
48
- }
49
-
50
- getMoveStruct(type: string): MoveStruct {
51
- const struct = this.typeMapping.get(type)
52
- if (!struct) {
53
- throw new Error('Failed to load type' + type)
54
- }
55
- return struct
56
- }
57
-
58
- getMoveFunction(type: string): MoveFunction {
59
- const func = this.funcMapping.get(type)
60
- if (!func) {
61
- throw new Error('Failed to load function' + type)
62
- }
63
- return func
64
- }
65
-
66
- decode(data: any, type: TypeDescriptor): any {
67
- // process simple type
68
- if (type.qname.startsWith('&')) {
69
- return data
70
- }
71
- switch (type.qname) {
72
- case 'signer': // TODO check this
73
- case 'address':
74
- case '0x1::string::String':
75
- case 'bool':
76
- case 'u8':
77
- case 'u16':
78
- case 'u32':
79
- return data
80
- case 'u64':
81
- case 'u128':
82
- return BigInt(data)
83
- }
84
-
85
- // process vector
86
- if (type.qname === VECTOR_STR) {
87
- // vector<u8> as hex string
88
- if (type.typeArgs[0].qname === 'u8') {
89
- return data
90
- }
91
-
92
- const res = []
93
- for (const entry of data) {
94
- res.push(this.decode(entry, type.typeArgs[0]))
95
- }
96
- return res
97
- }
98
-
99
- // Process complex type
100
- const struct = this.getMoveStruct(type.qname)
101
-
102
- const typeCtx = new Map<string, TypeDescriptor>()
103
- for (const [idx, typeArg] of type.typeArgs.entries()) {
104
- typeCtx.set('T' + idx, typeArg)
105
- }
106
-
107
- const typedData: any = {}
108
-
109
- for (const field of struct.fields) {
110
- let filedType = parseMoveType(field.type)
111
- filedType = filedType.applyTypeArgs(typeCtx)
112
- const value = this.decode(data[field.name], filedType)
113
- typedData[field.name] = value
19
+ if (this.contains(module.abi.address, module.abi.name)) {
20
+ return
114
21
  }
115
- return typedData
22
+ this.loadNeutral(toNeutralModule(module))
116
23
  }
117
24
 
118
25
  decodeEvent<T>(event: Event): TypedEventInstance<T> | undefined {
@@ -128,57 +35,16 @@ export class MoveCoder {
128
35
  return this.filterAndDecodeInternal(typeQname, resources)
129
36
  }
130
37
 
131
- private filterAndDecodeInternal<T>(typeQname: string, structs: StructWithTag[]): StructWithType<T>[] {
132
- if (!structs) {
133
- return []
134
- }
135
- const results: StructWithType<T>[] = []
136
- for (const resource of structs) {
137
- if (resource.type.split('<')[0] !== typeQname) {
138
- continue
139
- }
140
- const result = this.decodedInternal(resource)
141
- if (result) {
142
- results.push(result as StructWithType<T>)
143
- }
144
- }
145
- return results
146
- }
147
-
148
- private decodedInternal<T>(typeStruct: StructWithTag): StructWithType<T> | undefined {
149
- const registry = MOVE_CODER
150
- // this.loadTypes(registry)
151
- // TODO check if module is not loaded
152
-
153
- const typeDescriptor = parseMoveType(typeStruct.type)
154
- const typeArguments = typeDescriptor.typeArgs.map((t) => t.getSignature())
155
-
156
- let dataTyped = undefined
157
- try {
158
- dataTyped = registry.decode(typeStruct.data, typeDescriptor)
159
- } catch (e) {
160
- console.error('Decoding error for ', JSON.stringify(typeStruct), e)
161
- return undefined
162
- }
163
- return {
164
- ...typeStruct,
165
- data_decoded: dataTyped,
166
- type_arguments: typeArguments,
167
- } as StructWithType<T>
168
- }
169
-
170
38
  decodeFunctionPayload(payload: TransactionPayload_EntryFunctionPayload): TransactionPayload_EntryFunctionPayload {
171
- const registry = MOVE_CODER
172
- // this.loadTypes(registry)
173
39
  const argumentsTyped: any[] = []
174
40
 
175
41
  try {
176
- const func = registry.getMoveFunction(payload.function)
177
- const params = getMeaningfulFunctionParams(func)
42
+ const func = this.getMoveFunction(payload.function)
43
+ const params = getMeaningfulFunctionParams(func.params)
178
44
  for (const [idx, arg] of payload.arguments.entries()) {
179
45
  // TODO consider apply payload.type_arguments, but this might be hard since we don't code gen for them
180
- const argType = parseMoveType(params[idx])
181
- argumentsTyped.push(registry.decode(arg, argType))
46
+ const argType = params[idx]
47
+ argumentsTyped.push(this.decode(arg, argType))
182
48
  }
183
49
  } catch (e) {
184
50
  console.error('Decoding error for ', JSON.stringify(payload), e)