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