suidouble 1.0.5 → 1.6.0-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -294,20 +299,21 @@ Don't forget to test transactions sending real money on devnet/testnet first!
294
299
 
295
300
  ##### composing transaction block yourself
296
301
 
297
- If you need more flexebility, there's always an option to construct the transaction block yourself:
302
+ If you need more flexebility, there's always an option to construct the transaction yourself:
298
303
 
299
304
  ```javascript
300
- const { TransactionBlock, Transactions } = require('suidobule'); // this exposes classes from the "@mysten/sui.js", so you don't have to import them separately
305
+ const { Transaction, txInput } = require('suidobule'); // this exposes classes from the "@mysten/sui.js", so you don't have to import them separately
301
306
 
302
- const txb = new TransactionBlock();
303
- txb.moveCall({
307
+ const tx = new Transaction();
308
+ tx.moveCall({
304
309
  target: `package_id::module_id::method_name`,
305
310
  arguments: [
306
- txb.pure(contract.arg('u256', something)),
307
- txb.object(someid),
311
+ txInput(tx, 'u256', some_value),
312
+ txInput(tx, 'vector<bool>', some_array),
313
+ tx.object('0xc060006111016b8a020ad5b33834984a437aaa7d3c74c18e09a95d48aceab08c'), // object ids are ok t
308
314
  ],
309
315
  });
310
- const moveCallResult = await contract.moveCall('suidouble_chat', 'post_pay', {tx: txb});
316
+ const moveCallResult = await contract.moveCall('suidouble_chat', 'post_pay', {tx: tx});
311
317
  ```
312
318
 
313
319
 
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,
@@ -16,4 +17,6 @@ module.exports = {
16
17
  Transaction: Transaction,
17
18
  Commands: Commands,
18
19
  SuiUtils: SuiUtils,
20
+ txInput: SuiUtils.txInput,
21
+ bcs,
19
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 {import('@mysten/sui/transactions').Transaction} txb - Native SUI SDK Transaction
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 {import('@mysten/sui/transactions').TransactionObjectArgument}
228
+ * @returns {TransactionObjectArgument}
222
229
  */
223
230
  async coinOfAmountToTxCoin(txb, owner, amount, addEmptyCoins = false) {
224
231
  const normalizedAmount = await this.lazyNormalizeAmount(amount);
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) {
package/lib/SuiPackage.js CHANGED
@@ -452,8 +452,8 @@ class SuiPackage extends SuiObject {
452
452
 
453
453
  const authorizeUpgradeArguments = [
454
454
  cap,
455
- tx.pure(this.arg('u8', UpgradePolicyCOMPATIBLE)),
456
- tx.pure(this.arg('vector<u8>', this._builtDigest)),
455
+ this._suiMaster.utils.txInput(tx, 'u8', UpgradePolicyCOMPATIBLE),
456
+ this._suiMaster.utils.txInput(tx, 'vector<u8>', this._builtDigest),
457
457
  ];
458
458
 
459
459
  const ticket = tx.moveCall({
@@ -166,6 +166,11 @@ class SuiPackageModule extends SuiCommonMethods {
166
166
  const txCoinToSend = await suiCoin.coinOfAmountToTxCoin(tx, ownerAddress, param[0].amount);
167
167
 
168
168
  callArgs.push(tx.makeMoveVec({ type: suiCoin.coinObjectType, elements: [txCoinToSend]}));
169
+ } else if (typeof param === 'string' && param.indexOf('0x') === 0) {
170
+ callArgs.push(tx.object(param));
171
+ } else if (param && param.Pure && param.Pure.bytes) {
172
+ // already Pure
173
+ callArgs.push(this._suiMaster.utils.txInput(tx, param));
169
174
  } else {
170
175
  callArgs.push(tx.pure(param));
171
176
  }
package/lib/SuiUtils.js CHANGED
@@ -1,13 +1,32 @@
1
1
  const SuiCommonMethods = require('./SuiCommonMethods.js');
2
- const { Inputs } = require('@mysten/sui/transactions');
2
+ const { Inputs, Transaction, Argument } = require('@mysten/sui/transactions');
3
3
  const { bcs } = require('@mysten/sui/bcs');
4
+ const { fromB64 } = require('@mysten/bcs');
4
5
  const { SuiClient, getFullnodeUrl, SuiHTTPTransport } = require('@mysten/sui/client');
5
6
  const { normalizeSuiAddress } = require('@mysten/sui/utils');
6
7
 
7
8
  const WebSocketClient = require('websocket').w3cwebsocket;
8
9
 
10
+ /** Helpful methods using in different places of suidouble */
9
11
  class SuiUtils extends SuiCommonMethods {
10
12
 
13
+ /**
14
+ * Attach the parameter input into transaction, to be used for moveCall
15
+ * accepts an Inputs.Pure (result of .pureInput) or type + value directly
16
+ *
17
+ * @param {Transaction} tx
18
+ * @param {string | Inputs.Pure} typeOrInput
19
+ * @param {?Argument} value
20
+ * @returns Argument
21
+ */
22
+ static txInput(tx, typeOrInput, value = null) {
23
+ if (typeOrInput && typeOrInput.Pure && typeOrInput.Pure.bytes) {
24
+ return tx.pure(SuiUtils.pureInputToBytes(typeOrInput));
25
+ } else {
26
+ return tx.pure(SuiUtils.pureInputToBytes(SuiUtils.pureInput(typeOrInput, value)));
27
+ }
28
+ }
29
+
11
30
  /**
12
31
  * Returns and Inputs.Pure for a given type
13
32
  * to be used as moveCall parameters
@@ -19,13 +38,7 @@ class SuiUtils extends SuiCommonMethods {
19
38
  * SuiUtils.pureInput('string', 'metadata')
20
39
  * ]);
21
40
  *
22
- * or:
23
- * wrapped in tx.pure if you are going to construct tx yourself:
24
- * const tx = new Transaction();
25
- * tx.moveCall({ target: `x.x.x`, arguments: [
26
- * tx.pure(SuiUtils.pureInput('u8',22)),
27
- * tx.pure(SuiUtils.pureInput('string','test')),
28
- * ] });
41
+ * if you are going to construct tx yourself, you'd better use SuiUtils.txInput static method
29
42
  *
30
43
  * @param {string} type
31
44
  * @param {value} value
@@ -58,24 +71,34 @@ class SuiUtils extends SuiCommonMethods {
58
71
  }
59
72
  }
60
73
 
74
+ /**
75
+ * Convert sui's PureInput into bcs serialized bytes
76
+ * @param {Inputs.Pure} pureInput
77
+ */
78
+ static pureInputToBytes(pureInput) {
79
+ return fromB64(pureInput.Pure.bytes);
80
+ }
81
+
61
82
  /**
62
83
  * Wrapper for sui's utils normalizeSuiAddress
63
84
  * Perform the following operations:
85
+ * <pre>
64
86
  * 1. Make the address lower case
65
87
  * 2. Prepend `0x` if the string does not start with `0x`.
66
88
  * 3. Add more zeros if the length of the address(excluding `0x`) is less than `SUI_ADDRESS_LENGTH`
89
+ * </pre>
67
90
  *
68
91
  * @param {string} address
69
92
  * @returns string
70
93
  */
71
- normalizeSuiAddress(address) {
94
+ static normalizeSuiAddress(address) {
72
95
  return normalizeSuiAddress(address);
73
96
  }
74
97
 
75
98
  /**
76
99
  * As SUI removed websocket dependency for a node, we'll have it here as constructor wrapper
77
100
  * returning native WebSocket in browser and websocket's w3cwebsocket in node
78
- * @returns
101
+ * @returns WebSocketClient
79
102
  */
80
103
  static WebSocketConstructor() {
81
104
  return WebSocketClient;
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "suidouble",
3
- "version": "1.0.5",
3
+ "version": "1.6.0-2",
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": {
7
- "test": "tap -j=1 ./test/*.test.js",
8
- "coverage": "tap -j=1 ./test/*.test.js"
7
+ "test": "tap -j1 -t120 ./test/*.test.js",
8
+ "coverage": "tap -j1 -t120 ./test/*.test.js"
9
9
  },
10
10
  "keywords": [
11
11
  "sui",
@@ -21,22 +21,17 @@
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.0.5",
24
+ "@mysten/sui": "^1.6.0",
25
25
  "@wallet-standard/core": "^1.0.3",
26
26
  "websocket": "^1.0.35"
27
27
  },
28
28
  "devDependencies": {
29
- "tap": "^16.3.4"
29
+ "tap": "^21.0.1"
30
30
  },
31
31
  "browser": {
32
32
  "child_process": false,
33
33
  "fs": false,
34
34
  "path": false
35
35
  },
36
- "tap": {
37
- "branches": 90,
38
- "lines": 90,
39
- "functions": 90,
40
- "statements": 90
41
- }
36
+ "tap": {}
42
37
  }
@@ -89,7 +89,7 @@ test('getting coin objects for a transaction', async t => {
89
89
 
90
90
  const tx = new Transaction();
91
91
  const coinInput = await suiCoin.coinOfAmountToTxCoin(tx, suiMaster.address, suiMaster.MIST_PER_SUI); // pick 1 SUI
92
- tx.transferObjects([coinInput], tx.pure('0x1d20dcdb2bca4f508ea9613994683eb4e76e9c4ed371169677c1be02aaf0b12a')); // send it anywhere
92
+ tx.transferObjects([coinInput], '0x1d20dcdb2bca4f508ea9613994683eb4e76e9c4ed371169677c1be02aaf0b12a'); // send it anywhere
93
93
 
94
94
  const result = await suiMaster.signAndExecuteTransaction({
95
95
  transaction: tx,
@@ -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