@0xobelisk/client 0.0.1 → 0.0.3
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.
- package/README.md +2 -0
- package/dist/framework/bcs.d.ts +3 -0
- package/dist/framework/loader.d.ts +11 -0
- package/dist/framework/util.d.ts +90 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +373 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +375 -11
- package/dist/index.mjs.map +1 -1
- package/dist/libs/suiContractFactory/index.d.ts +21 -0
- package/dist/libs/suiContractFactory/types.d.ts +49 -0
- package/dist/libs/suiRpcProvider/index.d.ts +109 -1
- package/dist/metadata/index.d.ts +34 -0
- package/dist/obelisk.d.ts +194 -213
- package/dist/types/index.d.ts +62 -1
- package/package.json +8 -11
- package/src/framework/bcs.ts +6 -0
- package/src/framework/loader.ts +152 -0
- package/src/framework/util.ts +219 -0
- package/src/index.ts +1 -0
- package/src/libs/suiContractFactory/index.ts +121 -0
- package/src/libs/suiContractFactory/types.ts +54 -0
- package/src/libs/suiRpcProvider/index.ts +31 -0
- package/src/metadata/index.ts +40 -0
- package/src/obelisk.ts +215 -15
- package/src/types/index.ts +75 -1
- package/dist/test/tsconfig.tsbuildinfo +0 -1
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
|
|
2
|
+
import { FieldsWithTypes, Type, parseTypeName } from './util'
|
|
3
|
+
|
|
4
|
+
export type PrimitiveValue = string | number | boolean | bigint
|
|
5
|
+
|
|
6
|
+
export class StructClassLoader {
|
|
7
|
+
private map: Map<
|
|
8
|
+
string,
|
|
9
|
+
{
|
|
10
|
+
numTypeParams: number
|
|
11
|
+
fromFields: (fields: Record<string, any>, typeArgs?: Type[]) => any
|
|
12
|
+
fromFieldsWithTypes: (item: FieldsWithTypes) => any
|
|
13
|
+
}
|
|
14
|
+
> = new Map()
|
|
15
|
+
|
|
16
|
+
register(...classes: any) {
|
|
17
|
+
for (const cls of classes) {
|
|
18
|
+
if (
|
|
19
|
+
'$typeName' in cls === false ||
|
|
20
|
+
'$numTypeParams' in cls === false ||
|
|
21
|
+
'fromFields' in cls === false ||
|
|
22
|
+
'fromFieldsWithTypes' in cls === false
|
|
23
|
+
) {
|
|
24
|
+
throw new Error(`class ${cls.name} is not a valid struct class`)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const typeName = cls.$typeName
|
|
28
|
+
const numTypeParams = cls.$numTypeParams
|
|
29
|
+
|
|
30
|
+
this.map.set(typeName, {
|
|
31
|
+
numTypeParams,
|
|
32
|
+
fromFields: (fields: Record<string, any>, typeArgs: Type[] = []) => {
|
|
33
|
+
if (typeArgs.length !== numTypeParams) {
|
|
34
|
+
throw new Error(`expected ${numTypeParams} type args, got ${typeArgs.length}`)
|
|
35
|
+
}
|
|
36
|
+
if (numTypeParams === 0) {
|
|
37
|
+
return cls.fromFields(fields)
|
|
38
|
+
} else if (numTypeParams === 1) {
|
|
39
|
+
return cls.fromFields(typeArgs[0], fields)
|
|
40
|
+
} else {
|
|
41
|
+
return cls.fromFields(typeArgs, fields)
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
fromFieldsWithTypes: (item: FieldsWithTypes) => {
|
|
45
|
+
return cls.fromFieldsWithTypes(item)
|
|
46
|
+
},
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
fromFields(type: Type, value: Record<string, any> | PrimitiveValue) {
|
|
52
|
+
const ret = this.#handlePrimitiveValue(type, value, this.fromFields.bind(this))
|
|
53
|
+
if (ret !== undefined) {
|
|
54
|
+
return ret
|
|
55
|
+
}
|
|
56
|
+
value = value as FieldsWithTypes // type hint
|
|
57
|
+
|
|
58
|
+
const { typeName, typeArgs } = parseTypeName(type)
|
|
59
|
+
|
|
60
|
+
const loader = this.map.get(typeName)
|
|
61
|
+
if (!loader) {
|
|
62
|
+
throw new Error(`no loader registered for type ${typeName}, include relevant package in gen.toml`)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (loader.numTypeParams !== typeArgs.length) {
|
|
66
|
+
throw new Error(`expected ${loader.numTypeParams} type args, got ${typeArgs.length}`)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return loader.fromFields(value, typeArgs)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
fromFieldsWithTypes(type: Type, value: FieldsWithTypes | PrimitiveValue) {
|
|
73
|
+
const { typeName, typeArgs } = parseTypeName(type)
|
|
74
|
+
|
|
75
|
+
// some types are special-cased in the RPC so we need to handle this manually
|
|
76
|
+
// https://github.com/MystenLabs/sui/blob/416a980749ba8208917bae37a1ec1d43e50037b7/crates/sui-json-rpc-types/src/sui_move.rs#L482-L533
|
|
77
|
+
switch (typeName) {
|
|
78
|
+
case '0x1::string::String':
|
|
79
|
+
case '0x1::ascii::String':
|
|
80
|
+
case '0x2::url::Url':
|
|
81
|
+
return value
|
|
82
|
+
case '0x2::object::ID':
|
|
83
|
+
return value
|
|
84
|
+
case '0x2::object::UID':
|
|
85
|
+
return (value as unknown as { id: string }).id
|
|
86
|
+
case '0x2::balance::Balance': {
|
|
87
|
+
const loader = this.map.get('0x2::balance::Balance')
|
|
88
|
+
if (!loader) {
|
|
89
|
+
throw new Error('no loader registered for type 0x2::balance::Balance')
|
|
90
|
+
}
|
|
91
|
+
return loader.fromFields({ value }, typeArgs)
|
|
92
|
+
}
|
|
93
|
+
case '0x1::option::Option': {
|
|
94
|
+
if (value === null) {
|
|
95
|
+
return null
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const loader = this.map.get('0x1::option::Option')
|
|
99
|
+
if (!loader) {
|
|
100
|
+
throw new Error('no loader registered for type 0x1::option::Option')
|
|
101
|
+
}
|
|
102
|
+
return loader.fromFieldsWithTypes({
|
|
103
|
+
type: type,
|
|
104
|
+
fields: { vec: [value] },
|
|
105
|
+
}).vec[0]
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const ret = this.#handlePrimitiveValue(type, value, this.fromFieldsWithTypes.bind(this))
|
|
110
|
+
if (ret !== undefined) {
|
|
111
|
+
return ret
|
|
112
|
+
}
|
|
113
|
+
value = value as FieldsWithTypes // type hint
|
|
114
|
+
|
|
115
|
+
const loader = this.map.get(typeName)
|
|
116
|
+
if (!loader) {
|
|
117
|
+
throw new Error(`no loader registered for type ${typeName}, include relevant package in gen.toml`)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return loader.fromFieldsWithTypes(value)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
#handlePrimitiveValue(type: Type, value: any, vecCb: (type: Type, value: any) => any) {
|
|
124
|
+
const { typeName, typeArgs } = parseTypeName(type)
|
|
125
|
+
|
|
126
|
+
switch (typeName) {
|
|
127
|
+
case 'bool':
|
|
128
|
+
return value as boolean
|
|
129
|
+
case 'u8':
|
|
130
|
+
case 'u16':
|
|
131
|
+
case 'u32':
|
|
132
|
+
return value as number
|
|
133
|
+
case 'u64':
|
|
134
|
+
case 'u128':
|
|
135
|
+
case 'u256':
|
|
136
|
+
return BigInt(value)
|
|
137
|
+
case 'address':
|
|
138
|
+
return value as string
|
|
139
|
+
case 'signer':
|
|
140
|
+
return value as string
|
|
141
|
+
case 'vector':
|
|
142
|
+
value = value as any[]
|
|
143
|
+
return value.map((item: any) => vecCb(typeArgs[0], item))
|
|
144
|
+
default:
|
|
145
|
+
return undefined
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export const structClassLoaderSource = new StructClassLoader()
|
|
151
|
+
export const structClassLoaderOnchain = new StructClassLoader()
|
|
152
|
+
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
|
|
2
|
+
import {
|
|
3
|
+
is,
|
|
4
|
+
ObjectCallArg,
|
|
5
|
+
ObjectId,
|
|
6
|
+
TransactionArgument,
|
|
7
|
+
TransactionBlock,
|
|
8
|
+
normalizeSuiAddress,
|
|
9
|
+
bcs,
|
|
10
|
+
} from '@mysten/sui.js'
|
|
11
|
+
import { BCS } from '@mysten/bcs'
|
|
12
|
+
|
|
13
|
+
/** A Move type, e.g., `address`, `bool`, `u64`, `vector<u64>`, `0x2::sui::SUI`... */
|
|
14
|
+
export type Type = string
|
|
15
|
+
|
|
16
|
+
export interface FieldsWithTypes {
|
|
17
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
18
|
+
fields: Record<string, any>
|
|
19
|
+
type: string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type ObjectArg = ObjectId | ObjectCallArg | TransactionArgument
|
|
23
|
+
export type PureArg =
|
|
24
|
+
| bigint
|
|
25
|
+
| string
|
|
26
|
+
| number
|
|
27
|
+
| boolean
|
|
28
|
+
| null
|
|
29
|
+
| TransactionArgument
|
|
30
|
+
| Array<PureArg>
|
|
31
|
+
export type GenericArg = ObjectArg | PureArg | Array<ObjectArg> | Array<PureArg> | Array<GenericArg>
|
|
32
|
+
|
|
33
|
+
export function parseTypeName(name: Type): { typeName: string; typeArgs: Type[] } {
|
|
34
|
+
const parsed = bcs.parseTypeName(name)
|
|
35
|
+
return { typeName: parsed.name, typeArgs: parsed.params as string[] }
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function obj(txb: TransactionBlock, arg: ObjectArg) {
|
|
39
|
+
return is(arg, TransactionArgument) ? arg : txb.object(arg)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function pure(txb: TransactionBlock, arg: PureArg, type: Type) {
|
|
43
|
+
if (is(arg, TransactionArgument)) {
|
|
44
|
+
return obj(txb, arg)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function convertType(type: Type): string {
|
|
48
|
+
const { typeName, typeArgs } = parseTypeName(type)
|
|
49
|
+
switch (typeName) {
|
|
50
|
+
case '0x1::string::String':
|
|
51
|
+
case '0x1::ascii::String':
|
|
52
|
+
return BCS.STRING
|
|
53
|
+
case '0x2::object::ID':
|
|
54
|
+
return BCS.ADDRESS
|
|
55
|
+
case '0x1::option::Option':
|
|
56
|
+
return `vector<${convertType(typeArgs[0])}>`
|
|
57
|
+
case 'vector':
|
|
58
|
+
return `vector<${convertType(typeArgs[0])}>`
|
|
59
|
+
default:
|
|
60
|
+
return type
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function isOrHasNestedTransactionArgument(arg: PureArg): boolean {
|
|
65
|
+
if (Array.isArray(arg)) {
|
|
66
|
+
return arg.some(item => isOrHasNestedTransactionArgument(item))
|
|
67
|
+
}
|
|
68
|
+
return is(arg, TransactionArgument)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function convertArg(arg: PureArg, type: Type): PureArg {
|
|
72
|
+
const { typeName, typeArgs } = parseTypeName(type)
|
|
73
|
+
if (typeName === '0x1::option::Option') {
|
|
74
|
+
if (arg === null) {
|
|
75
|
+
return []
|
|
76
|
+
} else {
|
|
77
|
+
return [convertArg(arg, typeArgs[0])]
|
|
78
|
+
}
|
|
79
|
+
} else if (typeName === 'vector' && Array.isArray(arg)) {
|
|
80
|
+
return arg.map(item => convertArg(item, typeArgs[0]))
|
|
81
|
+
} else if (typeName === '0x2::object::ID' || typeName === 'address') {
|
|
82
|
+
return normalizeSuiAddress(arg as string)
|
|
83
|
+
} else {
|
|
84
|
+
return arg
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// handle some cases when TransactionArgument is nested within a vector or option
|
|
89
|
+
const { typeName, typeArgs } = parseTypeName(type)
|
|
90
|
+
switch (typeName) {
|
|
91
|
+
case '0x1::option::Option':
|
|
92
|
+
if (arg === null) {
|
|
93
|
+
return txb.pure([], `vector<${convertType(typeArgs[0])}>`)
|
|
94
|
+
}
|
|
95
|
+
if (isOrHasNestedTransactionArgument(arg)) {
|
|
96
|
+
throw new Error('nesting TransactionArgument is not currently supported')
|
|
97
|
+
}
|
|
98
|
+
break
|
|
99
|
+
case 'vector':
|
|
100
|
+
if (!Array.isArray(arg)) {
|
|
101
|
+
throw new Error('expected an array for vector type')
|
|
102
|
+
}
|
|
103
|
+
if (arg.length === 0) {
|
|
104
|
+
return txb.pure([], `vector<${convertType(typeArgs[0])}>`)
|
|
105
|
+
}
|
|
106
|
+
if (arg.some(arg => Array.isArray(arg) && isOrHasNestedTransactionArgument(arg))) {
|
|
107
|
+
throw new Error('nesting TransactionArgument is not currently supported')
|
|
108
|
+
}
|
|
109
|
+
if (
|
|
110
|
+
is(arg[0], TransactionArgument) &&
|
|
111
|
+
arg.filter(arg => !is(arg, TransactionArgument)).length > 0
|
|
112
|
+
) {
|
|
113
|
+
throw new Error('mixing TransactionArgument with other types is not currently supported')
|
|
114
|
+
}
|
|
115
|
+
if (is(arg[0], TransactionArgument)) {
|
|
116
|
+
return txb.makeMoveVec({
|
|
117
|
+
objects: arg as Array<TransactionArgument>,
|
|
118
|
+
type: typeArgs[0],
|
|
119
|
+
})
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return txb.pure(convertArg(arg, type), convertType(type))
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function option(txb: TransactionBlock, type: Type, arg: GenericArg | null) {
|
|
127
|
+
if (arg === null) {
|
|
128
|
+
return pure(txb, arg, `0x1::option::Option<${type}>`)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (typeArgIsPure(type)) {
|
|
132
|
+
return pure(txb, arg as PureArg | TransactionArgument, `0x1::option::Option<${type}>`)
|
|
133
|
+
} else if (is(arg, TransactionArgument)) {
|
|
134
|
+
return arg
|
|
135
|
+
} else {
|
|
136
|
+
if (arg === null) {
|
|
137
|
+
return pure(txb, arg, `vector<${type}>`)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// wrap it with some
|
|
141
|
+
const val = generic(txb, type, arg)
|
|
142
|
+
return txb.moveCall({
|
|
143
|
+
target: `0x1::option::some`,
|
|
144
|
+
typeArguments: [type],
|
|
145
|
+
arguments: [val],
|
|
146
|
+
})
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function generic(txb: TransactionBlock, type: Type, arg: GenericArg) {
|
|
151
|
+
if (typeArgIsPure(type)) {
|
|
152
|
+
return pure(txb, arg as PureArg | TransactionArgument, type)
|
|
153
|
+
} else {
|
|
154
|
+
const { typeName, typeArgs } = parseTypeName(type)
|
|
155
|
+
if (typeName === 'vector' && Array.isArray(arg)) {
|
|
156
|
+
const itemType = typeArgs[0]
|
|
157
|
+
|
|
158
|
+
return txb.makeMoveVec({
|
|
159
|
+
objects: arg.map(item => obj(txb, item as ObjectArg)),
|
|
160
|
+
type: itemType,
|
|
161
|
+
})
|
|
162
|
+
} else {
|
|
163
|
+
return obj(txb, arg as ObjectArg)
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export function vector(
|
|
169
|
+
txb: TransactionBlock,
|
|
170
|
+
itemType: Type,
|
|
171
|
+
items: Array<GenericArg> | TransactionArgument
|
|
172
|
+
) {
|
|
173
|
+
if (typeArgIsPure(itemType)) {
|
|
174
|
+
return pure(txb, items as PureArg, `vector<${itemType}>`)
|
|
175
|
+
} else if (is(items, TransactionArgument)) {
|
|
176
|
+
return items
|
|
177
|
+
} else {
|
|
178
|
+
const { typeName: itemTypeName, typeArgs: itemTypeArgs } = parseTypeName(itemType)
|
|
179
|
+
if (itemTypeName === '0x1::option::Option') {
|
|
180
|
+
const objects = items.map(item => option(txb, itemTypeArgs[0], item))
|
|
181
|
+
return txb.makeMoveVec({
|
|
182
|
+
objects,
|
|
183
|
+
type: itemType,
|
|
184
|
+
})
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return txb.makeMoveVec({
|
|
188
|
+
objects: items as Array<TransactionArgument>,
|
|
189
|
+
type: itemType,
|
|
190
|
+
})
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export function typeArgIsPure(type: Type): boolean {
|
|
195
|
+
const { typeName, typeArgs } = parseTypeName(type)
|
|
196
|
+
switch (typeName) {
|
|
197
|
+
case 'bool':
|
|
198
|
+
case 'u8':
|
|
199
|
+
case 'u16':
|
|
200
|
+
case 'u32':
|
|
201
|
+
case 'u64':
|
|
202
|
+
case 'u128':
|
|
203
|
+
case 'u256':
|
|
204
|
+
case 'address':
|
|
205
|
+
case 'signer':
|
|
206
|
+
return true
|
|
207
|
+
case 'vector':
|
|
208
|
+
return typeArgIsPure(typeArgs[0])
|
|
209
|
+
case '0x1::string::String':
|
|
210
|
+
case '0x1::ascii::String':
|
|
211
|
+
case '0x2::object::ID':
|
|
212
|
+
return true
|
|
213
|
+
case '0x1::option::Option':
|
|
214
|
+
return typeArgIsPure(typeArgs[0])
|
|
215
|
+
default:
|
|
216
|
+
return false
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
package/src/index.ts
CHANGED
|
@@ -7,4 +7,5 @@ export { Obelisk } from './obelisk';
|
|
|
7
7
|
export { SuiAccountManager } from './libs/suiAccountManager';
|
|
8
8
|
export { SuiTxBlock } from './libs/suiTxBuilder';
|
|
9
9
|
export { SuiRpcProvider } from './libs/suiRpcProvider';
|
|
10
|
+
export { SuiContractFactory } from './libs/suiContractFactory';
|
|
10
11
|
export type * from './types';
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { SuiMoveNormalizedModules} from '@mysten/sui.js';
|
|
2
|
+
import type { ContractFactoryParams, SuiMoveMoudleValueType } from './types';
|
|
3
|
+
export type ApiTypes = 'promise' | 'rxjs';
|
|
4
|
+
|
|
5
|
+
// export interface ContractQuery {
|
|
6
|
+
// (origin: AccountId | string | Uint8Array, options: ContractOptions, ...params: unknown[]): SuiTransactionBlockResponse<ApiType, ContractCallOutcome>;
|
|
7
|
+
// }
|
|
8
|
+
|
|
9
|
+
// export type MapMessageQuery<ApiType extends ApiTypes> = Record<string, ContractQuery<ApiType>>;
|
|
10
|
+
|
|
11
|
+
// // function createQuery <ApiType extends ApiTypes> (meta: AbiMessage, fn: (origin: string | AccountId | Uint8Array, options: ContractOptions, params: unknown[]) => ContractCallResult<ApiType, ContractCallOutcome>): ContractQuery<ApiType> {
|
|
12
|
+
// // return withMeta(meta, (origin: string | AccountId | Uint8Array, options: ContractOptions, ...params: unknown[]): ContractCallResult<ApiType, ContractCallOutcome> =>
|
|
13
|
+
// // fn(origin, options, params)
|
|
14
|
+
// // );
|
|
15
|
+
// // }
|
|
16
|
+
|
|
17
|
+
// export type MapMessageTx<ApiType extends ApiTypes> = Record<string, ContractTx<ApiType>>;
|
|
18
|
+
|
|
19
|
+
// export interface ContractOptions {
|
|
20
|
+
// gasLimit?: bigint | string | number | BN | WeightV2;
|
|
21
|
+
// storageDepositLimit?: bigint | string | number | BN | null;
|
|
22
|
+
// value?: bigint | BN | string | number;
|
|
23
|
+
// }
|
|
24
|
+
|
|
25
|
+
// export interface ContractTx {
|
|
26
|
+
// (options: ContractOptions, ...params: unknown[]): SubmittableExtrinsic<ApiType>;
|
|
27
|
+
// }
|
|
28
|
+
export class SuiContractFactory {
|
|
29
|
+
public packageId: string;
|
|
30
|
+
public metadata: SuiMoveNormalizedModules | undefined;
|
|
31
|
+
// readonly #query: MapMessageQuery<ApiTypes> = {};
|
|
32
|
+
// readonly #tx: MapMessageTx<ApiTypes> = {};
|
|
33
|
+
/**
|
|
34
|
+
* Support the following ways to init the SuiToolkit:
|
|
35
|
+
* 1. mnemonics
|
|
36
|
+
* 2. secretKey (base64 or hex)
|
|
37
|
+
* If none of them is provided, will generate a random mnemonics with 24 words.
|
|
38
|
+
*
|
|
39
|
+
* @param mnemonics, 12 or 24 mnemonics words, separated by space
|
|
40
|
+
* @param secretKey, base64 or hex string, when mnemonics is provided, secretKey will be ignored
|
|
41
|
+
*/
|
|
42
|
+
constructor({ packageId, metadata }: ContractFactoryParams = {}) {
|
|
43
|
+
// If the mnemonics or secretKey is provided, use it
|
|
44
|
+
// Otherwise, generate a random mnemonics with 24 words
|
|
45
|
+
this.packageId = packageId || '';
|
|
46
|
+
this.metadata = metadata || undefined;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
getFuncByModuleName(moduleName: string) {
|
|
50
|
+
Object.values(this.metadata as SuiMoveNormalizedModules).forEach(
|
|
51
|
+
(value) => {
|
|
52
|
+
const data = value as SuiMoveMoudleValueType;
|
|
53
|
+
console.log(`moudle name: ${data.name}`);
|
|
54
|
+
// console.log(data.exposedFunctions)
|
|
55
|
+
Object.entries(data.exposedFunctions).forEach(([key, value]) => {
|
|
56
|
+
console.log(`\tfunc name: ${key}`);
|
|
57
|
+
Object.values(value.parameters).forEach((values) => {
|
|
58
|
+
// console.log(values)
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
getAllFunc() {
|
|
66
|
+
Object.values(this.metadata as SuiMoveNormalizedModules).forEach(
|
|
67
|
+
(value) => {
|
|
68
|
+
const data = value as SuiMoveMoudleValueType;
|
|
69
|
+
console.log(`moudle name: ${data.name}`);
|
|
70
|
+
// console.log(data.exposedFunctions)
|
|
71
|
+
Object.entries(data.exposedFunctions).forEach(([key, value]) => {
|
|
72
|
+
console.log(`\tfunc name: ${key}`);
|
|
73
|
+
console.log(`\t\t${value.parameters.length}`);
|
|
74
|
+
Object.values(value.parameters).forEach((values) => {
|
|
75
|
+
// console.log(values)
|
|
76
|
+
console.log(`\t\targs: ${values}`);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
getAllModule() {
|
|
84
|
+
Object.values(this.metadata as SuiMoveNormalizedModules).forEach(
|
|
85
|
+
(value, index) => {
|
|
86
|
+
const data = value as SuiMoveMoudleValueType;
|
|
87
|
+
console.log(`${index}. ${data.name}`);
|
|
88
|
+
}
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
async worldCall() {}
|
|
92
|
+
|
|
93
|
+
// async call(arguments: ({
|
|
94
|
+
// kind: "Input";
|
|
95
|
+
// index: number;
|
|
96
|
+
// type?: "object" | "pure" | undefined;
|
|
97
|
+
// value?: any;
|
|
98
|
+
// } | {
|
|
99
|
+
// kind: "GasCoin";
|
|
100
|
+
// } | {
|
|
101
|
+
// kind: "Result";
|
|
102
|
+
// index: number;
|
|
103
|
+
// } | {
|
|
104
|
+
// kind: "NestedResult";
|
|
105
|
+
// index: number;
|
|
106
|
+
// resultIndex: number;
|
|
107
|
+
// })[], derivePathParams?: DerivePathParams) {
|
|
108
|
+
// const tx = new TransactionBlock();
|
|
109
|
+
// tx.moveCall({
|
|
110
|
+
// target: `${this.packageId}::${}::${}`,
|
|
111
|
+
// arguments,
|
|
112
|
+
// })
|
|
113
|
+
// return ;
|
|
114
|
+
// }
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// function createTx <ApiType extends ApiTypes> (meta: AbiMessage, fn: (options: ContractOptions, params: unknown[]) => SubmittableExtrinsic<ApiType>): ContractTx<ApiType> {
|
|
118
|
+
// return withMeta(meta, (options: ContractOptions, ...params: unknown[]): SubmittableExtrinsic<ApiType> =>
|
|
119
|
+
// fn(options, params)
|
|
120
|
+
// );
|
|
121
|
+
// }
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { SuiMoveNormalizedModules, SuiMoveNormalizedType } from "@mysten/sui.js";
|
|
2
|
+
|
|
3
|
+
export type ContractFactoryParams = {
|
|
4
|
+
packageId?: string;
|
|
5
|
+
metadata?: SuiMoveNormalizedModules;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
export type SuiMoveMoudleValueType = {
|
|
10
|
+
address: string;
|
|
11
|
+
name: string;
|
|
12
|
+
fileFormatVersion: number;
|
|
13
|
+
friends: {
|
|
14
|
+
address: string;
|
|
15
|
+
name: string;
|
|
16
|
+
}[];
|
|
17
|
+
structs: Record<string, {
|
|
18
|
+
fields: {
|
|
19
|
+
type: SuiMoveNormalizedType;
|
|
20
|
+
name: string;
|
|
21
|
+
}[];
|
|
22
|
+
abilities: {
|
|
23
|
+
abilities: string[];
|
|
24
|
+
};
|
|
25
|
+
typeParameters: {
|
|
26
|
+
constraints: {
|
|
27
|
+
abilities: string[];
|
|
28
|
+
};
|
|
29
|
+
isPhantom: boolean;
|
|
30
|
+
}[];
|
|
31
|
+
}>;
|
|
32
|
+
exposedFunctions: Record<string, {
|
|
33
|
+
visibility: "Private" | "Public" | "Friend";
|
|
34
|
+
isEntry: boolean;
|
|
35
|
+
typeParameters: {
|
|
36
|
+
abilities: string[];
|
|
37
|
+
}[];
|
|
38
|
+
parameters: SuiMoveNormalizedType[];
|
|
39
|
+
return: SuiMoveNormalizedType[];
|
|
40
|
+
}>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
export type SuiMoveMoudleFuncType = {
|
|
45
|
+
moudleName: string,
|
|
46
|
+
funcName: string,
|
|
47
|
+
visibility: "Private" | "Public" | "Friend";
|
|
48
|
+
isEntry: boolean;
|
|
49
|
+
typeParameters: {
|
|
50
|
+
abilities: string[];
|
|
51
|
+
}[];
|
|
52
|
+
parameters: SuiMoveNormalizedType[];
|
|
53
|
+
return: SuiMoveNormalizedType[];
|
|
54
|
+
}
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
getObjectFields,
|
|
7
7
|
getObjectDisplay,
|
|
8
8
|
getObjectVersion,
|
|
9
|
+
DynamicFieldName
|
|
9
10
|
} from '@mysten/sui.js';
|
|
10
11
|
import { requestFaucet } from './faucet';
|
|
11
12
|
import { getDefaultNetworkParams } from './defaultChainConfigs';
|
|
@@ -54,6 +55,32 @@ export class SuiRpcProvider {
|
|
|
54
55
|
return this.provider.getBalance({ owner: addr, coinType });
|
|
55
56
|
}
|
|
56
57
|
|
|
58
|
+
|
|
59
|
+
async getDynamicFieldObject(parentId: string, name: string | DynamicFieldName) {
|
|
60
|
+
return this.provider.getDynamicFieldObject({ parentId, name })
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async getDynamicFields(parentId: string, cursor?: string, limit?: number) {
|
|
64
|
+
return this.provider.getDynamicFields({ parentId, cursor, limit })
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async getObject(id: string) {
|
|
68
|
+
const options = { showContent: true, showDisplay: true, showType: true };
|
|
69
|
+
const object = await this.provider.getObject({ id, options });
|
|
70
|
+
const objectId = getObjectId(object);
|
|
71
|
+
const objectType = getObjectType(object);
|
|
72
|
+
const objectVersion = getObjectVersion(object);
|
|
73
|
+
const objectFields = getObjectFields(object);
|
|
74
|
+
const objectDisplay = getObjectDisplay(object);
|
|
75
|
+
return {
|
|
76
|
+
objectId,
|
|
77
|
+
objectType,
|
|
78
|
+
objectVersion,
|
|
79
|
+
objectFields,
|
|
80
|
+
objectDisplay,
|
|
81
|
+
} as ObjectData;
|
|
82
|
+
}
|
|
83
|
+
|
|
57
84
|
async getObjects(ids: string[]) {
|
|
58
85
|
const options = { showContent: true, showDisplay: true, showType: true };
|
|
59
86
|
const objects = await this.provider.multiGetObjects({ ids, options });
|
|
@@ -74,6 +101,10 @@ export class SuiRpcProvider {
|
|
|
74
101
|
return parsedObjects as ObjectData[];
|
|
75
102
|
}
|
|
76
103
|
|
|
104
|
+
async getNormalizedMoveModulesByPackage(packageId: string) {
|
|
105
|
+
return this.provider.getNormalizedMoveModulesByPackage({package: packageId});
|
|
106
|
+
}
|
|
107
|
+
|
|
77
108
|
/**
|
|
78
109
|
* @description Select coins that add up to the given amount.
|
|
79
110
|
* @param addr the address of the owner
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import {
|
|
2
|
+
RawSigner,
|
|
3
|
+
TransactionBlock,
|
|
4
|
+
DevInspectResults,
|
|
5
|
+
SuiTransactionBlockResponse, JsonRpcProvider, testnetConnection,
|
|
6
|
+
SuiMoveNormalizedModules, DynamicFieldPage, DynamicFieldName,
|
|
7
|
+
} from '@mysten/sui.js';
|
|
8
|
+
import { SuiAddress } from "@mysten/sui.js/src/types";
|
|
9
|
+
import { SuiRpcProvider } from '../libs/suiRpcProvider';
|
|
10
|
+
import { NetworkType } from '../libs/suiRpcProvider/types';
|
|
11
|
+
import * as fs from 'fs';
|
|
12
|
+
|
|
13
|
+
export async function initialize(networkType: NetworkType, packageId: string) {
|
|
14
|
+
const jsonFileName = `metadata/${packageId}.json`;
|
|
15
|
+
|
|
16
|
+
const rpcProvider = new SuiRpcProvider({
|
|
17
|
+
networkType,
|
|
18
|
+
});
|
|
19
|
+
try {
|
|
20
|
+
const data = await fs.promises.readFile(jsonFileName, 'utf-8');
|
|
21
|
+
const jsonData = JSON.parse(data);
|
|
22
|
+
|
|
23
|
+
return jsonData as SuiMoveNormalizedModules;
|
|
24
|
+
} catch (error) {
|
|
25
|
+
if (packageId !== undefined) {
|
|
26
|
+
const jsonData = await rpcProvider.getNormalizedMoveModulesByPackage(packageId);
|
|
27
|
+
|
|
28
|
+
fs.writeFile(jsonFileName, JSON.stringify(jsonData, null, 2), (err) => {
|
|
29
|
+
if (err) {
|
|
30
|
+
console.error('写入文件时出错:', err);
|
|
31
|
+
} else {
|
|
32
|
+
console.log('JSON 数据已保存到文件:', jsonFileName);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
return jsonData as SuiMoveNormalizedModules;
|
|
36
|
+
} else {
|
|
37
|
+
console.error('please set your package id.');
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|