suidouble 0.0.37 → 0.0.39

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
@@ -8,10 +8,12 @@ Set of provider, package and object classes for javascript representation of Sui
8
8
  - [Attaching a package](#attaching-a-package)
9
9
  - [Interacting with smart contract](#interacting-with-smart-contract)
10
10
  - [SuiObject](#suiobject)
11
+ - [Fetching objects](#fetching-objects)
11
12
  - [Fetching Events](#fetching-events)
12
13
  - [Subscribe to Events](#subscribing-to-events)
13
14
  - [Executing smart contract method](#executing-smart-contract-method)
14
- - [Fetching objects](#fetching-objects)
15
+ - [Sending sui / coins with smart contract methods](#sending-sui--coins-with-smart-contract-methods)
16
+ - [Composing transaction block yourself](#composing-transaction-block-yourself)
15
17
  - [Publishing the package](#publishing-the-package)
16
18
  - [Upgrading the package](#upgrading-the-package)
17
19
  - [Writing Sue Move intergration tests](#sui-move-integration-testing)
@@ -205,15 +207,65 @@ const res = await contract.moveCall('chat', 'post', ['0x10cded4f9df05e37b44e3be2
205
207
  }
206
208
  ```
207
209
 
208
- If you need to transfer some SUI as part of executing contract method, you can use a magic parameter in form of {type: 'SUI', amount: 400000000000n} where 400000000000 is the amount of MIST you want to send. SuiPackageModule will convert this amount to Coin object using Transactions.SplitCoins method.
210
+ ##### sending sui / coins with smart contract methods
211
+
212
+ If you need to transfer some SUI/coins as part of executing contract method, you can use a magic parameter in form of:
213
+
214
+ ```javascript
215
+ {type: 'SUI', amount: 400000000000n}
216
+ // 400000000000 MISTs, if amount is BigInt, it's used in decimal items
217
+ {type: 'SUI', amount: '0.2'}
218
+ // 0.2 SUI , if amount is String, it's translated to decimals, using coin metadata in a lazy way
219
+ {type: '0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN', amount: '1'}
220
+ // 1 USDC
221
+ {type: '0xc060006111016b8a020ad5b33834984a437aaa7d3c74c18e09a95d48aceab08c::coin::COIN', amount: '99.99'}
222
+ // 99.99 USDT
223
+ ```
209
224
 
210
- `amount: 400000000000n`, `amount: '400000000000'`, `amount: 400000000000` will work too
225
+ So executing
211
226
 
212
227
  ```javascript
213
- const moveCallResult = await contract.moveCall('suidouble_chat', 'post_pay', [chatShopObjectId, {type: 'SUI', amount: 400000000000n}, messageText, 'metadata']);
228
+ const params = [
229
+ chatShopObjectId,
230
+ {type: '0xc060006111016b8a020ad5b33834984a437aaa7d3c74c18e09a95d48aceab08c::coin::COIN', amount: '9.99'},
231
+ messageText,
232
+ ];
233
+ const moveCallResult = await contract.moveCall('suidouble_chat', 'post_pay', params);
234
+ ```
235
+
236
+ will send 9.99 USDT as the second parameter of the package method. Suidouble will convert needed coins using Sui's SplitCoins and MergeCoins internally to match amount you expect to send.
237
+
238
+ Some smart contracts requires clients to send coins in form of vectors. This is covered too, just pass magic parameter if the form of an array with one element:
239
+
240
+ ```javascript
241
+ const params = [
242
+ chatShopObjectId,
243
+ [{type: '0xc060006111016b8a020ad5b33834984a437aaa7d3c74c18e09a95d48aceab08c::coin::COIN', amount: '9.99'}],
244
+ messageText,
245
+ ];
246
+ ```
247
+
248
+ Don't forget to test transactions sending real money on devnet/testnet first!
249
+
250
+
251
+ ##### composing transaction block yourself
252
+
253
+ If you need more flexebility, there's always an option to construct the transaction block yourself:
254
+
255
+ ```javascript
256
+ const { TransactionBlock, Transactions } = require('suidobule'); // this exposes classes from the "@mysten/sui.js", so you don't have to import them separately
257
+
258
+ const txb = new TransactionBlock();
259
+ txb.moveCall({
260
+ target: `package_id::module_id::method_name`,
261
+ arguments: [
262
+ txb.pure(something),
263
+ txb.object(someid),
264
+ ],
265
+ });
266
+ const moveCallResult = await contract.moveCall('suidouble_chat', 'post_pay', {tx: txb});
214
267
  ```
215
268
 
216
- @todo: sending other Coins
217
269
 
218
270
  ##### fetching objects
219
271
 
@@ -369,8 +421,6 @@ Take a look at [unit tests](test) code for some inspiration.
369
421
 
370
422
  ### Todo
371
423
 
372
- - subscribe to events
373
- - sending other coins as contract methods execution
374
424
  - suiobject invalidation/fetching optimization
375
425
  - better documentation
376
426
  - unit tests coverage to 90%+
package/index.js CHANGED
@@ -3,6 +3,7 @@ const SuiInBrowser = require('./lib/SuiInBrowser.js');
3
3
  const SuiTestScenario = require('./lib/SuiTestScenario.js');
4
4
  const SuiObject = require('./lib/SuiObject.js');
5
5
  const SuiLocalTestValidator = require('./lib/SuiLocalTestValidator.js');
6
+ const sui = require('@mysten/sui.js');
6
7
 
7
8
  module.exports = {
8
9
  SuiMaster,
@@ -11,4 +12,7 @@ module.exports = {
11
12
  SuiTestScenario,
12
13
  SuiLocalTestValidator,
13
14
  MIST_PER_SUI: SuiMaster.MIST_PER_SUI,
15
+
16
+ TransactionBlock: sui.TransactionBlock,
17
+ Transactions: sui.Transactions,
14
18
  };
package/lib/SuiCoin.js ADDED
@@ -0,0 +1,257 @@
1
+ const { Transactions } = require('@mysten/sui.js/transactions');
2
+
3
+ const safeList = {
4
+ 'sui:mainnet': {
5
+ '0xa198f3be41cda8c07b3bf3fee02263526e535d682499806979a111e88a5a8d0f::coin::COIN': 'CELO',
6
+ '0x027792d9fed7f9844eb4839566001bb6f6cb4804f66aa2da6fe1ee242d896881::coin::COIN': 'tBTC',
7
+ '0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN': 'USDCeth',
8
+ '0xe32d3ebafa42e6011b87ef1087bbc6053b499bf6f095807b9013aff5a6ecd7bb::coin::COIN': 'USDCarb',
9
+ '0x909cba62ce96d54de25bec9502de5ca7b4f28901747bbf96b76c2e63ec5f1cba::coin::COIN': 'USDCbnb',
10
+ '0xcf72ec52c0f8ddead746252481fb44ff6e8485a39b803825bde6b00d77cdb0bb::coin::COIN': 'USDCpol',
11
+ '0xb231fcda8bbddb31f2ef02e6161444aec64a514e2c89279584ac9806ce9cf037::coin::COIN': 'USDCsol',
12
+ '0xc060006111016b8a020ad5b33834984a437aaa7d3c74c18e09a95d48aceab08c::coin::COIN': 'USDT',
13
+ '0x1e8b532cca6569cab9f9b9ebc73f8c13885012ade714729aa3b450e0339ac766::coin::COIN': 'WAVAX',
14
+ '0xb848cce11ef3a8f62eccea6eb5b35a12c4c2b1ee1af7755d02d7bd6218e8226f::coin::COIN': 'WBNB',
15
+ '0x027792d9fed7f9844eb4839566001bb6f6cb4804f66aa2da6fe1ee242d896881::coin::COIN': 'WBTC',
16
+ '0xaf8cd5edc19c4512f4259f0bee101a40d41ebed738ade5874359610ef8eeced5::coin::COIN': 'WETH',
17
+ '0x6081300950a4f1e2081580e919c210436a1bed49080502834950d31ee55a2396::coin::COIN': 'WFTM',
18
+ '0x66f87084e49c38f76502d17f87d17f943f183bb94117561eb573e075fdc5ff75::coin::COIN': 'WGLMR',
19
+ '0xdbe380b13a6d0f5cdedd58de8f04625263f113b3f9db32b3e1983f49e2841676::coin::COIN': 'WMATIC',
20
+ '0xb7844e289a8410e50fb3ca48d69eb9cf29e27d223ef90353fe1bd8e27ff8f3f8::coin::COIN': 'WSOL',
21
+ '0x2::sui::SUI': 'SUI',
22
+ },
23
+ };
24
+
25
+ class SuiCoin {
26
+ constructor(params = {}) {
27
+ this._coinType = params.coinType;
28
+ this._suiCoins = params.suiCoins;
29
+
30
+ this._exists = null;
31
+ this._metadata = null;
32
+ }
33
+
34
+ /**
35
+ * Normalize amount based on .decimals. Pass a string with a dot ('5.22', '0.0005') to convert it to units
36
+ * always use a dot, event for '1.0' or '100.0'.
37
+ * @param {String|Number|BigInt} amount
38
+ * @returns {BigInt}
39
+ */
40
+ normalizeAmount(amount) {
41
+ if (typeof(amount) == 'string' && amount.indexOf('.') !== -1) {
42
+ if (!this.decimals) {
43
+ throw new Error('Please load coin metadata first');
44
+ }
45
+
46
+ return BigInt(Math.floor(parseFloat(amount, 10) * Math.pow(10, this.decimals)));
47
+ }
48
+
49
+ return BigInt(amount);
50
+ }
51
+
52
+ /**
53
+ * Normalize amount based on .decimals. Pass a string with a dot ('5.22', '0.0005') to convert it to units. No worries about loading metadata first.
54
+ * @param {String|Number|BigInt} amount
55
+ * @returns {BigInt}
56
+ */
57
+ async lazyNormalizeAmount(amount) {
58
+ await this.getMetadata();
59
+ return this.normalizeAmount(amount);
60
+ }
61
+
62
+ amountToString(amount) {
63
+ if (!this.decimals) {
64
+ throw new Error('Please load coin metadata first');
65
+ }
66
+
67
+ const str = (''+BigInt(amount)).padStart(this.decimals + 1,'0');
68
+ const ind = str.length - this.decimals;
69
+ return str.substring(0, ind) + '.' + str.substring(ind);
70
+ }
71
+
72
+ get suiMaster() {
73
+ return this._suiCoins.suiMaster;
74
+ }
75
+
76
+ static safeList(connectedChain) {
77
+ return safeList[connectedChain];
78
+ }
79
+
80
+ get coinType() {
81
+ if (this._coinType.indexOf('0x') === 0) {
82
+ return this._coinType;
83
+ }
84
+
85
+ return '0x'+this._coinType;
86
+ }
87
+
88
+ get decimals() {
89
+ if (this.metadata) {
90
+ return this.metadata.decimals;
91
+ }
92
+ return undefined;
93
+ }
94
+
95
+ get metadata() {
96
+ return this._metadata;
97
+ }
98
+
99
+ get safeList() {
100
+ if (this.suiMaster && this.suiMaster.connectedChain) {
101
+ if (safeList[this.suiMaster.connectedChain]) {
102
+ return safeList[this.suiMaster.connectedChain];
103
+ }
104
+ }
105
+
106
+ return {};
107
+ }
108
+
109
+ get isSafe() {
110
+ if (this.safeList[this.coinType]) {
111
+ return true;
112
+ }
113
+
114
+ return false;
115
+ }
116
+
117
+ get symbol() {
118
+ if (this.safeList[this.coinType]) {
119
+ return this.safeList[this.coinType];
120
+ }
121
+
122
+ if (this.metadata) {
123
+ return this.metadata.symbol;
124
+ }
125
+
126
+ return null;
127
+ }
128
+
129
+ get name() {
130
+ return this.metadata.name;
131
+ }
132
+
133
+ isSUI() {
134
+ return this._coinType.toLowerCase().indexOf('sui') > -1;
135
+ }
136
+
137
+ async getMetadata() {
138
+ if (this._metadata) {
139
+ return this._metadata;
140
+ }
141
+
142
+ let result = null;
143
+ try {
144
+ result = await this.suiMaster.provider.getCoinMetadata({
145
+ coinType: this.coinType,
146
+ });
147
+ } catch (e) {
148
+ console.error(e);
149
+ result = null;
150
+ }
151
+ if (!result) {
152
+ this._exists = false;
153
+ } else {
154
+ this._metadata = result;
155
+ }
156
+
157
+ return this._metadata;
158
+ }
159
+
160
+ async getBalance(owner) {
161
+ const coins = [];
162
+ let result = null;
163
+ let cursor = null;
164
+ do {
165
+ result = await this.suiMaster.provider.getCoins({
166
+ owner: owner,
167
+ coinType: this.coinType,
168
+ limit: 50,
169
+ cursor: cursor,
170
+ });
171
+ coins.push(...result.data);
172
+
173
+ cursor = result.nextCursor;
174
+ } while (result.hasNextPage);
175
+
176
+ let totalAmount = BigInt(0);
177
+ for (const coin of coins) {
178
+ totalAmount = totalAmount + BigInt(coin.balance);
179
+ }
180
+
181
+ return totalAmount;
182
+ }
183
+
184
+ async coinOfAmountToTxCoin(txb, owner, amount, addEmptyCoins = false) {
185
+ const expectedAmountAsBigInt = BigInt(amount);
186
+ const coinIds = await this.coinObjectsEnoughForAmount(owner, expectedAmountAsBigInt, addEmptyCoins);
187
+
188
+ if (!coinIds || !coinIds.length) {
189
+ throw new Error('you do not have enough coins of type '+this.coinType);
190
+ }
191
+
192
+ if (coinIds.length == 1) {
193
+ // only one coin object enough to cover the expense
194
+ if (this.isSUI()) {
195
+ const coinInput = txb.add(Transactions.SplitCoins(txb.gas, [txb.pure(expectedAmountAsBigInt)]));
196
+ return coinInput;
197
+ } else {
198
+ // some other coin
199
+ const coinInput = txb.add(Transactions.SplitCoins(txb.object(coinIds[0]), [txb.pure(expectedAmountAsBigInt)]));
200
+ return coinInput;
201
+ }
202
+ } else {
203
+ // few coin objects to merge
204
+ const coinIdToMergeIn = coinIds.shift();
205
+ txb.add(Transactions.MergeCoins(txb.object(coinIdToMergeIn), coinIds.map((id)=>{return txb.object(id);})));
206
+ const coinInputSplet = txb.add(Transactions.SplitCoins(txb.object(coinIdToMergeIn), [txb.pure(expectedAmountAsBigInt)]));
207
+
208
+ return coinInputSplet;
209
+ }
210
+ }
211
+
212
+ async coinObjectsEnoughForAmount(owner, expectedAmount, addEmptyCoins = false) {
213
+ const expectedAmountAsBigInt = BigInt(expectedAmount);
214
+
215
+ const coinIds = [];
216
+ const coins = [];
217
+
218
+ let result = null;
219
+ let cursor = null;
220
+ do {
221
+ result = await this.suiMaster.provider.getCoins({
222
+ owner: owner,
223
+ coinType: this.coinType,
224
+ limit: 50,
225
+ cursor: cursor,
226
+ });
227
+ coins.push(...result.data);
228
+
229
+ cursor = result.nextCursor;
230
+ } while (result.hasNextPage);
231
+
232
+ coins.sort((a, b) => {
233
+ // From big to small
234
+ return Number(b.balance) - Number(a.balance);
235
+ });
236
+
237
+ let totalAmount = BigInt(0);
238
+ for (const coin of coins) {
239
+ if (totalAmount <= expectedAmountAsBigInt) {
240
+ coinIds.push(coin.coinObjectId);
241
+ totalAmount = totalAmount + BigInt(coin.balance);// totalAmount.add(coin.balance);
242
+ } else {
243
+ if (addEmptyCoins && BigInt(coin.balance) == 0n) {
244
+ coinIds.push(coin.coinObjectId);
245
+ }
246
+ }
247
+ }
248
+
249
+ if (totalAmount >= expectedAmountAsBigInt) {
250
+ return coinIds;
251
+ }
252
+
253
+ return null;
254
+ }
255
+ }
256
+
257
+ module.exports = SuiCoin;
@@ -0,0 +1,132 @@
1
+ const SuiCoin = require('./SuiCoin.js');
2
+ const SuiCommonMethods = require('./SuiCommonMethods.js');
3
+
4
+ class SuiCoins extends SuiCommonMethods {
5
+ constructor(params = {}) {
6
+ super(params);
7
+
8
+ this._suiMaster = params.suiMaster;
9
+ if (!this._suiMaster) {
10
+ throw new Error('suiMaster is required');
11
+ }
12
+ this._coins = {};
13
+
14
+ this._isInitialized = false;
15
+ }
16
+
17
+ get suiMaster() {
18
+ return this._suiMaster;
19
+ }
20
+
21
+ get coins() {
22
+ return this._coins;
23
+ }
24
+
25
+ /**
26
+ * Optional common initialized to get a list and metadata of all safe coins defined in SuiCoin.js
27
+ */
28
+ async init() {
29
+ if (this._isInitialized) {
30
+ return true;
31
+ }
32
+
33
+ const safeList = SuiCoin.safeList(this._suiMaster.connectedChain);
34
+ const metadataPromises = [];
35
+ for (const coinType in safeList) {
36
+ const normalizedCoinType = this.normalizeCoinType(coinType);
37
+ if (!this._coins[normalizedCoinType]) {
38
+ const suiCoin = new SuiCoin({
39
+ coinType: normalizedCoinType,
40
+ suiCoins: this,
41
+ });
42
+ console.log('adding coin with type', normalizedCoinType);
43
+ this._coins[normalizedCoinType] = suiCoin;
44
+
45
+ const metadataPromise = new Promise(async(res)=>{
46
+ try {
47
+ await suiCoin.getMetadata();
48
+ } catch (e) {
49
+ console.error(e);
50
+ }
51
+
52
+ res();
53
+ });
54
+ metadataPromises.push(metadataPromise);
55
+ }
56
+ }
57
+
58
+ await Promise.all(metadataPromises);
59
+
60
+ this._isInitialized = true;
61
+ }
62
+
63
+ normalizeCoinType(coinType) {
64
+ if (coinType.indexOf('::') == -1) {
65
+ if (coinType.toLowerCase() == 'sui') {
66
+ return '0x2::sui::SUI';
67
+ } else {
68
+ for (const key in this._coins) {
69
+ if (key == coinType) {
70
+ return this._coins[key].coinType;
71
+ }
72
+ }
73
+
74
+ const safeList = SuiCoin.safeList(this._suiMaster.connectedChain);
75
+ for (const key in safeList) {
76
+ if (safeList[key] == coinType) {
77
+ return key;
78
+ }
79
+ }
80
+ }
81
+
82
+ if (coinType.indexOf('0x') == -1) {
83
+ return '0x'+coinType+'::coin::COIN';
84
+ } else {
85
+ return ''+coinType+'::coin::COIN';
86
+ }
87
+ }
88
+
89
+ if (coinType.indexOf('0x') == -1) {
90
+ coinType = '0x'+coinType;
91
+ }
92
+
93
+ if (coinType == '0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI') {
94
+ return '0x2::sui::SUI';
95
+ }
96
+
97
+ return coinType;
98
+ }
99
+
100
+ get(coinType) {
101
+ const normalizedCoinType = this.normalizeCoinType(coinType);
102
+ let suiCoin = this._coins[normalizedCoinType];
103
+ if (suiCoin) {
104
+ return suiCoin;
105
+ }
106
+
107
+ suiCoin = new SuiCoin({
108
+ coinType: normalizedCoinType,
109
+ suiCoins: this,
110
+ });
111
+
112
+ this._coins[normalizedCoinType] = suiCoin;
113
+
114
+ return suiCoin;
115
+ }
116
+
117
+ static _singleInstances = {};
118
+ static getSingleton(params = {}) {
119
+ const suiMaster = params.suiMaster;
120
+ const connectedChain = suiMaster.connectedChain;
121
+
122
+ if (SuiCoins._singleInstances[connectedChain]) {
123
+ return SuiCoins._singleInstances[connectedChain];
124
+ }
125
+
126
+ SuiCoins._singleInstances[connectedChain] = new SuiCoins(params);
127
+ return SuiCoins._singleInstances[connectedChain];
128
+ }
129
+
130
+ };
131
+
132
+ module.exports = SuiCoins;
package/lib/SuiMaster.js CHANGED
@@ -7,6 +7,7 @@ const SuiPaginatedResponse = require('./SuiPaginatedResponse.js');
7
7
  const SuiObject = require('./SuiObject.js');
8
8
  const SuiTransaction = require('./SuiTransaction.js');
9
9
  const SuiEvent = require('./SuiEvent.js');
10
+ const SuiCoins = require('./SuiCoins.js');
10
11
 
11
12
  class SuiMaster extends SuiCommonMethods {
12
13
  constructor(params = {}) {
@@ -103,6 +104,15 @@ class SuiMaster extends SuiCommonMethods {
103
104
  this._initialized = false;
104
105
 
105
106
  this._packages = {};
107
+
108
+ this._suiCoins = new SuiCoins({
109
+ suiMaster: this,
110
+ debug: this._debug,
111
+ });
112
+ }
113
+
114
+ get suiCoins() {
115
+ return this._suiCoins;
106
116
  }
107
117
 
108
118
  get MIST_PER_SUI() {
@@ -237,26 +247,23 @@ class SuiMaster extends SuiCommonMethods {
237
247
  return amount;
238
248
  }
239
249
 
240
- async getBalance(coinType = '0x2::sui::SUI') {
250
+ /**
251
+ * Query the balance of specific coinType for an owner. If owner == null, returns balance of connected address owner
252
+ *
253
+ * @param {String} coinType
254
+ * @param {String|null} owner
255
+ * @returns BigInt
256
+ */
257
+ async getBalance(coinType = '0x2::sui::SUI', owner = null) {
241
258
  await this.initialize();
242
259
 
243
- this.log('requesting balance of coin', coinType, '...');
244
-
245
- let res = null;
246
- try {
247
- res = await this._provider.getBalance({owner: this._address, coinType});
248
- } catch (e) {
249
- this.log('error', e);
250
- res = null;
251
- }
252
-
253
- let ret = BigInt(0);
254
- if (res && res.totalBalance) {
255
- ret = BigInt(res.totalBalance);
260
+ let queryingBalanceOf = owner;
261
+ if (!queryingBalanceOf && this.address) {
262
+ queryingBalanceOf = this.address;
256
263
  }
257
264
 
258
- this.log('balance of', coinType, 'is', ret);
259
- return ret;
265
+ const suiCoin = this._suiCoins.get(coinType);
266
+ return await (suiCoin.getBalance(queryingBalanceOf));
260
267
  }
261
268
 
262
269
  // export type TransactionFilter =
@@ -115,29 +115,40 @@ class SuiPackageModule extends SuiCommonMethods {
115
115
  async moveCall(methodName, params) {
116
116
  await this._package.checkOnChainIfNeeded();
117
117
 
118
- const tx = new sui.TransactionBlock();
119
-
120
- const callArgs = [];
121
-
122
- for (let param of params) {
123
- if (param && param.type && param.amount && param.type === 'SUI') {
124
- let amount = BigInt(param.amount);
125
- const coin = tx.add(sui.Transactions.SplitCoins(tx.gas, [tx.pure(amount)]));
126
- callArgs.push(coin);
127
- } else if (param && Array.isArray(param) && param.length == 1 && param[0].type && param[0].amount && param[0].type === 'SUI') {
128
- // vector<Coin<SUI>>
129
- let amount = BigInt(param[0].amount);
130
- const coin = tx.add(sui.Transactions.SplitCoins(tx.gas, [tx.pure(amount)]));
131
- callArgs.push(tx.makeMoveVec({ objects: [coin]}));
132
- } else {
133
- callArgs.push(tx.pure(param));
118
+ let tx = null;
119
+ if (params.tx) {
120
+ tx = params.tx;
121
+ } else {
122
+ tx = new sui.TransactionBlock();
123
+
124
+ const callArgs = [];
125
+
126
+ for (let param of params) {
127
+ if (param && param.type && param.amount) {
128
+ const ownerAddress = this._suiMaster.address;
129
+
130
+ const suiCoin = await this._suiMaster.suiCoins.get(param.type);
131
+ const txCoinToSend = await suiCoin.coinOfAmountToTxCoin(tx, ownerAddress, param.amount);
132
+
133
+ callArgs.push(txCoinToSend);
134
+ } else if (param && Array.isArray(param) && param.length == 1 && param[0].type && param[0].amount) {
135
+ // vector<Coin<SUI>>
136
+ const ownerAddress = this._suiMaster.address;
137
+
138
+ const suiCoin = await this._suiMaster.suiCoins.get(param.type);
139
+ const txCoinToSend = await suiCoin.coinOfAmountToTxCoin(tx, ownerAddress, param.amount);
140
+
141
+ callArgs.push(tx.makeMoveVec({ objects: [txCoinToSend]}));
142
+ } else {
143
+ callArgs.push(tx.pure(param));
144
+ }
134
145
  }
146
+
147
+ tx.moveCall({
148
+ target: `${this._package.address}::${this._moduleName}::${methodName}`,
149
+ arguments: callArgs,
150
+ });
135
151
  }
136
-
137
- tx.moveCall({
138
- target: `${this._package.address}::${this._moduleName}::${methodName}`,
139
- arguments: callArgs,
140
- });
141
152
 
142
153
  const result = await this._suiMaster._signer.signAndExecuteTransactionBlock({
143
154
  transactionBlock: tx,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "suidouble",
3
- "version": "0.0.37",
3
+ "version": "0.0.39",
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.js": "^0.37.1",
24
+ "@mysten/sui.js": "^0.39.0",
25
25
  "@wallet-standard/core": "^1.0.3"
26
26
  },
27
27
  "devDependencies": {