@sentio/sdk 2.13.0-rc.5 → 2.13.0-rc.6

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 (58) hide show
  1. package/lib/aptos/aptos-chain-adapter.d.ts +4 -2
  2. package/lib/aptos/aptos-chain-adapter.js +9 -0
  3. package/lib/aptos/aptos-chain-adapter.js.map +1 -1
  4. package/lib/aptos/aptos-processor.d.ts +5 -4
  5. package/lib/aptos/aptos-processor.js +2 -2
  6. package/lib/aptos/aptos-processor.js.map +1 -1
  7. package/lib/aptos/codegen/codegen.js.map +1 -1
  8. package/lib/aptos/ext/aptos-dex.js +1 -1
  9. package/lib/aptos/ext/aptos-dex.js.map +1 -1
  10. package/lib/aptos/module-client.js +1 -1
  11. package/lib/aptos/module-client.js.map +1 -1
  12. package/lib/aptos/move-coder.d.ts +6 -6
  13. package/lib/aptos/move-coder.js +12 -6
  14. package/lib/aptos/move-coder.js.map +1 -1
  15. package/lib/move/abstract-codegen.d.ts +6 -6
  16. package/lib/move/abstract-codegen.js.map +1 -1
  17. package/lib/move/abstract-move-coder.d.ts +15 -20
  18. package/lib/move/abstract-move-coder.js +68 -51
  19. package/lib/move/abstract-move-coder.js.map +1 -1
  20. package/lib/move/chain-adapter.d.ts +3 -1
  21. package/lib/move/chain-adapter.js.map +1 -1
  22. package/lib/move/types.d.ts +6 -0
  23. package/lib/move/types.js +20 -0
  24. package/lib/move/types.js.map +1 -1
  25. package/lib/sui/builtin/0x2.d.ts +1 -4
  26. package/lib/sui/builtin/0x2.js +0 -5
  27. package/lib/sui/builtin/0x2.js.map +1 -1
  28. package/lib/sui/codegen/codegen.js +3 -0
  29. package/lib/sui/codegen/codegen.js.map +1 -1
  30. package/lib/sui/context.d.ts +1 -0
  31. package/lib/sui/context.js +2 -0
  32. package/lib/sui/context.js.map +1 -1
  33. package/lib/sui/move-coder.d.ts +9 -9
  34. package/lib/sui/move-coder.js +19 -28
  35. package/lib/sui/move-coder.js.map +1 -1
  36. package/lib/sui/sui-chain-adapter.d.ts +4 -2
  37. package/lib/sui/sui-chain-adapter.js +22 -1
  38. package/lib/sui/sui-chain-adapter.js.map +1 -1
  39. package/lib/sui/sui-processor.d.ts +4 -3
  40. package/lib/sui/sui-processor.js +2 -2
  41. package/lib/sui/sui-processor.js.map +1 -1
  42. package/package.json +4 -4
  43. package/src/aptos/aptos-chain-adapter.ts +13 -2
  44. package/src/aptos/aptos-processor.ts +8 -7
  45. package/src/aptos/codegen/codegen.ts +2 -2
  46. package/src/aptos/ext/aptos-dex.ts +4 -1
  47. package/src/aptos/module-client.ts +1 -1
  48. package/src/aptos/move-coder.ts +20 -12
  49. package/src/move/abstract-codegen.ts +6 -6
  50. package/src/move/abstract-move-coder.ts +77 -67
  51. package/src/move/chain-adapter.ts +4 -1
  52. package/src/move/types.ts +21 -0
  53. package/src/sui/builtin/0x2.ts +1 -4
  54. package/src/sui/codegen/codegen.ts +5 -2
  55. package/src/sui/context.ts +2 -0
  56. package/src/sui/move-coder.ts +34 -42
  57. package/src/sui/sui-chain-adapter.ts +32 -2
  58. package/src/sui/sui-processor.ts +6 -5
@@ -21,29 +21,37 @@ export class MoveCoder extends AbstractMoveCoder<AptosNetwork, MoveModuleBytecod
21
21
  if (!module.abi) {
22
22
  throw Error('Module without abi')
23
23
  }
24
- if (this.contains(module.abi.address, module.abi.name)) {
25
- return
24
+ let m = this.moduleMapping.get(module.abi.address + '::' + module.abi.name)
25
+ // if (this.contains(module.abi.address, module.abi.name)) {
26
+ // return
27
+ // }
28
+ if (m) {
29
+ return m
26
30
  }
27
- this.loadInternal(toInternalModule(module))
31
+ m = toInternalModule(module)
32
+ this.loadInternal(m)
33
+ return m
28
34
  }
29
35
 
30
- decodeEvent<T>(event: Event): TypedEventInstance<T> | undefined {
31
- return this.decodedStruct<T>(event) as TypedEventInstance<T>
36
+ decodeEvent<T>(event: Event): Promise<TypedEventInstance<T> | undefined> {
37
+ return this.decodedStruct<T>(event) as any
32
38
  }
33
- filterAndDecodeEvents<T>(typeQname: string, resources: Event[]): TypedEventInstance<T>[] {
34
- return this.filterAndDecodeStruct(typeQname, resources) as TypedEventInstance<T>[]
39
+ filterAndDecodeEvents<T>(typeQname: string, resources: Event[]): Promise<TypedEventInstance<T>[]> {
40
+ return this.filterAndDecodeStruct(typeQname, resources) as any
35
41
  }
36
- decodeResource<T>(res: MoveResource): TypedMoveResource<T> | undefined {
42
+ decodeResource<T>(res: MoveResource): Promise<TypedMoveResource<T> | undefined> {
37
43
  return this.decodedStruct<T>(res)
38
44
  }
39
- filterAndDecodeResources<T>(typeQname: string, resources: MoveResource[]): TypedMoveResource<T>[] {
45
+ filterAndDecodeResources<T>(typeQname: string, resources: MoveResource[]): Promise<TypedMoveResource<T>[]> {
40
46
  return this.filterAndDecodeStruct(typeQname, resources) as any
41
47
  }
42
48
 
43
- decodeFunctionPayload(payload: TransactionPayload_EntryFunctionPayload): TransactionPayload_EntryFunctionPayload {
44
- const func = this.getMoveFunction(payload.function)
49
+ async decodeFunctionPayload(
50
+ payload: TransactionPayload_EntryFunctionPayload
51
+ ): Promise<TransactionPayload_EntryFunctionPayload> {
52
+ const func = await this.getMoveFunction(payload.function)
45
53
  const params = this.adapter.getMeaningfulFunctionParams(func.params)
46
- const argumentsDecoded = this.decodeArray(payload.arguments, params)
54
+ const argumentsDecoded = await this.decodeArray(payload.arguments, params)
47
55
 
48
56
  return {
49
57
  ...payload,
@@ -25,7 +25,7 @@ interface Config<NetworkType> {
25
25
  network: NetworkType
26
26
  }
27
27
 
28
- export abstract class AbstractCodegen<ModuleTypes, NetworkType> {
28
+ export abstract class AbstractCodegen<NetworkType, ModuleTypes, StructType> {
29
29
  TEST_NET: NetworkType
30
30
  MAIN_NET: NetworkType
31
31
  ADDRESS_TYPE: string
@@ -36,9 +36,9 @@ export abstract class AbstractCodegen<ModuleTypes, NetworkType> {
36
36
  PAYLOAD_OPTIONAL = false
37
37
  SYSTEM_MODULES = new Set(['0x1', '0x2', '0x3'])
38
38
 
39
- chainAdapter: ChainAdapter<NetworkType, ModuleTypes>
39
+ chainAdapter: ChainAdapter<NetworkType, ModuleTypes, StructType>
40
40
 
41
- protected constructor(chainAdapter: ChainAdapter<NetworkType, ModuleTypes>) {
41
+ protected constructor(chainAdapter: ChainAdapter<NetworkType, ModuleTypes, StructType>) {
42
42
  this.chainAdapter = chainAdapter
43
43
  }
44
44
 
@@ -447,15 +447,15 @@ export abstract class AbstractCodegen<ModuleTypes, NetworkType> {
447
447
  }
448
448
  }
449
449
 
450
- export class AccountCodegen<ModuleType, NetworkType> {
450
+ export class AccountCodegen<NetworkType, ModuleType, StructType> {
451
451
  modules: InternalMoveModule[]
452
452
  config: Config<NetworkType>
453
453
  abi: ModuleType[]
454
454
  loader: AccountRegister
455
- moduleGen: AbstractCodegen<ModuleType, NetworkType>
455
+ moduleGen: AbstractCodegen<NetworkType, ModuleType, StructType>
456
456
 
457
457
  constructor(
458
- moduleGen: AbstractCodegen<ModuleType, NetworkType>,
458
+ moduleGen: AbstractCodegen<NetworkType, ModuleType, StructType>,
459
459
  loader: AccountRegister,
460
460
  abi: ModuleType[],
461
461
  modules: InternalMoveModule[],
@@ -1,25 +1,20 @@
1
1
  import { moduleQname, SPLITTER, VECTOR_STR } from './utils.js'
2
- import { parseMoveType, TypeDescriptor } from './types.js'
2
+ import { matchType, parseMoveType, TypeDescriptor } from './types.js'
3
3
  import { InternalMoveFunction, InternalMoveModule, InternalMoveStruct } from './internal-models.js'
4
4
  import { bytesToBigInt } from '../utils/index.js'
5
5
  import { ChainAdapter } from './chain-adapter.js'
6
6
 
7
- export type StructWithTag<Base> = {
8
- type: string
9
- data: Base
10
- }
11
-
12
- export type DecodedStructWithTag<B, T> = StructWithTag<B> & {
7
+ export type DecodedStructWithTag<B, T> = B & {
13
8
  data_decoded: T
14
9
  type_arguments: string[]
15
10
  }
16
11
 
17
12
  export abstract class AbstractMoveCoder<Network, ModuleType, StructType> {
18
- private moduleMapping = new Map<string, InternalMoveModule>()
13
+ protected moduleMapping = new Map<string, InternalMoveModule>()
19
14
  private typeMapping = new Map<string, InternalMoveStruct>()
20
15
  private funcMapping = new Map<string, InternalMoveFunction>()
21
16
  network: Network
22
- adapter: ChainAdapter<Network, ModuleType>
17
+ adapter: ChainAdapter<Network, ModuleType, StructType>
23
18
 
24
19
  protected constructor(network: Network) {
25
20
  this.network = network
@@ -29,11 +24,7 @@ export abstract class AbstractMoveCoder<Network, ModuleType, StructType> {
29
24
  return this.moduleMapping.has(account + '::' + name)
30
25
  }
31
26
 
32
- // protected abstract getMeaningfulFunctionParams(params: TypeDescriptor[]): TypeDescriptor[]
33
-
34
- protected toStructWithTag(val: StructType): StructWithTag<StructType> {
35
- return val as any
36
- }
27
+ abstract load(module: ModuleType): InternalMoveModule
37
28
 
38
29
  protected loadInternal(module: InternalMoveModule) {
39
30
  if (this.contains(module.address, module.name)) {
@@ -70,23 +61,53 @@ export abstract class AbstractMoveCoder<Network, ModuleType, StructType> {
70
61
  return '0x' + data.toString(16)
71
62
  }
72
63
 
73
- getMoveStruct(type: string): InternalMoveStruct {
74
- const struct = this.typeMapping.get(type)
75
- if (!struct) {
76
- throw new Error('Failed to load type' + type + ' type are not imported anywhere')
64
+ private requestMap = new Map<string, Promise<InternalMoveModule>>()
65
+
66
+ async getMoveStruct(type: string): Promise<InternalMoveStruct> {
67
+ let struct = this.typeMapping.get(type)
68
+ if (struct) {
69
+ return struct
70
+ }
71
+ const [account, module, typeName] = type.split(SPLITTER)
72
+ const key = account + SPLITTER + module
73
+ let resp = this.requestMap.get(account + SPLITTER + module)
74
+ if (!resp) {
75
+ resp = this.adapter.fetchModule(account, module, this.network).then((m) => {
76
+ return this.load(m)
77
+ })
78
+ this.requestMap.set(key, resp)
77
79
  }
78
- return struct
80
+ await resp
81
+ struct = this.typeMapping.get(type)
82
+ if (struct) {
83
+ return struct
84
+ }
85
+ throw new Error('Failed to load function ' + type + ' type are not imported anywhere')
79
86
  }
80
87
 
81
- getMoveFunction(type: string): InternalMoveFunction {
82
- const func = this.funcMapping.get(type)
83
- if (!func) {
84
- throw new Error('Failed to load function ' + type + ' type are not imported anywhere')
88
+ async getMoveFunction(type: string): Promise<InternalMoveFunction> {
89
+ let func = this.funcMapping.get(type)
90
+ if (func) {
91
+ return func
92
+ }
93
+ const [account, module, typeName] = type.split(SPLITTER)
94
+ const key = account + SPLITTER + module
95
+ let resp = this.requestMap.get(account + SPLITTER + module)
96
+ if (!resp) {
97
+ resp = this.adapter.fetchModule(account, module, this.network).then((m) => {
98
+ return this.load(m)
99
+ })
100
+ this.requestMap.set(key, resp)
85
101
  }
86
- return func
102
+ await resp
103
+ func = this.funcMapping.get(type)
104
+ if (func) {
105
+ return func
106
+ }
107
+ throw new Error('Failed to load function ' + type + ' type are not imported anywhere')
87
108
  }
88
109
 
89
- decode(data: any, type: TypeDescriptor): any {
110
+ async decode(data: any, type: TypeDescriptor): Promise<any> {
90
111
  // process simple type
91
112
  if (type.reference) {
92
113
  return data
@@ -121,13 +142,13 @@ export abstract class AbstractMoveCoder<Network, ModuleType, StructType> {
121
142
 
122
143
  const res = []
123
144
  for (const entry of data) {
124
- res.push(this.decode(entry, type.typeArgs[0]))
145
+ res.push(await this.decode(entry, type.typeArgs[0]))
125
146
  }
126
147
  return res
127
148
  }
128
149
 
129
150
  // Process complex type
130
- const struct = this.getMoveStruct(type.qname)
151
+ const struct = await this.getMoveStruct(type.qname)
131
152
 
132
153
  const typeCtx = new Map<string, TypeDescriptor>()
133
154
  for (const [idx, typeArg] of type.typeArgs.entries()) {
@@ -139,13 +160,14 @@ export abstract class AbstractMoveCoder<Network, ModuleType, StructType> {
139
160
  for (const field of struct.fields) {
140
161
  let filedType = field.type
141
162
  filedType = filedType.applyTypeArgs(typeCtx)
142
- const value = this.decode(data[field.name], filedType)
163
+ const fieldValue = this.adapter.getData(data)[field.name]
164
+ const value = await this.decode(fieldValue, filedType)
143
165
  typedData[field.name] = value
144
166
  }
145
167
  return typedData
146
168
  }
147
169
 
148
- encode(data: any, type: TypeDescriptor): any {
170
+ async encode(data: any, type: TypeDescriptor): Promise<any> {
149
171
  // process simple type
150
172
  if (type.reference) {
151
173
  return data
@@ -190,7 +212,7 @@ export abstract class AbstractMoveCoder<Network, ModuleType, StructType> {
190
212
  }
191
213
 
192
214
  // Process complex type
193
- const struct = this.getMoveStruct(type.qname)
215
+ const struct = await this.getMoveStruct(type.qname)
194
216
 
195
217
  const typeCtx = new Map<string, TypeDescriptor>()
196
218
  for (const [idx, typeArg] of type.typeArgs.entries()) {
@@ -202,19 +224,19 @@ export abstract class AbstractMoveCoder<Network, ModuleType, StructType> {
202
224
  for (const field of struct.fields) {
203
225
  let filedType = field.type
204
226
  filedType = filedType.applyTypeArgs(typeCtx)
205
- const value = this.encode(data[field.name], filedType)
227
+ const value = await this.encode(data[field.name], filedType)
206
228
  typedData[field.name] = value
207
229
  }
208
230
  return typedData
209
231
  }
210
232
 
211
- decodeArray(entries: any[], types: TypeDescriptor[]): any[] {
233
+ async decodeArray(entries: any[], types: TypeDescriptor[]): Promise<any[]> {
212
234
  const entriesDecoded: any[] = []
213
235
  for (const [idx, arg] of entries.entries()) {
214
236
  // TODO consider apply payload.type_arguments, but this might be hard since we don't code gen for them
215
237
  const argType = types[idx]
216
238
  try {
217
- entriesDecoded.push(this.decode(arg, argType))
239
+ entriesDecoded.push(await this.decode(arg, argType))
218
240
  } catch (e) {
219
241
  console.error(e, 'Decoding error for ', JSON.stringify(arg), 'using type', argType)
220
242
  return entries
@@ -223,13 +245,13 @@ export abstract class AbstractMoveCoder<Network, ModuleType, StructType> {
223
245
  return entriesDecoded
224
246
  }
225
247
 
226
- encodeArray(entriesDecoded: any[], types: TypeDescriptor[]): any[] {
248
+ async encodeArray(entriesDecoded: any[], types: TypeDescriptor[]): Promise<any[]> {
227
249
  const entries: any[] = []
228
250
  for (const [idx, arg] of entriesDecoded.entries()) {
229
251
  // TODO consider apply payload.type_arguments, but this might be hard since we don't code gen for them
230
252
  const argType = types[idx]
231
253
  try {
232
- entries.push(this.encode(arg, argType))
254
+ entries.push(await this.encode(arg, argType))
233
255
  } catch (e) {
234
256
  throw Error('Decoding error for ' + JSON.stringify(arg) + 'using type' + argType + e.toString())
235
257
  }
@@ -237,61 +259,49 @@ export abstract class AbstractMoveCoder<Network, ModuleType, StructType> {
237
259
  return entries
238
260
  }
239
261
 
240
- encodeCallArgs(args: any[], func: string): any[] {
241
- const f = this.getMoveFunction(func)
262
+ async encodeCallArgs(args: any[], func: string): Promise<any[]> {
263
+ const f = await this.getMoveFunction(func)
242
264
  return this.encodeArray(args, this.adapter.getMeaningfulFunctionParams(f.params))
243
265
  }
244
266
 
245
- decodeCallResult(res: any[], func: string): any[] {
246
- const f = this.getMoveFunction(func)
267
+ async decodeCallResult(res: any[], func: string): Promise<any[]> {
268
+ const f = await this.getMoveFunction(func)
247
269
  return this.decodeArray(res, f.return)
248
270
  }
249
271
 
250
- protected filterAndDecodeStruct(typeQname: string, structs: StructType[]): any {
251
- if (!structs) {
252
- return []
253
- }
254
- const withTags = structs.map((s) => this.toStructWithTag(s))
255
- return this.filterAndDecodeStructWithTags(typeQname, withTags)
256
- }
257
-
258
- private filterAndDecodeStructWithTags<T>(
259
- typeQname: string,
260
- structsWithTags: StructWithTag<StructType>[]
261
- ): DecodedStructWithTag<StructType, T>[] {
272
+ protected async filterAndDecodeStruct<T>(
273
+ typeMatcher: string,
274
+ structsWithTags: StructType[]
275
+ ): Promise<DecodedStructWithTag<StructType, T>[]> {
262
276
  if (!structsWithTags) {
263
- return []
277
+ return [] as any
264
278
  }
279
+ const typeMatcherDescriptor = parseMoveType(typeMatcher)
265
280
  const results: DecodedStructWithTag<StructType, T>[] = []
266
281
  for (const resource of structsWithTags) {
267
- if (typeQname.includes('<')) {
268
- if (resource.type !== typeQname) {
269
- continue
270
- }
271
- } else if (resource.type.split('<')[0] !== typeQname) {
282
+ const resourceType = this.adapter.getType(resource)
283
+ const resourceTypeDescriptor = parseMoveType(resourceType)
284
+ if (!matchType(typeMatcherDescriptor, resourceTypeDescriptor)) {
272
285
  continue
273
286
  }
274
- const result = this.decodedStructWithTag(resource)
287
+
288
+ const result = await this.decodedStruct(resource)
275
289
  if (result) {
276
290
  results.push(result as DecodedStructWithTag<StructType, T>)
291
+ } else {
292
+ console.log('')
277
293
  }
278
294
  }
279
295
  return results
280
296
  }
281
297
 
282
- protected decodedStruct<T>(typeStruct: StructType): DecodedStructWithTag<StructType, T> | undefined {
283
- return this.decodedStructWithTag(this.toStructWithTag(typeStruct)) as any
284
- }
285
-
286
- private decodedStructWithTag<T>(
287
- typeStruct: StructWithTag<StructType>
288
- ): DecodedStructWithTag<StructType, T> | undefined {
289
- const typeDescriptor = parseMoveType(typeStruct.type)
298
+ protected async decodedStruct<T>(typeStruct: StructType): Promise<DecodedStructWithTag<StructType, T> | undefined> {
299
+ const typeDescriptor = parseMoveType(this.adapter.getType(typeStruct))
290
300
  const typeArguments = typeDescriptor.typeArgs.map((t) => t.getSignature())
291
301
 
292
302
  let dataTyped = undefined
293
303
  try {
294
- dataTyped = this.decode(this.toStructWithTag(typeStruct.data), typeDescriptor)
304
+ dataTyped = await this.decode(typeStruct, typeDescriptor)
295
305
  } catch (e) {
296
306
  console.error('Decoding error for ', JSON.stringify(typeStruct), e)
297
307
  return undefined
@@ -1,7 +1,7 @@
1
1
  import { InternalMoveModule, InternalMoveStruct } from './internal-models.js'
2
2
  import { TypeDescriptor } from './types.js'
3
3
 
4
- export abstract class ChainAdapter<NetworkType, ModuleType> {
4
+ export abstract class ChainAdapter<NetworkType, ModuleType, StructType> {
5
5
  abstract fetchModule(account: string, module: string, network: NetworkType): Promise<ModuleType>
6
6
 
7
7
  abstract fetchModules(account: string, network: NetworkType): Promise<ModuleType[]>
@@ -11,4 +11,7 @@ export abstract class ChainAdapter<NetworkType, ModuleType> {
11
11
  // Get the parameters that actually have arguments in runtime
12
12
  // Aptos first signer and Sui's last TxContext are no use
13
13
  abstract getMeaningfulFunctionParams(params: TypeDescriptor[]): TypeDescriptor[]
14
+
15
+ abstract getType(base: StructType): string
16
+ abstract getData<T>(base: StructType): any
14
17
  }
package/src/move/types.ts CHANGED
@@ -154,3 +154,24 @@ function adjustType(type: TypeDescriptor) {
154
154
  type.qname = type.qname.slice(3)
155
155
  }
156
156
  }
157
+
158
+ /**
159
+ *
160
+ * @param matcher
161
+ * @param type
162
+ */
163
+ export function matchType(matcher: TypeDescriptor, type: TypeDescriptor): boolean {
164
+ if (matcher.qname === 'any') {
165
+ return true
166
+ }
167
+ if (matcher.qname !== type.qname) {
168
+ return false
169
+ }
170
+ for (const [idx, matcherTarg] of matcher.typeArgs.entries()) {
171
+ const targ = type.typeArgs[idx]
172
+ if (!matchType(matcherTarg, targ)) {
173
+ return false
174
+ }
175
+ }
176
+ return true
177
+ }
@@ -31,10 +31,7 @@ export namespace bag {
31
31
  }
32
32
 
33
33
  export namespace balance {
34
- export class Balance<T0> {
35
- static TYPE_QNAME = "0x2::balance::Balance";
36
- value: bigint;
37
- }
34
+ export type Balance<T> = string;
38
35
 
39
36
  export class Supply<T0> {
40
37
  static TYPE_QNAME = "0x2::balance::Supply";
@@ -1,4 +1,4 @@
1
- import { SuiMoveNormalizedModule } from '@mysten/sui.js'
1
+ import { SuiMoveNormalizedModule, SuiEvent, SuiMoveObject } from '@mysten/sui.js'
2
2
 
3
3
  import { SuiNetwork } from '../network.js'
4
4
  import * as fs from 'fs'
@@ -18,7 +18,7 @@ export async function codegen(abisDir: string, outDir = join('src', 'types', 'su
18
18
  console.log(chalk.green(`Generated ${numFiles} for Sui`))
19
19
  }
20
20
 
21
- class SuiCodegen extends AbstractCodegen<SuiMoveNormalizedModule, SuiNetwork> {
21
+ class SuiCodegen extends AbstractCodegen<SuiNetwork, SuiMoveNormalizedModule, SuiEvent | SuiMoveObject> {
22
22
  ADDRESS_TYPE = 'SuiAddress'
23
23
  MAIN_NET = SuiNetwork.MAIN_NET
24
24
  TEST_NET = SuiNetwork.TEST_NET
@@ -45,6 +45,8 @@ class SuiCodegen extends AbstractCodegen<SuiMoveNormalizedModule, SuiNetwork> {
45
45
  return `export type ${struct.name} = string`
46
46
  case '0x2::coin::Coin':
47
47
  return `export type ${struct.name}<T> = string`
48
+ case '0x2::balance::Balance':
49
+ return `export type ${struct.name}<T> = string`
48
50
  case '0x1::option::Option':
49
51
  return `export type Option<T> = T | undefined`
50
52
  }
@@ -56,6 +58,7 @@ class SuiCodegen extends AbstractCodegen<SuiMoveNormalizedModule, SuiNetwork> {
56
58
  case '0x2::object::ID':
57
59
  case '0x2::coin::Coin':
58
60
  case '0x1::option::Option':
61
+ case '0x2::balance::Balance':
59
62
  return ''
60
63
  }
61
64
  return super.generateOnEvents(module, struct)
@@ -60,6 +60,7 @@ export class SuiObjectsContext extends BaseContext {
60
60
  network: SuiNetwork
61
61
  slot: bigint
62
62
  timestamp: Date
63
+ coder: MoveCoder
63
64
 
64
65
  constructor(network: SuiNetwork, address: string, slot: bigint, timestamp: Date) {
65
66
  super()
@@ -67,6 +68,7 @@ export class SuiObjectsContext extends BaseContext {
67
68
  this.network = network
68
69
  this.slot = slot
69
70
  this.timestamp = timestamp
71
+ this.coder = defaultMoveCoder(network)
70
72
  }
71
73
 
72
74
  getChainId(): string {
@@ -1,18 +1,12 @@
1
- import { TypedEventInstance, TypedFunctionPayload, TypedSuiMoveObject } from './models.js'
2
- import { AbstractMoveCoder, StructWithTag } from '../move/abstract-move-coder.js'
3
- import {
4
- MoveCallSuiTransaction,
5
- SuiCallArg,
6
- SuiEvent,
7
- SuiMoveNormalizedModule,
8
- SuiMoveObject,
9
- SuiRawData,
10
- } from '@mysten/sui.js'
1
+ import { TypedEventInstance, TypedFunctionPayload } from './models.js'
2
+ import { AbstractMoveCoder } from '../move/abstract-move-coder.js'
3
+ import { MoveCallSuiTransaction, SuiCallArg, SuiEvent, SuiMoveNormalizedModule, SuiMoveObject } from '@mysten/sui.js'
11
4
  import { toInternalModule } from './move-types.js'
12
5
  import { SPLITTER, TypeDescriptor } from '../move/index.js'
13
6
  import { dynamic_field } from './builtin/0x2.js'
14
7
  import { SuiNetwork } from './network.js'
15
8
  import { SuiChainAdapter } from './sui-chain-adapter.js'
9
+ import { InternalMoveModule } from '../move/internal-models.js'
16
10
 
17
11
  export class MoveCoder extends AbstractMoveCoder<SuiNetwork, SuiMoveNormalizedModule, SuiEvent | SuiMoveObject> {
18
12
  constructor(network: SuiNetwork) {
@@ -20,60 +14,58 @@ export class MoveCoder extends AbstractMoveCoder<SuiNetwork, SuiMoveNormalizedMo
20
14
  this.adapter = new SuiChainAdapter()
21
15
  }
22
16
 
23
- load(module: SuiMoveNormalizedModule) {
24
- if (this.contains(module.address, module.name)) {
25
- return
17
+ load(module: SuiMoveNormalizedModule): InternalMoveModule {
18
+ let m = this.moduleMapping.get(module.address + '::' + module.name)
19
+ if (m) {
20
+ return m
26
21
  }
27
- this.loadInternal(toInternalModule(module))
22
+ m = toInternalModule(module)
23
+ this.loadInternal(m)
24
+ return m
28
25
  }
29
26
 
30
27
  decode(data: any, type: TypeDescriptor): any {
31
28
  switch (type.qname) {
32
29
  case '0x2::object::ID':
33
30
  case '0x2::coin::Coin':
31
+ case '0x2::balance::Balance':
34
32
  return data
35
33
  case '0x1::option::Option':
36
- // return this.decode(data, type.typeArgs[0])
37
- return data
34
+ if (data === null) {
35
+ return data
36
+ }
37
+ return this.decode(data, type.typeArgs[0])
38
38
  default:
39
39
  return super.decode(data, type)
40
40
  }
41
41
  }
42
42
 
43
- toStructWithTag(val: SuiEvent | SuiMoveObject): StructWithTag<SuiEvent> {
44
- if (SuiEvent.is(val)) {
45
- return {
46
- ...val,
47
- data: val.parsedJson as any,
48
- }
49
- }
50
- if (SuiRawData.is(val)) {
51
- return {
52
- ...val,
53
- data: val.fields as any,
54
- }
55
- }
56
- return val as any
57
- }
58
-
59
- decodeEvent<T>(event: SuiEvent): TypedEventInstance<T> | undefined {
43
+ decodeEvent<T>(event: SuiEvent): Promise<TypedEventInstance<T> | undefined> {
60
44
  return this.decodedStruct<T>(event) as any
61
45
  }
62
- filterAndDecodeEvents<T>(typeQname: string, resources: SuiEvent[]): TypedEventInstance<T>[] {
63
- return this.filterAndDecodeStruct(typeQname, resources)
46
+ filterAndDecodeEvents<T>(typeQname: string, resources: SuiEvent[]): Promise<TypedEventInstance<T>[]> {
47
+ return this.filterAndDecodeStruct(typeQname, resources) as any
64
48
  }
65
49
 
66
- getObjectsFromDynamicFields<Name, Value>(objects: SuiMoveObject[]): dynamic_field.Field<Name, Value>[] {
67
- return this.filterAndDecodeObjects(`0x2::dynamic_field::Field`, objects).map((o) => o.data_decoded) as any
50
+ async getDynamicFields(
51
+ objects: SuiMoveObject[],
52
+ keyTypeMatcher: string = 'any',
53
+ valueTypeMatcher: string = 'any'
54
+ ): Promise<dynamic_field.Field<any, any>[]> {
55
+ const res = (await this.filterAndDecodeObjects(
56
+ `0x2::dynamic_field::Field<${keyTypeMatcher}, ${valueTypeMatcher}>`,
57
+ objects
58
+ )) as any[]
59
+ return res.map((o) => o.data_decoded) as any
68
60
  }
69
61
 
70
- filterAndDecodeObjects<T>(typeQname: string, objects: SuiMoveObject[]): TypedSuiMoveObject<T>[] {
71
- return this.filterAndDecodeStruct(typeQname, objects)
62
+ filterAndDecodeObjects(typeMatcher: string, objects: SuiMoveObject[]): Promise<any[]> {
63
+ return this.filterAndDecodeStruct(typeMatcher, objects) as any
72
64
  }
73
65
 
74
- decodeFunctionPayload(payload: MoveCallSuiTransaction, inputs: SuiCallArg[]): MoveCallSuiTransaction {
66
+ async decodeFunctionPayload(payload: MoveCallSuiTransaction, inputs: SuiCallArg[]): Promise<MoveCallSuiTransaction> {
75
67
  const functionType = [payload.package, payload.module, payload.function].join(SPLITTER)
76
- const func = this.getMoveFunction(functionType)
68
+ const func = await this.getMoveFunction(functionType)
77
69
  const params = this.adapter.getMeaningfulFunctionParams(func.params)
78
70
  const args = []
79
71
  for (const value of payload.arguments || []) {
@@ -95,7 +87,7 @@ export class MoveCoder extends AbstractMoveCoder<SuiNetwork, SuiMoveNormalizedMo
95
87
  }
96
88
  }
97
89
 
98
- const argumentsTyped = this.decodeArray(args, params)
90
+ const argumentsTyped = await this.decodeArray(args, params)
99
91
  return {
100
92
  ...payload,
101
93
  arguments_decoded: argumentsTyped,
@@ -2,9 +2,16 @@ import { ChainAdapter, moduleQname, SPLITTER, TypeDescriptor } from '../move/ind
2
2
  import { toInternalModule } from './move-types.js'
3
3
  import { SuiNetwork } from './network.js'
4
4
  import { InternalMoveModule, InternalMoveStruct } from '../move/internal-models.js'
5
- import { Connection, JsonRpcProvider, SuiMoveNormalizedModule } from '@mysten/sui.js'
5
+ import {
6
+ Connection,
7
+ JsonRpcProvider,
8
+ SuiMoveNormalizedModule,
9
+ SuiEvent,
10
+ SuiMoveObject,
11
+ SuiParsedData,
12
+ } from '@mysten/sui.js'
6
13
 
7
- export class SuiChainAdapter extends ChainAdapter<SuiNetwork, SuiMoveNormalizedModule> {
14
+ export class SuiChainAdapter extends ChainAdapter<SuiNetwork, SuiMoveNormalizedModule, SuiEvent | SuiMoveObject> {
8
15
  static INSTANCE = new SuiChainAdapter()
9
16
 
10
17
  async fetchModule(account: string, module: string, network: SuiNetwork): Promise<SuiMoveNormalizedModule> {
@@ -41,6 +48,29 @@ export class SuiChainAdapter extends ChainAdapter<SuiNetwork, SuiMoveNormalizedM
41
48
  }
42
49
  return eventMap
43
50
  }
51
+
52
+ getType(base: SuiEvent | SuiMoveObject): string {
53
+ return base.type
54
+ }
55
+
56
+ getData(val: SuiEvent | SuiMoveObject) {
57
+ if (SuiEvent.is(val)) {
58
+ return val.parsedJson as any
59
+ }
60
+ if (SuiParsedData.is(val)) {
61
+ return val.fields as any
62
+ }
63
+ // if (SuiMoveObject.is(val)) {
64
+ // return val.fields as any
65
+ // }
66
+ // This may not be perfect, just think everything has
67
+ if ('fields' in val) {
68
+ if ('type' in val && Object.keys(val).length === 2) {
69
+ return val.fields as any
70
+ }
71
+ }
72
+ return val as any
73
+ }
44
74
  }
45
75
 
46
76
  function getRpcEndpoint(network: SuiNetwork): string {