@alephium/web3 0.2.0-rc.15 → 0.2.0-rc.16

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.
@@ -317,8 +317,11 @@ export interface ChangeActiveAddress {
317
317
  export interface CompileContractResult {
318
318
  name: string;
319
319
  bytecode: string;
320
+ bytecodeDebugPatch: string;
320
321
  /** @format 32-byte-hash */
321
322
  codeHash: string;
323
+ /** @format 32-byte-hash */
324
+ codeHashDebug: string;
322
325
  fields: FieldsSig;
323
326
  functions: FunctionSig[];
324
327
  events: EventSig[];
@@ -331,6 +334,7 @@ export interface CompileProjectResult {
331
334
  export interface CompileScriptResult {
332
335
  name: string;
333
336
  bytecodeTemplate: string;
337
+ bytecodeDebugPatch: string;
334
338
  fields: FieldsSig;
335
339
  functions: FunctionSig[];
336
340
  warnings: string[];
@@ -422,6 +426,11 @@ export interface ContractState {
422
426
  fields: Val[];
423
427
  asset: AssetState;
424
428
  }
429
+ export interface DebugMessage {
430
+ /** @format address */
431
+ contractAddress: string;
432
+ message: string;
433
+ }
425
434
  export interface DecodeUnsignedTx {
426
435
  unsignedTx: string;
427
436
  }
@@ -672,6 +681,7 @@ export interface TestContractResult {
672
681
  txInputs: string[];
673
682
  txOutputs: Output[];
674
683
  events: ContractEventByTxId[];
684
+ debugMessages: DebugMessage[];
675
685
  }
676
686
  export interface TestInputAsset {
677
687
  /** @format address */
@@ -37,18 +37,18 @@ declare class Compiled<T extends Artifact> {
37
37
  warnings: string[];
38
38
  constructor(sourceFile: SourceFile, artifact: T, warnings: string[]);
39
39
  }
40
+ declare type CodeInfo = {
41
+ sourceCodeHash: string;
42
+ bytecodeDebugPatch: string;
43
+ codeHashDebug: string;
44
+ warnings: string[];
45
+ };
40
46
  declare class ProjectArtifact {
41
47
  static readonly artifactFileName = ".project.json";
42
48
  compilerOptionsUsed: node.CompilerOptions;
43
- infos: Map<string, {
44
- sourceCodeHash: string;
45
- warnings: string[];
46
- }>;
49
+ infos: Map<string, CodeInfo>;
47
50
  static checkCompilerOptionsParameter(compilerOptions: node.CompilerOptions): void;
48
- constructor(compilerOptionsUsed: node.CompilerOptions, infos: Map<string, {
49
- sourceCodeHash: string;
50
- warnings: string[];
51
- }>);
51
+ constructor(compilerOptionsUsed: node.CompilerOptions, infos: Map<string, CodeInfo>);
52
52
  saveToFile(rootPath: string): Promise<void>;
53
53
  needToReCompile(compilerOptions: node.CompilerOptions, files: SourceFile[]): boolean;
54
54
  static from(rootPath: string): Promise<ProjectArtifact | undefined>;
@@ -94,20 +94,24 @@ export declare abstract class Artifact {
94
94
  }
95
95
  export declare class Contract extends Artifact {
96
96
  readonly bytecode: string;
97
+ readonly bytecodeDebugPatch: string;
97
98
  readonly codeHash: string;
98
99
  readonly fieldsSig: FieldsSig;
99
100
  readonly eventsSig: EventSig[];
100
- constructor(name: string, bytecode: string, codeHash: string, fieldsSig: FieldsSig, eventsSig: EventSig[], functions: FunctionSig[]);
101
- static fromJson(artifact: any): Contract;
101
+ readonly bytecodeDebug: string;
102
+ readonly codeHashDebug: string;
103
+ constructor(name: string, bytecode: string, bytecodeDebugPatch: string, codeHash: string, codeHashDebug: string, fieldsSig: FieldsSig, eventsSig: EventSig[], functions: FunctionSig[]);
104
+ static fromJson(artifact: any, bytecodeDebugPatch?: string, codeHashDebug?: string): Contract;
102
105
  static fromCompileResult(result: node.CompileContractResult): Contract;
103
- static fromArtifactFile(path: string): Promise<Contract>;
106
+ static fromArtifactFile(path: string, bytecodeDebugPatch: string, codeHashDebug: string): Promise<Contract>;
104
107
  fetchState(address: string, group: number): Promise<ContractState>;
105
108
  toString(): string;
106
109
  toState(fields: Fields, asset: Asset, address?: string): ContractState;
107
110
  static randomAddress(): string;
111
+ private _printDebugMessages;
108
112
  private _test;
109
- testPublicMethod(funcName: string, params: TestContractParams): Promise<TestContractResult>;
110
- testPrivateMethod(funcName: string, params: TestContractParams): Promise<TestContractResult>;
113
+ testPublicMethod(funcName: string, params: TestContractParams, printDebugMessages?: boolean): Promise<TestContractResult>;
114
+ testPrivateMethod(funcName: string, params: TestContractParams, printDebugMessages?: boolean): Promise<TestContractResult>;
111
115
  toApiFields(fields?: Fields): node.Val[];
112
116
  toApiArgs(funcName: string, args?: Arguments): node.Val[];
113
117
  getMethodIndex(funcName: string): number;
@@ -124,11 +128,12 @@ export declare class Contract extends Artifact {
124
128
  }
125
129
  export declare class Script extends Artifact {
126
130
  readonly bytecodeTemplate: string;
131
+ readonly bytecodeDebugPatch: string;
127
132
  readonly fieldsSig: FieldsSig;
128
- constructor(name: string, bytecodeTemplate: string, fieldsSig: FieldsSig, functions: FunctionSig[]);
133
+ constructor(name: string, bytecodeTemplate: string, bytecodeDebugPatch: string, fieldsSig: FieldsSig, functions: FunctionSig[]);
129
134
  static fromCompileResult(result: node.CompileScriptResult): Script;
130
- static fromJson(artifact: any): Script;
131
- static fromArtifactFile(path: string): Promise<Script>;
135
+ static fromJson(artifact: any, bytecodeDebugPatch?: string): Script;
136
+ static fromArtifactFile(path: string, bytecodeDebugPatch: string): Promise<Script>;
132
137
  toString(): string;
133
138
  paramsForDeployment(params: BuildExecuteScriptTx): Promise<SignExecuteScriptTxParams>;
134
139
  transactionForDeployment(signer: SignerWithNodeProvider, params: Omit<BuildExecuteScriptTx, 'signerAddress'>): Promise<BuildScriptTxResult>;
@@ -174,14 +179,17 @@ export interface ContractEventByTxId {
174
179
  name: string;
175
180
  fields: Fields;
176
181
  }
182
+ export declare type DebugMessage = node.DebugMessage;
177
183
  export interface TestContractResult {
178
184
  address: string;
179
185
  contractId: string;
186
+ contractAddress: string;
180
187
  returns: Val[];
181
188
  gasUsed: number;
182
189
  contracts: ContractState[];
183
190
  txOutputs: Output[];
184
191
  events: ContractEventByTxId[];
192
+ debugMessages: DebugMessage[];
185
193
  }
186
194
  export declare type Output = AssetOutput | ContractOutput;
187
195
  export interface AssetOutput extends Asset {
@@ -172,12 +172,16 @@ class Project {
172
172
  contracts.forEach((c) => {
173
173
  files.set(c.sourceFile.contractPath, {
174
174
  sourceCodeHash: c.sourceFile.sourceCodeHash,
175
+ bytecodeDebugPatch: c.artifact.bytecodeDebugPatch,
176
+ codeHashDebug: c.artifact.codeHashDebug,
175
177
  warnings: c.warnings
176
178
  });
177
179
  });
178
180
  scripts.forEach((s) => {
179
181
  files.set(s.sourceFile.contractPath, {
180
182
  sourceCodeHash: s.sourceFile.sourceCodeHash,
183
+ bytecodeDebugPatch: s.artifact.bytecodeDebugPatch,
184
+ codeHashDebug: '',
181
185
  warnings: s.warnings
182
186
  });
183
187
  });
@@ -185,6 +189,8 @@ class Project {
185
189
  sourceFiles.slice(compiledSize).forEach((c) => {
186
190
  files.set(c.contractPath, {
187
191
  sourceCodeHash: c.sourceCodeHash,
192
+ bytecodeDebugPatch: '',
193
+ codeHashDebug: '',
188
194
  warnings: []
189
195
  });
190
196
  });
@@ -243,7 +249,7 @@ class Project {
243
249
  await this.projectArtifact.saveToFile(this.artifactsRootDir);
244
250
  }
245
251
  contractByCodeHash(codeHash) {
246
- const contract = this.contracts.find((c) => c.artifact.codeHash === codeHash);
252
+ const contract = this.contracts.find((c) => c.artifact.codeHash === codeHash || c.artifact.codeHashDebug == codeHash);
247
253
  if (typeof contract === 'undefined') {
248
254
  throw new Error(`Unknown code with code hash: ${codeHash}`);
249
255
  }
@@ -284,11 +290,11 @@ class Project {
284
290
  const warnings = info.warnings;
285
291
  const artifactDir = file.getArtifactPath(artifactsRootDir);
286
292
  if (file.type === SourceType.Contract) {
287
- const artifact = await Contract.fromArtifactFile(artifactDir);
293
+ const artifact = await Contract.fromArtifactFile(artifactDir, info.bytecodeDebugPatch, info.codeHashDebug);
288
294
  contracts.push(new Compiled(file, artifact, warnings));
289
295
  }
290
296
  else if (file.type === SourceType.Script) {
291
- const artifact = await Script.fromArtifactFile(artifactDir);
297
+ const artifact = await Script.fromArtifactFile(artifactDir, info.bytecodeDebugPatch);
292
298
  scripts.push(new Compiled(file, artifact, warnings));
293
299
  }
294
300
  }
@@ -385,15 +391,18 @@ class Artifact {
385
391
  }
386
392
  exports.Artifact = Artifact;
387
393
  class Contract extends Artifact {
388
- constructor(name, bytecode, codeHash, fieldsSig, eventsSig, functions) {
394
+ constructor(name, bytecode, bytecodeDebugPatch, codeHash, codeHashDebug, fieldsSig, eventsSig, functions) {
389
395
  super(name, functions);
390
396
  this.bytecode = bytecode;
397
+ this.bytecodeDebugPatch = bytecodeDebugPatch;
391
398
  this.codeHash = codeHash;
392
399
  this.fieldsSig = fieldsSig;
393
400
  this.eventsSig = eventsSig;
401
+ this.bytecodeDebug = ralph.buildDebugBytecode(this.bytecode, this.bytecodeDebugPatch);
402
+ this.codeHashDebug = codeHashDebug;
394
403
  }
395
404
  // TODO: safely parse json
396
- static fromJson(artifact) {
405
+ static fromJson(artifact, bytecodeDebugPatch = '', codeHashDebug = '') {
397
406
  if (artifact.name == null ||
398
407
  artifact.bytecode == null ||
399
408
  artifact.codeHash == null ||
@@ -402,17 +411,17 @@ class Contract extends Artifact {
402
411
  artifact.functions == null) {
403
412
  throw Error('The artifact JSON for contract is incomplete');
404
413
  }
405
- const contract = new Contract(artifact.name, artifact.bytecode, artifact.codeHash, artifact.fieldsSig, artifact.eventsSig, artifact.functions);
414
+ const contract = new Contract(artifact.name, artifact.bytecode, bytecodeDebugPatch, artifact.codeHash, codeHashDebug ? codeHashDebug : artifact.codeHash, artifact.fieldsSig, artifact.eventsSig, artifact.functions);
406
415
  return contract;
407
416
  }
408
417
  static fromCompileResult(result) {
409
- return new Contract(result.name, result.bytecode, result.codeHash, result.fields, result.events, result.functions);
418
+ return new Contract(result.name, result.bytecode, result.bytecodeDebugPatch, result.codeHash, result.codeHashDebug, result.fields, result.events, result.functions);
410
419
  }
411
420
  // support both 'code.ral' and 'code.ral.json'
412
- static async fromArtifactFile(path) {
421
+ static async fromArtifactFile(path, bytecodeDebugPatch, codeHashDebug) {
413
422
  const content = await fs_2.promises.readFile(path);
414
423
  const artifact = JSON.parse(content.toString());
415
- return Contract.fromJson(artifact);
424
+ return Contract.fromJson(artifact, bytecodeDebugPatch, codeHashDebug);
416
425
  }
417
426
  async fetchState(address, group) {
418
427
  const state = await Project.currentProject.nodeProvider.contracts.getContractsAddressState(address, {
@@ -450,11 +459,20 @@ class Contract extends Artifact {
450
459
  bytes[0] = 3;
451
460
  return utils_1.bs58.encode(bytes);
452
461
  }
453
- async _test(funcName, params, expectPublic, accessType) {
462
+ _printDebugMessages(funcName, messages) {
463
+ if (messages.length != 0) {
464
+ console.log(`Testing ${this.name}.${funcName}:`);
465
+ messages.forEach((m) => console.log(`Debug - ${m.contractAddress} - ${m.message}`));
466
+ }
467
+ }
468
+ async _test(funcName, params, expectPublic, accessType, printDebugMessages) {
454
469
  const apiParams = this.toTestContract(funcName, params);
455
470
  const apiResult = await Project.currentProject.nodeProvider.contracts.postContractsTestContract(apiParams);
456
471
  const methodIndex = typeof params.testMethodIndex !== 'undefined' ? params.testMethodIndex : this.getMethodIndex(funcName);
457
472
  const isPublic = this.functions[`${methodIndex}`].isPublic;
473
+ if (printDebugMessages) {
474
+ this._printDebugMessages(funcName, apiResult.debugMessages);
475
+ }
458
476
  if (isPublic === expectPublic) {
459
477
  const result = await this.fromTestContractResult(methodIndex, apiResult);
460
478
  return result;
@@ -463,11 +481,11 @@ class Contract extends Artifact {
463
481
  throw new Error(`The test method ${funcName} is not ${accessType}`);
464
482
  }
465
483
  }
466
- async testPublicMethod(funcName, params) {
467
- return this._test(funcName, params, true, 'public');
484
+ async testPublicMethod(funcName, params, printDebugMessages = true) {
485
+ return this._test(funcName, params, true, 'public', printDebugMessages);
468
486
  }
469
- async testPrivateMethod(funcName, params) {
470
- return this._test(funcName, params, false, 'private');
487
+ async testPrivateMethod(funcName, params, printDebugMessages = true) {
488
+ return this._test(funcName, params, false, 'private', printDebugMessages);
471
489
  }
472
490
  toApiFields(fields) {
473
491
  if (typeof fields === 'undefined') {
@@ -499,7 +517,7 @@ class Contract extends Artifact {
499
517
  return {
500
518
  group: params.group,
501
519
  address: params.address,
502
- bytecode: this.bytecode,
520
+ bytecode: this.bytecodeDebug,
503
521
  initialFields: this.toApiFields(params.initialFields),
504
522
  initialAsset: typeof params.initialAsset !== 'undefined' ? toApiAsset(params.initialAsset) : undefined,
505
523
  methodIndex: this.getMethodIndex(funcName),
@@ -547,6 +565,7 @@ class Contract extends Artifact {
547
565
  return {
548
566
  address: result.address,
549
567
  contractId: (0, utils_1.binToHex)((0, utils_1.contractIdFromAddress)(result.address)),
568
+ contractAddress: result.address,
550
569
  returns: (0, api_1.fromApiArray)(result.returns, this.functions[`${methodIndex}`].returnTypes),
551
570
  gasUsed: result.gasUsed,
552
571
  contracts: await Promise.all(result.contracts.map((contract) => this.fromApiContractState(contract))),
@@ -560,7 +579,8 @@ class Contract extends Artifact {
560
579
  else {
561
580
  throw Error(`Cannot find codeHash for the contract address: ${contractAddress}`);
562
581
  }
563
- }))
582
+ })),
583
+ debugMessages: result.debugMessages
564
584
  };
565
585
  }
566
586
  async paramsForDeployment(params) {
@@ -600,28 +620,29 @@ Contract.ContractDestroyedEvent = {
600
620
  fieldTypes: ['Address']
601
621
  };
602
622
  class Script extends Artifact {
603
- constructor(name, bytecodeTemplate, fieldsSig, functions) {
623
+ constructor(name, bytecodeTemplate, bytecodeDebugPatch, fieldsSig, functions) {
604
624
  super(name, functions);
605
625
  this.bytecodeTemplate = bytecodeTemplate;
626
+ this.bytecodeDebugPatch = bytecodeDebugPatch;
606
627
  this.fieldsSig = fieldsSig;
607
628
  }
608
629
  static fromCompileResult(result) {
609
- return new Script(result.name, result.bytecodeTemplate, result.fields, result.functions);
630
+ return new Script(result.name, result.bytecodeTemplate, result.bytecodeDebugPatch, result.fields, result.functions);
610
631
  }
611
632
  // TODO: safely parse json
612
- static fromJson(artifact) {
633
+ static fromJson(artifact, bytecodeDebugPatch = '') {
613
634
  if (artifact.name == null ||
614
635
  artifact.bytecodeTemplate == null ||
615
636
  artifact.fieldsSig == null ||
616
637
  artifact.functions == null) {
617
638
  throw Error('The artifact JSON for script is incomplete');
618
639
  }
619
- return new Script(artifact.name, artifact.bytecodeTemplate, artifact.fieldsSig, artifact.functions);
640
+ return new Script(artifact.name, artifact.bytecodeTemplate, bytecodeDebugPatch, artifact.fieldsSig, artifact.functions);
620
641
  }
621
- static async fromArtifactFile(path) {
642
+ static async fromArtifactFile(path, bytecodeDebugPatch) {
622
643
  const content = await fs_2.promises.readFile(path);
623
644
  const artifact = JSON.parse(content.toString());
624
- return this.fromJson(artifact);
645
+ return this.fromJson(artifact, bytecodeDebugPatch);
625
646
  }
626
647
  toString() {
627
648
  const object = {
@@ -10,3 +10,4 @@ export declare function encodeScriptField(tpe: string, value: Val): Uint8Array;
10
10
  export declare function buildScriptByteCode(bytecodeTemplate: string, fields: Fields, fieldsSig: FieldsSig): string;
11
11
  export declare function buildContractByteCode(bytecode: string, fields: Fields, fieldsSig: FieldsSig): string;
12
12
  export declare function encodeContractField(tpe: string, value: Val): Uint8Array[];
13
+ export declare function buildDebugBytecode(bytecode: string, bytecodePatch: string): string;
@@ -18,7 +18,7 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
18
18
  */
19
19
  var _a;
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.encodeContractField = exports.buildContractByteCode = exports.buildScriptByteCode = exports.encodeScriptField = exports.encodeScriptFieldAsString = exports.encodeAddress = exports.encodeByteVec = exports.encodeU256 = exports.encodeI256 = exports.encodeBool = void 0;
21
+ exports.buildDebugBytecode = exports.encodeContractField = exports.buildContractByteCode = exports.buildScriptByteCode = exports.encodeScriptField = exports.encodeScriptFieldAsString = exports.encodeAddress = exports.encodeByteVec = exports.encodeU256 = exports.encodeI256 = exports.encodeBool = void 0;
22
22
  const buffer_1 = require("buffer/");
23
23
  const utils_1 = require("../utils");
24
24
  const bigIntZero = BigInt(0);
@@ -343,6 +343,32 @@ exports.encodeContractField = encodeContractField;
343
343
  function invalidVal(tpe, value) {
344
344
  return Error(`Invalid API value ${value} for type ${tpe}`);
345
345
  }
346
+ function buildDebugBytecode(bytecode, bytecodePatch) {
347
+ if (bytecodePatch === '') {
348
+ return bytecode;
349
+ }
350
+ const pattern = /[=+-][0-9a-f]*/g;
351
+ let result = '';
352
+ let index = 0;
353
+ for (const parts of bytecodePatch.matchAll(pattern)) {
354
+ const part = parts[0];
355
+ const diffType = part[0];
356
+ if (diffType === '=') {
357
+ const length = parseInt(part.substring(1));
358
+ result = result + bytecode.slice(index, index + length);
359
+ index = index + length;
360
+ }
361
+ else if (diffType === '+') {
362
+ result = result + part.substring(1);
363
+ }
364
+ else {
365
+ const length = parseInt(part.substring(1));
366
+ index = index + length;
367
+ }
368
+ }
369
+ return result;
370
+ }
371
+ exports.buildDebugBytecode = buildDebugBytecode;
346
372
  // export function buildContractByteCode(
347
373
  // compiled: node.TemplateContractByteCode,
348
374
  // templateVariables: TemplateVariables
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alephium/web3",
3
- "version": "0.2.0-rc.15",
3
+ "version": "0.2.0-rc.16",
4
4
  "description": "A JS/TS library to interact with the Alephium platform",
5
5
  "license": "GPL",
6
6
  "main": "dist/src/index.js",
@@ -27,8 +27,8 @@
27
27
  },
28
28
  "author": "Alephium dev <dev@alephium.org>",
29
29
  "config": {
30
- "alephium_version": "1.5.0-rc8",
31
- "explorer_backend_version": "1.8.0"
30
+ "alephium_version": "1.5.0-rc9",
31
+ "explorer_backend_version": "1.9.0-rc0"
32
32
  },
33
33
  "scripts": {
34
34
  "build": "rm -rf dist/* && npx tsc --build . && webpack",
@@ -437,9 +437,13 @@ export interface ChangeActiveAddress {
437
437
  export interface CompileContractResult {
438
438
  name: string
439
439
  bytecode: string
440
+ bytecodeDebugPatch: string
440
441
 
441
442
  /** @format 32-byte-hash */
442
443
  codeHash: string
444
+
445
+ /** @format 32-byte-hash */
446
+ codeHashDebug: string
443
447
  fields: FieldsSig
444
448
  functions: FunctionSig[]
445
449
  events: EventSig[]
@@ -454,6 +458,7 @@ export interface CompileProjectResult {
454
458
  export interface CompileScriptResult {
455
459
  name: string
456
460
  bytecodeTemplate: string
461
+ bytecodeDebugPatch: string
457
462
  fields: FieldsSig
458
463
  functions: FunctionSig[]
459
464
  warnings: string[]
@@ -574,6 +579,12 @@ export interface ContractState {
574
579
  asset: AssetState
575
580
  }
576
581
 
582
+ export interface DebugMessage {
583
+ /** @format address */
584
+ contractAddress: string
585
+ message: string
586
+ }
587
+
577
588
  export interface DecodeUnsignedTx {
578
589
  unsignedTx: string
579
590
  }
@@ -895,6 +906,7 @@ export interface TestContractResult {
895
906
  txInputs: string[]
896
907
  txOutputs: Output[]
897
908
  events: ContractEventByTxId[]
909
+ debugMessages: DebugMessage[]
898
910
  }
899
911
 
900
912
  export interface TestInputAsset {