@caict/bop-typescript-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +5 -0
  4. package/README.md +112 -0
  5. package/package.json +90 -0
  6. package/src/bop/bop-base/README.md +5 -0
  7. package/src/bop/bop-base/base.ts +366 -0
  8. package/src/bop/bop-base/index.ts +83 -0
  9. package/src/bop/bop-base/permit.ts +116 -0
  10. package/src/bop/bop-base/test/base.test.ts +867 -0
  11. package/src/bop/bop-base/test/index.test.ts +69 -0
  12. package/src/bop/bop-base/test/permit.test.ts +125 -0
  13. package/src/bop/bop-base/tsconfig.json +8 -0
  14. package/src/bop/bop-proto/README.md +2 -0
  15. package/src/bop/bop-proto/bop-ws.proto +266 -0
  16. package/src/bop/bop-proto/bop-ws.ts +4447 -0
  17. package/src/bop/bop-proto/bop.proto +898 -0
  18. package/src/bop/bop-proto/bop.ts +12890 -0
  19. package/src/bop/bop-proto/tsconfig.json +8 -0
  20. package/src/bop/bop-ws/index.ts +315 -0
  21. package/src/bop/bop-ws/sample/sample.ts +107 -0
  22. package/src/bop/bop-ws/tsconfig.json +8 -0
  23. package/src/bop/index.ts +14 -0
  24. package/src/bop-sdk/index.ts +22 -0
  25. package/src/bop-sdk/interface/abstract-service/abstract-account.ts +23 -0
  26. package/src/bop-sdk/interface/abstract-service/abstract-chain.ts +9 -0
  27. package/src/bop-sdk/interface/abstract-service/abstract-contract.ts +16 -0
  28. package/src/bop-sdk/interface/abstract-service/abstract-ledger.ts +15 -0
  29. package/src/bop-sdk/interface/abstract-service/abstract-provider.ts +13 -0
  30. package/src/bop-sdk/interface/abstract-service/abstract-signer.ts +133 -0
  31. package/src/bop-sdk/interface/abstract-service/abstract-transaction.ts +86 -0
  32. package/src/bop-sdk/interface/provider-ws.ts +10 -0
  33. package/src/bop-sdk/interface/provider.ts +22 -0
  34. package/src/bop-sdk/interface/service/3rd.ts +54 -0
  35. package/src/bop-sdk/interface/service/account.ts +86 -0
  36. package/src/bop-sdk/interface/service/chain.ts +27 -0
  37. package/src/bop-sdk/interface/service/contract.ts +51 -0
  38. package/src/bop-sdk/interface/service/helper.ts +426 -0
  39. package/src/bop-sdk/interface/service/ledger.ts +75 -0
  40. package/src/bop-sdk/interface/service/offline/check/index.js +138 -0
  41. package/src/bop-sdk/interface/service/offline/common/constant.js +6 -0
  42. package/src/bop-sdk/interface/service/offline/common/snowFlakeUtils.js +192 -0
  43. package/src/bop-sdk/interface/service/offline/common/util.js +511 -0
  44. package/src/bop-sdk/interface/service/offline/exception/customErrors.js +29 -0
  45. package/src/bop-sdk/interface/service/offline/exception/errors.js +90 -0
  46. package/src/bop-sdk/interface/service/offline/exception/index.js +5 -0
  47. package/src/bop-sdk/interface/service/offline/operation/accountCreateOperation.js +28 -0
  48. package/src/bop-sdk/interface/service/offline/operation/accountSetMetadataOperation.js +44 -0
  49. package/src/bop-sdk/interface/service/offline/operation/accountSetPrivilegeOperation.js +49 -0
  50. package/src/bop-sdk/interface/service/offline/operation/contractCreateOperation.js +43 -0
  51. package/src/bop-sdk/interface/service/offline/operation/contractInvokeOperation.js +42 -0
  52. package/src/bop-sdk/interface/service/offline/operation/contractInvokeRequestOperation.js +69 -0
  53. package/src/bop-sdk/interface/service/offline/operation/gasSendOperation.js +29 -0
  54. package/src/bop-sdk/interface/service/offline/operation/gasSendRequestOperation.js +61 -0
  55. package/src/bop-sdk/interface/service/offline/operation/index.js +20 -0
  56. package/src/bop-sdk/interface/service/offline/proto/chain_pb.js +12079 -0
  57. package/src/bop-sdk/interface/service/offline/proto/common_pb.js +2867 -0
  58. package/src/bop-sdk/interface/service/offline/transaction/index.js +988 -0
  59. package/src/bop-sdk/interface/service/offline/transaction/operations.js +188 -0
  60. package/src/bop-sdk/interface/service/offline/validate/account.js +152 -0
  61. package/src/bop-sdk/interface/service/offline/validate/contract.js +101 -0
  62. package/src/bop-sdk/interface/service/offline/validate/index.js +10 -0
  63. package/src/bop-sdk/interface/service/offline/validate/transaction.js +51 -0
  64. package/src/bop-sdk/interface/service/transaction.ts +731 -0
  65. package/src/bop-sdk/interface/signer.ts +46 -0
  66. package/src/bop-sdk/interface/test/3rd.test.ts +1571 -0
  67. package/src/bop-sdk/interface/test/account.test.ts +284 -0
  68. package/src/bop-sdk/interface/test/chain.test.ts +45 -0
  69. package/src/bop-sdk/interface/test/contract.test.ts +283 -0
  70. package/src/bop-sdk/interface/test/ledger.test.ts +166 -0
  71. package/src/bop-sdk/interface/test/provider.test.ts +407 -0
  72. package/src/bop-sdk/interface/test/signer.test.ts +105 -0
  73. package/src/bop-sdk/interface/test/transaction.test.ts +713 -0
  74. package/src/bop-sdk/proto/bop-sdk-common.proto +159 -0
  75. package/src/bop-sdk/proto/bop-sdk-common.ts +829 -0
  76. package/src/bop-sdk/proto/bop-sdk-interface.proto +581 -0
  77. package/src/bop-sdk/proto/bop-sdk-interface.ts +10839 -0
  78. package/src/bop-sdk/proto/bop-sdk-utils.proto +86 -0
  79. package/src/bop-sdk/proto/bop-sdk-utils.ts +1495 -0
  80. package/src/bop-sdk/utils/abi/abi-coder.ts +147 -0
  81. package/src/bop-sdk/utils/abi/address.ts +109 -0
  82. package/src/bop-sdk/utils/abi/bignumber.ts +403 -0
  83. package/src/bop-sdk/utils/abi/bytes.ts +565 -0
  84. package/src/bop-sdk/utils/abi/coders/abstract-coder.ts +239 -0
  85. package/src/bop-sdk/utils/abi/coders/address.ts +58 -0
  86. package/src/bop-sdk/utils/abi/coders/anonymous.ts +25 -0
  87. package/src/bop-sdk/utils/abi/coders/array.ts +275 -0
  88. package/src/bop-sdk/utils/abi/coders/boolean.ts +21 -0
  89. package/src/bop-sdk/utils/abi/coders/bytes.ts +36 -0
  90. package/src/bop-sdk/utils/abi/coders/fixed-bytes.ts +35 -0
  91. package/src/bop-sdk/utils/abi/coders/null.ts +25 -0
  92. package/src/bop-sdk/utils/abi/coders/number.ts +56 -0
  93. package/src/bop-sdk/utils/abi/coders/string.ts +24 -0
  94. package/src/bop-sdk/utils/abi/coders/tuple.ts +73 -0
  95. package/src/bop-sdk/utils/abi/constants/addresses.ts +1 -0
  96. package/src/bop-sdk/utils/abi/constants/bignumbers.ts +30 -0
  97. package/src/bop-sdk/utils/abi/constants/hashes.ts +2 -0
  98. package/src/bop-sdk/utils/abi/constants/index.ts +15 -0
  99. package/src/bop-sdk/utils/abi/constants/strings.ts +2 -0
  100. package/src/bop-sdk/utils/abi/fragments.ts +1243 -0
  101. package/src/bop-sdk/utils/abi/id.ts +6 -0
  102. package/src/bop-sdk/utils/abi/index.ts +46 -0
  103. package/src/bop-sdk/utils/abi/interface.ts +921 -0
  104. package/src/bop-sdk/utils/abi/keccak256.ts +9 -0
  105. package/src/bop-sdk/utils/abi/properties.ts +172 -0
  106. package/src/bop-sdk/utils/abi/strings/bytes32.ts +40 -0
  107. package/src/bop-sdk/utils/abi/strings/idna.ts +258 -0
  108. package/src/bop-sdk/utils/abi/strings/index.ts +28 -0
  109. package/src/bop-sdk/utils/abi/strings/utf8.ts +373 -0
  110. package/src/bop-sdk/utils/encryption-address.ts +501 -0
  111. package/src/bop-sdk/utils/encryption-crypto.ts +427 -0
  112. package/src/bop-sdk/utils/encryption-mnemonics.ts +120 -0
  113. package/src/bop-sdk/utils/index.ts +27 -0
  114. package/src/bop-sdk/utils/logger.ts +480 -0
  115. package/src/index.ts +35 -0
@@ -0,0 +1,988 @@
1
+ const long = require("long");
2
+ const chain_pb = require("../proto/chain_pb");
3
+ const operations = require("./operations");
4
+ const Operation = require("../validate");
5
+ const crypto = require("crypto");
6
+ const BigNumber = require("bignumber.js");
7
+ const errors = require("../exception");
8
+ const util = require("../common/util");
9
+ const keyPair = require("@caict/bif-encryption");
10
+ const Snowflake = require("../common/snowFlakeUtils");
11
+ const check = require("../check/index");
12
+
13
+ const Operaction = require("../operation");
14
+ const OperactionType = new Operaction();
15
+ const GasSendRequestOperation = require("../operation/gasSendRequestOperation");
16
+ const signer = require("../../../abstract-service/abstract-signer");
17
+ const {
18
+ SubmitTransactionParams,
19
+ } = require("../../../../proto/bop-sdk-interface");
20
+ class Transaction {
21
+ constructor() {
22
+ this.operations = [];
23
+ this.blob = "";
24
+ this.hash = "";
25
+ }
26
+
27
+ getBlob() {
28
+ return this.blob;
29
+ }
30
+
31
+ getHash() {
32
+ return this.hash;
33
+ }
34
+
35
+ /**
36
+ * Add operation
37
+ *
38
+ * @param {String} type
39
+ * @param {Object} options
40
+ */
41
+ addOperation(type, params = {}) {
42
+ for (let i = 0; i < params.length; i++) {
43
+ const args = params[i];
44
+ switch (type) {
45
+ case "payCoin":
46
+ this.operations.push(operations.payCoin(args));
47
+ break;
48
+ case "setMetadata":
49
+ this.operations.push(operations.setMetadata(args));
50
+ break;
51
+ case "activateAccount":
52
+ this.operations.push(operations.activateAccount(args));
53
+ break;
54
+ case "setPrivilegeOperation":
55
+ this.operations.push(operations.accountSetPrivilegeOperation(args));
56
+ break;
57
+ case "createContract":
58
+ this.operations.push(operations.createContract(args));
59
+ break;
60
+ default:
61
+ throw new Error("unknown operation");
62
+ }
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Build transaction
68
+ *
69
+ * @param {Object} args
70
+ * @param {String} args.sourceAddress
71
+ * @param {String} args.nonce
72
+ * @param {String} [args.feeLimit]
73
+ * @param {String} [args.gasPrice]
74
+ * @param {String} [args.seq]
75
+ * @param {String} [args.metadata]
76
+ * @returns {string}
77
+ */
78
+ buildTransaction(args = {}) {
79
+ if (this.operations.length === 0) {
80
+ throw new Error("must add operation first");
81
+ }
82
+ const {
83
+ sourceAddress,
84
+ nonce,
85
+ feeLimit,
86
+ gasPrice,
87
+ seqOffset,
88
+ metadata,
89
+ nonceType,
90
+ maxLedgerSeq,
91
+ } = args;
92
+ const tx = new chain_pb.Transaction();
93
+ tx.setSourceAddress(sourceAddress);
94
+ if (nonce !== 0 && nonce !== "0") {
95
+ tx.setNonce(long.fromValue(nonce));
96
+ }
97
+ if (feeLimit !== 0 && feeLimit !== "0") {
98
+ tx.setFeeLimit(long.fromValue(feeLimit));
99
+ }
100
+ if (gasPrice !== 0 && gasPrice !== "0") {
101
+ tx.setGasPrice(long.fromValue(gasPrice));
102
+ }
103
+ if (seqOffset) {
104
+ tx.setCeilLedgerSeq(long.fromValue(seqOffset));
105
+ }
106
+ if (metadata) {
107
+ tx.setMetadata(Uint8Array.from(Buffer.from(metadata, "utf8")));
108
+ }
109
+ if (nonceType && nonceType != "0") {
110
+ tx.setNonceType(nonceType);
111
+ }
112
+ if (maxLedgerSeq) {
113
+ tx.setMaxLedgerSeq(Number(maxLedgerSeq));
114
+ }
115
+ tx.setOperationsList(this.operations);
116
+
117
+ const blob = Buffer.from(tx.serializeBinary()).toString("hex");
118
+
119
+ const buffer = Buffer.from(blob, "hex");
120
+ const hash = crypto.createHash("sha256");
121
+ hash.update(buffer);
122
+
123
+ this.blob = blob;
124
+ this.hash = hash.digest("hex");
125
+ }
126
+
127
+ async buildOperation(type, option = {}) {
128
+ let param = option;
129
+ for (let i = 0; i < param.length; i++) {
130
+ let option = param[i];
131
+ let operation, item;
132
+ switch (type) {
133
+ case "ACCOUNT_ACTIVATE": {
134
+ operation = OperactionType.accountCreateOperation;
135
+ operation = option;
136
+ item = {
137
+ create_account: {
138
+ dest_address: operation.getDestAddress(),
139
+ init_balance: operation.getInitBalance(),
140
+ priv: {
141
+ master_weight: 1,
142
+ thresholds: {
143
+ tx_threshold: 1,
144
+ },
145
+ },
146
+ },
147
+ type: operation.getActionType(),
148
+ };
149
+ break;
150
+ }
151
+ case "ACCOUNT_SET_METADATA": {
152
+ operation = OperactionType.accountSetMetadataOperation;
153
+ operation = option;
154
+ item = {
155
+ set_metadata: {
156
+ key: operation.getKey(),
157
+ value: operation.getValue(),
158
+ version: operation.getVersion(),
159
+ },
160
+ type: operation.getActionType(),
161
+ };
162
+ break;
163
+ }
164
+ case "ACCOUNT_SET_PRIVILEGE": {
165
+ operation = OperactionType.accountSetPrivilegeOperation;
166
+ operation = option;
167
+ item = {
168
+ set_privilege: {
169
+ master_weight: operation.getMasterWeight(),
170
+ signers: operation.getSigners(),
171
+ tx_threshold: operation.getTxThreshold(),
172
+ type_thresholds: operation.getTypeThresholds(),
173
+ },
174
+ type: operation.getActionType(),
175
+ };
176
+ break;
177
+ }
178
+ case "GAS_SEND": {
179
+ operation = OperactionType.gasSendOperation;
180
+ operation = option;
181
+ item = {
182
+ pay_coin: {
183
+ dest_address: operation.getDestAddress(),
184
+ amount: operation.getAmount(),
185
+ },
186
+ type: operation.getActionType(),
187
+ };
188
+ break;
189
+ }
190
+ case "CONTRACT_CREATE": {
191
+ operation = OperactionType.contractCreateOperation;
192
+ operation = option;
193
+ item = {
194
+ create_account: {
195
+ contract: {
196
+ payload: operation.getPayload(),
197
+ },
198
+ init_balance: operation.getInitBalance(),
199
+ init_input: operation.getInitInput(),
200
+ priv: {
201
+ master_weight: 0,
202
+ thresholds: {
203
+ tx_threshold: 1,
204
+ },
205
+ },
206
+ },
207
+ type: operation.getActionType(),
208
+ };
209
+ break;
210
+ }
211
+ case "CONTRACT_INVOKE": {
212
+ operation = OperactionType.contractInvokeOperation;
213
+ operation = option;
214
+ item = {
215
+ pay_coin: {
216
+ dest_address: operation.getContractAddress(),
217
+ amount: operation.getAmount(),
218
+ input: operation.getInput(),
219
+ },
220
+ type: operation.getActionType(),
221
+ };
222
+ break;
223
+ }
224
+ default: {
225
+ throw new Error("unknown operation");
226
+ }
227
+ }
228
+ return item;
229
+ }
230
+ }
231
+
232
+ /**
233
+ * gasSend
234
+ * @param request
235
+ * @returns {Promise<{header: *}|{errorDesc: *, errorCode: *}>}
236
+ */
237
+ async gasSend(object = {}, signer) {
238
+ // 校验参数
239
+ let request = check.validateObject(object);
240
+ if (request.errorCode) {
241
+ return request;
242
+ }
243
+ let {
244
+ sourceAddress,
245
+ destAddress,
246
+ remarks,
247
+ amount,
248
+ ceilLedgerSeq,
249
+ gasPrice,
250
+ feeLimit,
251
+ nonceType,
252
+ } = request;
253
+ // 必传校验
254
+ if (!keyPair.isAddress(sourceAddress) || !keyPair.isAddress(destAddress)) {
255
+ return util._responseError(errors.INVALID_ADDRESS_ERROR);
256
+ }
257
+
258
+ // 参数校验
259
+ let operation = new Operation();
260
+ let data = operation.SendOperation(request);
261
+ if (data.errorCode !== 0) {
262
+ return data;
263
+ }
264
+
265
+ let gasSend = {
266
+ to: destAddress,
267
+ amount: amount,
268
+ };
269
+ let operations = [gasSend];
270
+ this.addOperation("payCoin", operations);
271
+
272
+ let nonce;
273
+ let maxLedgerSeq;
274
+ let blockNumberFind;
275
+ if (nonceType == "1") {
276
+ let res = await signer.getLedgerNumber();
277
+ if (res.errorCode !== 0) {
278
+ return res;
279
+ }
280
+ maxLedgerSeq =
281
+ Number(res.result) + Number(Snowflake.getDefaultRangeRandom());
282
+ nonce = Snowflake.randomLenNum().toString();
283
+ } else {
284
+ let nonceResult = await signer.getIncreaseNonce();
285
+ if (nonceResult.errorCode !== 0) {
286
+ return nonceResult;
287
+ }
288
+ nonce = nonceResult.result;
289
+ nonce = new BigNumber(nonce).plus(1).toString(10);
290
+ }
291
+
292
+ // 获取blockNumber
293
+ if (ceilLedgerSeq != null && ceilLedgerSeq !== "") {
294
+ if (blockNumberFind) {
295
+ ceilLedgerSeq =
296
+ Number(ceilLedgerSeq) + Number(blockNumberFind.header.blockNumber);
297
+ } else {
298
+ let blockNumber = await signer.getLedgerNumber();
299
+ ceilLedgerSeq = Number(ceilLedgerSeq) + Number(blockNumber.result);
300
+ }
301
+ }
302
+ let tranactionParameter = {
303
+ sourceAddress: sourceAddress,
304
+ nonce: nonce,
305
+ feeLimit: feeLimit,
306
+ gasPrice: gasPrice,
307
+ metadata: remarks,
308
+ seqOffset: ceilLedgerSeq,
309
+ nonceType: nonceType,
310
+ maxLedgerSeq: maxLedgerSeq,
311
+ };
312
+ console.log(tranactionParameter);
313
+ this.buildTransaction(tranactionParameter);
314
+ let response = {
315
+ errorCode: 0,
316
+ errorDesc: "ok",
317
+ result: this.blob,
318
+ };
319
+
320
+ return util._response(response);
321
+ }
322
+
323
+ /**
324
+ * batchGasSend
325
+ * @param request
326
+ * @returns {Promise<{header: *}|{errorDesc: *, errorCode: *}>}
327
+ */
328
+ async batchGasSend(object = {}, signer) {
329
+ // 校验参数
330
+ let request = check.validateObject(object);
331
+ if (request.errorCode) {
332
+ return request;
333
+ }
334
+ let {
335
+ senderAddress,
336
+ feeLimit,
337
+ gasPrice,
338
+ remarks,
339
+ ceilLedgerSeq,
340
+ operations,
341
+ nonceType,
342
+ } = request;
343
+ // 必传校验
344
+ if (!keyPair.isAddress(senderAddress)) {
345
+ return util._responseError(errors.INVALID_ADDRESS_ERROR);
346
+ }
347
+ // 参数校验
348
+ let operation = new Operation();
349
+ let data = operation.GasSendRequestOperation(request);
350
+ if (data.errorCode !== 0) {
351
+ return data;
352
+ }
353
+
354
+ // 参数验证及合约账号校验
355
+ let operationsArr = [];
356
+ let map = new Map();
357
+ for (let key in operations) {
358
+ let { destAddress } = operations[key];
359
+ if (!map.has(destAddress)) {
360
+ if (!keyPair.isAddress(destAddress)) {
361
+ return util._responseError(errors.INVALID_ADDRESS_ERROR);
362
+ }
363
+ map.set(destAddress, 1);
364
+ }
365
+ let { amount } = operations[key];
366
+ if (amount == null || amount === "" || !util._isAvailableValue(amount)) {
367
+ return util._responseError(errors.INVALID_AMOUNT_ERROR);
368
+ }
369
+ let gasSendParam = {
370
+ to: destAddress,
371
+ amount: amount,
372
+ };
373
+ operationsArr.push(gasSendParam);
374
+ }
375
+
376
+ this.addOperation("payCoin", operationsArr);
377
+
378
+ // 随机nonce
379
+ let nonce;
380
+ let maxLedgerSeq;
381
+ if (nonceType == "1") {
382
+ let res = await signer.getLedgerNumber();
383
+ if (res.errorCode !== 0) {
384
+ return res;
385
+ }
386
+ maxLedgerSeq =
387
+ Number(res.result) + Number(Snowflake.getDefaultRangeRandom());
388
+ nonce = Snowflake.randomLenNum().toString();
389
+ } else {
390
+ let nonceResult = await signer.getIncreaseNonce();
391
+ if (nonceResult.errorCode !== 0) {
392
+ return nonceResult;
393
+ }
394
+ nonce = nonceResult.result;
395
+ nonce = new BigNumber(nonce).plus(1).toString(10);
396
+ }
397
+
398
+ // 获取blockNumber
399
+ if (ceilLedgerSeq != null && ceilLedgerSeq !== "") {
400
+ let blockNumber = await signer.getLedgerNumber();
401
+ ceilLedgerSeq = Number(ceilLedgerSeq) + Number(blockNumber.result);
402
+ }
403
+ let tranactionParameter = {
404
+ sourceAddress: senderAddress,
405
+ nonce: nonce,
406
+ feeLimit: feeLimit,
407
+ gasPrice: gasPrice,
408
+ metadata: remarks,
409
+ seqOffset: ceilLedgerSeq,
410
+ };
411
+ this.buildTransaction(tranactionParameter);
412
+
413
+ let response = {
414
+ errorCode: 0,
415
+ errorDesc: "ok",
416
+ result: this.blob,
417
+ };
418
+
419
+ return util._response(response);
420
+ }
421
+
422
+ async createContract(object = {}, signer) {
423
+ // 校验参数
424
+ let request = check.validateObject(object);
425
+ if (request.errorCode) {
426
+ return request;
427
+ }
428
+ let {
429
+ sourceAddress,
430
+ payload,
431
+ initBalance,
432
+ remarks,
433
+ type,
434
+ feeLimit,
435
+ gasPrice,
436
+ ceilLedgerSeq,
437
+ initInput,
438
+ nonceType,
439
+ } = request;
440
+ // 必传校验
441
+ if (!keyPair.isAddress(sourceAddress)) {
442
+ return util._responseError(errors.INVALID_ADDRESS_ERROR);
443
+ }
444
+
445
+ // 参数校验
446
+ let operation = new Operation();
447
+ let data = operation.contractCreateOperation(request);
448
+ if (data.errorCode !== 0) {
449
+ return data;
450
+ }
451
+
452
+ let createContractOperation = {
453
+ initBalance: initBalance,
454
+ payload: payload,
455
+ initInput: initInput,
456
+ type: type,
457
+ };
458
+ let operations = [createContractOperation];
459
+ this.addOperation("createContract", operations);
460
+ // 随机nonce
461
+ let nonce;
462
+ let maxLedgerSeq;
463
+ if (nonceType == "1") {
464
+ let res = await signer.getLedgerNumber();
465
+ if (res.errorCode !== 0) {
466
+ return res;
467
+ }
468
+ maxLedgerSeq =
469
+ Number(res.result) + Number(Snowflake.getDefaultRangeRandom());
470
+ nonce = Snowflake.randomLenNum().toString();
471
+ } else {
472
+ let nonceResult = await signer.getIncreaseNonce();
473
+ if (nonceResult.errorCode !== 0) {
474
+ return nonceResult;
475
+ }
476
+ nonce = nonceResult.result;
477
+ nonce = new BigNumber(nonce).plus(1).toString(10);
478
+ }
479
+
480
+ // 获取blockNumber
481
+ if (ceilLedgerSeq != null && ceilLedgerSeq !== "") {
482
+ let blockNumber = await signer.getLedgerNumber();
483
+ ceilLedgerSeq = Number(ceilLedgerSeq) + Number(blockNumber.result);
484
+ }
485
+ let tranactionParameter = {
486
+ sourceAddress: sourceAddress,
487
+ nonce: nonce,
488
+ feeLimit: feeLimit,
489
+ gasPrice: gasPrice,
490
+ seqOffset: ceilLedgerSeq,
491
+ metadata: remarks,
492
+ nonceType: nonceType,
493
+ maxLedgerSeq: maxLedgerSeq,
494
+ };
495
+ this.buildTransaction(tranactionParameter);
496
+
497
+ let response = {
498
+ errorCode: 0,
499
+ errorDesc: "ok",
500
+ result: this.blob,
501
+ };
502
+
503
+ return util._response(response);
504
+ }
505
+
506
+ /**
507
+ * contract Invoke
508
+ * @param request
509
+ * @returns {Promise<{header: *}|{errorDesc: *, errorCode: *}>}
510
+ */
511
+ async contractInvoke(object = {}, signer) {
512
+ // 校验参数
513
+ let request = check.validateObject(object);
514
+ if (request.errorCode) {
515
+ return request;
516
+ }
517
+ let {
518
+ sourceAddress,
519
+ feeLimit,
520
+ gasPrice,
521
+ contractAddress,
522
+ remarks,
523
+ amount,
524
+ ceilLedgerSeq,
525
+ input,
526
+ nonceType,
527
+ } = request;
528
+ // 必传校验
529
+ if (!keyPair.isAddress(contractAddress)) {
530
+ return util._responseError(errors.INVALID_CONTRACTADDRESS_ERROR);
531
+ }
532
+ if (!keyPair.isAddress(sourceAddress)) {
533
+ return util._responseError(errors.INVALID_ADDRESS_ERROR);
534
+ }
535
+ // 参数校验
536
+ let operation = new Operation();
537
+ let data = operation.contractInvokeOperation(request);
538
+ if (data.errorCode !== 0) {
539
+ return data;
540
+ }
541
+
542
+ // 调用合约账户接口判断是否为合约账户
543
+ let contractAccount = await signer.getAccount(contractAddress);
544
+ if (contractAccount.errorCode != 0) {
545
+ return util._responseError(errors.INVALID_CONTRACTADDRESS_ERROR);
546
+ }
547
+ console.log(contractAccount);
548
+ if (contractAccount.result.contract.payload === undefined) {
549
+ return util._responseError(
550
+ errors.CONTRACTADDRESS_NOT_CONTRACTACCOUNT_ERROR,
551
+ );
552
+ }
553
+ let contractInvoke = {
554
+ to: contractAddress,
555
+ amount: amount,
556
+ input: input,
557
+ };
558
+ let operations = [contractInvoke];
559
+ this.addOperation("payCoin", operations);
560
+ // 随机nonce
561
+ let nonce;
562
+ let maxLedgerSeq;
563
+ if (nonceType == "1") {
564
+ let res = await signer.getLedgerNumber();
565
+ if (res.errorCode !== 0) {
566
+ return res;
567
+ }
568
+ maxLedgerSeq =
569
+ Number(res.result) + Number(Snowflake.getDefaultRangeRandom());
570
+ nonce = Snowflake.randomLenNum().toString();
571
+ } else {
572
+ let nonceResult = await signer.getIncreaseNonce(sourceAddress);
573
+ if (nonceResult.errorCode !== 0) {
574
+ return nonceResult;
575
+ }
576
+ nonce = nonceResult.result;
577
+ nonce = new BigNumber(nonce).plus(1).toString(10);
578
+ }
579
+
580
+ // 获取blockNumber
581
+ if (ceilLedgerSeq != null && ceilLedgerSeq !== "") {
582
+ let blockNumber = await signer.getLedgerNumber();
583
+ ceilLedgerSeq = Number(ceilLedgerSeq) + Number(blockNumber.result);
584
+ }
585
+ let tranactionParameter = {
586
+ sourceAddress: sourceAddress,
587
+ nonce: nonce,
588
+ feeLimit: feeLimit,
589
+ gasPrice: gasPrice,
590
+ metadata: remarks,
591
+ seqOffset: ceilLedgerSeq,
592
+ nonceType: nonceType,
593
+ maxLedgerSeq: maxLedgerSeq,
594
+ };
595
+ this.buildTransaction(tranactionParameter);
596
+
597
+ let response = {
598
+ errorCode: 0,
599
+ errorDesc: "ok",
600
+ result: this.blob,
601
+ };
602
+
603
+ return util._response(response);
604
+ }
605
+
606
+ /**
607
+ * contract Invoke
608
+ * @param request
609
+ * @returns {Promise<{header: *}|{errorDesc: *, errorCode: *}>}
610
+ */
611
+ async batchContractInvoke(object = {}, signer) {
612
+ // 校验参数
613
+ let request = check.validateObject(object);
614
+ if (request.errorCode) {
615
+ return request;
616
+ }
617
+ let {
618
+ senderAddress,
619
+ feeLimit,
620
+ gasPrice,
621
+ remarks,
622
+ ceilLedgerSeq,
623
+ operations,
624
+ nonceType,
625
+ } = request;
626
+ // 必传校验
627
+ if (!keyPair.isAddress(senderAddress)) {
628
+ return util._responseError(errors.INVALID_ADDRESS_ERROR);
629
+ }
630
+ // 参数校验
631
+ let operation = new Operation();
632
+ let data = operation.contractInvokeRequestOperation(request);
633
+ if (data.errorCode !== 0) {
634
+ return data;
635
+ }
636
+
637
+ // 参数验证及合约账号校验
638
+ let operationsArr = [];
639
+ let map = new Map();
640
+ for (let key in operations) {
641
+ let { contractAddress } = operations[key];
642
+ if (map.has(contractAddress)) {
643
+ map.set(contractAddress, operations[key]);
644
+ } else {
645
+ let tmpList = [];
646
+ tmpList.push(operations[key]);
647
+ if (!keyPair.isAddress(contractAddress)) {
648
+ return util._responseError(errors.INVALID_ADDRESS_ERROR);
649
+ }
650
+ // 调用合约账户接口判断是否为合约账户
651
+ let contractAccount = await signer.getAccount(contractAddress);
652
+ if (contractAccount.errorCode != 0) {
653
+ return util._responseError(errors.INVALID_CONTRACTADDRESS_ERROR);
654
+ }
655
+ if (contractAccount.result.contract.payload === undefined) {
656
+ return util._responseError(
657
+ errors.CONTRACTADDRESS_NOT_CONTRACTACCOUNT_ERROR,
658
+ );
659
+ }
660
+ map.set(contractAddress, tmpList);
661
+ }
662
+ let { amount } = operations[key];
663
+ if (amount == null || amount === "" || !util._isAvailableValue(amount)) {
664
+ return util._responseError(errors.INVALID_AMOUNT_ERROR);
665
+ }
666
+ let contractInvokeParam = {
667
+ to: contractAddress,
668
+ amount: amount,
669
+ input: operations[key].input,
670
+ };
671
+ operationsArr.push(contractInvokeParam);
672
+ }
673
+ this.addOperation("payCoin", operationsArr);
674
+ // 随机nonce
675
+ let nonce;
676
+ let maxLedgerSeq;
677
+ if (nonceType == "1") {
678
+ let res = await signer.getLedgerNumber();
679
+ if (res.errorCode !== 0) {
680
+ return res;
681
+ }
682
+ maxLedgerSeq =
683
+ Number(res.result) + Number(Snowflake.getDefaultRangeRandom());
684
+ nonce = Snowflake.randomLenNum().toString();
685
+ } else {
686
+ let nonceResult = await signer.getIncreaseNonce();
687
+ if (nonceResult.errorCode !== 0) {
688
+ return nonceResult;
689
+ }
690
+ nonce = nonceResult.result;
691
+ nonce = new BigNumber(nonce).plus(1).toString(10);
692
+ }
693
+ // 获取blockNumber
694
+ if (ceilLedgerSeq != null && ceilLedgerSeq !== "") {
695
+ let blockNumber = await signer.getLedgerNumber();
696
+ ceilLedgerSeq = Number(ceilLedgerSeq) + Number(blockNumber.result);
697
+ }
698
+ let tranactionParameter = {
699
+ sourceAddress: senderAddress,
700
+ nonce: nonce,
701
+ feeLimit: feeLimit,
702
+ gasPrice: gasPrice,
703
+ metadata: remarks,
704
+ seqOffset: ceilLedgerSeq,
705
+ };
706
+ this.buildTransaction(tranactionParameter);
707
+
708
+ let response = {
709
+ errorCode: 0,
710
+ errorDesc: "ok",
711
+ result: this.blob,
712
+ };
713
+
714
+ return util._response(response);
715
+ }
716
+
717
+ /**
718
+ * create account
719
+ * @param request
720
+ * @returns {Promise<{errorDesc: *, errorCode: *}>}
721
+ */
722
+ async createAccount(object = {}, signer) {
723
+ // 校验参数
724
+ let request = check.validateObject(object);
725
+ if (request.errorCode) {
726
+ return request;
727
+ }
728
+ let {
729
+ sourceAddress,
730
+ ceilLedgerSeq,
731
+ remarks,
732
+ destAddress,
733
+ initBalance,
734
+ feeLimit,
735
+ gasPrice,
736
+ nonceType,
737
+ } = request;
738
+ // 必传校验
739
+ if (!keyPair.isAddress(sourceAddress) || !keyPair.isAddress(destAddress)) {
740
+ return util._responseError(errors.INVALID_ADDRESS_ERROR);
741
+ }
742
+
743
+ let operation = new Operation();
744
+ let data = operation.accountActivateOperation(request);
745
+ if (data.errorCode !== 0) {
746
+ return data;
747
+ }
748
+
749
+ let createAccOperation = {
750
+ to: destAddress,
751
+ initBalance: initBalance,
752
+ };
753
+ let operations = [createAccOperation];
754
+ this.addOperation("activateAccount", operations);
755
+ let nonce;
756
+ let maxLedgerSeq;
757
+ // 判断获取blockNumber是否需要接口获取 (目前版本不需要这块业务逻辑调整)
758
+ // 随机nonce
759
+ if (nonceType == "1") {
760
+ let res = await signer.getLedgerNumber();
761
+ if (res.errorCode !== 0) {
762
+ return res;
763
+ }
764
+ maxLedgerSeq =
765
+ Number(res.result) + Number(Snowflake.getDefaultRangeRandom());
766
+ nonce = Snowflake.randomLenNum().toString();
767
+ } else {
768
+ let nonceResult = await signer.getIncreaseNonce();
769
+ if (nonceResult.errorCode !== 0) {
770
+ return nonceResult;
771
+ }
772
+ nonce = nonceResult.result;
773
+ nonce = new BigNumber(nonce).plus(1).toString(10);
774
+ }
775
+ // 获取blockNumber
776
+ if (ceilLedgerSeq != null && ceilLedgerSeq !== "") {
777
+ let blockNumber = await signer.getLedgerNumber();
778
+ ceilLedgerSeq = Number(ceilLedgerSeq) + Number(blockNumber.result);
779
+ }
780
+ let tranactionParameter = {
781
+ sourceAddress: sourceAddress,
782
+ nonce: nonce,
783
+ feeLimit: feeLimit,
784
+ gasPrice: gasPrice,
785
+ seqOffset: ceilLedgerSeq,
786
+ metadata: remarks,
787
+ nonceType: nonceType,
788
+ maxLedgerSeq: maxLedgerSeq,
789
+ };
790
+ this.buildTransaction(tranactionParameter);
791
+ let response = {
792
+ errorCode: 0,
793
+ errorDesc: "ok",
794
+ result: this.blob,
795
+ };
796
+
797
+ return util._response(response);
798
+ }
799
+
800
+ /**
801
+ * set account metadatas
802
+ * @param request
803
+ * @returns {Promise<{errorDesc: *, errorCode: *}>}
804
+ */
805
+ async setMetadatas(object = {}, signer) {
806
+ // 校验参数
807
+ let request = check.validateObject(object);
808
+ if (request.errorCode) {
809
+ return request;
810
+ }
811
+ let {
812
+ sourceAddress,
813
+ remarks,
814
+ key,
815
+ value,
816
+ version,
817
+ deleteFlag,
818
+ feeLimit,
819
+ gasPrice,
820
+ ceilLedgerSeq,
821
+ nonceType,
822
+ } = request;
823
+ // 必传校验
824
+ if (!keyPair.isAddress(sourceAddress)) {
825
+ return util._responseError(errors.INVALID_ADDRESS_ERROR);
826
+ }
827
+
828
+ if (key.trim().length > 1024 || key.trim().length < 1) {
829
+ return util._responseError(errors.INVALID_DATAKEY_ERROR);
830
+ }
831
+
832
+ if (value.trim().length > 256000 || value.trim().length < 1) {
833
+ return util._responseError(errors.INVALID_DATAVALUE_ERROR);
834
+ }
835
+
836
+ // 参数校验
837
+ let operation = new Operation();
838
+ let data = operation.accountSetMetadataOperation(request);
839
+ if (data.errorCode !== 0) {
840
+ return data;
841
+ }
842
+
843
+ let setMetadatas = {
844
+ key: key,
845
+ value: value,
846
+ version: version,
847
+ deleteFlag: deleteFlag,
848
+ };
849
+ let operations = [setMetadatas];
850
+ this.addOperation("setMetadata", operations);
851
+ let nonce;
852
+ let maxLedgerSeq;
853
+ // 随机nonce
854
+ if (nonceType == "1") {
855
+ let res = await signer.getLedgerNumber();
856
+ if (res.errorCode !== 0) {
857
+ return res;
858
+ }
859
+ maxLedgerSeq =
860
+ Number(res.result) + Number(Snowflake.getDefaultRangeRandom());
861
+ nonce = Snowflake.randomLenNum().toString();
862
+ } else {
863
+ let nonceResult = await signer.getIncreaseNonce();
864
+ if (nonceResult.errorCode !== 0) {
865
+ return nonceResult;
866
+ }
867
+ nonce = nonceResult.result;
868
+ nonce = new BigNumber(nonce).plus(1).toString(10);
869
+ }
870
+
871
+ // 获取blockNumber
872
+ if (ceilLedgerSeq != null && ceilLedgerSeq !== "") {
873
+ let blockNumber = await signer.getLedgerNumber();
874
+ ceilLedgerSeq = Number(ceilLedgerSeq) + Number(blockNumber.result);
875
+ }
876
+ let tranactionParameter = {
877
+ sourceAddress: sourceAddress,
878
+ nonce: nonce,
879
+ feeLimit: feeLimit,
880
+ gasPrice: gasPrice,
881
+ metadata: remarks,
882
+ seqOffset: ceilLedgerSeq,
883
+ nonceType: nonceType,
884
+ maxLedgerSeq: maxLedgerSeq,
885
+ };
886
+ this.buildTransaction(tranactionParameter);
887
+
888
+ let response = {
889
+ errorCode: 0,
890
+ errorDesc: "ok",
891
+ result: this.blob,
892
+ };
893
+
894
+ return util._response(response);
895
+ }
896
+
897
+ /**
898
+ * set account privilege
899
+ * @param request
900
+ * @returns {Promise<{errorDesc: *, errorCode: *}>}
901
+ */
902
+ async setPrivilege(object = {}, signer) {
903
+ // 校验参数
904
+ let request = check.validateObject(object);
905
+ if (request.errorCode) {
906
+ return request;
907
+ }
908
+
909
+ let {
910
+ sourceAddress,
911
+ txThreshold,
912
+ signers,
913
+ typeThresholds,
914
+ feeLimit,
915
+ gasPrice,
916
+ ceilLedgerSeq,
917
+ remarks,
918
+ masterWeight,
919
+ nonceType,
920
+ } = request;
921
+ // 必传校验
922
+ if (!keyPair.isAddress(sourceAddress)) {
923
+ return util._responseError(errors.INVALID_ADDRESS_ERROR);
924
+ }
925
+
926
+ // 参数校验
927
+ let operation = new Operation();
928
+ let data = operation.accountSetPrivilegeOperation(request);
929
+ if (data.errorCode !== 0) {
930
+ return data;
931
+ }
932
+
933
+ let setPrivilege = {
934
+ txThreshold: txThreshold,
935
+ signers: signers,
936
+ typeThresholds: typeThresholds,
937
+ masterWeight: masterWeight,
938
+ };
939
+ let operations = [setPrivilege];
940
+ this.addOperation("setPrivilegeOperation", operations);
941
+ // 随机nonce
942
+ let nonce;
943
+ let maxLedgerSeq;
944
+ if (nonceType == "1") {
945
+ let res = await signer.getLedgerNumber();
946
+ if (res.errorCode !== 0) {
947
+ return res;
948
+ }
949
+ maxLedgerSeq =
950
+ Number(res.result) + Number(Snowflake.getDefaultRangeRandom());
951
+ nonce = Snowflake.randomLenNum().toString();
952
+ } else {
953
+ let nonceResult = await signer.getIncreaseNonce();
954
+ if (nonceResult.errorCode !== 0) {
955
+ return nonceResult;
956
+ }
957
+ nonce = nonceResult.result;
958
+ nonce = new BigNumber(nonce).plus(1).toString(10);
959
+ }
960
+
961
+ // 获取blockNumber
962
+ if (ceilLedgerSeq != null && ceilLedgerSeq !== "") {
963
+ let blockNumber = await signer.getLedgerNumber();
964
+ ceilLedgerSeq = Number(ceilLedgerSeq) + Number(blockNumber.result);
965
+ }
966
+
967
+ let tranactionParameter = {
968
+ sourceAddress: sourceAddress,
969
+ nonce: nonce,
970
+ feeLimit: feeLimit,
971
+ gasPrice: gasPrice,
972
+ metadata: remarks,
973
+ seqOffset: ceilLedgerSeq,
974
+ nonceType: nonceType,
975
+ maxLedgerSeq: maxLedgerSeq,
976
+ };
977
+ this.buildTransaction(tranactionParameter);
978
+ let response = {
979
+ errorCode: 0,
980
+ errorDesc: "ok",
981
+ result: this.blob,
982
+ };
983
+
984
+ return util._response(response);
985
+ }
986
+ }
987
+
988
+ module.exports = Transaction;