suidouble 1.6.0 → 1.11.0
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 +6 -1
- package/index.js +2 -0
- package/lib/SuiCoin.js +13 -6
- package/lib/SuiMaster.js +30 -2
- package/lib/SuiPackage.js +18 -7
- package/lib/SuiPackageModule.js +1 -1
- package/lib/SuiUtils.js +11 -14
- package/package.json +3 -4
- package/test/sui_master_basic.test.js +9 -0
package/README.md
CHANGED
|
@@ -46,13 +46,18 @@ Main class to interact with blockchain is SuiMaster:
|
|
|
46
46
|
const { SuiMaster } = require('suidouble');
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
You can initialize it directly, if you have keypair, secret phrase and can use it in code (so on node.js side - server side or CLI apps):
|
|
49
|
+
You can initialize it directly, if you have keypair, secret phrase, or privateKey and can use it in code (so on node.js side - server side or CLI apps):
|
|
50
50
|
```javascript
|
|
51
51
|
const suiMaster = new SuiMaster({
|
|
52
52
|
keypair: Ed25519Keypair || Secp256r1Keypair || Secp256k1Keypair,
|
|
53
53
|
debug: true, // echo testing messages to console
|
|
54
54
|
client: 'test', // 'test', 'dev', 'local', 'main' or instance of this lib's SuiLocalTestValidator
|
|
55
55
|
});
|
|
56
|
+
const suiMaster = new SuiMaster({
|
|
57
|
+
debug: false,
|
|
58
|
+
privateKey: 'suiprivkey1qpwly9xrfsv50mqug706s40l58klez5q6mpchq4f5ldzktjyr4x7yhj9lf2',
|
|
59
|
+
client: 'dev',
|
|
60
|
+
});
|
|
56
61
|
const suiMaster = new SuiMaster({
|
|
57
62
|
debug: false,
|
|
58
63
|
phrase: 'thrive mean two thrive mean two thrive mean two thrive mean two', // secret phrase to generate keypair
|
package/index.js
CHANGED
|
@@ -5,6 +5,7 @@ const SuiObject = require('./lib/SuiObject.js');
|
|
|
5
5
|
const SuiUtils = require('./lib/SuiUtils.js');
|
|
6
6
|
const SuiLocalTestValidator = require('./lib/SuiLocalTestValidator.js');
|
|
7
7
|
const { Transaction, Commands } = require('@mysten/sui/transactions');
|
|
8
|
+
const { bcs } = require('@mysten/sui/bcs');
|
|
8
9
|
|
|
9
10
|
module.exports = {
|
|
10
11
|
SuiMaster,
|
|
@@ -17,4 +18,5 @@ module.exports = {
|
|
|
17
18
|
Commands: Commands,
|
|
18
19
|
SuiUtils: SuiUtils,
|
|
19
20
|
txInput: SuiUtils.txInput,
|
|
21
|
+
bcs,
|
|
20
22
|
};
|
package/lib/SuiCoin.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
const { Commands, Transaction } = require('@mysten/sui/transactions');
|
|
1
|
+
const { Commands, Transaction, TransactionObjectArgument } = require('@mysten/sui/transactions');
|
|
2
2
|
const { bcs } = require('@mysten/sui/bcs');
|
|
3
|
-
// console.log(bcs);
|
|
4
3
|
|
|
5
4
|
|
|
6
5
|
const safeList = {
|
|
@@ -25,7 +24,15 @@ const safeList = {
|
|
|
25
24
|
},
|
|
26
25
|
};
|
|
27
26
|
|
|
27
|
+
/** Coin metadata object */
|
|
28
28
|
class SuiCoin {
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* SuiCoin constructor
|
|
32
|
+
* @param {Object} params - Initialization parameters
|
|
33
|
+
* @param {string} params.coinType - sui object type for a coin, without Coin<...>, only the inside type
|
|
34
|
+
* @param {SuiCoins} params.suiCoins - instance of SuiCoins
|
|
35
|
+
*/
|
|
29
36
|
constructor(params = {}) {
|
|
30
37
|
this._coinType = params.coinType;
|
|
31
38
|
this._suiCoins = params.suiCoins;
|
|
@@ -214,11 +221,11 @@ class SuiCoin {
|
|
|
214
221
|
/**
|
|
215
222
|
* Returns TransactionObjectArgument with Coin of amount to be used in tranasctions
|
|
216
223
|
*
|
|
217
|
-
* @param {
|
|
224
|
+
* @param {Transaction} txb - Native SUI SDK Transaction
|
|
218
225
|
* @param {string} owner - address of the owner
|
|
219
226
|
* @param {BigInt|string} amount - amount of coin. BigIng or String to be normalized via Coin decimals, "0.05" for 0.05 sui
|
|
220
227
|
* @param {boolean} addEmptyCoins - attach coins == 0 to the list
|
|
221
|
-
* @returns {
|
|
228
|
+
* @returns {TransactionObjectArgument}
|
|
222
229
|
*/
|
|
223
230
|
async coinOfAmountToTxCoin(txb, owner, amount, addEmptyCoins = false) {
|
|
224
231
|
const normalizedAmount = await this.lazyNormalizeAmount(amount);
|
|
@@ -237,14 +244,14 @@ class SuiCoin {
|
|
|
237
244
|
return coinInput;
|
|
238
245
|
} else {
|
|
239
246
|
// some other coin
|
|
240
|
-
const coinInput = txb.add(Commands.SplitCoins(txb.object(coinIds[0]), [txb.pure(expectedAmountAsBigInt)]));
|
|
247
|
+
const coinInput = txb.add(Commands.SplitCoins(txb.object(coinIds[0]), [txb.pure.u64(expectedAmountAsBigInt)]));
|
|
241
248
|
return coinInput;
|
|
242
249
|
}
|
|
243
250
|
} else {
|
|
244
251
|
// few coin objects to merge
|
|
245
252
|
const coinIdToMergeIn = coinIds.shift();
|
|
246
253
|
txb.add(Commands.MergeCoins(txb.object(coinIdToMergeIn), coinIds.map((id)=>{return txb.object(id);})));
|
|
247
|
-
const coinInputSplet = txb.add(Commands.SplitCoins(txb.object(coinIdToMergeIn), [txb.pure(expectedAmountAsBigInt)]));
|
|
254
|
+
const coinInputSplet = txb.add(Commands.SplitCoins(txb.object(coinIdToMergeIn), [txb.pure.u64(expectedAmountAsBigInt)]));
|
|
248
255
|
|
|
249
256
|
return coinInputSplet;
|
|
250
257
|
}
|
package/lib/SuiMaster.js
CHANGED
|
@@ -14,6 +14,7 @@ const { Secp256r1Keypair } = require('@mysten/sui/keypairs/secp256r1');
|
|
|
14
14
|
const { Secp256k1Keypair } = require('@mysten/sui/keypairs/secp256k1');
|
|
15
15
|
const { requestSuiFromFaucetV0, getFaucetHost } = require('@mysten/sui/faucet');
|
|
16
16
|
const { Transaction, Commands } = require('@mysten/sui/transactions');
|
|
17
|
+
const { decodeSuiPrivateKey } = require('@mysten/sui/cryptography');
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
class SuiMaster extends SuiCommonMethods {
|
|
@@ -36,6 +37,17 @@ class SuiMaster extends SuiCommonMethods {
|
|
|
36
37
|
}
|
|
37
38
|
} else if (params.keypair) {
|
|
38
39
|
this._keypair = params.keypair;
|
|
40
|
+
} else if (params.privateKey) {
|
|
41
|
+
const parsed = decodeSuiPrivateKey(params.privateKey);
|
|
42
|
+
if (parsed && parsed.schema) {
|
|
43
|
+
if (parsed.schema === 'ED25519') {
|
|
44
|
+
this._keypair = Ed25519Keypair.fromSecretKey(parsed.secretKey);
|
|
45
|
+
} else if (parsed.schema == 'Secp256k1') {
|
|
46
|
+
this._keypair = Secp256k1Keypair.fromSecretKey(parsed.secretKey);
|
|
47
|
+
} else if (parsed.schema == 'Secp256r1') {
|
|
48
|
+
this._keypair = Secp256r1Keypair.fromSecretKey(parsed.secretKey);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
39
51
|
} else if (params.phrase) {
|
|
40
52
|
if (params.keypairAlgo && (''+params.keypairAlgo).toLowerCase() == 'secp256r1') {
|
|
41
53
|
if (!params.accountIndex) {
|
|
@@ -229,12 +241,28 @@ class SuiMaster extends SuiCommonMethods {
|
|
|
229
241
|
}
|
|
230
242
|
|
|
231
243
|
async signAndExecuteTransaction(params) {
|
|
244
|
+
let txResults = null;
|
|
232
245
|
if (this._keypair) {
|
|
233
246
|
params.signer = this._keypair;
|
|
234
|
-
|
|
247
|
+
txResults = await this._client.signAndExecuteTransaction(params);
|
|
235
248
|
} else if (this._signer) {
|
|
236
|
-
|
|
249
|
+
txResults = await this._signer.signAndExecuteTransaction(params);
|
|
237
250
|
}
|
|
251
|
+
|
|
252
|
+
try {
|
|
253
|
+
if (params && params.requestType && params.requestType == 'WaitForLocalExecution') {
|
|
254
|
+
const detailedResults = await this.client.waitForTransaction({
|
|
255
|
+
digest: txResults.digest,
|
|
256
|
+
options: (params.options || {}),
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
return detailedResults;
|
|
260
|
+
}
|
|
261
|
+
} catch (e) {
|
|
262
|
+
this.log(e);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return txResults;
|
|
238
266
|
}
|
|
239
267
|
|
|
240
268
|
async requestSuiFromFaucet() {
|
package/lib/SuiPackage.js
CHANGED
|
@@ -394,9 +394,9 @@ class SuiPackage extends SuiObject {
|
|
|
394
394
|
}
|
|
395
395
|
}
|
|
396
396
|
|
|
397
|
-
async publish() {
|
|
397
|
+
async publish(params = {}) {
|
|
398
398
|
if (!this._isBuilt) {
|
|
399
|
-
await this.build();
|
|
399
|
+
await this.build(params);
|
|
400
400
|
}
|
|
401
401
|
if (this.address) {
|
|
402
402
|
throw new Error('already published. Maybe you need to upgrade() it?');
|
|
@@ -422,6 +422,13 @@ class SuiPackage extends SuiObject {
|
|
|
422
422
|
},
|
|
423
423
|
});
|
|
424
424
|
|
|
425
|
+
// const suiTransaction = new this._suiMaster.SuiTransaction({
|
|
426
|
+
// suiMaster: this._suiMaster,
|
|
427
|
+
// debug: this._debug,
|
|
428
|
+
// data: result,
|
|
429
|
+
// });
|
|
430
|
+
// await suiTransaction.waitForTransaction();
|
|
431
|
+
|
|
425
432
|
const success = await this.storeInfoFromPublishResult(result);
|
|
426
433
|
|
|
427
434
|
if (success) {
|
|
@@ -431,11 +438,11 @@ class SuiPackage extends SuiObject {
|
|
|
431
438
|
return this.address;
|
|
432
439
|
}
|
|
433
440
|
|
|
434
|
-
async upgrade() {
|
|
441
|
+
async upgrade(params = {}) {
|
|
435
442
|
await this.checkOnChainIfNeeded();
|
|
436
443
|
|
|
437
444
|
if (!this._isBuilt) {
|
|
438
|
-
await this.build();
|
|
445
|
+
await this.build(params);
|
|
439
446
|
}
|
|
440
447
|
|
|
441
448
|
this.log('upgrading package...');
|
|
@@ -473,7 +480,7 @@ class SuiPackage extends SuiObject {
|
|
|
473
480
|
arguments: [cap, receipt],
|
|
474
481
|
});
|
|
475
482
|
|
|
476
|
-
console.log(tx);
|
|
483
|
+
// console.log(tx);
|
|
477
484
|
|
|
478
485
|
const result = await this._suiMaster.signAndExecuteTransaction({
|
|
479
486
|
transaction: tx,
|
|
@@ -496,7 +503,7 @@ class SuiPackage extends SuiObject {
|
|
|
496
503
|
* Build a Move project using `sui move build`
|
|
497
504
|
* @returns Boolean true on success
|
|
498
505
|
*/
|
|
499
|
-
async build() {
|
|
506
|
+
async build(params = {}) {
|
|
500
507
|
this.log('builing a package...');
|
|
501
508
|
|
|
502
509
|
const path = this._path;
|
|
@@ -505,7 +512,11 @@ class SuiPackage extends SuiObject {
|
|
|
505
512
|
throw new Error('Cant build a package with no path defined');
|
|
506
513
|
}
|
|
507
514
|
|
|
508
|
-
|
|
515
|
+
let command = `sui move build --dump-bytecode-as-base64 --path ${path}`;
|
|
516
|
+
if (params.withUnpublishedDependencies) {
|
|
517
|
+
command = `sui move build --with-unpublished-dependencies --dump-bytecode-as-base64 --path ${path}`;
|
|
518
|
+
}
|
|
519
|
+
const buildResult = await SuiCliCommands.exec(command);
|
|
509
520
|
const { modules, dependencies, digest } = JSON.parse(buildResult);
|
|
510
521
|
|
|
511
522
|
this._builtModules = modules;
|
package/lib/SuiPackageModule.js
CHANGED
|
@@ -196,12 +196,12 @@ class SuiPackageModule extends SuiCommonMethods {
|
|
|
196
196
|
showDisplay: true,
|
|
197
197
|
},
|
|
198
198
|
});
|
|
199
|
+
|
|
199
200
|
const suiTransaction = new this._suiMaster.SuiTransaction({
|
|
200
201
|
suiMaster: this._suiMaster,
|
|
201
202
|
debug: this._debug,
|
|
202
203
|
data: result,
|
|
203
204
|
});
|
|
204
|
-
|
|
205
205
|
const status = suiTransaction.status;
|
|
206
206
|
|
|
207
207
|
const listCreated = [];
|
package/lib/SuiUtils.js
CHANGED
|
@@ -7,22 +7,23 @@ const { normalizeSuiAddress } = require('@mysten/sui/utils');
|
|
|
7
7
|
|
|
8
8
|
const WebSocketClient = require('websocket').w3cwebsocket;
|
|
9
9
|
|
|
10
|
+
/** Helpful methods using in different places of suidouble */
|
|
10
11
|
class SuiUtils extends SuiCommonMethods {
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
|
-
*
|
|
14
|
+
* Attach the parameter input into transaction, to be used for moveCall
|
|
14
15
|
* accepts an Inputs.Pure (result of .pureInput) or type + value directly
|
|
15
16
|
*
|
|
16
17
|
* @param {Transaction} tx
|
|
17
|
-
* @param {Inputs.Pure
|
|
18
|
-
* @param {
|
|
18
|
+
* @param {string | Inputs.Pure} typeOrInput
|
|
19
|
+
* @param {?Argument} value
|
|
19
20
|
* @returns Argument
|
|
20
21
|
*/
|
|
21
22
|
static txInput(tx, typeOrInput, value = null) {
|
|
22
23
|
if (typeOrInput && typeOrInput.Pure && typeOrInput.Pure.bytes) {
|
|
23
|
-
return tx.pure(
|
|
24
|
+
return tx.pure(SuiUtils.pureInputToBytes(typeOrInput));
|
|
24
25
|
} else {
|
|
25
|
-
return tx.pure(
|
|
26
|
+
return tx.pure(SuiUtils.pureInputToBytes(SuiUtils.pureInput(typeOrInput, value)));
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
|
|
@@ -37,13 +38,7 @@ class SuiUtils extends SuiCommonMethods {
|
|
|
37
38
|
* SuiUtils.pureInput('string', 'metadata')
|
|
38
39
|
* ]);
|
|
39
40
|
*
|
|
40
|
-
*
|
|
41
|
-
* wrapped in tx.pure if you are going to construct tx yourself:
|
|
42
|
-
* const tx = new Transaction();
|
|
43
|
-
* tx.moveCall({ target: `x.x.x`, arguments: [
|
|
44
|
-
* tx.pure(SuiUtils.pureInput('u8',22)),
|
|
45
|
-
* tx.pure(SuiUtils.pureInput('string','test')),
|
|
46
|
-
* ] });
|
|
41
|
+
* if you are going to construct tx yourself, you'd better use SuiUtils.txInput static method
|
|
47
42
|
*
|
|
48
43
|
* @param {string} type
|
|
49
44
|
* @param {value} value
|
|
@@ -87,21 +82,23 @@ class SuiUtils extends SuiCommonMethods {
|
|
|
87
82
|
/**
|
|
88
83
|
* Wrapper for sui's utils normalizeSuiAddress
|
|
89
84
|
* Perform the following operations:
|
|
85
|
+
* <pre>
|
|
90
86
|
* 1. Make the address lower case
|
|
91
87
|
* 2. Prepend `0x` if the string does not start with `0x`.
|
|
92
88
|
* 3. Add more zeros if the length of the address(excluding `0x`) is less than `SUI_ADDRESS_LENGTH`
|
|
89
|
+
* </pre>
|
|
93
90
|
*
|
|
94
91
|
* @param {string} address
|
|
95
92
|
* @returns string
|
|
96
93
|
*/
|
|
97
|
-
normalizeSuiAddress(address) {
|
|
94
|
+
static normalizeSuiAddress(address) {
|
|
98
95
|
return normalizeSuiAddress(address);
|
|
99
96
|
}
|
|
100
97
|
|
|
101
98
|
/**
|
|
102
99
|
* As SUI removed websocket dependency for a node, we'll have it here as constructor wrapper
|
|
103
100
|
* returning native WebSocket in browser and websocket's w3cwebsocket in node
|
|
104
|
-
* @returns
|
|
101
|
+
* @returns WebSocketClient
|
|
105
102
|
*/
|
|
106
103
|
static WebSocketConstructor() {
|
|
107
104
|
return WebSocketClient;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "suidouble",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.0",
|
|
4
4
|
"description": "Set of provider, package and object classes for javascript representation of Sui Move smart contracts. Use same code for publishing, upgrading, integration testing, interaction with smart contracts and integration in browser web3 dapps",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"author": "Jeka Kiselyov <jeka911@gmail.com> (https://github.com/jeka-kiselyov)",
|
|
22
22
|
"license": "Apache-2.0",
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@mysten/sui": "^1.
|
|
24
|
+
"@mysten/sui": "^1.11.0",
|
|
25
25
|
"@wallet-standard/core": "^1.0.3",
|
|
26
26
|
"websocket": "^1.0.35"
|
|
27
27
|
},
|
|
@@ -33,6 +33,5 @@
|
|
|
33
33
|
"fs": false,
|
|
34
34
|
"path": false
|
|
35
35
|
},
|
|
36
|
-
"tap": {
|
|
37
|
-
}
|
|
36
|
+
"tap": {}
|
|
38
37
|
}
|
|
@@ -39,6 +39,15 @@ test('pseudo-random keypairs generation works ok', async t => {
|
|
|
39
39
|
t.equal(`${suiMasterAsAdminAnother.address}`, `${suiMasterAsAdmin.address}`, 'same string should generate same pseudo-random');
|
|
40
40
|
});
|
|
41
41
|
|
|
42
|
+
test('keypair generation with privateKey works ok', async t => {
|
|
43
|
+
const privateKey = 'suiprivkey1qpwly9xrfsv50mqug706s40l58klez5q6mpchq4f5ldzktjyr4x7yhj9lf2';
|
|
44
|
+
const suiMaster = new SuiMaster({client: 'test', privateKey: privateKey});
|
|
45
|
+
await suiMaster.initialize();
|
|
46
|
+
|
|
47
|
+
t.equal(`${suiMaster.address}`, `0x4d07e4a382dcb69288a8a4589e8fc0534378dad76b75565fda0c1e9ada45b7d1`, 'by privateKey generated ok');
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
|
|
42
51
|
test('keypair generation with seed phrase works ok', async t => {
|
|
43
52
|
// Ed25519
|
|
44
53
|
const phrase = 'seek weekend run rival noodle dog alone mosquito decide hover aerobic fiction'; // 0x2bfe9c35ca9400c42e24e4b424cbd2dfb51bcb7c2487e1b4694ff53d8ca00262
|