@partisiablockchain/abi-client 6.37.0 → 6.62.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.
@@ -27,14 +27,24 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  exports.DeploymentBuilder = void 0;
30
- exports.getSupportedBinderVersions = getSupportedBinderVersions;
30
+ exports.parsePubState = parsePubState;
31
31
  exports.findBinderId = findBinderId;
32
32
  exports.findFailureCause = findFailureCause;
33
+ exports.parseAbi = parseAbi;
34
+ exports.unsupportedBinderError = unsupportedBinderError;
35
+ exports.unsupportedBinderDetails = unsupportedBinderDetails;
36
+ exports.isSupported = isSupported;
37
+ exports.validateInputFiles = validateInputFiles;
38
+ exports.validatePubVersions = validatePubVersions;
39
+ exports.validateRealVersions = validateRealVersions;
40
+ exports.isSpecificNodes = isSpecificNodes;
41
+ const DeploymentTypes_1 = require("./DeploymentTypes");
33
42
  const sections_1 = require("@partisiablockchain/sections");
34
43
  const AbiParser_1 = require("../parser/AbiParser");
35
44
  const StateReader_1 = require("../state/StateReader");
36
- const AbiVersion_1 = require("../model/AbiVersion");
37
45
  const RpcContractBuilder_1 = require("../rpc/RpcContractBuilder");
46
+ const bitmanipulation_ts_1 = require("@secata-public/bitmanipulation-ts");
47
+ const Configuration_1 = require("../parser/Configuration");
38
48
  class DeploymentBuilder {
39
49
  constructor(blockchainClient) {
40
50
  this.blockchainClient = blockchainClient;
@@ -49,63 +59,7 @@ class DeploymentBuilder {
49
59
  * @returns this builder
50
60
  */
51
61
  pbcFile(pbcFile) {
52
- let pbc;
53
- if (Buffer.isBuffer(pbcFile)) {
54
- pbc = sections_1.PbcFile.fromBytes(pbcFile);
55
- }
56
- else {
57
- pbc = pbcFile;
58
- }
59
- this.isZk = pbc.isZk;
60
- this.abiBytes = pbc.getAbiBytes();
61
- if (pbc.isZk) {
62
- this.contractBytes = pbc.getZkwaBytes();
63
- }
64
- else {
65
- this.contractBytes = pbc.getWasmBytes();
66
- }
67
- return this;
68
- }
69
- /**
70
- * Set the abi of the contract to deploy.
71
- *
72
- * <p>It is required to provide the abi either through this method or through {@link #pbcFile}.
73
- *
74
- * @param abi abi bytes to deploy
75
- * @returns this builder
76
- */
77
- abi(abi) {
78
- this.abiBytes = abi;
79
- return this;
80
- }
81
- /**
82
- * Set the contract bytes of the contract to deploy. Using this function denotes that it is a zk
83
- * contract you are trying to deploy.
84
- *
85
- * <p>It is required to provide the contract bytes either though this method, {@link wasm}, or
86
- * {@link pbcFile}.
87
- *
88
- * @param zkwa contract bytes to deploy
89
- * @returns this builder
90
- */
91
- zkwa(zkwa) {
92
- this.isZk = true;
93
- this.contractBytes = zkwa;
94
- return this;
95
- }
96
- /**
97
- * Set the contract bytes of the contract to deploy. Using this function denotes that it is a
98
- * public contract you are trying to deploy.
99
- *
100
- * <p>It is required to provide the contract bytes either though this method, {@link #zkwa}, or
101
- * {@link #pbcFile}.
102
- *
103
- * @param wasm contract bytes to deploy
104
- * @returns this builder
105
- */
106
- wasm(wasm) {
107
- this.isZk = false;
108
- this.contractBytes = wasm;
62
+ this.pbcFileField = pbcFile;
109
63
  return this;
110
64
  }
111
65
  /**
@@ -164,6 +118,19 @@ class DeploymentBuilder {
164
118
  this.allowedJurisdictionsField = allowedJurisdictions;
165
119
  return this;
166
120
  }
121
+ /**
122
+ * Set the specific nodes that will be allocated to this zk contract.
123
+ *
124
+ * <p>This argument is not allowed if trying to deploy a public contract. It is not required if
125
+ * deploying a zk contract and nodes will by default be allocated according to the {@link #allowedJurisdictions}.
126
+ *
127
+ * @param nodes nodes to be allocated to this contract
128
+ * @returns this builder
129
+ */
130
+ specificNodes(nodes) {
131
+ this.specificNodesField = nodes;
132
+ return this;
133
+ }
167
134
  /**
168
135
  * Set the required stakes from the nodes selected for the deployed zk contract.
169
136
  *
@@ -179,19 +146,6 @@ class DeploymentBuilder {
179
146
  this.requiredStakesField = requiredStakes;
180
147
  return this;
181
148
  }
182
- /**
183
- * Set the binder id used to determine which binder to deploy the contract with.
184
- *
185
- * <p>This argument is not required. By default it will read the state of the deploy contract to
186
- * find a binder which supports the given contract.
187
- *
188
- * @param binderId binder id
189
- * @returns this builder
190
- */
191
- binderId(binderId) {
192
- this.binderIdField = binderId;
193
- return this;
194
- }
195
149
  /**
196
150
  * Set the gas cost used to deploy the contract.
197
151
  *
@@ -216,24 +170,16 @@ class DeploymentBuilder {
216
170
  */
217
171
  buildRpc() {
218
172
  return __awaiter(this, void 0, void 0, function* () {
219
- this.validateRequiredParameters();
173
+ const validationResult = yield this.validateRequiredParameters();
220
174
  this.validateOptionalParameters();
221
- const deployContract = yield this.blockchainClient
222
- .getContract(this.deployContractAddressField)
223
- .catch(() => {
224
- throw new Error("Unable to get deploy contract state");
225
- });
226
- const deployAbiBytes = Buffer.from(deployContract.abi, "base64");
227
- const deployState = Buffer.from(deployContract.serializedContract, "base64");
228
- const deployAbi = new AbiParser_1.AbiParser(deployAbiBytes).parseAbi().contract();
229
- const abiToBeDeployed = new AbiParser_1.AbiParser(this.abiBytes).parseAbi();
230
- const binderId = this.determineBinderId(abiToBeDeployed, deployAbi, deployState);
231
- const initializationBytes = this.getInitializationBytes(abiToBeDeployed);
232
- if (this.isZk) {
233
- return this.realDeployRpc(deployAbi, initializationBytes, binderId);
175
+ const initializationBytes = this.getInitializationBytes(validationResult.abi);
176
+ if (validationResult.abi.contract().isZk()) {
177
+ const realState = yield this.getRealState();
178
+ return this.realDeployRpc(realState.abi, validationResult, initializationBytes);
234
179
  }
235
180
  else {
236
- return this.pubDeployRpc(deployAbi, initializationBytes, binderId);
181
+ const pubState = yield this.getPubState();
182
+ return DeploymentBuilder.createPubDeployRpc(pubState.abi, validationResult, initializationBytes);
237
183
  }
238
184
  });
239
185
  }
@@ -280,15 +226,22 @@ class DeploymentBuilder {
280
226
  });
281
227
  }
282
228
  validateRequiredParameters() {
283
- if (this.contractBytes === undefined) {
284
- throw new Error("Missing contract bytes");
285
- }
286
- if (this.abiBytes === undefined) {
287
- throw new Error("Missing abi bytes");
288
- }
289
- if (this.initRpcBytes === undefined) {
290
- throw new Error("Missing initialization bytes");
291
- }
229
+ return __awaiter(this, void 0, void 0, function* () {
230
+ const validationResult = yield this.validateContract();
231
+ if (validationResult.type === DeploymentTypes_1.ResultType.INSUFFICIENT_INPUT) {
232
+ throw new Error("Missing contract files");
233
+ }
234
+ if (validationResult.type !== DeploymentTypes_1.ResultType.VALID) {
235
+ const details = validationResult.message.details === undefined
236
+ ? ""
237
+ : `\nDetails: [${validationResult.message.details.join(", ")}]`;
238
+ throw new Error(`${validationResult.message.title}: ${validationResult.message.summary}${details}`);
239
+ }
240
+ if (this.initRpcBytes === undefined) {
241
+ throw new Error("Missing initialization bytes");
242
+ }
243
+ return validationResult;
244
+ });
292
245
  }
293
246
  validateOptionalParameters() {
294
247
  if (this.deployContractAddressField === undefined) {
@@ -299,50 +252,49 @@ class DeploymentBuilder {
299
252
  this.deployContractAddressField = DeploymentBuilder.DEFAULT_PUB_ADDRESS;
300
253
  }
301
254
  }
302
- if (this.isZk && this.allowedJurisdictionsField === undefined) {
303
- this.allowedJurisdictionsField = DeploymentBuilder.DEFAULT_ALLOWED_JURISDICTION;
304
- }
305
255
  if (!this.isZk && this.allowedJurisdictionsField !== undefined) {
306
256
  throw new Error("Allowed jurisdictions is not allowed as argument to pub deploy");
307
257
  }
308
- if (this.isZk && this.requiredStakesField === undefined) {
309
- this.requiredStakesField = DeploymentBuilder.DEFAULT_REQUIRED_STAKES;
258
+ if (!this.isZk && this.specificNodesField !== undefined) {
259
+ throw new Error("Specific nodes is not allowed as argument to pub deploy");
310
260
  }
311
261
  if (!this.isZk && this.requiredStakesField !== undefined) {
312
262
  throw new Error("Required stakes is not allowed as argument to pub deploy");
313
263
  }
314
264
  }
315
- determineBinderId(abiToBeDeployed, deployAbi, deployState) {
316
- if (this.binderIdField !== undefined) {
317
- return this.binderIdField;
318
- }
319
- const binderVersions = getSupportedBinderVersions(deployState, deployAbi);
320
- const binderVersion = abiToBeDeployed.versionBinder;
321
- return findBinderId(binderVersions, binderVersion);
322
- }
323
- realDeployRpc(deployAbi, initializationBytes, binderId) {
324
- const fnBuilder = new RpcContractBuilder_1.RpcContractBuilder(deployAbi, "deployContractV3");
325
- fnBuilder.addVecU8(this.contractBytes);
326
- fnBuilder.addVecU8(initializationBytes);
327
- fnBuilder.addVecU8(this.abiBytes);
328
- fnBuilder.addI64(this.requiredStakesField);
329
- const vecBuilder = fnBuilder.addVec();
330
- for (const allowedJurisdiction of this.allowedJurisdictionsField) {
331
- const vecVecBuilder = vecBuilder.addVec();
332
- for (const allowed of allowedJurisdiction) {
333
- vecVecBuilder.addI32(allowed);
265
+ /**
266
+ * Validate that the supplied contracts can be deployed.
267
+ */
268
+ validateContract() {
269
+ return __awaiter(this, void 0, void 0, function* () {
270
+ try {
271
+ const inputFilesResult = validateInputFiles(this.pbcFileField);
272
+ if (!inputFilesResult.ok) {
273
+ return inputFilesResult.error;
274
+ }
275
+ this.isZk = inputFilesResult.value.abi.contract().isZk();
276
+ if (this.isZk) {
277
+ const realState = yield this.getRealState();
278
+ return validateRealVersions(realState, inputFilesResult.value.abi, inputFilesResult.value.pbcFile);
279
+ }
280
+ else {
281
+ const pubState = yield this.getPubState();
282
+ return validatePubVersions(pubState, inputFilesResult.value.abi, inputFilesResult.value.pbcFile);
283
+ }
334
284
  }
335
- }
336
- fnBuilder.addI32(binderId);
337
- return fnBuilder.getBytes();
285
+ catch (e) {
286
+ const error = e;
287
+ return { type: DeploymentTypes_1.ResultType.ERROR, message: { title: error.name, summary: error.message } };
288
+ }
289
+ });
338
290
  }
339
- pubDeployRpc(deployAbi, initializationBytes, binderId) {
340
- const fnBuilder = new RpcContractBuilder_1.RpcContractBuilder(deployAbi, "deployContractWithBinderId");
341
- fnBuilder.addVecU8(this.contractBytes);
342
- fnBuilder.addVecU8(this.abiBytes);
343
- fnBuilder.addVecU8(initializationBytes);
344
- fnBuilder.addI32(binderId);
345
- return fnBuilder.getBytes();
291
+ realDeployRpc(deployAbi, validationResult, initializationBytes) {
292
+ if (this.specificNodesField === undefined) {
293
+ return DeploymentBuilder.createRealDeployRpc(deployAbi, validationResult, initializationBytes, this.requiredStakesField, this.allowedJurisdictionsField);
294
+ }
295
+ else {
296
+ return DeploymentBuilder.createRealDeployRpc(deployAbi, validationResult, initializationBytes, this.requiredStakesField, this.specificNodesField);
297
+ }
346
298
  }
347
299
  getInitializationBytes(abiToBeDeployed) {
348
300
  if (Buffer.isBuffer(this.initRpcBytes)) {
@@ -353,6 +305,117 @@ class DeploymentBuilder {
353
305
  this.initRpcBytes(fnBuilder);
354
306
  return fnBuilder.getBytes();
355
307
  }
308
+ getPubState() {
309
+ return __awaiter(this, void 0, void 0, function* () {
310
+ if (this.pubState === undefined) {
311
+ const deployContract = yield this.getContractState(DeploymentBuilder.DEFAULT_PUB_ADDRESS);
312
+ this.pubState = parsePubState(Buffer.from(deployContract.abi, "base64"), Buffer.from(deployContract.serializedContract, "base64"));
313
+ }
314
+ return this.pubState;
315
+ });
316
+ }
317
+ getRealState() {
318
+ return __awaiter(this, void 0, void 0, function* () {
319
+ if (this.realState === undefined) {
320
+ const deployContract = yield this.getContractState(DeploymentBuilder.DEFAULT_REAL_ADDRESS);
321
+ this.realState = parseRealState(Buffer.from(deployContract.abi, "base64"), Buffer.from(deployContract.serializedContract, "base64"));
322
+ }
323
+ return this.realState;
324
+ });
325
+ }
326
+ getContractState(defaultDeployAddress) {
327
+ var _a;
328
+ return this.blockchainClient
329
+ .getContract((_a = this.deployContractAddressField) !== null && _a !== void 0 ? _a : defaultDeployAddress)
330
+ .catch(() => {
331
+ throw new Error("Unable to get deploy contract state");
332
+ });
333
+ }
334
+ /**
335
+ * Validate that the supplied pbc file can be deployed using a deploy contract with the given
336
+ * state.
337
+ *
338
+ * @param pubState state of the public deploy contract
339
+ * @param realState state of the REAL deploy contract
340
+ * @param pbcFile the contract files as a pbc file
341
+ * @return a validation result containing either the successful validation or the error message
342
+ */
343
+ static validateContract(pubState, realState, pbcFile) {
344
+ try {
345
+ const inputFilesResult = validateInputFiles(pbcFile);
346
+ if (!inputFilesResult.ok) {
347
+ return inputFilesResult.error;
348
+ }
349
+ if (inputFilesResult.value.abi.contract().isZk()) {
350
+ return validateRealVersions(realState, inputFilesResult.value.abi, inputFilesResult.value.pbcFile);
351
+ }
352
+ else {
353
+ return validatePubVersions(pubState, inputFilesResult.value.abi, inputFilesResult.value.pbcFile);
354
+ }
355
+ }
356
+ catch (e) {
357
+ const error = e;
358
+ return { type: DeploymentTypes_1.ResultType.ERROR, message: { title: error.name, summary: error.message } };
359
+ }
360
+ }
361
+ /**
362
+ * Create rpc needed for a deployment of public contract from a successful validation result and
363
+ * the contract initialization rpc.
364
+ *
365
+ * @param pubDeployAbi abi for the public deployment contract
366
+ * @param validationResult the successful deployment result
367
+ * @param initRpc the contract's initialization rpc
368
+ * @return the deployment rpc
369
+ */
370
+ static createPubDeployRpc(pubDeployAbi, validationResult, initRpc) {
371
+ const fnBuilder = new RpcContractBuilder_1.RpcContractBuilder(pubDeployAbi, "deployContractWithBinderId");
372
+ fnBuilder.addVecU8(validationResult.pbcFile.getWasmBytes());
373
+ fnBuilder.addVecU8(validationResult.pbcFile.getAbiBytes());
374
+ fnBuilder.addVecU8(initRpc);
375
+ fnBuilder.addI32(validationResult.binderId);
376
+ return fnBuilder.getBytes();
377
+ }
378
+ static createRealDeployRpc(realDeployAbi, validationResult, initRpc, requiredStakes, nodeSelection) {
379
+ const actualRequiredStakes = requiredStakes !== null && requiredStakes !== void 0 ? requiredStakes : DeploymentBuilder.DEFAULT_REQUIRED_STAKES;
380
+ if (validationResult.isRealV2) {
381
+ const fnBuilder = new RpcContractBuilder_1.RpcContractBuilder(realDeployAbi, "deployContractWithEe");
382
+ fnBuilder.addVecU8(validationResult.pbcFile.getZkwaBytes());
383
+ fnBuilder.addVecU8(validationResult.pbcFile.getAbiBytes());
384
+ fnBuilder.addVecU8(initRpc);
385
+ fnBuilder.addI32(validationResult.binderId);
386
+ return fnBuilder.getBytes();
387
+ }
388
+ else if (isSpecificNodes(nodeSelection)) {
389
+ const fnBuilder = new RpcContractBuilder_1.RpcContractBuilder(realDeployAbi, "deployContractWithSpecificNodes");
390
+ fnBuilder.addVecU8(validationResult.pbcFile.getZkwaBytes());
391
+ fnBuilder.addVecU8(initRpc);
392
+ fnBuilder.addVecU8(validationResult.pbcFile.getAbiBytes());
393
+ fnBuilder.addI64(actualRequiredStakes);
394
+ fnBuilder.addI32(validationResult.binderId);
395
+ fnBuilder.addAddress(nodeSelection[0]);
396
+ fnBuilder.addAddress(nodeSelection[1]);
397
+ fnBuilder.addAddress(nodeSelection[2]);
398
+ fnBuilder.addAddress(nodeSelection[3]);
399
+ return fnBuilder.getBytes();
400
+ }
401
+ else {
402
+ const allowedJurisdictions = nodeSelection !== null && nodeSelection !== void 0 ? nodeSelection : DeploymentBuilder.DEFAULT_ALLOWED_JURISDICTION;
403
+ const fnBuilder = new RpcContractBuilder_1.RpcContractBuilder(realDeployAbi, "deployContractV3");
404
+ fnBuilder.addVecU8(validationResult.pbcFile.getZkwaBytes());
405
+ fnBuilder.addVecU8(initRpc);
406
+ fnBuilder.addVecU8(validationResult.pbcFile.getAbiBytes());
407
+ fnBuilder.addI64(actualRequiredStakes);
408
+ const vecBuilder = fnBuilder.addVec();
409
+ for (const allowedJurisdiction of allowedJurisdictions) {
410
+ const vecVecBuilder = vecBuilder.addVec();
411
+ for (const allowed of allowedJurisdiction) {
412
+ vecVecBuilder.addI32(allowed);
413
+ }
414
+ }
415
+ fnBuilder.addI32(validationResult.binderId);
416
+ return fnBuilder.getBytes();
417
+ }
418
+ }
356
419
  }
357
420
  exports.DeploymentBuilder = DeploymentBuilder;
358
421
  DeploymentBuilder.DEFAULT_PUB_ADDRESS = "0197a0e238e924025bad144aa0c4913e46308f9a4d";
@@ -361,14 +424,39 @@ DeploymentBuilder.DEFAULT_ALLOWED_JURISDICTION = [];
361
424
  DeploymentBuilder.DEFAULT_REQUIRED_STAKES = 20000000;
362
425
  DeploymentBuilder.DEFAULT_PUB_GAS_COST = 800000;
363
426
  DeploymentBuilder.DEFAULT_REAL_GAS_COST = 2000000;
364
- function getSupportedBinderVersions(deployState, deployAbi) {
365
- const state = StateReader_1.StateReader.create(deployState, deployAbi).readState();
427
+ function parsePubState(abi, serializedContract) {
428
+ const deployAbi = new AbiParser_1.AbiParser(abi).parseAbi().contract();
429
+ const state = StateReader_1.StateReader.create(serializedContract, deployAbi).readState();
366
430
  const binders = state.getFieldValue("binders").optionValue().innerValue.mapValue();
367
431
  const entries = [...binders.map.entries()].map(([k, v]) => [
368
432
  k.optionValue().innerValue.asNumber(),
369
- versionIntervalFromScBinderInfo(v.optionValue().innerValue.structValue()),
433
+ { versionInterval: versionIntervalFromScBinderInfo(v.optionValue().innerValue.structValue()) },
370
434
  ]);
371
- return new Map(entries);
435
+ return { binders: Object.fromEntries(entries), abi: deployAbi };
436
+ }
437
+ function parseRealState(abi, serializedContract) {
438
+ const deployAbi = new AbiParser_1.AbiParser(abi).parseAbi().contract();
439
+ const state = StateReader_1.StateReader.create(serializedContract, deployAbi).readState();
440
+ const binders = state.getFieldValue("binders").optionValue().innerValue.mapValue();
441
+ const entries = [...binders.map.entries()].map(([k, v]) => {
442
+ var _a;
443
+ const binderInfoStruct = v.optionValue().innerValue.structValue();
444
+ return [
445
+ k.optionValue().innerValue.asNumber(),
446
+ {
447
+ versionInterval: versionIntervalFromScBinderInfo(binderInfoStruct),
448
+ supportedZkbcVersionMax: versionFromScVersion(binderInfoStruct
449
+ .getFieldValue("supportedZkbcVersionMax")
450
+ .optionValue()
451
+ .innerValue.structValue()),
452
+ usedEeVersion: (_a = binderInfoStruct
453
+ .getFieldValue("usedEeVersion")
454
+ .optionValue()
455
+ .innerValue) === null || _a === void 0 ? void 0 : _a.asNumber(),
456
+ },
457
+ ];
458
+ });
459
+ return { binders: Object.fromEntries(entries), abi: deployAbi };
372
460
  }
373
461
  function versionIntervalFromScBinderInfo(binderInfo) {
374
462
  const versionInterval = binderInfo
@@ -383,19 +471,26 @@ function versionIntervalFromScBinderInfo(binderInfo) {
383
471
  .getFieldValue("supportedBinderVersionMax")
384
472
  .optionValue()
385
473
  .innerValue.structValue();
386
- const min = new AbiVersion_1.AbiVersion(scMin.getFieldValue("major").asNumber(), scMin.getFieldValue("minor").asNumber(), scMin.getFieldValue("patch").asNumber());
387
- const max = new AbiVersion_1.AbiVersion(scMax.getFieldValue("major").asNumber(), scMax.getFieldValue("minor").asNumber(), scMax.getFieldValue("patch").asNumber());
388
- return { min, max };
474
+ const supportedBinderVersionMin = versionFromScVersion(scMin);
475
+ const supportedBinderVersionMax = versionFromScVersion(scMax);
476
+ return { supportedBinderVersionMin, supportedBinderVersionMax };
477
+ }
478
+ function versionFromScVersion(scVersion) {
479
+ return {
480
+ major: scVersion.getFieldValue("major").asNumber(),
481
+ minor: scVersion.getFieldValue("minor").asNumber(),
482
+ patch: scVersion.getFieldValue("patch").asNumber(),
483
+ };
389
484
  }
390
485
  function findBinderId(binders, binderVersion) {
391
- const entry = [...binders.entries()].find(([_, v]) => checkDeployVersion(binderVersion, v));
486
+ const entry = [...Object.entries(binders)].find(([_, v]) => checkDeployVersion(binderVersion, v.versionInterval));
392
487
  if (entry === undefined) {
393
- throw new Error("No binders exists supporting version " + binderVersion.toString());
488
+ return undefined;
394
489
  }
395
- return entry[0];
490
+ return parseInt(entry[0]);
396
491
  }
397
492
  function checkDeployVersion(binderVersion, versionInterval) {
398
- return checkVersion(binderVersion, versionInterval.max.major, versionInterval.max.minor, versionInterval.min.major, versionInterval.min.minor);
493
+ return checkVersion(binderVersion, versionInterval.supportedBinderVersionMax.major, versionInterval.supportedBinderVersionMax.minor, versionInterval.supportedBinderVersionMin.major, versionInterval.supportedBinderVersionMin.minor);
399
494
  }
400
495
  function checkVersion(binderVersion, maxMajor, maxMinor, minMajor, minMinor) {
401
496
  return (maxMajor >= binderVersion.major &&
@@ -416,4 +511,177 @@ function executedToErrorMsg(executedTransaction) {
416
511
  }
417
512
  return executedTransaction.executionStatus.failure.errorMessage;
418
513
  }
514
+ function parseAbi(abiBytes) {
515
+ const abiParser = new AbiParser_1.AbiParser(abiBytes);
516
+ const header = abiParser.parseHeader();
517
+ if (Configuration_1.Configuration.isSupportedVersion(header.versionClient)) {
518
+ return { ok: true, value: abiParser.parseChainComponent(header) };
519
+ }
520
+ else {
521
+ const supportedVersions = Configuration_1.Configuration.getSupportedVersions();
522
+ return {
523
+ ok: false,
524
+ error: {
525
+ type: DeploymentTypes_1.ResultType.ERROR,
526
+ message: {
527
+ title: "Invalid abi",
528
+ summary: `Unsupported client ABI version ${header.versionClient.toString()}.`,
529
+ details: [
530
+ `Latest supported version is ${supportedVersions[supportedVersions.length - 1].toString()}`,
531
+ ],
532
+ },
533
+ },
534
+ };
535
+ }
536
+ }
537
+ function unsupportedBinderError(abi, binders) {
538
+ return {
539
+ type: DeploymentTypes_1.ResultType.ERROR,
540
+ message: {
541
+ title: "Version Error",
542
+ summary: "The contract requires a binder version that is not supported by the blockchain.",
543
+ details: unsupportedBinderDetails(abi.versionBinder, Object.values(binders).map((binder) => binder.versionInterval.supportedBinderVersionMax)),
544
+ },
545
+ };
546
+ }
547
+ function unsupportedBinderDetails(contractVersion, supportedVersions) {
548
+ var _a;
549
+ const max = (_a = maxVersion(supportedVersions.filter((version) => version.major === contractVersion.major))) !== null && _a !== void 0 ? _a : maxVersion(supportedVersions);
550
+ if (max === undefined) {
551
+ return ["No binders are available"];
552
+ }
553
+ else if (isGreater(contractVersion, max)) {
554
+ return [
555
+ "Contract requires a too new binder version " + versionToString(contractVersion),
556
+ "Blockchain supports latest version " + versionToString(max),
557
+ "Please downgrade your contract-sdk",
558
+ ];
559
+ }
560
+ else {
561
+ return [
562
+ "Contract requires a too old binder version " + versionToString(contractVersion),
563
+ "Blockchain supports latest version " + versionToString(max),
564
+ "Please update your contract-sdk",
565
+ ];
566
+ }
567
+ }
568
+ function maxVersion(versions) {
569
+ // Stryker disable next-line BlockStatement
570
+ if (versions.length === 0) {
571
+ return undefined;
572
+ }
573
+ else {
574
+ return versions.reduce((acc, val) => (isGreater(acc, val) ? acc : val));
575
+ }
576
+ }
577
+ function isGreater(version1, version2) {
578
+ return (version1.major > version2.major ||
579
+ (version1.major === version2.major && version1.minor > version2.minor));
580
+ }
581
+ function versionToString(version) {
582
+ return `${version.major}.${version.minor}.0`;
583
+ }
584
+ function invalidContractTypeError(contractType) {
585
+ return {
586
+ type: DeploymentTypes_1.ResultType.ERROR,
587
+ message: {
588
+ title: "Invalid Contract Type",
589
+ summary: `Deployment of ${contractType} contracts is currently disabled.`,
590
+ },
591
+ };
592
+ }
593
+ function unsupportedZkbcError(zkbcVersion, supportedZkbcVersionMax) {
594
+ return {
595
+ type: DeploymentTypes_1.ResultType.ERROR,
596
+ message: {
597
+ title: "Version Error",
598
+ summary: "The contract requires a ZKBC version that the binder doesn't support",
599
+ details: [
600
+ `Contract requires version ${zkbcVersion.major}.${zkbcVersion.minor}.0`,
601
+ `Binder supports up to version ${supportedZkbcVersionMax.major}.${supportedZkbcVersionMax.minor}.0`,
602
+ ],
603
+ },
604
+ };
605
+ }
606
+ function extractZkbcVersion(pbcFile) {
607
+ const zkbcBytes = pbcFile.getZkbcBytes();
608
+ const stream = new bitmanipulation_ts_1.BigEndianByteInput(zkbcBytes);
609
+ stream.readBytes(4); // Magic bytes
610
+ const major = stream.readI16();
611
+ const minor = stream.readI16();
612
+ return { major, minor, patch: 0 };
613
+ }
614
+ function isSupported(zkbcVersion, supportedZkbcVersionMax) {
615
+ return (zkbcVersion.major === supportedZkbcVersionMax.major &&
616
+ zkbcVersion.minor <= supportedZkbcVersionMax.minor);
617
+ }
618
+ /**
619
+ * Parse and validate that the ABI is well-formed.
620
+ *
621
+ * @param pbcFile pbc file to validate
622
+ * @return result of the parsed abi of the error if it couldn't be parsed
623
+ */
624
+ function validateInputFiles(pbcFile) {
625
+ if (pbcFile === undefined) {
626
+ return { ok: false, error: { type: DeploymentTypes_1.ResultType.INSUFFICIENT_INPUT } };
627
+ }
628
+ let pbc;
629
+ if (Buffer.isBuffer(pbcFile)) {
630
+ pbc = sections_1.PbcFile.fromBytes(pbcFile);
631
+ }
632
+ else {
633
+ pbc = pbcFile;
634
+ }
635
+ const abiResult = parseAbi(pbc.getAbiBytes());
636
+ if (!abiResult.ok) {
637
+ return abiResult;
638
+ }
639
+ return { ok: true, value: { pbcFile: pbc, abi: abiResult.value } };
640
+ }
641
+ /**
642
+ * Validate that the there exists a public binder that the supports the contract being deployed.
643
+ *
644
+ * @param pubState state of public deploy contract
645
+ * @param abi parsed abi of the contract to be deployed
646
+ * @param pbcFile pbc file containing the contract files
647
+ * @return a validation result containing either the successful validation or the error message
648
+ */
649
+ function validatePubVersions(pubState, abi, pbcFile) {
650
+ if (pubState === undefined) {
651
+ return invalidContractTypeError("PUBLIC");
652
+ }
653
+ const binderId = findBinderId(pubState.binders, abi.versionBinder);
654
+ if (binderId === undefined) {
655
+ return unsupportedBinderError(abi, pubState.binders);
656
+ }
657
+ return { type: DeploymentTypes_1.ResultType.VALID, abi, pbcFile, binderId, isRealV2: false };
658
+ }
659
+ /**
660
+ * Validate that the there exists a REAL binder that the supports the contract being deployed.
661
+ *
662
+ * @param realState state of REAL deploy contract
663
+ * @param abi parsed abi of the contract to be deployed
664
+ * @param pbcFile pbc file containing the contract files
665
+ * @return a validation result containing either the successful validation or the error message
666
+ */
667
+ function validateRealVersions(realState, abi, pbcFile) {
668
+ if (realState === undefined) {
669
+ return invalidContractTypeError("MPC");
670
+ }
671
+ const binderId = findBinderId(realState.binders, abi.versionBinder);
672
+ if (binderId === undefined) {
673
+ return unsupportedBinderError(abi, realState.binders);
674
+ }
675
+ const zkbcVersion = extractZkbcVersion(pbcFile);
676
+ const binder = realState.binders[binderId];
677
+ const supportedZkbcVersionMax = binder.supportedZkbcVersionMax;
678
+ if (!isSupported(zkbcVersion, supportedZkbcVersionMax)) {
679
+ return unsupportedZkbcError(zkbcVersion, supportedZkbcVersionMax);
680
+ }
681
+ const isRealV2 = binder.usedEeVersion !== undefined;
682
+ return { type: DeploymentTypes_1.ResultType.VALID, abi, pbcFile, binderId, isRealV2 };
683
+ }
684
+ function isSpecificNodes(nodeSelection) {
685
+ return nodeSelection !== undefined && typeof nodeSelection[0] === "string";
686
+ }
419
687
  //# sourceMappingURL=DeploymentBuilder.js.map