suidouble 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/LICENSE +201 -0
- package/README.md +302 -0
- package/index.js +9 -0
- package/lib/SuiCliCommands.js +67 -0
- package/lib/SuiCommonMethods.js +44 -0
- package/lib/SuiEvent.js +35 -0
- package/lib/SuiInBrowser.js +284 -0
- package/lib/SuiInBrowserAdapter.js +181 -0
- package/lib/SuiLocalTestValidator.js +93 -0
- package/lib/SuiMaster.js +199 -0
- package/lib/SuiMemoryObjectStorage.js +69 -0
- package/lib/SuiObject.js +211 -0
- package/lib/SuiPackage.js +520 -0
- package/lib/SuiPackageModule.js +314 -0
- package/lib/SuiPaginatedResponse.js +76 -0
- package/lib/SuiPseudoRandomAddress.js +35 -0
- package/lib/SuiTestScenario.js +161 -0
- package/lib/data/icons.json +8 -0
- package/package.json +15 -0
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
const sui = require('@mysten/sui.js');
|
|
2
|
+
const SuiObject = require('./SuiObject.js');
|
|
3
|
+
|
|
4
|
+
const SuiCommonMethods = require('./SuiCommonMethods.js');
|
|
5
|
+
const SuiPaginatedResponse = require('./SuiPaginatedResponse.js');
|
|
6
|
+
// fromB64, toB64
|
|
7
|
+
|
|
8
|
+
class SuiPackageModule extends SuiCommonMethods {
|
|
9
|
+
constructor(params = {}) {
|
|
10
|
+
super(params);
|
|
11
|
+
|
|
12
|
+
this._package = params.package;
|
|
13
|
+
if (!this._package) {
|
|
14
|
+
throw new Error('package is required for SuiPackageModule');
|
|
15
|
+
}
|
|
16
|
+
this._suiMaster = params.suiMaster;
|
|
17
|
+
if (!this._suiMaster) {
|
|
18
|
+
throw new Error('suiMaster is requried for SuiPackageModule');
|
|
19
|
+
}
|
|
20
|
+
this._moduleName = params.moduleName;
|
|
21
|
+
if (!this._moduleName) {
|
|
22
|
+
throw new Error('moduleName is required for SuiPackageModule');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// this._objects = {};
|
|
26
|
+
// this._objectsArray = [];
|
|
27
|
+
|
|
28
|
+
// we need to get very first version's address of this package to use for types, so we are doing this in separate call
|
|
29
|
+
this._checkedOnChain = false;
|
|
30
|
+
this._normalizedMoveModule = {};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
get objectStorage() {
|
|
34
|
+
return this._suiMaster.objectStorage;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
get objects() {
|
|
38
|
+
return this.objectStorage._objects;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
get objectsArray() {
|
|
42
|
+
return this.objectStorage.asArray();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
pushObject(suiObjectOrAddress) {
|
|
46
|
+
let address = `${suiObjectOrAddress}`;
|
|
47
|
+
if (suiObjectOrAddress.address) {
|
|
48
|
+
address = suiObjectOrAddress.address;
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
address = sui.normalizeSuiAddress(address);
|
|
52
|
+
if (!this.objectStorage.byAddress(address)) {
|
|
53
|
+
if (suiObjectOrAddress.address) {
|
|
54
|
+
// instance of suiObject
|
|
55
|
+
this.objectStorage.push(suiObjectOrAddress);
|
|
56
|
+
} else {
|
|
57
|
+
const obj = new SuiObject({
|
|
58
|
+
suiMaster: this._suiMaster,
|
|
59
|
+
debug: this._debug,
|
|
60
|
+
id: address,
|
|
61
|
+
});
|
|
62
|
+
this.objectStorage.push(obj);
|
|
63
|
+
this.emit('added', obj);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return this.objectStorage.byAddress(address);
|
|
68
|
+
} catch (e) {
|
|
69
|
+
this.log('error', e);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async moveCall(methodName, params) {
|
|
76
|
+
await this._package.checkOnChainIfNeeded();
|
|
77
|
+
|
|
78
|
+
const tx = new sui.TransactionBlock();
|
|
79
|
+
|
|
80
|
+
const callArgs = [];
|
|
81
|
+
for (let param of params) {
|
|
82
|
+
callArgs.push(tx.pure(param));
|
|
83
|
+
}
|
|
84
|
+
tx.moveCall({
|
|
85
|
+
target: `${this._package.address}::${this._moduleName}::${methodName}`,
|
|
86
|
+
arguments: callArgs,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const result = await this._suiMaster._signer.signAndExecuteTransactionBlock({
|
|
90
|
+
transactionBlock: tx,
|
|
91
|
+
requestType: 'WaitForLocalExecution',
|
|
92
|
+
options: {
|
|
93
|
+
"showEffects": true, // @todo: remove?
|
|
94
|
+
"showEvents": true, // @todo: remove?
|
|
95
|
+
"showObjectChanges": true,
|
|
96
|
+
showType: true,
|
|
97
|
+
showContent: true,
|
|
98
|
+
showOwner: true,
|
|
99
|
+
showDisplay: true,
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const listCreated = [];
|
|
104
|
+
const listMutated = [];
|
|
105
|
+
const listDeleted = [];
|
|
106
|
+
|
|
107
|
+
console.error('result', result);
|
|
108
|
+
|
|
109
|
+
for (const objectChange of result.objectChanges) {
|
|
110
|
+
if (objectChange.objectId) {
|
|
111
|
+
if (this.objectStorage.byAddress(objectChange.objectId)) {
|
|
112
|
+
this.objectStorage.byAddress(objectChange.objectId).tryToFillDataFromObjectChange(objectChange);
|
|
113
|
+
} else {
|
|
114
|
+
const obj = new SuiObject({
|
|
115
|
+
suiMaster: this._suiMaster,
|
|
116
|
+
debug: this._debug,
|
|
117
|
+
objectChange: objectChange,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
if (obj.address) {
|
|
121
|
+
this.objectStorage.push(obj);
|
|
122
|
+
|
|
123
|
+
this.emit('added', obj);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Mark objects as deleted so we don't fetch them
|
|
130
|
+
if (result.effects && result.effects.deleted && result.effects.deleted.length) {
|
|
131
|
+
for (const effect of result.effects.deleted) {
|
|
132
|
+
// if (effect.reference && effect.reference.objectId) {
|
|
133
|
+
// if (this._objects[effect.reference.objectId]) {
|
|
134
|
+
// this.log('object is deleted', effect.reference.objectId);
|
|
135
|
+
// this._objects[effect.reference.objectId].markAsDeleted();
|
|
136
|
+
// }
|
|
137
|
+
// }
|
|
138
|
+
if (effect.objectId) {
|
|
139
|
+
if (this.objectStorage.byAddress(effect.objectId)) {
|
|
140
|
+
this.log('object is deleted', effect.objectId);
|
|
141
|
+
this.objectStorage.byAddress(effect.objectId).markAsDeleted();
|
|
142
|
+
this.emit('deleted', this.objectStorage.byAddress(effect.objectId));
|
|
143
|
+
|
|
144
|
+
listDeleted.push(this.objectStorage.byAddress(effect.objectId));
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
await this.fetchObjects();
|
|
151
|
+
|
|
152
|
+
// Emit events based on result.effects
|
|
153
|
+
if (result.effects) {
|
|
154
|
+
const events = ['created', 'mutated']; // events names are the same as properties in result.effects
|
|
155
|
+
|
|
156
|
+
for (const eventName of events) {
|
|
157
|
+
if (result.effects[eventName] && result.effects[eventName].length) {
|
|
158
|
+
for (const effect of result.effects[eventName]) {
|
|
159
|
+
if (effect.reference && effect.reference.objectId) {
|
|
160
|
+
if (this.objectStorage.byAddress(effect.reference.objectId)) {
|
|
161
|
+
this.emit(eventName, this.objectStorage.byAddress(effect.reference.objectId));
|
|
162
|
+
|
|
163
|
+
if (eventName === 'created') {
|
|
164
|
+
listCreated.push(this.objectStorage.byAddress(effect.reference.objectId));
|
|
165
|
+
} else if (eventName === 'mutated') {
|
|
166
|
+
listMutated.push(this.objectStorage.byAddress(effect.reference.objectId));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (result.events && result.events.length) {
|
|
176
|
+
for (const event of result.events) {
|
|
177
|
+
const eventType = event.type;
|
|
178
|
+
const eventTypeName = eventType.split(':').pop(); // last name, without package and module names
|
|
179
|
+
|
|
180
|
+
const eventData = event.parsedJson;
|
|
181
|
+
this.emit(eventTypeName, eventData);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return {
|
|
186
|
+
created: listCreated,
|
|
187
|
+
mutated: listMutated,
|
|
188
|
+
deleted: listDeleted,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
async fetchEvents(params = {}) {
|
|
193
|
+
const moduleFilter = {};
|
|
194
|
+
|
|
195
|
+
// we need very first package version's id here. So we are getting it from normalized data
|
|
196
|
+
const normalizedPackageAddress = await this.getNormalizedPackageAddress();
|
|
197
|
+
if (params.eventTypeName) {
|
|
198
|
+
moduleFilter.MoveEventType = `${normalizedPackageAddress}::${this._moduleName}::${params.eventTypeName}`;
|
|
199
|
+
this.log('queriying for events of type: ', moduleFilter.MoveEventType);
|
|
200
|
+
} else {
|
|
201
|
+
moduleFilter.MoveModule = { package: normalizedPackageAddress, module: this._moduleName };
|
|
202
|
+
this.log('queriying for all events of module: ', this._moduleName);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const queryParams = {
|
|
206
|
+
descending_order: false,
|
|
207
|
+
query: moduleFilter,
|
|
208
|
+
limit: params.limit || 50,
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
const paginatedResponse = new SuiPaginatedResponse({
|
|
212
|
+
debug: this._debug,
|
|
213
|
+
suiMaster: this._suiMaster,
|
|
214
|
+
params: queryParams,
|
|
215
|
+
method: 'queryEvents',
|
|
216
|
+
order: params.order,
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
await paginatedResponse.fetch();
|
|
220
|
+
|
|
221
|
+
return paginatedResponse;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
async fetchObjects() {
|
|
225
|
+
const objectsToFetch = this.objectStorage.asArray(); //Object.values(this._objects);
|
|
226
|
+
|
|
227
|
+
const objectIds = [];
|
|
228
|
+
for (const object of objectsToFetch) {
|
|
229
|
+
if (!object.isDeleted && objectIds.indexOf(object.address) === -1) {
|
|
230
|
+
objectIds.push(object.address);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
this.log('querying details about', objectIds.length, 'objects');
|
|
235
|
+
this.log(objectIds);
|
|
236
|
+
|
|
237
|
+
let results = [];
|
|
238
|
+
const maxCountToFetch = 50;
|
|
239
|
+
for (let i = 0; i < objectIds.length; i += maxCountToFetch) {
|
|
240
|
+
const objectIdsSlice = objectIds.slice(i, i + maxCountToFetch);
|
|
241
|
+
|
|
242
|
+
let resultsSlice = [];
|
|
243
|
+
let consoleWarnMessage = null;
|
|
244
|
+
try {
|
|
245
|
+
const originalConsoleWarn = console.warn;
|
|
246
|
+
console.warn = (e)=>{
|
|
247
|
+
consoleWarnMessage = e;
|
|
248
|
+
};
|
|
249
|
+
resultsSlice = await this._suiMaster._provider.multiGetObjects({
|
|
250
|
+
ids: objectIdsSlice,
|
|
251
|
+
// only fetch the object type
|
|
252
|
+
options: { showType: true, showContent: true, showOwner: true, showDisplay: true, },
|
|
253
|
+
});
|
|
254
|
+
console.warn = originalConsoleWarn;
|
|
255
|
+
} catch(e) {
|
|
256
|
+
console.error(e);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (consoleWarnMessage) {
|
|
260
|
+
this.log('got', resultsSlice.length, 'objects but with warning (ok, but probably it is different client vs rpc versions)');
|
|
261
|
+
} else {
|
|
262
|
+
this.log('got', resultsSlice.length, 'objects');
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (resultsSlice && resultsSlice.length) {
|
|
266
|
+
results = results.concat(resultsSlice);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
for (const object of objectsToFetch) {
|
|
271
|
+
const foundInResults = results.find(element => object.idEquals(element?.data?.objectId));
|
|
272
|
+
if (foundInResults) {
|
|
273
|
+
object.tryToFillDataFromObjectChange(foundInResults);
|
|
274
|
+
// this.log('got updates for object', object.address, object.fields);
|
|
275
|
+
} else {
|
|
276
|
+
// object is removed?
|
|
277
|
+
const foundInRemoved = results.find(element => (element?.error?.code == 'deleted' && object.idEquals(element?.error?.object_id)));
|
|
278
|
+
if (foundInRemoved) {
|
|
279
|
+
object.markAsDeleted();
|
|
280
|
+
} else {
|
|
281
|
+
this.log('not found in results', object);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
async getNormalizedPackageAddress() {
|
|
288
|
+
await this.checkOnChainIfNeeded();
|
|
289
|
+
if (this._normalizedMoveModule && this._normalizedMoveModule.address) {
|
|
290
|
+
return this._normalizedMoveModule.address;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
async checkOnChainIfNeeded() {
|
|
295
|
+
if (this._checkedOnChain) {
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const normalized = await this._suiMaster._provider.getNormalizedMoveModule({
|
|
300
|
+
package: this._package.address,
|
|
301
|
+
module: this._moduleName,
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
if (normalized && normalized.address) {
|
|
305
|
+
this._normalizedMoveModule = normalized;
|
|
306
|
+
this._checkedOnChain = true;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return true;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
module.exports = SuiPackageModule;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
const sui = require('@mysten/sui.js');
|
|
2
|
+
const SuiCommonMethods = require('./SuiCommonMethods.js');
|
|
3
|
+
const SuiEvent = require('./SuiEvent.js');
|
|
4
|
+
|
|
5
|
+
class SuiPaginatedResponse extends SuiCommonMethods {
|
|
6
|
+
constructor(params = {}) {
|
|
7
|
+
super(params);
|
|
8
|
+
|
|
9
|
+
this._suiMaster = params.suiMaster;
|
|
10
|
+
if (!this._suiMaster) {
|
|
11
|
+
throw new Error('suiMaster is requried for SuiPaginatedResponse');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
this._method = params.method;
|
|
15
|
+
this._params = params.params;
|
|
16
|
+
this._order = params.order || 'descending'; // default - newest first, pass {order: 'ascending'} for oldest first
|
|
17
|
+
|
|
18
|
+
this._hasNextPage = true;
|
|
19
|
+
this._nextCursor = null;
|
|
20
|
+
|
|
21
|
+
this._data = [];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
get hasNextPage() {
|
|
25
|
+
return this._hasNextPage;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
get data() {
|
|
29
|
+
return this._data;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async nextPage() {
|
|
33
|
+
if (this._hasNextPage) {
|
|
34
|
+
return await this.fetch({cursor: this._nextCursor});
|
|
35
|
+
} else {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async fetch(params = {}) {
|
|
41
|
+
const paramsCopy = Object.assign({}, this._params);
|
|
42
|
+
// paramsCopy.limit = 3;
|
|
43
|
+
|
|
44
|
+
if (params.cursor) {
|
|
45
|
+
paramsCopy.cursor = params.cursor;
|
|
46
|
+
}
|
|
47
|
+
paramsCopy.order = this._order;
|
|
48
|
+
|
|
49
|
+
const response = await this._suiMaster.provider[this._method](paramsCopy);
|
|
50
|
+
let responseCount = 0;
|
|
51
|
+
if (response.data && response.data.length) {
|
|
52
|
+
responseCount = response.data.length;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (response.hasNextPage) {
|
|
56
|
+
this._hasNextPage = true;
|
|
57
|
+
this._nextCursor = response.nextCursor;
|
|
58
|
+
} else {
|
|
59
|
+
this._hasNextPage = false;
|
|
60
|
+
this._nextCursor = null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
this.log('got', responseCount, 'items. Has next page: ', response.hasNextPage);
|
|
64
|
+
|
|
65
|
+
if (this._method === 'queryEvents') {
|
|
66
|
+
// convert data to SuiEvent instances
|
|
67
|
+
this._data = response.data.map((raw)=>(new SuiEvent({data: raw, suiMaster: this._suiMaster, debug: this._debug})));
|
|
68
|
+
} else {
|
|
69
|
+
this._data = response.data;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return this._data;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
module.exports = SuiPaginatedResponse;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const { entropyToMnemonic } = require('@scure/bip39');
|
|
2
|
+
const { wordlist } = require('@scure/bip39/wordlists/english');
|
|
3
|
+
const { Ed25519Keypair } = require('@mysten/sui.js');
|
|
4
|
+
|
|
5
|
+
class SuiPseudoRandomAddress {
|
|
6
|
+
static stringToKeyPair(as) {
|
|
7
|
+
const pseudoRandomPhrase = SuiPseudoRandomAddress.stringToPhrase(as);
|
|
8
|
+
return Ed25519Keypair.deriveKeypair(pseudoRandomPhrase);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
static stringToPhrase(as) {
|
|
12
|
+
let asToHash = `${as}`;
|
|
13
|
+
// calculate very simple 32 bytes hash of a string
|
|
14
|
+
do {
|
|
15
|
+
asToHash = asToHash.repeat(2) + '*"'; // just some chars so 'test' and 'testtest' would not produce the same hash
|
|
16
|
+
} while (asToHash.length < 32);
|
|
17
|
+
const asBytes = Array.from(`${asToHash}`).map((e) => e.charCodeAt(0));
|
|
18
|
+
if (asBytes.length > 32) {
|
|
19
|
+
// we fill all bytes into first 32 bytes
|
|
20
|
+
for (let i = 32; i < asBytes.length; i++) {
|
|
21
|
+
const addToPos = i % 32;
|
|
22
|
+
asBytes[addToPos] = (asBytes[addToPos] + asBytes[i]) % 256;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const asUint8Array = new Uint8Array(32); // see .slice(0,32) below
|
|
26
|
+
asUint8Array.set(asBytes.slice(0,32));
|
|
27
|
+
// console.log(asUint8Array);
|
|
28
|
+
// use @scure/bip39 to get mnemonic out of pseudo-random array:
|
|
29
|
+
const phrase = entropyToMnemonic(asUint8Array, wordlist);
|
|
30
|
+
|
|
31
|
+
return phrase;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
module.exports = SuiPseudoRandomAddress;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
const SuiCommonMethods = require('./SuiCommonMethods.js');
|
|
2
|
+
const SuiLocalTestValidator = require('./SuiLocalTestValidator.js');
|
|
3
|
+
const SuiMaster = require('./SuiMaster.js');
|
|
4
|
+
|
|
5
|
+
class SuiTestScenario extends SuiCommonMethods {
|
|
6
|
+
constructor(params = {}) {
|
|
7
|
+
super(params);
|
|
8
|
+
|
|
9
|
+
this._path = params.path; // path to Move package's root
|
|
10
|
+
this._provider = null;
|
|
11
|
+
|
|
12
|
+
this._defaultAs = null; // 'as'(string for pseudo-random keypair generator) for default user and package's owner
|
|
13
|
+
// (we will publish and init from this user)
|
|
14
|
+
this._currentAs = null; // 'as' for current wrapped transaction
|
|
15
|
+
|
|
16
|
+
this._masters = { // suiMaster and package for each 'as'
|
|
17
|
+
};
|
|
18
|
+
this._packages = {
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
this._publishedPackageId = null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Start local test validator and set up `as` as owner of package deploy transaction.
|
|
26
|
+
* Package will be deployed with method `init`, as we try to mimic Sui Move's test_scenario
|
|
27
|
+
* @param {String} as
|
|
28
|
+
*/
|
|
29
|
+
async begin(as) {
|
|
30
|
+
this._provider = await SuiLocalTestValidator.launch({debug: true});
|
|
31
|
+
this._defaultAs = as;
|
|
32
|
+
this._currentAs = as;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Shut down test validator and finish test scenario
|
|
37
|
+
*/
|
|
38
|
+
async end() {
|
|
39
|
+
await SuiLocalTestValidator.stop();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Deploy the package. Move will execute it's init function.
|
|
44
|
+
*/
|
|
45
|
+
async init() {
|
|
46
|
+
if (!this._defaultAs) {
|
|
47
|
+
throw new Error('please call .begin(as) first');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
this._currentAs = this._defaultAs;
|
|
51
|
+
await this.initMaster(this._defaultAs);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Temorary assign user to `as`
|
|
57
|
+
* @param {String} as
|
|
58
|
+
* @param {Function} func
|
|
59
|
+
*/
|
|
60
|
+
async next_tx(as, func) {
|
|
61
|
+
if (!this._defaultAs) {
|
|
62
|
+
throw new Error('please call .begin(as) first');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
await this.initMaster(as);
|
|
67
|
+
this._currentAs = as;
|
|
68
|
+
await func(this);
|
|
69
|
+
this._currentAs = this._defaultAs;
|
|
70
|
+
} catch (e) {
|
|
71
|
+
throw e;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async nextTx(as, func) {
|
|
75
|
+
return this.next_tx(as, func);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
take_from_sender(typeName) {
|
|
79
|
+
const asAsAddress = this._masters[this._currentAs].address;
|
|
80
|
+
const objectStorage = this._masters[this._currentAs].objectStorage; // it's same object for different 'as' connected to the same provider, but we don't care here
|
|
81
|
+
return objectStorage.findMostRecent((object)=>{
|
|
82
|
+
return (object.typeName == typeName && object.isOwnedBy(asAsAddress));
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
takeFromSender(typeName) {
|
|
86
|
+
return this.take_from_sender(typeName);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
take_shared(typeName) {
|
|
90
|
+
const objectStorage = this._masters[this._currentAs].objectStorage; // it's same object for different 'as' connected to the same provider, but we don't care here
|
|
91
|
+
return objectStorage.findMostRecent((object)=>{
|
|
92
|
+
return (object.isShared && object.typeName == typeName);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
takeShared(typeName) {
|
|
96
|
+
return this.take_shared(typeName);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
take_immutable(typeName) {
|
|
100
|
+
const objectStorage = this._masters[this._currentAs].objectStorage; // it's same object for different 'as' connected to the same provider, but we don't care here
|
|
101
|
+
return objectStorage.findMostRecent((object)=>{
|
|
102
|
+
return (object.isImmutable && object.typeName == typeName);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
takeImmutable(typeName) {
|
|
106
|
+
return this.take_immutable(typeName);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async moveCall(moduleName, methodName, params) {
|
|
110
|
+
if (!this._currentAs) {
|
|
111
|
+
throw new Error('please call moveCall inside .next_tx(as, ()=>{}) wrapper');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
await this._packages[this._currentAs].modules[moduleName].moveCall(methodName, params);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async initMaster(as) {
|
|
118
|
+
if (this._masters[as]) {
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const suiMaster = new SuiMaster({debug: this._debug, as: as, provider: this._provider, });
|
|
123
|
+
|
|
124
|
+
await suiMaster.initialize();
|
|
125
|
+
await suiMaster.requestSuiFromFaucet();
|
|
126
|
+
|
|
127
|
+
const addPackageParams = {};
|
|
128
|
+
if (this._publishedPackageId) {
|
|
129
|
+
// already pulished
|
|
130
|
+
addPackageParams.id = this._publishedPackageId;
|
|
131
|
+
} else {
|
|
132
|
+
// to be build and published
|
|
133
|
+
addPackageParams.path = this._path;
|
|
134
|
+
}
|
|
135
|
+
const addedPackage = suiMaster.addPackage(addPackageParams);
|
|
136
|
+
// addedPackage.addEventListener('added', (data)=>{
|
|
137
|
+
// const object = data.detail;
|
|
138
|
+
// if (object && !this._objects[object.address]) { // there may be few same object instances in different suiMaster's.
|
|
139
|
+
// this._objects[object.address] = object;
|
|
140
|
+
// }
|
|
141
|
+
// });
|
|
142
|
+
|
|
143
|
+
if (!this._publishedPackageId) {
|
|
144
|
+
await addedPackage.publish();
|
|
145
|
+
this._publishedPackageId = addedPackage.id;
|
|
146
|
+
|
|
147
|
+
if (!this._publishedPackageId) {
|
|
148
|
+
this.log('can not publish a package');
|
|
149
|
+
}
|
|
150
|
+
} else {
|
|
151
|
+
await addedPackage.isOnChain(); // check modules etc for other user
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
this._masters[as] = suiMaster;
|
|
156
|
+
this._packages[as] = addedPackage;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
module.exports = SuiTestScenario;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"SUI": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNzIiIGhlaWdodD0iNzIiIHZpZXdCb3g9IjAgMCA3MiA3MiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjcyIiBoZWlnaHQ9IjcyIiByeD0iMTYiIGZpbGw9IiM2RkJDRjAiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yMC40MjEzIDUyLjc4MzhDMjMuNjQ5NiA1OC4zNzYgMjkuNDMyMSA2MS43MTQyIDM1Ljg4ODggNjEuNzE0MkM0Mi4zNDU1IDYxLjcxNDIgNDguMTI3IDU4LjM3NiA1MS4zNTY0IDUyLjc4MzhDNTQuNTg0OCA0Ny4xOTI2IDU0LjU4NDggNDAuNTE2MyA1MS4zNTY0IDM0LjkyNEwzNy43NTI0IDExLjM2MTVDMzYuOTI0MSA5LjkyNzAxIDM0Ljg1MzUgOS45MjcwMSAzNC4wMjUzIDExLjM2MTVMMjAuNDIxMyAzNC45MjRDMTcuMTkyOSA0MC41MTUyIDE3LjE5MjkgNDcuMTkxNSAyMC40MjEzIDUyLjc4MzhaTTMyLjA1NjYgMjIuNTcxM0wzNC45NTcxIDE3LjU0NzRDMzUuMzcxMiAxNi44MzAxIDM2LjQwNjUgMTYuODMwMSAzNi44MjA2IDE3LjU0NzRMNDcuOTc5MSAzNi44NzQ4QzUwLjAyOTEgNDAuNDI1NCA1MC40MTM5IDQ0LjUzNSA0OS4xMzM1IDQ4LjI5NTRDNDkuMDAwMiA0Ny42ODE5IDQ4LjgxMzggNDcuMDU0MiA0OC41NjI2IDQ2LjQyMDFDNDcuMDIxMyA0Mi41MzA0IDQzLjUzNjMgMzkuNTI4OSAzOC4yMDIzIDM3LjQ5ODJDMzQuNTM1MSAzNi4xMDcxIDMyLjE5NDMgMzQuMDYxMyAzMS4yNDMxIDMxLjQxNzFDMzAuMDE4IDI4LjAwODkgMzEuMjk3NiAyNC4yOTI0IDMyLjA1NjYgMjIuNTcxM1pNMjcuMTEwNyAzMS4xMzc5TDIzLjc5ODYgMzYuODc0OEMyMS4yNzQ4IDQxLjI0NTkgMjEuMjc0OCA0Ni40NjQxIDIzLjc5ODYgNTAuODM1M0MyNi4zMjIzIDU1LjIwNjQgMzAuODQxMyA1Ny44MTUgMzUuODg4OCA1Ny44MTVDMzkuMjQxMyA1Ny44MTUgNDIuMzYxNSA1Ni42NjMzIDQ0LjgxODQgNTQuNjA4OEM0NS4xMzg4IDUzLjgwMjEgNDYuMTMxIDUwLjg0OTIgNDQuOTA1MiA0Ny44MDU4QzQzLjc3MyA0NC45OTU0IDQxLjA0ODIgNDIuNzUxOSAzNi44MDYxIDQxLjEzNkMzMi4wMTEgMzkuMzE3MSAyOC44OTU4IDM2LjQ3NzQgMjcuNTQ4NiAzMi42OTg0QzI3LjM2MzEgMzIuMTc4MSAyNy4yMTg5IDMxLjY1NjggMjcuMTEwNyAzMS4xMzc5WiIgZmlsbD0id2hpdGUiLz4KPC9zdmc+",
|
|
3
|
+
"SUIET": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjQiIGhlaWdodD0iNjQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX3JhZGlhbF8zMDVfMTI1MTYpIi8+PHBhdGggZD0iTTUxLjUgNDMuNmMtMy45IDAtNy42LTMuOS05LjUtNi40LTEuOSAyLjUtNS42IDYuNC05LjUgNi40LTQgMC03LjctMy45LTkuNS02LjQtMS44IDIuNS01LjUgNi40LTkuNSA2LjQtLjggMC0xLjUtLjYtMS41LTEuNSAwLS44LjctMS41IDEuNS0xLjUgMy4yIDAgNy4xLTUuMSA4LjItNi45LjMtLjQuOC0uNyAxLjMtLjdzMSAuMiAxLjMuN2MxLjEgMS44IDUgNi45IDguMiA2LjkgMy4xIDAgNy4xLTUuMSA4LjItNi45LjMtLjQuOC0uNyAxLjMtLjdzMSAuMiAxLjIuN2MxLjEgMS44IDUgNi45IDguMiA2LjkuOSAwIDEuNi43IDEuNiAxLjUgMCAuOS0uNiAxLjUtMS41IDEuNXoiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNNTEuNSA1Mi4zYy0zLjkgMC03LjYtMy45LTkuNS02LjQtMS45IDIuNS01LjYgNi40LTkuNSA2LjQtNCAwLTcuNy0zLjktOS41LTYuNC0xLjggMi41LTUuNSA2LjQtOS41IDYuNC0uOCAwLTEuNS0uNi0xLjUtMS41IDAtLjguNy0xLjUgMS41LTEuNSAzLjIgMCA3LjEtNS4xIDguMi02LjkuMy0uNC44LS43IDEuMy0uN3MxIC4zIDEuMy43YzEuMSAxLjggNSA2LjkgOC4yIDYuOSAzLjEgMCA3LjEtNS4xIDguMi02LjkuMy0uNC44LS43IDEuMy0uN3MxIC4zIDEuMi43YzEuMSAxLjggNSA2LjkgOC4yIDYuOS45IDAgMS42LjcgMS42IDEuNSAwIC45LS42IDEuNS0xLjUgMS41ek0xNC42IDM2LjdjLS44IDAtMS40LS41LTEuNi0xLjNsLS4zLTMuNmMwLTEwLjkgOC45LTE5LjggMTkuOC0xOS44IDExIDAgMTkuOCA4LjkgMTkuOCAxOS44bC0uMyAzLjZjLS4xLjgtLjkgMS40LTEuNyAxLjItLjktLjEtMS41LS45LTEuMy0xLjhsLjMtM2MwLTkuMi03LjUtMTYuOC0xNi44LTE2LjgtOS4yIDAtMTYuNyA3LjUtMTYuNyAxNi44bC4yIDMuMWMuMi44LS4zIDEuNi0xLjEgMS44aC0uM3oiIGZpbGw9IiNmZmYiLz48ZGVmcz48cmFkaWFsR3JhZGllbnQgaWQ9InBhaW50MF9yYWRpYWxfMzA1XzEyNTE2IiBjeD0iMCIgY3k9IjAiIHI9IjEiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDUyLjc1ODAzIDUxLjM1OCAtNTEuNDM5NDcgNTIuODQxNzIgMCA3LjQwNykiPjxzdG9wIHN0b3AtY29sb3I9IiMwMDU4REQiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM2N0M4RkYiLz48L3JhZGlhbEdyYWRpZW50PjwvZGVmcz48L3N2Zz4=",
|
|
4
|
+
"GLASS": "data:image/png;base64,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",
|
|
5
|
+
"ETHOS": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIiByeD0iOCIgZmlsbD0iIzZEMjhEOSIvPgo8cGF0aCBvcGFjaXR5PSIwLjgiIGQ9Ik05LjEyMTg3IDYuODU3MDZIMTkuOTU4M0MyMC40NTcxIDYuODU3MDYgMjAuODYxNCA3LjI2MTQxIDIwLjg2MTQgNy43NjAyVjE5Ljk4ODZDMjAuODYxNCAyMC40ODc0IDIwLjQ1NzEgMjAuODkxOCAxOS45NTgzIDIwLjg5MThIOS4xMjE4N0M4LjYyMzA4IDIwLjg5MTggOC4yMTg3MiAyMC40ODc0IDguMjE4NzIgMTkuOTg4NlY3Ljc2MDJDOC4yMTg3MiA3LjI2MTQxIDguNjIzMDggNi44NTcwNiA5LjEyMTg3IDYuODU3MDZaIiBzdHJva2U9InVybCgjcGFpbnQwX2xpbmVhcl82OTlfMjY5OCkiIHN0cm9rZS13aWR0aD0iMC40NTE1NzIiLz4KPHBhdGggZD0iTTguNzEyNzQgNy40NTQ1OUwxNi4wOTQ1IDEwLjg4OTRDMTYuNDEyOSAxMS4wMzc2IDE2LjYxNjYgMTEuMzU3IDE2LjYxNjYgMTEuNzA4M1YyMy44MUMxNi42MTY2IDI0LjQ2MzUgMTUuOTQ0IDI0LjkwMDcgMTUuMzQ2OCAyNC42MzUzTDcuOTY1MDIgMjEuMzU1NkM3LjYzODgyIDIxLjIxMDcgNy40Mjg1OCAyMC44ODcyIDcuNDI4NTggMjAuNTMwM1Y4LjI3MzQzQzcuNDI4NTggNy42MTMxMSA4LjExNDA2IDcuMTc2MDIgOC43MTI3NCA3LjQ1NDU5WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTIzLjM3ODIgMTUuMzc2N0MyMy40MzAzIDE1LjEzMjEgMjMuNTUzOCAxNC45MDg2IDIzLjczMzIgMTQuNzM0M0MyMy45MTI1IDE0LjU2IDI0LjEzOTYgMTQuNDQzIDI0LjM4NTYgMTQuMzk3OUwyNS4wNDA0IDE0LjI3ODRMMjQuMzg1NSAxNC4xNTg4SDI0LjM4NTZDMjQuMTM5NiAxNC4xMTM3IDIzLjkxMjUgMTMuOTk2NyAyMy43MzMyIDEzLjgyMjRDMjMuNTUzOCAxMy42NDgxIDIzLjQzMDMgMTMuNDI0NiAyMy4zNzgyIDEzLjE4TDIzLjIzNDEgMTIuNTAxM0wyMy4wOSAxMy4xOEMyMy4wMzc5IDEzLjQyNDYgMjIuOTE0NCAxMy42NDgxIDIyLjczNTEgMTMuODIyNEMyMi41NTU4IDEzLjk5NjcgMjIuMzI4NyAxNC4xMTM4IDIyLjA4MjcgMTQuMTU4OEwyMS40Mjc4IDE0LjI3ODRMMjIuMDgyNyAxNC4zOTc5SDIyLjA4MjdDMjIuMzI4NyAxNC40NDMgMjIuNTU1NyAxNC41NiAyMi43MzUgMTQuNzM0M0MyMi45MTQ0IDE0LjkwODYgMjMuMDM3OSAxNS4xMzIxIDIzLjA5IDE1LjM3NjdMMjMuMjM0MSAxNi4wNTU0TDIzLjM3ODIgMTUuMzc2N1oiIGZpbGw9IndoaXRlIi8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfNjk5XzI2OTgiIHgxPSIyMC44NjE0IiB5MT0iMTAuNTkyNiIgeDI9IjE0LjUzOTgiIHkyPSIxMy43NTM0IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IndoaXRlIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0id2hpdGUiIHN0b3Atb3BhY2l0eT0iMCIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo=",
|
|
6
|
+
"SURF": "https://src.surf.tech/icon/surf_vector.svg",
|
|
7
|
+
"NIGHTLY": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTYiIGhlaWdodD0iOTYiIHZpZXdCb3g9IjAgMCA5NiA5NiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQ4IDk2Qzc0LjUwOTcgOTYgOTYgNzQuNTA5NyA5NiA0OEM5NiAyMS40OTAzIDc0LjUwOTcgMCA0OCAwQzIxLjQ5MDMgMCAwIDIxLjQ5MDMgMCA0OEMwIDc0LjUwOTcgMjEuNDkwMyA5NiA0OCA5NloiIGZpbGw9IiM2RDczRjgiLz4KPHBhdGggZD0iTTQ4IDg1LjYzNTZDNDggODUuNjM1NiA1Mi40NTMzIDg1LjYzNTYgNTUuNDQgODIuNTg2N0M1OC45MTU1IDc5LjI4MDEgNTcuMzUxMSA3NS40MzEyIDYyLjI3NTUgNzEuNDMxMkM2Ni45ODY2IDY3LjY0NDUgNzIuOTI0NCA3MC4zMzc5IDcyLjkyNDQgNzAuMzM3OUM3Ny4wMjIyIDYyLjEyNDUgNzQuNzkxMSA1Mi41NjkgNzQuNzkxMSA1Mi41NjlDODEuNzY4OCAzNC4yNTc5IDc1Ljk2NDQgMjEuMTU1NyA3NC40NDQ0IDE3LjM2MDFDNjkuNDQ4OCAyNC4zMzc5IDYzLjE5MTEgMjkuMTczNCA1NS43OTU1IDMyLjQwOUM1My4yMjY2IDMxLjcwNjggNTAuNTk1NSAzMS4zMzM0IDQ4IDMxLjM2MDFDNDUuNDEzMyAzMS4zMzM0IDQyLjc3MzMgMzEuNzA2OCA0MC4yMDQ0IDMyLjQwOUMzMi44MTc3IDI5LjE2NDUgMjYuNTUxMSAyNC4zMzc5IDIxLjU1NTUgMTcuMzYwMUMyMC4wMzU1IDIxLjE1NTcgMTQuMjMxMSAzNC4yNTc5IDIxLjIwODkgNTIuNTY5QzIxLjIwODkgNTIuNTY5IDE4Ljk3NzggNjIuMTI0NSAyMy4wNzU1IDcwLjMzNzlDMjMuMDc1NSA3MC4zMzc5IDI5LjAxMzMgNjcuNjQ0NSAzMy43MjQ0IDcxLjQzMTJDMzguNjU3NyA3NS40MzEyIDM3LjA4NDQgNzkuMjgwMSA0MC41NiA4Mi41ODY3QzQzLjU0NjYgODUuNjM1NiA0OCA4NS42MzU2IDQ4IDg1LjYzNTZaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNNDIuNDc5OSA2NS4yOThDNDIuMjkzMyA1OS4yMTggMzYuMzAyMSA1Ny4yNjI0IDMyLjIxMzMgNTkuODIyNEMzMi4yMTMzIDU5LjgyMjQgMzIuODUzMyA2Mi40MzU4IDM1LjgzOTkgNjMuNzUxM0MzOC4yNzU1IDY0LjgyNjkgMzkuMzI0NCA2My4zODY5IDQyLjQ3OTkgNjUuMjk4WiIgZmlsbD0iIzdCODFGOSIvPgo8cGF0aCBkPSJNMjIuNDk3NyAyMy4wOTM1QzIwLjA4ODggMzEuNTQ2OCAyMS4xMjg4IDQyLjI0MDIgMjQuOTMzMyA1MC4wMjY5QzI4LjgyNjYgNDcuMjcxMyAzMi45MTU1IDQzLjAxMzUgMzUuMDkzMyAzOC41MDY5QzI5Ljk2NDQgMzQuNzExMyAyNS42NjIyIDMxLjEwMjQgMjIuNDk3NyAyMy4wOTM1WiIgZmlsbD0iIzdCODFGOSIvPgo8cGF0aCBkPSJNNTMuNTE5OSA2NS4yOThDNTMuNzA2NiA1OS4yMTggNTkuNjk3NyA1Ny4yNjI0IDYzLjc4NjYgNTkuODIyNEM2My43ODY2IDU5LjgyMjQgNjMuMTQ2NiA2Mi40MzU4IDYwLjE1OTkgNjMuNzUxM0M1Ny43MjQzIDY0LjgyNjkgNTYuNjc1NSA2My4zODY5IDUzLjUxOTkgNjUuMjk4WiIgZmlsbD0iIzdCODFGOSIvPgo8cGF0aCBkPSJNNzMuNTAyMiAyMy4wOTM1Qzc1LjkxMTEgMzEuNTQ2OCA3NC44NzExIDQyLjI0MDIgNzEuMDY2NiA1MC4wMjY5QzY3LjE3MzMgNDcuMjcxMyA2My4wODQ0IDQzLjAxMzUgNjAuOTA2NiAzOC41MDY5QzY2LjAzNTUgMzQuNzExMyA3MC4zMzc3IDMxLjEwMjQgNzMuNTAyMiAyMy4wOTM1WiIgZmlsbD0iIzdCODFGOSIvPgo8cGF0aCBkPSJNNDcuOTk5OSA4NS4zMDY5QzUwLjE0MDQgODUuMzA2OSA1MS44NzU1IDgzLjc3ODcgNTEuODc1NSA4MS44OTM2QzUxLjg3NTUgODAuMDA4NCA1MC4xNDA0IDc4LjQ4MDIgNDcuOTk5OSA3OC40ODAyQzQ1Ljg1OTUgNzguNDgwMiA0NC4xMjQ0IDgwLjAwODQgNDQuMTI0NCA4MS44OTM2QzQ0LjEyNDQgODMuNzc4NyA0NS44NTk1IDg1LjMwNjkgNDcuOTk5OSA4NS4zMDY5WiIgZmlsbD0iIzdCODFGOSIvPgo8L3N2Zz4K"
|
|
8
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "suidouble",
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"author": "",
|
|
10
|
+
"license": "Apache-2.0",
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@mysten/sui.js": "^0.34.0",
|
|
13
|
+
"@wallet-standard/core": "^1.0.3"
|
|
14
|
+
}
|
|
15
|
+
}
|