@alephium/web3 0.31.1 → 0.32.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.
@@ -995,7 +995,7 @@ export declare class HttpClient<SecurityDataType = unknown> {
995
995
  }
996
996
  /**
997
997
  * @title Alephium API
998
- * @version 2.8.5
998
+ * @version 2.9.0
999
999
  * @baseUrl ../
1000
1000
  */
1001
1001
  export declare class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDataType> {
@@ -151,7 +151,7 @@ class HttpClient {
151
151
  exports.HttpClient = HttpClient;
152
152
  /**
153
153
  * @title Alephium API
154
- * @version 2.8.5
154
+ * @version 2.9.0
155
155
  * @baseUrl ../
156
156
  */
157
157
  class Api extends HttpClient {
@@ -90,7 +90,7 @@ class NodeProvider {
90
90
  }
91
91
  else {
92
92
  const failedCollectionIndexResult = result.results[1];
93
- if (failedCollectionIndexResult.error.startsWith('VM execution error: InvalidMethodIndex')) {
93
+ if (failedCollectionIndexResult.error.startsWith('VM execution error: Invalid method index')) {
94
94
  throw new Error('Deprecated NFT contract');
95
95
  }
96
96
  else {
@@ -221,6 +221,22 @@ class ProjectArtifact {
221
221
  }
222
222
  exports.ProjectArtifact = ProjectArtifact;
223
223
  ProjectArtifact.artifactFileName = '.project.json';
224
+ function removeOldArtifacts(dir) {
225
+ const files = fs_1.default.readdirSync(dir);
226
+ files.forEach((file) => {
227
+ const filePath = path.join(dir, file);
228
+ const stat = fs_1.default.statSync(filePath);
229
+ if (stat.isDirectory()) {
230
+ removeOldArtifacts(filePath);
231
+ }
232
+ else if (filePath.endsWith('.ral.json') || filePath.endsWith('.ral')) {
233
+ fs_1.default.unlinkSync(filePath);
234
+ }
235
+ });
236
+ if (fs_1.default.readdirSync(dir).length === 0) {
237
+ fs_1.default.rmdirSync(dir);
238
+ }
239
+ }
224
240
  class Project {
225
241
  static buildProjectArtifact(fullNodeVersion, sourceInfos, contracts, scripts, compilerOptions) {
226
242
  const files = new Map();
@@ -491,6 +507,9 @@ class Project {
491
507
  const projectArtifact = await ProjectArtifact.from(projectRootDir);
492
508
  if (projectArtifact === undefined ||
493
509
  projectArtifact.needToReCompile(nodeCompilerOptions, sourceFiles, fullNodeVersion)) {
510
+ if (fs_1.default.existsSync(artifactsRootDir)) {
511
+ removeOldArtifacts(artifactsRootDir);
512
+ }
494
513
  console.log(`Compiling contracts in folder "${contractsRootDir}"`);
495
514
  Project.currentProject = await Project.compile(fullNodeVersion, provider, sourceFiles, projectRootDir, contractsRootDir, artifactsRootDir, errorOnWarnings, nodeCompilerOptions);
496
515
  }
@@ -7,6 +7,11 @@ export declare function encodeByteVec(bytes: string): Uint8Array;
7
7
  export declare function encodeAddress(address: string): Uint8Array;
8
8
  export declare function encodeScriptFieldAsString(tpe: string, value: Val): string;
9
9
  export declare function encodeScriptField(tpe: string, value: Val): Uint8Array;
10
+ export declare function falttenFields(fields: Fields, fieldsSig: FieldsSig): {
11
+ name: string;
12
+ type: string;
13
+ value: Val;
14
+ }[];
10
15
  export declare function buildScriptByteCode(bytecodeTemplate: string, fields: Fields, fieldsSig: FieldsSig): string;
11
16
  export declare function buildContractByteCode(bytecode: string, fields: Fields, fieldsSig: FieldsSig): string;
12
17
  export declare function encodeContractField(tpe: string, value: Val): Uint8Array[];
@@ -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.buildDebugBytecode = 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.falttenFields = 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 api_1 = require("../api");
24
24
  const utils_1 = require("../utils");
@@ -201,7 +201,6 @@ function encodeScriptFieldAsString(tpe, value) {
201
201
  return buffer_1.Buffer.from(encodeScriptField(tpe, value)).toString('hex');
202
202
  }
203
203
  exports.encodeScriptFieldAsString = encodeScriptFieldAsString;
204
- // TODO: support array type
205
204
  function encodeScriptField(tpe, value) {
206
205
  switch (tpe) {
207
206
  case 'Bool':
@@ -223,20 +222,53 @@ function encodeScriptField(tpe, value) {
223
222
  throw invalidScriptField(tpe, value);
224
223
  }
225
224
  exports.encodeScriptField = encodeScriptField;
226
- const scriptFieldRegex = /\{([0-9]*)\}/g;
227
- function buildScriptByteCode(bytecodeTemplate, fields, fieldsSig) {
228
- return bytecodeTemplate.replace(scriptFieldRegex, (_, fieldIndex) => {
229
- const fieldName = fieldsSig.names[`${fieldIndex}`];
230
- const fieldType = fieldsSig.types[`${fieldIndex}`];
231
- if (fieldName in fields) {
232
- const fieldValue = fields[`${fieldName}`];
233
- return _encodeField(fieldName, () => encodeScriptFieldAsString(fieldType, fieldValue));
225
+ function flattenArray(name, type, val, acc) {
226
+ const semiColonIndex = type.lastIndexOf(';');
227
+ if (semiColonIndex == -1) {
228
+ throw new Error(`Invalid array type: ${type}`);
229
+ }
230
+ const subType = type.slice(1, semiColonIndex);
231
+ val.forEach((v, index) => {
232
+ const isArrayType = subType.includes(';');
233
+ const isArrayValue = Array.isArray(v);
234
+ if (isArrayType && isArrayValue) {
235
+ flattenArray(`${name}[${index}]`, subType, v, acc);
236
+ }
237
+ else if (!isArrayType && !isArrayValue) {
238
+ acc.push({ name: `${name}[${index}]`, type: subType, value: v });
234
239
  }
235
240
  else {
236
- throw new Error(`The value of field ${fieldName} is not provided`);
241
+ const value = isArrayValue ? `[` + v.join(', ') + `]` : v.toString();
242
+ throw new Error(`Invalid field, expected type is ${subType}, but value is ${value}`);
237
243
  }
238
244
  });
239
245
  }
246
+ function falttenFields(fields, fieldsSig) {
247
+ const allFields = [];
248
+ fieldsSig.names.forEach((name, index) => {
249
+ const field = fields[`${name}`];
250
+ if (!(name in fields)) {
251
+ throw new Error(`The value of field ${name} is not provided`);
252
+ }
253
+ const type = fieldsSig.types[`${index}`];
254
+ if (Array.isArray(field)) {
255
+ flattenArray(name, type, field, allFields);
256
+ }
257
+ else {
258
+ allFields.push({ name, type, value: field });
259
+ }
260
+ });
261
+ return allFields;
262
+ }
263
+ exports.falttenFields = falttenFields;
264
+ const scriptFieldRegex = /\{([0-9]*)\}/g;
265
+ function buildScriptByteCode(bytecodeTemplate, fields, fieldsSig) {
266
+ const allFields = falttenFields(fields, fieldsSig);
267
+ return bytecodeTemplate.replace(scriptFieldRegex, (_, fieldIndex) => {
268
+ const field = allFields[`${fieldIndex}`];
269
+ return _encodeField(field.name, () => encodeScriptFieldAsString(field.type, field.value));
270
+ });
271
+ }
240
272
  exports.buildScriptByteCode = buildScriptByteCode;
241
273
  function _encodeField(fieldName, encodeFunc) {
242
274
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alephium/web3",
3
- "version": "0.31.1",
3
+ "version": "0.32.0",
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,7 +27,7 @@
27
27
  },
28
28
  "author": "Alephium dev <dev@alephium.org>",
29
29
  "config": {
30
- "alephium_version": "2.8.5",
30
+ "alephium_version": "2.9.0",
31
31
  "explorer_backend_version": "1.16.1"
32
32
  },
33
33
  "type": "commonjs",
@@ -1292,7 +1292,7 @@ export class HttpClient<SecurityDataType = unknown> {
1292
1292
 
1293
1293
  /**
1294
1294
  * @title Alephium API
1295
- * @version 2.8.5
1295
+ * @version 2.9.0
1296
1296
  * @baseUrl ../
1297
1297
  */
1298
1298
  export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDataType> {
@@ -173,7 +173,7 @@ export class NodeProvider implements NodeProviderApis {
173
173
  return { tokenUri, collectionId, nftIndex }
174
174
  } else {
175
175
  const failedCollectionIndexResult = result.results[1] as CallContractFailed
176
- if (failedCollectionIndexResult.error.startsWith('VM execution error: InvalidMethodIndex')) {
176
+ if (failedCollectionIndexResult.error.startsWith('VM execution error: Invalid method index')) {
177
177
  throw new Error('Deprecated NFT contract')
178
178
  } else {
179
179
  throw new Error(`Failed to call contract, error: ${failedCollectionIndexResult.error}`)
@@ -309,6 +309,23 @@ export class ProjectArtifact {
309
309
  }
310
310
  }
311
311
 
312
+ function removeOldArtifacts(dir: string) {
313
+ const files = fs.readdirSync(dir)
314
+ files.forEach((file) => {
315
+ const filePath = path.join(dir, file)
316
+ const stat = fs.statSync(filePath)
317
+ if (stat.isDirectory()) {
318
+ removeOldArtifacts(filePath)
319
+ } else if (filePath.endsWith('.ral.json') || filePath.endsWith('.ral')) {
320
+ fs.unlinkSync(filePath)
321
+ }
322
+ })
323
+
324
+ if (fs.readdirSync(dir).length === 0) {
325
+ fs.rmdirSync(dir)
326
+ }
327
+ }
328
+
312
329
  export class Project {
313
330
  sourceInfos: SourceInfo[]
314
331
  contracts: Map<string, Compiled<Contract>>
@@ -731,6 +748,9 @@ export class Project {
731
748
  projectArtifact === undefined ||
732
749
  projectArtifact.needToReCompile(nodeCompilerOptions, sourceFiles, fullNodeVersion)
733
750
  ) {
751
+ if (fs.existsSync(artifactsRootDir)) {
752
+ removeOldArtifacts(artifactsRootDir)
753
+ }
734
754
  console.log(`Compiling contracts in folder "${contractsRootDir}"`)
735
755
  Project.currentProject = await Project.compile(
736
756
  fullNodeVersion,
@@ -197,7 +197,6 @@ export function encodeScriptFieldAsString(tpe: string, value: Val): string {
197
197
  return Buffer.from(encodeScriptField(tpe, value)).toString('hex')
198
198
  }
199
199
 
200
- // TODO: support array type
201
200
  export function encodeScriptField(tpe: string, value: Val): Uint8Array {
202
201
  switch (tpe) {
203
202
  case 'Bool':
@@ -220,18 +219,50 @@ export function encodeScriptField(tpe: string, value: Val): Uint8Array {
220
219
  throw invalidScriptField(tpe, value)
221
220
  }
222
221
 
222
+ function flattenArray(name: string, type: string, val: Val[], acc: { name: string; type: string; value: Val }[]) {
223
+ const semiColonIndex = type.lastIndexOf(';')
224
+ if (semiColonIndex == -1) {
225
+ throw new Error(`Invalid array type: ${type}`)
226
+ }
227
+ const subType = type.slice(1, semiColonIndex)
228
+ val.forEach((v, index) => {
229
+ const isArrayType = subType.includes(';')
230
+ const isArrayValue = Array.isArray(v)
231
+ if (isArrayType && isArrayValue) {
232
+ flattenArray(`${name}[${index}]`, subType, v, acc)
233
+ } else if (!isArrayType && !isArrayValue) {
234
+ acc.push({ name: `${name}[${index}]`, type: subType, value: v })
235
+ } else {
236
+ const value = isArrayValue ? `[` + v.join(', ') + `]` : v.toString()
237
+ throw new Error(`Invalid field, expected type is ${subType}, but value is ${value}`)
238
+ }
239
+ })
240
+ }
241
+
242
+ export function falttenFields(fields: Fields, fieldsSig: FieldsSig): { name: string; type: string; value: Val }[] {
243
+ const allFields: { name: string; type: string; value: Val }[] = []
244
+ fieldsSig.names.forEach((name, index) => {
245
+ const field = fields[`${name}`]
246
+ if (!(name in fields)) {
247
+ throw new Error(`The value of field ${name} is not provided`)
248
+ }
249
+ const type = fieldsSig.types[`${index}`]
250
+ if (Array.isArray(field)) {
251
+ flattenArray(name, type, field, allFields)
252
+ } else {
253
+ allFields.push({ name, type, value: field })
254
+ }
255
+ })
256
+ return allFields
257
+ }
258
+
223
259
  const scriptFieldRegex = /\{([0-9]*)\}/g
224
260
 
225
261
  export function buildScriptByteCode(bytecodeTemplate: string, fields: Fields, fieldsSig: FieldsSig): string {
262
+ const allFields = falttenFields(fields, fieldsSig)
226
263
  return bytecodeTemplate.replace(scriptFieldRegex, (_, fieldIndex: string) => {
227
- const fieldName = fieldsSig.names[`${fieldIndex}`]
228
- const fieldType = fieldsSig.types[`${fieldIndex}`]
229
- if (fieldName in fields) {
230
- const fieldValue = fields[`${fieldName}`]
231
- return _encodeField(fieldName, () => encodeScriptFieldAsString(fieldType, fieldValue))
232
- } else {
233
- throw new Error(`The value of field ${fieldName} is not provided`)
234
- }
264
+ const field = allFields[`${fieldIndex}`]
265
+ return _encodeField(field.name, () => encodeScriptFieldAsString(field.type, field.value))
235
266
  })
236
267
  }
237
268