@ocap/client 1.6.3 → 1.6.10
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 +1 -1
- package/dist/base.js +36 -22
- package/dist/base.js.map +1 -1
- package/dist/browser.d.ts +997 -590
- package/dist/browser.js +1 -8
- package/dist/browser.js.map +1 -1
- package/dist/bundle.js +3 -3
- package/dist/client.js +11 -7
- package/dist/client.js.map +1 -1
- package/dist/extension.js +502 -462
- package/dist/extension.js.map +1 -1
- package/dist/methods.js +0 -142
- package/dist/methods.js.map +1 -1
- package/dist/report.html +2 -2
- package/dist/schema/graphql.json +9048 -4442
- package/dist/schema/graphql.txt +2 -2
- package/dist/types.js +2143 -1924
- package/dist/types.js.map +1 -1
- package/docs/QUERIES.md +1547 -1494
- package/docs/README.md +3269 -3138
- package/examples/asset.js +7 -7
- package/examples/create-secondary-token.js +44 -0
- package/examples/declare.js +9 -9
- package/examples/{delegate_exchange_both.js → delegate-exchange-both.js} +12 -8
- package/examples/{delegate_exchange.js → delegate-exchange.js} +11 -7
- package/examples/{delegate_transfer.js → delegate-transfer.js} +12 -6
- package/examples/exchange-secondary-token.js +100 -0
- package/examples/exchange.js +9 -9
- package/examples/{migrate_account.js → migrate-account.js} +5 -5
- package/examples/run-no-debug.sh +8 -8
- package/examples/run.sh +8 -8
- package/examples/subscribe.js +16 -0
- package/examples/{transfer_asset.js → transfer-asset.js} +11 -11
- package/examples/{transfer_token.js → transfer-primary-token.js} +10 -10
- package/examples/transfer-secondary-token.js +62 -0
- package/lib/base.js +36 -22
- package/lib/base.js.map +1 -1
- package/lib/client.js +11 -7
- package/lib/client.js.map +1 -1
- package/lib/extension.js +502 -462
- package/lib/extension.js.map +1 -1
- package/lib/methods.js +0 -142
- package/lib/methods.js.map +1 -1
- package/lib/node.d.ts +997 -590
- package/lib/node.js +0 -6
- package/lib/node.js.map +1 -1
- package/lib/schema/graphql.json +9048 -4442
- package/lib/schema/graphql.txt +2 -2
- package/lib/types.js +2143 -1924
- package/lib/types.js.map +1 -1
- package/package.json +30 -32
- package/examples/atomic_swap.js +0 -145
- package/examples/consume_asset_gatekeeper.js +0 -105
- package/examples/consume_asset_simple.js +0 -91
- package/examples/declare_forgeweb.js +0 -60
- package/examples/declare_restricted.js +0 -47
- package/examples/delegate_atomic_swap.js +0 -177
- package/examples/get_free_token.js +0 -33
- package/examples/subscribe_new_block.js +0 -36
- package/examples/subscribe_transfer.js +0 -80
package/lib/extension.js
CHANGED
|
@@ -1,17 +1,27 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
/* eslint-disable prefer-object-spread */
|
|
3
4
|
/* eslint-disable no-underscore-dangle */
|
|
4
5
|
/* eslint-disable object-curly-newline */
|
|
5
6
|
const get = require('lodash/get');
|
|
7
|
+
const omit = require('lodash/omit');
|
|
8
|
+
const cloneDeep = require('lodash/cloneDeep');
|
|
6
9
|
const camelCase = require('lodash/camelCase');
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const { isValid: isValidDID, toTypeInfo } = require('@arcblock/did');
|
|
11
|
-
const { toDelegateAddress, toSwapAddress, toAssetAddress } = require('@arcblock/did-util');
|
|
12
|
-
const { transactions, typeUrls, multiSignTxs } = require('@ocap/proto');
|
|
13
|
-
const { createMessage, getMessageType, decodeAny } = require('@ocap/message');
|
|
10
|
+
const { toTypeInfo, isValid } = require('@arcblock/did');
|
|
11
|
+
const { transactions, typeUrls, multiSignTxs, multiSignV2Txs } = require('@ocap/proto');
|
|
12
|
+
const { createMessage, getMessageType, toTypeUrl } = require('@ocap/message');
|
|
14
13
|
const { bytesToHex, toBase58, toBase64, toHex, toBuffer, fromTokenToUnit, fromUnitToToken } = require('@ocap/util');
|
|
14
|
+
const { DEFAULT_TOKEN_DECIMAL } = require('@ocap/util/lib/constant');
|
|
15
|
+
const { formatFactoryState, preMintFromFactory, isValidFactory } = require('@ocap/asset');
|
|
16
|
+
const {
|
|
17
|
+
toDelegateAddress,
|
|
18
|
+
toAssetAddress,
|
|
19
|
+
toFactoryAddress,
|
|
20
|
+
toTokenAddress,
|
|
21
|
+
toStakeAddress,
|
|
22
|
+
toRollupAddress
|
|
23
|
+
} = require('@arcblock/did-util');
|
|
24
|
+
|
|
15
25
|
const debug = require('debug')(require('../package.json').name);
|
|
16
26
|
|
|
17
27
|
/**
|
|
@@ -22,6 +32,14 @@ const debug = require('debug')(require('../package.json').name);
|
|
|
22
32
|
* @param {object} [{ encodeTxAsBase64 = false }={}]
|
|
23
33
|
*/
|
|
24
34
|
const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
35
|
+
Object.defineProperty(client, 'ctx', {
|
|
36
|
+
value: {
|
|
37
|
+
loading: false,
|
|
38
|
+
ready: false,
|
|
39
|
+
callbacks: []
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
25
43
|
/**
|
|
26
44
|
* Format big number presentation amount to token number
|
|
27
45
|
*
|
|
@@ -32,7 +50,7 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
32
50
|
* @returns {string}
|
|
33
51
|
*/
|
|
34
52
|
client.fromUnitToToken = async value => {
|
|
35
|
-
const { token } = await client.
|
|
53
|
+
const { token } = await client.getContext();
|
|
36
54
|
return fromUnitToToken(value, token.decimal);
|
|
37
55
|
};
|
|
38
56
|
|
|
@@ -46,36 +64,13 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
46
64
|
* @returns {BN}
|
|
47
65
|
*/
|
|
48
66
|
client.fromTokenToUnit = async amount => {
|
|
49
|
-
const { token } = await client.
|
|
67
|
+
const { token } = await client.getContext();
|
|
50
68
|
return fromTokenToUnit(amount, token.decimal);
|
|
51
69
|
};
|
|
52
70
|
|
|
53
|
-
/**
|
|
54
|
-
* Converts a relative locktime to absolute locktime
|
|
55
|
-
*
|
|
56
|
-
* @memberof GraphQLClient
|
|
57
|
-
* @function
|
|
58
|
-
* @name GraphQLClient#toLocktime
|
|
59
|
-
* @param {number} number - number of blocks want to lock
|
|
60
|
-
* @param {object} [options={}] - options to underlying methods
|
|
61
|
-
* @returns {number}
|
|
62
|
-
*/
|
|
63
|
-
client.toLocktime = async number => {
|
|
64
|
-
const result = await client.doRawQuery(`{
|
|
65
|
-
getChainInfo {
|
|
66
|
-
code
|
|
67
|
-
info {
|
|
68
|
-
blockHeight
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}`);
|
|
72
|
-
|
|
73
|
-
return +get(result, 'getChainInfo.info.blockHeight', 0) + number;
|
|
74
|
-
};
|
|
75
|
-
|
|
76
71
|
/**
|
|
77
72
|
* List all transaction send methods
|
|
78
|
-
* Each method can send one kind of transactions supported by forge core, such as `DeclareTx
|
|
73
|
+
* Each method can send one kind of transactions supported by forge core, such as `DeclareTx`
|
|
79
74
|
*
|
|
80
75
|
* @memberof GraphQLClient
|
|
81
76
|
* @function
|
|
@@ -112,7 +107,7 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
112
107
|
* @name GraphQLClient#getTxMultiSignMethods
|
|
113
108
|
* @returns {Array<string>} method name list
|
|
114
109
|
*/
|
|
115
|
-
client.getTxMultiSignMethods = () => multiSignTxs.map(x => camelCase(`multi_sign_${x}`));
|
|
110
|
+
client.getTxMultiSignMethods = () => multiSignTxs.concat(multiSignV2Txs).map(x => camelCase(`multi_sign_${x}`));
|
|
116
111
|
|
|
117
112
|
/**
|
|
118
113
|
* Get protobuf message class by name, only supports forge-built-in types
|
|
@@ -139,17 +134,6 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
139
134
|
return Transaction.deserializeBinary(toBuffer(input)).toObject();
|
|
140
135
|
};
|
|
141
136
|
|
|
142
|
-
if (typeof client._createResponseError !== 'function') {
|
|
143
|
-
client._createResponseError = (code, method) => {
|
|
144
|
-
const type = snakeCase(method);
|
|
145
|
-
const message = (errorCodes[code][type] || errorCodes[code].default || code).trim();
|
|
146
|
-
const error = new Error(`${code}: ${message}`);
|
|
147
|
-
error.code = code;
|
|
148
|
-
error.type = type;
|
|
149
|
-
return error;
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
|
|
153
137
|
/**
|
|
154
138
|
* Ensure a connection is bootstrapped with some meta info fetched from chain node
|
|
155
139
|
*
|
|
@@ -157,50 +141,97 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
157
141
|
* @param {string} [conn=undefined]
|
|
158
142
|
* @returns {object}
|
|
159
143
|
*/
|
|
160
|
-
client.
|
|
161
|
-
if (
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
144
|
+
client.getContext = async () => {
|
|
145
|
+
if (client.ctx.ready) {
|
|
146
|
+
return client.context;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (client.ctx.loading) {
|
|
150
|
+
return new Promise(resolve => {
|
|
151
|
+
client.ctx.callbacks.push(() => resolve(client.context));
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
client.ctx.loading = true;
|
|
156
|
+
const result = await client.doRawQuery(`{
|
|
157
|
+
getChainInfo {
|
|
158
|
+
code
|
|
159
|
+
info {
|
|
160
|
+
network
|
|
161
|
+
consensusVersion
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
getForgeState {
|
|
165
|
+
code
|
|
166
|
+
state {
|
|
167
|
+
token {
|
|
168
|
+
decimal
|
|
169
|
+
symbol
|
|
169
170
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
decimal
|
|
175
|
-
symbol
|
|
176
|
-
}
|
|
177
|
-
txConfig {
|
|
178
|
-
poke {
|
|
179
|
-
amount
|
|
180
|
-
dailyLimit
|
|
181
|
-
enabled
|
|
182
|
-
}
|
|
183
|
-
}
|
|
171
|
+
txConfig {
|
|
172
|
+
txFee {
|
|
173
|
+
fee
|
|
174
|
+
typeUrl
|
|
184
175
|
}
|
|
185
176
|
}
|
|
186
|
-
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}`);
|
|
180
|
+
|
|
181
|
+
client.context = {
|
|
182
|
+
chainId: get(result, 'getChainInfo.info.network'),
|
|
183
|
+
consensus: get(result, 'getChainInfo.info.consensusVersion'),
|
|
184
|
+
token: get(result, 'getForgeState.state.token'),
|
|
185
|
+
txConfig: get(result, 'getForgeState.state.txConfig'),
|
|
186
|
+
tokenStateMap: new Map()
|
|
187
|
+
};
|
|
187
188
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
189
|
+
client.ctx.ready = true;
|
|
190
|
+
client.ctx.loading = false;
|
|
191
|
+
client.ctx.callbacks.forEach(cb => cb());
|
|
192
|
+
debug('context ready');
|
|
193
|
+
|
|
194
|
+
return client.context;
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
client.getTokenStateMap = async addressList => {
|
|
198
|
+
const result = new Map();
|
|
199
|
+
const notExistAddressList = [];
|
|
200
|
+
addressList.forEach(address => {
|
|
201
|
+
if (client.context.tokenStateMap.has(address)) {
|
|
202
|
+
result.set(address, client.context.tokenStateMap.get(address));
|
|
193
203
|
} else {
|
|
194
|
-
|
|
195
|
-
client.context = {
|
|
196
|
-
chainId: info.network,
|
|
197
|
-
token: state.token,
|
|
198
|
-
poke: state.txConfig.poke
|
|
199
|
-
};
|
|
204
|
+
notExistAddressList.push(address);
|
|
200
205
|
}
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
if (result.size === addressList.length) {
|
|
209
|
+
return result;
|
|
201
210
|
}
|
|
202
211
|
|
|
203
|
-
|
|
212
|
+
const getTokenState = async address => {
|
|
213
|
+
const {
|
|
214
|
+
getTokenState: { code, state }
|
|
215
|
+
} = await client.doRawQuery(`{
|
|
216
|
+
getTokenState(address: "${address}") {
|
|
217
|
+
code
|
|
218
|
+
state {
|
|
219
|
+
decimal
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}`);
|
|
223
|
+
|
|
224
|
+
if (code !== 'OK') {
|
|
225
|
+
throw new Error(`get token ${address} state failed`);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
result.set(address, state);
|
|
229
|
+
client.context.tokenStateMap.set(address, state);
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
await Promise.all(notExistAddressList.map(address => getTokenState(address)));
|
|
233
|
+
|
|
234
|
+
return result;
|
|
204
235
|
};
|
|
205
236
|
|
|
206
237
|
// Unify a client wallet | forge managed wallet
|
|
@@ -214,7 +245,7 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
214
245
|
|
|
215
246
|
if (typeof wallet.toAddress === 'function') {
|
|
216
247
|
return {
|
|
217
|
-
address: wallet.
|
|
248
|
+
address: wallet.address,
|
|
218
249
|
publicKey: wallet.publicKey
|
|
219
250
|
};
|
|
220
251
|
}
|
|
@@ -236,14 +267,15 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
236
267
|
* @param {object} [input.tx.from] - the sender address, can be derived from wallet
|
|
237
268
|
* @param {object} [input.tx.nonce] - the tx nonce, defaults to Date.now if not set
|
|
238
269
|
* @param {object} [input.tx.chainId] - the chainId
|
|
239
|
-
* @param {object} [input.tx.signature] - the
|
|
240
|
-
* @param {object} [input.tx.signatures] - the
|
|
241
|
-
* @param {object} input.wallet - the wallet used to sign the transaction
|
|
270
|
+
* @param {object} [input.tx.signature] - the signature
|
|
271
|
+
* @param {object} [input.tx.signatures] - the signature list
|
|
272
|
+
* @param {object} input.wallet - the wallet used to sign the transaction
|
|
242
273
|
* @param {object} input.delegator - the wallet address that delegated permissions to the `input.wallet` address
|
|
243
274
|
* @returns Promise
|
|
244
275
|
*/
|
|
245
276
|
const txEncodeFn = async ({ tx, wallet, delegator }) => {
|
|
246
277
|
const w = getWallet(wallet);
|
|
278
|
+
const context = await client.getContext();
|
|
247
279
|
|
|
248
280
|
// Determine sender address
|
|
249
281
|
const address = tx.from || w.address;
|
|
@@ -251,9 +283,8 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
251
283
|
|
|
252
284
|
// Determine chainId & nonce, only attach new one when not exist
|
|
253
285
|
const nonce = typeof tx.nonce === 'undefined' ? Date.now() : tx.nonce;
|
|
254
|
-
let chainId = tx.chainId ||
|
|
286
|
+
let chainId = tx.chainId || '';
|
|
255
287
|
if (!chainId) {
|
|
256
|
-
const context = await client._ensureContext();
|
|
257
288
|
// eslint-disable-next-line prefer-destructuring
|
|
258
289
|
chainId = context.chainId;
|
|
259
290
|
}
|
|
@@ -277,6 +308,9 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
277
308
|
itx = { type: x, value: tx.itx };
|
|
278
309
|
}
|
|
279
310
|
|
|
311
|
+
const type = itx.typeUrl || toTypeUrl(itx.type);
|
|
312
|
+
const feeConfig = get(context, 'txConfig.txFee', []).find(t => t.typeUrl === type);
|
|
313
|
+
|
|
280
314
|
const txObj = createMessage('Transaction', {
|
|
281
315
|
from: tx.delegator ? address : delegator || address,
|
|
282
316
|
nonce,
|
|
@@ -285,7 +319,8 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
285
319
|
signature: tx.signature || Buffer.from([]),
|
|
286
320
|
signatures,
|
|
287
321
|
delegator: tx.delegator || (delegator ? address : ''),
|
|
288
|
-
itx
|
|
322
|
+
itx,
|
|
323
|
+
serviceFee: feeConfig ? feeConfig.fee : '0'
|
|
289
324
|
});
|
|
290
325
|
const txToSignBytes = txObj.serializeBinary();
|
|
291
326
|
|
|
@@ -346,16 +381,6 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
346
381
|
resolve(hash);
|
|
347
382
|
}
|
|
348
383
|
} catch (err) {
|
|
349
|
-
if (Array.isArray(err.errors)) {
|
|
350
|
-
const code = err.errors[0].message;
|
|
351
|
-
if (errorCodes[code]) {
|
|
352
|
-
const error = client._createResponseError(code, x);
|
|
353
|
-
error.errors = err.errors;
|
|
354
|
-
reject(error);
|
|
355
|
-
return;
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
|
|
359
384
|
reject(err);
|
|
360
385
|
}
|
|
361
386
|
});
|
|
@@ -410,13 +435,13 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
410
435
|
tx.signaturesList.unshift({
|
|
411
436
|
pk: wallet.publicKey,
|
|
412
437
|
signer: delegator,
|
|
413
|
-
delegator: wallet.
|
|
438
|
+
delegator: wallet.address,
|
|
414
439
|
data
|
|
415
440
|
});
|
|
416
441
|
} else {
|
|
417
442
|
tx.signaturesList.unshift({
|
|
418
443
|
pk: wallet.publicKey,
|
|
419
|
-
signer: wallet.
|
|
444
|
+
signer: wallet.address,
|
|
420
445
|
delegator: '',
|
|
421
446
|
data
|
|
422
447
|
});
|
|
@@ -430,6 +455,31 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
430
455
|
txMultiSignFn.__tx__ = multiSignMethod;
|
|
431
456
|
client[multiSignMethod] = txMultiSignFn;
|
|
432
457
|
}
|
|
458
|
+
|
|
459
|
+
if (multiSignV2Txs.includes(x)) {
|
|
460
|
+
const txMultiSignFn = async ({ tx, wallet, encoding = '' }) => {
|
|
461
|
+
if (typeof wallet.toAddress !== 'function') {
|
|
462
|
+
throw new Error('Multisig requires a valid wallet');
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
const signer = wallet.address;
|
|
466
|
+
const signatures = cloneDeep(tx.signatures || tx.signaturesList || []);
|
|
467
|
+
const item = signatures.find(s => s.signer === signer || s.delegator === signer);
|
|
468
|
+
if (!item) {
|
|
469
|
+
throw new Error('Signer not in the list');
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
tx.signaturesList = signatures.map(s => omit(s, ['signature']));
|
|
473
|
+
const { object, buffer } = await txEncodeFn({ tx, wallet });
|
|
474
|
+
|
|
475
|
+
item.signature = wallet.sign(bytesToHex(buffer));
|
|
476
|
+
object.signaturesList = signatures;
|
|
477
|
+
return _formatEncodedTx(object, encoding);
|
|
478
|
+
};
|
|
479
|
+
const multiSignMethod = camelCase(`multi_sign_${x}`);
|
|
480
|
+
txMultiSignFn.__tx__ = multiSignMethod;
|
|
481
|
+
client[multiSignMethod] = txMultiSignFn;
|
|
482
|
+
}
|
|
433
483
|
});
|
|
434
484
|
|
|
435
485
|
/**
|
|
@@ -450,9 +500,8 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
450
500
|
let itxData = data;
|
|
451
501
|
|
|
452
502
|
// If there is no data attached to the account, we can attach wallet type by default
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
itxData = { typeUrl: 'json', value: toTypeInfo(typeData, true) };
|
|
503
|
+
if (!itxData) {
|
|
504
|
+
itxData = { typeUrl: 'json', value: toTypeInfo(wallet.address, true) };
|
|
456
505
|
}
|
|
457
506
|
|
|
458
507
|
return client.sendDeclareTx({
|
|
@@ -463,53 +512,6 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
463
512
|
}, extra);
|
|
464
513
|
};
|
|
465
514
|
|
|
466
|
-
/**
|
|
467
|
-
* Prepare an declare transaction when the chain has enabled restricted declare
|
|
468
|
-
*
|
|
469
|
-
* @memberof GraphQLClient
|
|
470
|
-
* @function
|
|
471
|
-
* @name GraphQLClient#prepareDeclare
|
|
472
|
-
* @param {object} params
|
|
473
|
-
* @param {string} params.moniker - account moniker
|
|
474
|
-
* @param {string} params.issuer - issuer address
|
|
475
|
-
* @param {string} params.delegator - the delegator address
|
|
476
|
-
* @param {WalletObject} params.wallet - the wallet that want to do the declare
|
|
477
|
-
* @param {object} extra - other param to underlying client implementation
|
|
478
|
-
* @returns {Promise} the `transaction` object once resolved
|
|
479
|
-
*/
|
|
480
|
-
client.prepareDeclare = async ({ moniker, issuer, wallet, data, delegator = '' }, extra) => client.signDeclareTx({
|
|
481
|
-
tx: {
|
|
482
|
-
itx: {
|
|
483
|
-
moniker,
|
|
484
|
-
issuer,
|
|
485
|
-
data
|
|
486
|
-
}
|
|
487
|
-
},
|
|
488
|
-
delegator,
|
|
489
|
-
wallet
|
|
490
|
-
}, extra);
|
|
491
|
-
|
|
492
|
-
/**
|
|
493
|
-
* Finalize an declare transaction using the issuer's account
|
|
494
|
-
*
|
|
495
|
-
* @memberof GraphQLClient
|
|
496
|
-
* @function
|
|
497
|
-
* @name GraphQLClient#finalizeExchange
|
|
498
|
-
* @param {object} params
|
|
499
|
-
* @param {object} params.tx - the transaction object from `prepareExchange`
|
|
500
|
-
* @param {string} params.delegator - who authorized this transaction
|
|
501
|
-
* @param {object} params.data - extra data in the multi sig
|
|
502
|
-
* @param {WalletObject} params.wallet - issuer's wallet
|
|
503
|
-
* @param {object} extra - other param to underlying client implementation
|
|
504
|
-
* @returns {Promise} the `transaction` object once resolved
|
|
505
|
-
*/
|
|
506
|
-
client.finalizeDeclare = ({ tx, delegator = '', data, wallet }, extra) => client.multiSignDeclareTx({
|
|
507
|
-
tx,
|
|
508
|
-
delegator,
|
|
509
|
-
data,
|
|
510
|
-
wallet
|
|
511
|
-
}, extra);
|
|
512
|
-
|
|
513
515
|
/**
|
|
514
516
|
* Migrate current account to a new account
|
|
515
517
|
*
|
|
@@ -525,7 +527,7 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
525
527
|
client.migrateAccount = ({ from, to }, extra) => client.sendAccountMigrateTx({
|
|
526
528
|
tx: {
|
|
527
529
|
itx: {
|
|
528
|
-
address: to.
|
|
530
|
+
address: to.address,
|
|
529
531
|
pk: to.publicKey,
|
|
530
532
|
type: to.type
|
|
531
533
|
}
|
|
@@ -562,12 +564,12 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
562
564
|
throw new Error('Invalid type url provided for delegation');
|
|
563
565
|
}
|
|
564
566
|
|
|
565
|
-
const address = toDelegateAddress(from.
|
|
567
|
+
const address = toDelegateAddress(from.address, to.address);
|
|
566
568
|
const hash = await client.sendDelegateTx({
|
|
567
569
|
tx: {
|
|
568
570
|
itx: {
|
|
569
571
|
address,
|
|
570
|
-
to: to.
|
|
572
|
+
to: to.address,
|
|
571
573
|
ops
|
|
572
574
|
}
|
|
573
575
|
},
|
|
@@ -593,8 +595,8 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
593
595
|
client.revokeDelegate = ({ from, to, privileges }, extra) => client.sendRevokeDelegateTx({
|
|
594
596
|
tx: {
|
|
595
597
|
itx: {
|
|
596
|
-
address: toDelegateAddress(from.
|
|
597
|
-
to: to.
|
|
598
|
+
address: toDelegateAddress(from.address, to.address),
|
|
599
|
+
to: to.address,
|
|
598
600
|
typeUrls: privileges.filter(Boolean).map(x => x.toString())
|
|
599
601
|
}
|
|
600
602
|
},
|
|
@@ -614,13 +616,28 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
614
616
|
* @param {number} params.ttl - ttl after first consumption
|
|
615
617
|
* @param {boolean} params.readonly - whether the asset can be updated after creation
|
|
616
618
|
* @param {boolean} params.transferrable - whether the asset can be transferred to another account
|
|
619
|
+
* @param {object} params.display - the display of the asset
|
|
620
|
+
* @param {object} params.endpoint - the endpoint of the asset
|
|
621
|
+
* @param {string} params.tags - the tag list of the asset
|
|
617
622
|
* @param {string} params.delegator - who authorized this transaction
|
|
618
623
|
* @param {WalletObject} params.wallet - the initial owner of the asset
|
|
619
624
|
* @param {object} extra - other param to underlying client implementation
|
|
620
625
|
* @returns {Promise} the `[transactionHash, assetAddress]` once resolved
|
|
621
626
|
*/
|
|
622
|
-
client.createAsset = async ({
|
|
623
|
-
|
|
627
|
+
client.createAsset = async ({
|
|
628
|
+
moniker,
|
|
629
|
+
parent = '',
|
|
630
|
+
ttl = 0,
|
|
631
|
+
data,
|
|
632
|
+
readonly = false,
|
|
633
|
+
transferrable = true,
|
|
634
|
+
display,
|
|
635
|
+
endpoint,
|
|
636
|
+
tags = [],
|
|
637
|
+
delegator = '',
|
|
638
|
+
wallet
|
|
639
|
+
}, extra) => {
|
|
640
|
+
const payload = { moniker, parent, ttl, readonly, transferrable, data, display, endpoint, tags };
|
|
624
641
|
const address = toAssetAddress(payload);
|
|
625
642
|
payload.address = address;
|
|
626
643
|
const hash = await client.sendCreateAssetTx({
|
|
@@ -641,12 +658,11 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
641
658
|
* @param {string} params.address - asset address
|
|
642
659
|
* @param {string} params.moniker - asset name
|
|
643
660
|
* @param {object} params.data - asset data payload
|
|
644
|
-
* @param {string} params.delegator - who authorized this transaction
|
|
645
661
|
* @param {WalletObject} params.wallet - the wallet to sign the transaction
|
|
646
662
|
* @param {object} extra - other param to underlying client implementation
|
|
647
663
|
* @returns {Promise} the `transactionHash` once resolved
|
|
648
664
|
*/
|
|
649
|
-
client.updateAsset = ({ address, moniker, data,
|
|
665
|
+
client.updateAsset = ({ address, moniker, data, wallet }, extra) => client.sendUpdateAssetTx({
|
|
650
666
|
tx: {
|
|
651
667
|
itx: {
|
|
652
668
|
moniker,
|
|
@@ -654,344 +670,369 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
654
670
|
data
|
|
655
671
|
}
|
|
656
672
|
},
|
|
657
|
-
delegator,
|
|
658
673
|
wallet
|
|
659
674
|
}, extra);
|
|
660
675
|
|
|
661
676
|
/**
|
|
662
|
-
*
|
|
677
|
+
* Create an asset factory that can be used to mint new assets in future transactions
|
|
663
678
|
*
|
|
664
679
|
* @memberof GraphQLClient
|
|
665
680
|
* @function
|
|
666
|
-
* @name GraphQLClient#
|
|
681
|
+
* @name GraphQLClient#createAssetFactory
|
|
667
682
|
* @param {object} params
|
|
668
|
-
* @param {string} params.
|
|
669
|
-
* @param {
|
|
670
|
-
* @param {object} params.data - extra data payload
|
|
671
|
-
* @param {string} params.delegator - who authorized this transaction
|
|
672
|
-
* @param {WalletObject} params.wallet - the wallet to sign the transaction
|
|
683
|
+
* @param {string} params.factory - asset factory
|
|
684
|
+
* @param {WalletObject} params.wallet - the initial owner of the asset
|
|
673
685
|
* @param {object} extra - other param to underlying client implementation
|
|
674
|
-
* @returns {Promise} the `transactionHash` once resolved
|
|
686
|
+
* @returns {Promise} the `[transactionHash, factoryAddress]` once resolved
|
|
675
687
|
*/
|
|
676
|
-
client.
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
688
|
+
client.createAssetFactory = async ({ factory, wallet }, extra) => {
|
|
689
|
+
const itx = {
|
|
690
|
+
name: factory.name,
|
|
691
|
+
description: factory.description,
|
|
692
|
+
settlement: factory.settlement || 'instant',
|
|
693
|
+
limit: factory.limit || 0,
|
|
694
|
+
trustedIssuers: factory.trustedIssuers || [],
|
|
695
|
+
input: factory.input,
|
|
696
|
+
output: factory.output,
|
|
697
|
+
data: factory.data || null,
|
|
698
|
+
hooks: factory.hooks || [],
|
|
699
|
+
display: factory.display || null
|
|
700
|
+
};
|
|
701
|
+
|
|
702
|
+
isValidFactory(itx, true);
|
|
703
|
+
|
|
704
|
+
itx.address = toFactoryAddress(itx);
|
|
705
|
+
|
|
706
|
+
const hash = await client.sendCreateFactoryTx({ tx: { itx }, wallet }, extra);
|
|
707
|
+
return [hash, itx.address];
|
|
708
|
+
};
|
|
687
709
|
|
|
688
710
|
/**
|
|
689
|
-
* Prepare
|
|
711
|
+
* Prepare an acquire_asset itx
|
|
690
712
|
*
|
|
691
713
|
* @memberof GraphQLClient
|
|
692
714
|
* @function
|
|
693
|
-
* @name GraphQLClient#
|
|
715
|
+
* @name GraphQLClient#preMintAsset
|
|
694
716
|
* @param {object} params
|
|
695
|
-
* @param {
|
|
696
|
-
* @param {
|
|
697
|
-
* @param {string} params.
|
|
698
|
-
* @param {WalletObject} params.wallet - the wallet
|
|
699
|
-
* @param {object} extra - other param to
|
|
700
|
-
* @returns {Promise} the `transactionHash` once resolved
|
|
717
|
+
* @param {string} params.factory - asset factory address
|
|
718
|
+
* @param {object} params.inputs - factory inputs
|
|
719
|
+
* @param {string} params.owner - who will own the asset
|
|
720
|
+
* @param {WalletObject} params.wallet - the wallet of the asset issuer
|
|
721
|
+
* @param {object} extra - other param to merge into the itx
|
|
722
|
+
* @returns {Promise} the `[transactionHash, factoryAddress]` once resolved
|
|
701
723
|
*/
|
|
702
|
-
client.
|
|
703
|
-
|
|
704
|
-
|
|
724
|
+
client.preMintAsset = async ({ factory, inputs = {}, owner, wallet, extra = {} }) => {
|
|
725
|
+
const options = { ignoreFields: ['context.genesisTx', 'context.renaissanceTx'] };
|
|
726
|
+
const [{ state: factoryState }, { state: issuerState }] = await Promise.all([client.getFactoryState({ address: factory }, options), client.getAccountState({ address: wallet.address }, options)]);
|
|
727
|
+
|
|
728
|
+
if (!factoryState) {
|
|
729
|
+
throw new Error('Factory does not exist on chain');
|
|
705
730
|
}
|
|
706
731
|
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
732
|
+
if (!issuerState) {
|
|
733
|
+
throw new Error('Issuer does not exist on chain');
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
const { asset, address, issuer, variables } = preMintFromFactory({
|
|
737
|
+
factory: formatFactoryState(factoryState),
|
|
738
|
+
inputs,
|
|
739
|
+
owner,
|
|
740
|
+
issuer: { wallet, name: issuerState.moniker }
|
|
741
|
+
});
|
|
742
|
+
|
|
743
|
+
return Object.assign({}, extra, {
|
|
744
|
+
asset: Object.assign({ address, owner, parent: factory }, asset),
|
|
745
|
+
factory,
|
|
746
|
+
address,
|
|
747
|
+
variables: Object.entries(variables).map(([key, value]) => ({ name: key, value })),
|
|
748
|
+
issuer,
|
|
749
|
+
owner
|
|
750
|
+
});
|
|
716
751
|
};
|
|
717
752
|
|
|
718
753
|
/**
|
|
719
|
-
*
|
|
754
|
+
* Acquire an asset from factory
|
|
720
755
|
*
|
|
721
756
|
* @memberof GraphQLClient
|
|
722
757
|
* @function
|
|
723
|
-
* @name GraphQLClient#
|
|
758
|
+
* @name GraphQLClient#acquireAsset
|
|
724
759
|
* @param {object} params
|
|
725
|
-
* @param {
|
|
726
|
-
* @param {
|
|
760
|
+
* @param {AcquireAssetV2Tx} params.itx - result from preMintAsset
|
|
761
|
+
* @param {string} params.delegator - who authorized this transaction
|
|
762
|
+
* @param {WalletObject} params.wallet - the initial owner of the asset
|
|
727
763
|
* @param {object} extra - other param to underlying client implementation
|
|
728
764
|
* @returns {Promise} the `transactionHash` once resolved
|
|
729
765
|
*/
|
|
730
|
-
client.
|
|
766
|
+
client.acquireAsset = ({ itx, delegator = '', wallet }, extra) => client.sendAcquireAssetV2Tx({ tx: { itx }, delegator, wallet }, extra);
|
|
731
767
|
|
|
732
768
|
/**
|
|
733
|
-
*
|
|
769
|
+
* Mint an asset from factory
|
|
734
770
|
*
|
|
735
771
|
* @memberof GraphQLClient
|
|
736
772
|
* @function
|
|
737
|
-
* @name GraphQLClient#
|
|
773
|
+
* @name GraphQLClient#mintAsset
|
|
738
774
|
* @param {object} params
|
|
739
|
-
* @param {
|
|
740
|
-
* @param {object} params.factory - asset factory attributes
|
|
741
|
-
* @param {string} params.factory.description - asset factory name
|
|
742
|
-
* @param {number} params.factory.limit - how many assets can be generated from this factory
|
|
743
|
-
* @param {price} params.factory.price - how much should charge user when acquire asset
|
|
744
|
-
* @param {string} params.factory.template - mustache compatible
|
|
745
|
-
* @param {Array} params.factory.templateVariables - list of allowed template variables
|
|
746
|
-
* @param {string} params.factory.assetName - protobuf type known to forge that can be used to create this asset
|
|
747
|
-
* @param {string} params.factory.attributes - attributes for assets that are generated from this factory
|
|
748
|
-
* @param {boolean} params.readonly - whether the asset can be updated after creation
|
|
749
|
-
* @param {boolean} params.transferrable - whether the asset can be transferred to another account
|
|
750
|
-
* @param {string} params.delegator - who authorized this transaction
|
|
775
|
+
* @param {MintAssetTx} params.itx - result from preMintAsset
|
|
751
776
|
* @param {WalletObject} params.wallet - the initial owner of the asset
|
|
752
777
|
* @param {object} extra - other param to underlying client implementation
|
|
753
|
-
* @returns {Promise} the `
|
|
778
|
+
* @returns {Promise} the `transactionHash` once resolved
|
|
754
779
|
*/
|
|
755
|
-
client.
|
|
756
|
-
const payload = {
|
|
757
|
-
moniker,
|
|
758
|
-
readonly,
|
|
759
|
-
transferrable,
|
|
760
|
-
data: {
|
|
761
|
-
type: 'AssetFactory',
|
|
762
|
-
value: {
|
|
763
|
-
description: factory.description,
|
|
764
|
-
limit: factory.limit,
|
|
765
|
-
price: await client.fromTokenToUnit(factory.price),
|
|
766
|
-
template: factory.template,
|
|
767
|
-
allowedSpecArgs: factory.templateVariables,
|
|
768
|
-
assetName: factory.assetName,
|
|
769
|
-
// eslint-disable-next-line prefer-object-spread
|
|
770
|
-
attributes: Object.assign({ ttl: 0, transferrable: true }, factory.attributes || {})
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
};
|
|
774
|
-
const factoryAddress = toAssetAddress(payload);
|
|
775
|
-
payload.address = factoryAddress;
|
|
776
|
-
|
|
777
|
-
const hash = await client.sendCreateAssetTx({
|
|
778
|
-
tx: {
|
|
779
|
-
itx: payload
|
|
780
|
-
},
|
|
781
|
-
delegator,
|
|
782
|
-
wallet
|
|
783
|
-
}, extra);
|
|
784
|
-
return [hash, factoryAddress];
|
|
785
|
-
};
|
|
780
|
+
client.mintAsset = ({ itx, wallet }, extra) => client.sendMintAssetTx({ tx: { itx }, wallet }, extra);
|
|
786
781
|
|
|
787
782
|
/**
|
|
788
|
-
*
|
|
783
|
+
* Transfer token or assets to another account
|
|
789
784
|
*
|
|
790
785
|
* @memberof GraphQLClient
|
|
791
786
|
* @function
|
|
792
|
-
* @name GraphQLClient#
|
|
787
|
+
* @name GraphQLClient#transfer
|
|
793
788
|
* @param {object} params
|
|
794
|
-
* @param {
|
|
795
|
-
* @param {Array} params.
|
|
796
|
-
* @param {
|
|
797
|
-
* @param {
|
|
798
|
-
* @param {number} params.ttl - asset expire
|
|
789
|
+
* @param {number} params.token - how much token can be transferred
|
|
790
|
+
* @param {Array} params.assets - which assets should be transferred
|
|
791
|
+
* @param {string} params.to - who receive the transfer
|
|
792
|
+
* @param {string} params.memo - transaction note
|
|
799
793
|
* @param {string} params.delegator - who authorized this transaction
|
|
800
|
-
* @param {WalletObject} params.wallet - the
|
|
794
|
+
* @param {WalletObject} params.wallet - the wallet to sign the transaction
|
|
801
795
|
* @param {object} extra - other param to underlying client implementation
|
|
802
|
-
* @returns {Promise} the `
|
|
796
|
+
* @returns {Promise} the `transactionHash` once resolved
|
|
803
797
|
*/
|
|
804
|
-
client.
|
|
805
|
-
if (
|
|
806
|
-
throw new Error('
|
|
798
|
+
client.transfer = async ({ token = 0, assets = [], tokens = [], to = '', memo = '', delegator = '', wallet }, extra) => {
|
|
799
|
+
if (isValid(to) === false) {
|
|
800
|
+
throw new Error('Can not transfer without valid recipient');
|
|
807
801
|
}
|
|
808
|
-
if (!
|
|
809
|
-
throw new Error('
|
|
802
|
+
if (!token && tokens.length === 0 && assets.length === 0) {
|
|
803
|
+
throw new Error('Can not transfer without payload');
|
|
810
804
|
}
|
|
811
805
|
|
|
812
|
-
const {
|
|
813
|
-
if (!state) {
|
|
814
|
-
throw new Error('Asset factory address does not exist on chain');
|
|
815
|
-
}
|
|
806
|
+
const { token: contextToken } = await client.getContext();
|
|
816
807
|
|
|
817
|
-
|
|
818
|
-
if (
|
|
819
|
-
|
|
808
|
+
let tmpTokens = [];
|
|
809
|
+
if (tokens.length > 0) {
|
|
810
|
+
const tokensMap = await client.getTokenStateMap(tokens.map(t => t.address));
|
|
811
|
+
tmpTokens = tokens.map(t => {
|
|
812
|
+
t.value = fromTokenToUnit(t.value, tokensMap.get(t.address).decimal).toString();
|
|
813
|
+
return t;
|
|
814
|
+
});
|
|
820
815
|
}
|
|
821
816
|
|
|
822
|
-
|
|
823
|
-
debug('acquireAsset.factory', factory);
|
|
824
|
-
|
|
825
|
-
const assets = assetVariables.map(x => {
|
|
826
|
-
const payload = {
|
|
827
|
-
readonly: true,
|
|
828
|
-
transferrable: factory.attributes.transferrable,
|
|
829
|
-
ttl: factory.attributes.ttl,
|
|
830
|
-
parent: assetFactory,
|
|
831
|
-
data: {
|
|
832
|
-
type: factory.assetName,
|
|
833
|
-
value: x
|
|
834
|
-
}
|
|
835
|
-
};
|
|
836
|
-
|
|
837
|
-
const address = toAssetAddress(payload);
|
|
838
|
-
|
|
839
|
-
return { address, data: JSON.stringify(x) };
|
|
840
|
-
});
|
|
841
|
-
|
|
842
|
-
const hash = await client.sendAcquireAssetTx({
|
|
817
|
+
return client.sendTransferV2Tx({
|
|
843
818
|
tx: {
|
|
844
819
|
itx: {
|
|
845
|
-
to
|
|
846
|
-
|
|
820
|
+
to,
|
|
821
|
+
value: fromTokenToUnit(token, contextToken.decimal),
|
|
822
|
+
assets,
|
|
823
|
+
tokens: tmpTokens,
|
|
824
|
+
data: {
|
|
825
|
+
typeUrl: 'json',
|
|
826
|
+
value: memo || 'empty'
|
|
827
|
+
}
|
|
847
828
|
}
|
|
848
829
|
},
|
|
849
830
|
delegator,
|
|
850
831
|
wallet
|
|
851
832
|
}, extra);
|
|
852
|
-
|
|
853
|
-
return [hash, assets.map(x => x.address)];
|
|
854
833
|
};
|
|
855
834
|
|
|
856
835
|
/**
|
|
857
|
-
*
|
|
836
|
+
* Stake token or assets for another account
|
|
858
837
|
*
|
|
859
838
|
* @memberof GraphQLClient
|
|
860
839
|
* @function
|
|
861
|
-
* @name GraphQLClient#
|
|
840
|
+
* @name GraphQLClient#stake
|
|
862
841
|
* @param {object} params
|
|
863
|
-
* @param {
|
|
864
|
-
* @param {
|
|
865
|
-
* @param {string} params.
|
|
842
|
+
* @param {Array} params.assets - which assets to stake
|
|
843
|
+
* @param {Array} params.tokens - which tokens to stake
|
|
844
|
+
* @param {string} params.to - who receive the stake
|
|
845
|
+
* @param {string} params.locked - is the stake locked on creation
|
|
846
|
+
* @param {string} params.message - stake note
|
|
866
847
|
* @param {WalletObject} params.wallet - the wallet to sign the transaction
|
|
867
848
|
* @param {object} extra - other param to underlying client implementation
|
|
868
|
-
* @returns {Promise} the `transactionHash` once resolved
|
|
849
|
+
* @returns {Promise} the `transactionHash` and `stakeAddress` once resolved
|
|
869
850
|
*/
|
|
870
|
-
client.
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
*
|
|
879
|
-
* @memberof GraphQLClient
|
|
880
|
-
* @function
|
|
881
|
-
* @name GraphQLClient#setupSwap
|
|
882
|
-
* @param {object} params
|
|
883
|
-
* @param {number} params.token - how much token to offer
|
|
884
|
-
* @param {Array} params.assets - how much assets to offer
|
|
885
|
-
* @param {string} params.receiver - who can retrieve this swap
|
|
886
|
-
* @param {string} params.hashlock - sha3 from hashkey
|
|
887
|
-
* @param {string} params.delegator - who authorized this transaction
|
|
888
|
-
* @param {number} [params.locktime=1000] - how much block height to lock the swap before it can be revoked
|
|
889
|
-
* @param {WalletObject} params.wallet - the wallet to sign the transaction
|
|
890
|
-
* @param {object} extra - other param to underlying client implementation
|
|
891
|
-
* @returns {Promise} the `[transactionHash, swapAddress]` once resolved
|
|
892
|
-
*/
|
|
893
|
-
client.setupSwap = async ({
|
|
894
|
-
token = 0,
|
|
895
|
-
assets = [],
|
|
896
|
-
receiver = '',
|
|
897
|
-
hashlock = '',
|
|
898
|
-
locktime = 1000,
|
|
899
|
-
isLocktimeAbsolute = false,
|
|
900
|
-
delegator = '',
|
|
901
|
-
wallet
|
|
902
|
-
}, extra) => {
|
|
903
|
-
let finalLocktime = await client.toLocktime(locktime);
|
|
904
|
-
if (isLocktimeAbsolute) {
|
|
905
|
-
finalLocktime = locktime;
|
|
851
|
+
client.stake = async ({ assets = [], tokens = [], to = '', locked = false, message = '', wallet }, extra) => {
|
|
852
|
+
let tmpTokens = [];
|
|
853
|
+
if (tokens.length > 0) {
|
|
854
|
+
const tokensMap = await client.getTokenStateMap(tokens.map(t => t.address));
|
|
855
|
+
tmpTokens = tokens.map(t => {
|
|
856
|
+
t.value = fromTokenToUnit(t.value, tokensMap.get(t.address).decimal).toString();
|
|
857
|
+
return t;
|
|
858
|
+
});
|
|
906
859
|
}
|
|
907
|
-
|
|
860
|
+
|
|
861
|
+
const from = wallet.address;
|
|
862
|
+
const address = toStakeAddress(from, to);
|
|
863
|
+
let tx = await client.multiSignStakeTx({
|
|
908
864
|
tx: {
|
|
909
865
|
itx: {
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
866
|
+
address,
|
|
867
|
+
receiver: to,
|
|
868
|
+
locked,
|
|
869
|
+
message,
|
|
870
|
+
inputs: [{
|
|
871
|
+
owner: from,
|
|
872
|
+
assets,
|
|
873
|
+
tokens: tmpTokens
|
|
874
|
+
}]
|
|
875
|
+
},
|
|
876
|
+
signatures: [{
|
|
877
|
+
signer: from,
|
|
878
|
+
pk: wallet.publicKey
|
|
879
|
+
}]
|
|
916
880
|
},
|
|
917
|
-
delegator,
|
|
918
881
|
wallet
|
|
919
882
|
}, extra);
|
|
920
883
|
|
|
921
|
-
|
|
884
|
+
tx = await client.signStakeTx({ tx, wallet });
|
|
885
|
+
const hash = await client.sendStakeTx({ tx, wallet }, extra);
|
|
922
886
|
return [hash, address];
|
|
923
887
|
};
|
|
924
888
|
|
|
925
889
|
/**
|
|
926
|
-
*
|
|
890
|
+
* Revoke token or assets from some stake
|
|
927
891
|
*
|
|
928
892
|
* @memberof GraphQLClient
|
|
929
893
|
* @function
|
|
930
|
-
* @name GraphQLClient#
|
|
894
|
+
* @name GraphQLClient#revokeStake
|
|
931
895
|
* @param {object} params
|
|
932
|
-
* @param {
|
|
933
|
-
* @param {
|
|
934
|
-
* @param {string} params.
|
|
896
|
+
* @param {Array} params.assets - which assets to stake
|
|
897
|
+
* @param {Array} params.tokens - which tokens to stake
|
|
898
|
+
* @param {string} params.from - stake address
|
|
935
899
|
* @param {WalletObject} params.wallet - the wallet to sign the transaction
|
|
936
900
|
* @param {object} extra - other param to underlying client implementation
|
|
937
901
|
* @returns {Promise} the `transactionHash` once resolved
|
|
938
902
|
*/
|
|
939
|
-
client.
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
903
|
+
client.revokeStake = async ({ assets = [], tokens = [], from = '', wallet }, extra) => {
|
|
904
|
+
let tmpTokens = [];
|
|
905
|
+
if (tokens.length > 0) {
|
|
906
|
+
const tokensMap = await client.getTokenStateMap(tokens.map(t => t.address));
|
|
907
|
+
tmpTokens = tokens.map(t => {
|
|
908
|
+
t.value = fromTokenToUnit(t.value, tokensMap.get(t.address).decimal).toString();
|
|
909
|
+
return t;
|
|
910
|
+
});
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
return client.sendRevokeStakeTx({
|
|
914
|
+
tx: {
|
|
915
|
+
itx: {
|
|
916
|
+
address: from,
|
|
917
|
+
outputs: [{
|
|
918
|
+
owner: wallet.address,
|
|
919
|
+
assets,
|
|
920
|
+
tokens: tmpTokens
|
|
921
|
+
}]
|
|
922
|
+
}
|
|
923
|
+
},
|
|
924
|
+
wallet
|
|
925
|
+
}, extra);
|
|
926
|
+
};
|
|
944
927
|
|
|
945
928
|
/**
|
|
946
|
-
*
|
|
929
|
+
* Claim revoked token or assets from stake
|
|
947
930
|
*
|
|
948
931
|
* @memberof GraphQLClient
|
|
949
932
|
* @function
|
|
950
|
-
* @name GraphQLClient#
|
|
933
|
+
* @name GraphQLClient#claimStake
|
|
951
934
|
* @param {object} params
|
|
952
|
-
* @param {string} params.
|
|
953
|
-
* @param {
|
|
935
|
+
* @param {string} params.from - stake address
|
|
936
|
+
* @param {Array} params.evidence - which revoke tx hash to use
|
|
954
937
|
* @param {WalletObject} params.wallet - the wallet to sign the transaction
|
|
955
938
|
* @param {object} extra - other param to underlying client implementation
|
|
956
939
|
* @returns {Promise} the `transactionHash` once resolved
|
|
957
940
|
*/
|
|
958
|
-
client.
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
941
|
+
client.claimStake = async ({ from, evidence, wallet }, extra) => {
|
|
942
|
+
if (!evidence) {
|
|
943
|
+
throw new Error('Can not claim stake without valid evidence tx hash');
|
|
944
|
+
}
|
|
945
|
+
if (!from) {
|
|
946
|
+
throw new Error('Can not claim stake without stake address');
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
return client.sendClaimStakeTx({
|
|
950
|
+
tx: {
|
|
951
|
+
itx: {
|
|
952
|
+
address: from,
|
|
953
|
+
evidence: { hash: evidence }
|
|
954
|
+
}
|
|
955
|
+
},
|
|
956
|
+
wallet
|
|
957
|
+
}, extra);
|
|
958
|
+
};
|
|
963
959
|
|
|
964
960
|
/**
|
|
965
|
-
*
|
|
961
|
+
* Create an rollup (sub-chain that lives in ocap)
|
|
966
962
|
*
|
|
967
963
|
* @memberof GraphQLClient
|
|
968
964
|
* @function
|
|
969
|
-
* @name GraphQLClient#
|
|
965
|
+
* @name GraphQLClient#createRollup
|
|
970
966
|
* @param {object} params
|
|
971
|
-
* @param {
|
|
972
|
-
* @param {
|
|
973
|
-
* @param {string} params.
|
|
974
|
-
* @param {string} params.
|
|
975
|
-
* @param {
|
|
976
|
-
* @param {
|
|
967
|
+
* @param {string} params.tokenAddress - ocap token address
|
|
968
|
+
* @param {string} params.contractAddress - rollup contract address
|
|
969
|
+
* @param {string} params.minStakeAmount
|
|
970
|
+
* @param {string} params.maxStakeAmount
|
|
971
|
+
* @param {number} params.minSignerCount
|
|
972
|
+
* @param {number} params.maxSignerCount
|
|
973
|
+
* @param {number} params.minBlockSize
|
|
974
|
+
* @param {number} params.maxBlockSize
|
|
975
|
+
* @param {number} params.minBlockInterval - in seconds
|
|
976
|
+
* @param {number} params.minBlockConfirmation
|
|
977
|
+
* @param {number} params.leaveWaitingPeriod
|
|
978
|
+
* @param {number} params.publishWaitingPeriod
|
|
979
|
+
* @param {number} params.publishSlashRate
|
|
980
|
+
* @param {Array} params.seedValidators - list of seed validators
|
|
981
|
+
* @param {object} params.data - data payload
|
|
982
|
+
* @param {WalletObject} params.wallet - the initial owner of the asset
|
|
977
983
|
* @param {object} extra - other param to underlying client implementation
|
|
978
|
-
* @returns {Promise} the `transactionHash` once resolved
|
|
984
|
+
* @returns {Promise} the `[transactionHash, rollupAddress]` once resolved
|
|
979
985
|
*/
|
|
980
|
-
client.
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
assets,
|
|
986
|
-
data: {
|
|
987
|
-
typeUrl: 'json',
|
|
988
|
-
value: memo || 'empty'
|
|
989
|
-
}
|
|
986
|
+
client.createRollup = async (props, extra) => {
|
|
987
|
+
const requiredProps = ['tokenAddress', 'contractAddress', 'seedValidators', 'minStakeAmount'];
|
|
988
|
+
for (const key of requiredProps) {
|
|
989
|
+
if (!props[key]) {
|
|
990
|
+
throw new Error(`Missing required property: ${key} when creating rollup`);
|
|
990
991
|
}
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
const { state } = await client.getTokenState({ address: props.tokenAddress });
|
|
995
|
+
if (!state) {
|
|
996
|
+
throw new Error(`Token ${props.tokenAddress} not found when creating rollup`);
|
|
997
|
+
}
|
|
998
|
+
if (!state.foreignToken) {
|
|
999
|
+
throw new Error(`Token ${props.tokenAddress} does not have foreignToken attached`);
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
const toBNStr = n => fromTokenToUnit(n, state.decimal).toString(10);
|
|
1003
|
+
const itx = Object.assign({
|
|
1004
|
+
maxStakeAmount: props.minStakeAmount,
|
|
1005
|
+
minSignerCount: 3,
|
|
1006
|
+
maxSignerCount: 5,
|
|
1007
|
+
minBlockSize: 1,
|
|
1008
|
+
maxBlockSize: 10,
|
|
1009
|
+
minBlockInterval: 1 * 60, // 1 minute
|
|
1010
|
+
minBlockConfirmation: 3,
|
|
1011
|
+
minDepositAmount: toBNStr(100),
|
|
1012
|
+
maxDepositAmount: toBNStr(1000000),
|
|
1013
|
+
minWithdrawAmount: toBNStr(100),
|
|
1014
|
+
maxWithdrawAmount: toBNStr(1000000),
|
|
1015
|
+
depositFeeRate: 100, // 1%
|
|
1016
|
+
withdrawFeeRate: 100, // 1%
|
|
1017
|
+
publisherFeeShare: 6000, // 60%
|
|
1018
|
+
proposerFeeShare: 3000, // 30%
|
|
1019
|
+
// validatorFeeShare: 1000, // 10%
|
|
1020
|
+
minDepositFee: toBNStr(1),
|
|
1021
|
+
maxDepositFee: toBNStr(10000),
|
|
1022
|
+
minWithdrawFee: toBNStr(1),
|
|
1023
|
+
maxWithdrawFee: toBNStr(10000),
|
|
1024
|
+
leaveWaitingPeriod: 60 * 60, // 1 hour
|
|
1025
|
+
publishWaitingPeriod: 60 * 60, // 1 hour
|
|
1026
|
+
publishSlashRate: 10 // 0.1%
|
|
1027
|
+
}, props);
|
|
1028
|
+
|
|
1029
|
+
const address = toRollupAddress(itx);
|
|
1030
|
+
itx.address = address;
|
|
1031
|
+
|
|
1032
|
+
const hash = await client.sendCreateRollupTx({ tx: { itx }, wallet: props.wallet }, extra);
|
|
1033
|
+
|
|
1034
|
+
return [hash, address];
|
|
1035
|
+
};
|
|
995
1036
|
|
|
996
1037
|
/**
|
|
997
1038
|
* Prepare an exchange transaction between multiple accounts
|
|
@@ -1016,31 +1057,49 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
1016
1057
|
offerAssets = [],
|
|
1017
1058
|
demandToken = 0,
|
|
1018
1059
|
demandAssets = [],
|
|
1060
|
+
offerTokens = [],
|
|
1061
|
+
demandTokens = [],
|
|
1019
1062
|
receiver = '',
|
|
1020
1063
|
memo = '',
|
|
1021
1064
|
delegator = '',
|
|
1022
1065
|
wallet
|
|
1023
|
-
}, extra) =>
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1066
|
+
}, extra) => {
|
|
1067
|
+
const { token } = await client.getContext();
|
|
1068
|
+
const tokensMap = await client.getTokenStateMap([...offerTokens, ...demandTokens].map(t => t.address));
|
|
1069
|
+
|
|
1070
|
+
const tmpOfferTokens = offerTokens.map(t => {
|
|
1071
|
+
t.value = fromTokenToUnit(t.value, tokensMap.get(t.address).decimal).toString();
|
|
1072
|
+
return t;
|
|
1073
|
+
});
|
|
1074
|
+
const tmpDemandTokens = demandTokens.map(t => {
|
|
1075
|
+
t.value = fromTokenToUnit(t.value, tokensMap.get(t.address).decimal).toString();
|
|
1076
|
+
return t;
|
|
1077
|
+
});
|
|
1078
|
+
|
|
1079
|
+
return client.signExchangeV2Tx({
|
|
1080
|
+
tx: {
|
|
1081
|
+
itx: {
|
|
1082
|
+
to: receiver,
|
|
1083
|
+
sender: {
|
|
1084
|
+
value: fromTokenToUnit(offerToken, token.decimal),
|
|
1085
|
+
assets: Array.isArray(offerAssets) ? offerAssets : [],
|
|
1086
|
+
tokens: tmpOfferTokens
|
|
1087
|
+
},
|
|
1088
|
+
receiver: {
|
|
1089
|
+
value: fromTokenToUnit(demandToken, token.decimal),
|
|
1090
|
+
assets: Array.isArray(demandAssets) ? demandAssets : [],
|
|
1091
|
+
tokens: tmpDemandTokens
|
|
1092
|
+
},
|
|
1093
|
+
data: {
|
|
1094
|
+
typeUrl: 'json',
|
|
1095
|
+
value: memo || 'empty'
|
|
1096
|
+
}
|
|
1038
1097
|
}
|
|
1039
|
-
}
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
}
|
|
1098
|
+
},
|
|
1099
|
+
delegator,
|
|
1100
|
+
wallet
|
|
1101
|
+
}, extra);
|
|
1102
|
+
};
|
|
1044
1103
|
|
|
1045
1104
|
/**
|
|
1046
1105
|
* Finalize an exchange transaction between multiple accounts
|
|
@@ -1056,12 +1115,7 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
1056
1115
|
* @param {object} extra - other param to underlying client implementation
|
|
1057
1116
|
* @returns {Promise} the `transaction` object once resolved
|
|
1058
1117
|
*/
|
|
1059
|
-
client.finalizeExchange = ({ tx, delegator = '', data, wallet }, extra) => client.
|
|
1060
|
-
tx,
|
|
1061
|
-
delegator,
|
|
1062
|
-
data,
|
|
1063
|
-
wallet
|
|
1064
|
-
}, extra);
|
|
1118
|
+
client.finalizeExchange = ({ tx, delegator = '', data, wallet }, extra) => client.multiSignExchangeV2Tx({ tx, delegator, data, wallet }, extra);
|
|
1065
1119
|
|
|
1066
1120
|
/**
|
|
1067
1121
|
* Send an exchange transaction
|
|
@@ -1075,65 +1129,51 @@ const createExtensionMethods = (client, { encodeTxAsBase64 = false } = {}) => {
|
|
|
1075
1129
|
* @param {object} extra - other param to underlying client implementation
|
|
1076
1130
|
* @returns {Promise} the `transactionHash` once resolved
|
|
1077
1131
|
*/
|
|
1078
|
-
client.exchange = ({ tx, wallet }, extra) => client.
|
|
1132
|
+
client.exchange = ({ tx, wallet }, extra) => client.sendExchangeV2Tx({ tx, wallet }, extra);
|
|
1079
1133
|
|
|
1080
1134
|
/**
|
|
1081
|
-
*
|
|
1135
|
+
* Create an new token
|
|
1082
1136
|
*
|
|
1083
1137
|
* @memberof GraphQLClient
|
|
1084
1138
|
* @function
|
|
1085
|
-
* @name GraphQLClient#
|
|
1139
|
+
* @name GraphQLClient#createToken
|
|
1086
1140
|
* @param {object} params
|
|
1087
|
-
* @param {
|
|
1141
|
+
* @param {string} params.name
|
|
1142
|
+
* @param {string} params.description
|
|
1143
|
+
* @param {string} params.symbol
|
|
1144
|
+
* @param {string} params.unit
|
|
1145
|
+
* @param {string} params.icon
|
|
1146
|
+
* @param {number} params.totalSupply
|
|
1147
|
+
* @param {number} params.initialSupply
|
|
1148
|
+
* @param {number} params.foreignToken
|
|
1149
|
+
* @param {object} params.data - asset data payload
|
|
1150
|
+
* @param {WalletObject} params.wallet - the initial owner of the asset
|
|
1088
1151
|
* @param {object} extra - other param to underlying client implementation
|
|
1089
|
-
* @returns {Promise} the `transactionHash` once resolved
|
|
1152
|
+
* @returns {Promise} the `[transactionHash, assetAddress]` once resolved
|
|
1090
1153
|
*/
|
|
1091
|
-
client.
|
|
1092
|
-
const
|
|
1093
|
-
const year = date.getUTCFullYear();
|
|
1094
|
-
const month = date.getUTCMonth() + 1;
|
|
1095
|
-
const day = date.getUTCDate();
|
|
1096
|
-
|
|
1097
|
-
return client.sendPokeTx({
|
|
1098
|
-
tx: {
|
|
1099
|
-
nonce: 0,
|
|
1100
|
-
itx: {
|
|
1101
|
-
date: `${year}-${padStart(month, 2, '0')}-${padStart(day, 2, '0')}`,
|
|
1102
|
-
address: 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'
|
|
1103
|
-
}
|
|
1104
|
-
},
|
|
1105
|
-
wallet
|
|
1106
|
-
}, extra);
|
|
1107
|
-
};
|
|
1154
|
+
client.createToken = async ({ name, description, symbol, unit, decimal, icon, totalSupply, initialSupply, foreignToken, data, wallet }, extra) => {
|
|
1155
|
+
const tokenDecimal = typeof decimal === 'undefined' ? DEFAULT_TOKEN_DECIMAL : decimal;
|
|
1108
1156
|
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
client.refuel = ({ wallet, data }, extra) => {
|
|
1122
|
-
const date = new Date();
|
|
1123
|
-
const year = date.getUTCFullYear();
|
|
1124
|
-
const month = date.getUTCMonth() + 1;
|
|
1125
|
-
const day = date.getUTCDate();
|
|
1157
|
+
const payload = {
|
|
1158
|
+
name,
|
|
1159
|
+
description,
|
|
1160
|
+
symbol,
|
|
1161
|
+
unit,
|
|
1162
|
+
decimal: tokenDecimal,
|
|
1163
|
+
icon,
|
|
1164
|
+
totalSupply: fromTokenToUnit(totalSupply, tokenDecimal).toString(),
|
|
1165
|
+
initialSupply: fromTokenToUnit(initialSupply || totalSupply, tokenDecimal).toString(),
|
|
1166
|
+
foreignToken: foreignToken || null,
|
|
1167
|
+
data
|
|
1168
|
+
};
|
|
1126
1169
|
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
date: `${year}-${padStart(month, 2, '0')}-${padStart(day, 2, '0')}`,
|
|
1132
|
-
data
|
|
1133
|
-
}
|
|
1134
|
-
},
|
|
1170
|
+
const address = toTokenAddress(payload);
|
|
1171
|
+
payload.address = address;
|
|
1172
|
+
const hash = await client.sendCreateTokenTx({
|
|
1173
|
+
tx: { itx: payload },
|
|
1135
1174
|
wallet
|
|
1136
1175
|
}, extra);
|
|
1176
|
+
return [hash, address];
|
|
1137
1177
|
};
|
|
1138
1178
|
};
|
|
1139
1179
|
|