@qevm/abi 5.7.1 → 5.7.3

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 (62) hide show
  1. package/README.md +3 -4
  2. package/lib/_version.d.ts +1 -1
  3. package/lib/_version.js +1 -1
  4. package/lib/abi-coder.d.ts.map +1 -1
  5. package/lib/abi-coder.js +12 -7
  6. package/lib/abi-coder.js.map +1 -1
  7. package/lib/coders/abstract-coder.d.ts.map +1 -1
  8. package/lib/coders/abstract-coder.js +20 -9
  9. package/lib/coders/abstract-coder.js.map +1 -1
  10. package/lib/coders/address.d.ts.map +1 -1
  11. package/lib/coders/address.js +2 -2
  12. package/lib/coders/address.js.map +1 -1
  13. package/lib/coders/array.d.ts.map +1 -1
  14. package/lib/coders/array.js +17 -11
  15. package/lib/coders/array.js.map +1 -1
  16. package/lib/coders/boolean.d.ts.map +1 -1
  17. package/lib/coders/boolean.js.map +1 -1
  18. package/lib/coders/bytes.js.map +1 -1
  19. package/lib/coders/fixed-bytes.d.ts.map +1 -1
  20. package/lib/coders/fixed-bytes.js +1 -1
  21. package/lib/coders/fixed-bytes.js.map +1 -1
  22. package/lib/coders/function.d.ts +8 -0
  23. package/lib/coders/function.d.ts.map +1 -0
  24. package/lib/coders/function.js +46 -0
  25. package/lib/coders/function.js.map +1 -0
  26. package/lib/coders/null.d.ts.map +1 -1
  27. package/lib/coders/null.js.map +1 -1
  28. package/lib/coders/number.js +1 -1
  29. package/lib/coders/number.js.map +1 -1
  30. package/lib/coders/string.d.ts.map +1 -1
  31. package/lib/coders/string.js +1 -1
  32. package/lib/coders/string.js.map +1 -1
  33. package/lib/coders/tuple.d.ts.map +1 -1
  34. package/lib/coders/tuple.js +1 -1
  35. package/lib/coders/tuple.js.map +1 -1
  36. package/lib/fragments.d.ts.map +1 -1
  37. package/lib/fragments.js +127 -65
  38. package/lib/fragments.js.map +1 -1
  39. package/lib/index.d.ts +1 -1
  40. package/lib/index.d.ts.map +1 -1
  41. package/lib/index.js.map +1 -1
  42. package/lib/interface.d.ts +1 -1
  43. package/lib/interface.d.ts.map +1 -1
  44. package/lib/interface.js +84 -44
  45. package/lib/interface.js.map +1 -1
  46. package/package.json +35 -31
  47. package/src.ts/_version.ts +1 -1
  48. package/src.ts/abi-coder.ts +64 -26
  49. package/src.ts/coders/abstract-coder.ts +78 -33
  50. package/src.ts/coders/address.ts +3 -5
  51. package/src.ts/coders/array.ts +90 -47
  52. package/src.ts/coders/boolean.ts +1 -3
  53. package/src.ts/coders/bytes.ts +1 -3
  54. package/src.ts/coders/fixed-bytes.ts +7 -2
  55. package/src.ts/coders/function.ts +64 -0
  56. package/src.ts/coders/null.ts +4 -3
  57. package/src.ts/coders/number.ts +1 -2
  58. package/src.ts/coders/string.ts +1 -2
  59. package/src.ts/coders/tuple.ts +31 -16
  60. package/src.ts/fragments.ts +411 -178
  61. package/src.ts/index.ts +20 -8
  62. package/src.ts/interface.ts +405 -153
@@ -1,50 +1,64 @@
1
1
  "use strict";
2
2
 
3
- import { Logger } from "@ethersproject/logger";
3
+ import { Logger } from "@qevm/logger";
4
4
  import { version } from "../_version";
5
5
  const logger = new Logger(version);
6
6
 
7
7
  import { Coder, Reader, Result, Writer } from "./abstract-coder";
8
8
  import { AnonymousCoder } from "./anonymous";
9
9
 
10
- export function pack(writer: Writer, coders: ReadonlyArray<Coder>, values: Array<any> | { [ name: string ]: any }): number {
10
+ export function pack(
11
+ writer: Writer,
12
+ coders: ReadonlyArray<Coder>,
13
+ values: Array<any> | { [name: string]: any },
14
+ ): number {
11
15
  let arrayValues: Array<any> = null;
12
16
 
13
17
  if (Array.isArray(values)) {
14
- arrayValues = values;
15
-
16
- } else if (values && typeof(values) === "object") {
17
- let unique: { [ name: string ]: boolean } = { };
18
+ arrayValues = values;
19
+ } else if (values && typeof values === "object") {
20
+ let unique: { [name: string]: boolean } = {};
18
21
 
19
22
  arrayValues = coders.map((coder) => {
20
23
  const name = coder.localName;
21
24
  if (!name) {
22
- logger.throwError("cannot encode object for signature with missing names", Logger.errors.INVALID_ARGUMENT, {
23
- argument: "values",
24
- coder: coder,
25
- value: values
26
- });
25
+ logger.throwError(
26
+ "cannot encode object for signature with missing names",
27
+ Logger.errors.INVALID_ARGUMENT,
28
+ {
29
+ argument: "values",
30
+ coder: coder,
31
+ value: values,
32
+ },
33
+ );
27
34
  }
28
35
 
29
36
  if (unique[name]) {
30
- logger.throwError("cannot encode object for signature with duplicate names", Logger.errors.INVALID_ARGUMENT, {
31
- argument: "values",
32
- coder: coder,
33
- value: values
34
- });
37
+ logger.throwError(
38
+ "cannot encode object for signature with duplicate names",
39
+ Logger.errors.INVALID_ARGUMENT,
40
+ {
41
+ argument: "values",
42
+ coder: coder,
43
+ value: values,
44
+ },
45
+ );
35
46
  }
36
47
 
37
48
  unique[name] = true;
38
49
 
39
50
  return values[name];
40
51
  });
41
-
42
52
  } else {
43
53
  logger.throwArgumentError("invalid tuple value", "tuple", values);
44
54
  }
45
55
 
46
56
  if (coders.length !== arrayValues.length) {
47
- logger.throwArgumentError("types/value length mismatch", "tuple", values);
57
+ logger.throwArgumentError(
58
+ "types/value length mismatch",
59
+ "tuple",
60
+ values,
61
+ );
48
62
  }
49
63
 
50
64
  let staticWriter = new Writer(writer.wordSize);
@@ -66,14 +80,15 @@ export function pack(writer: Writer, coders: ReadonlyArray<Coder>, values: Array
66
80
  updateFuncs.push((baseOffset: number) => {
67
81
  updateFunc(baseOffset + dynamicOffset);
68
82
  });
69
-
70
83
  } else {
71
84
  coder.encode(staticWriter, value);
72
85
  }
73
86
  });
74
87
 
75
88
  // Backfill all the dynamic offsets, now that we know the static length
76
- updateFuncs.forEach((func) => { func(staticWriter.length); });
89
+ updateFuncs.forEach((func) => {
90
+ func(staticWriter.length);
91
+ });
77
92
 
78
93
  let length = writer.appendWriter(staticWriter);
79
94
  length += writer.appendWriter(dynamicWriter);
@@ -96,19 +111,22 @@ export function unpack(reader: Reader, coders: Array<Coder>): Result {
96
111
  value = coder.decode(offsetReader);
97
112
  } catch (error) {
98
113
  // Cannot recover from this
99
- if (error.code === Logger.errors.BUFFER_OVERRUN) { throw error; }
114
+ if (error.code === Logger.errors.BUFFER_OVERRUN) {
115
+ throw error;
116
+ }
100
117
  value = error;
101
118
  value.baseType = coder.name;
102
119
  value.name = coder.localName;
103
120
  value.type = coder.type;
104
121
  }
105
-
106
122
  } else {
107
123
  try {
108
124
  value = coder.decode(reader);
109
125
  } catch (error) {
110
126
  // Cannot recover from this
111
- if (error.code === Logger.errors.BUFFER_OVERRUN) { throw error; }
127
+ if (error.code === Logger.errors.BUFFER_OVERRUN) {
128
+ throw error;
129
+ }
112
130
  value = error;
113
131
  value.baseType = coder.name;
114
132
  value.name = coder.localName;
@@ -122,30 +140,43 @@ export function unpack(reader: Reader, coders: Array<Coder>): Result {
122
140
  });
123
141
 
124
142
  // We only output named properties for uniquely named coders
125
- const uniqueNames = coders.reduce((accum, coder) => {
126
- const name = coder.localName;
127
- if (name) {
128
- if (!accum[name]) { accum[name] = 0; }
129
- accum[name]++;
130
- }
131
- return accum;
132
- }, <{ [ name: string ]: number }>{ });
143
+ const uniqueNames = coders.reduce(
144
+ (accum, coder) => {
145
+ const name = coder.localName;
146
+ if (name) {
147
+ if (!accum[name]) {
148
+ accum[name] = 0;
149
+ }
150
+ accum[name]++;
151
+ }
152
+ return accum;
153
+ },
154
+ <{ [name: string]: number }>{},
155
+ );
133
156
 
134
157
  // Add any named parameters (i.e. tuples)
135
158
  coders.forEach((coder: Coder, index: number) => {
136
159
  let name = coder.localName;
137
- if (!name || uniqueNames[name] !== 1) { return; }
160
+ if (!name || uniqueNames[name] !== 1) {
161
+ return;
162
+ }
138
163
 
139
- if (name === "length") { name = "_length"; }
164
+ if (name === "length") {
165
+ name = "_length";
166
+ }
140
167
 
141
- if (values[name] != null) { return; }
168
+ if (values[name] != null) {
169
+ return;
170
+ }
142
171
 
143
172
  const value = values[index];
144
173
 
145
174
  if (value instanceof Error) {
146
175
  Object.defineProperty(values, name, {
147
176
  enumerable: true,
148
- get: () => { throw value; }
177
+ get: () => {
178
+ throw value;
179
+ },
149
180
  });
150
181
  } else {
151
182
  values[name] = value;
@@ -157,7 +188,9 @@ export function unpack(reader: Reader, coders: Array<Coder>): Result {
157
188
  if (value instanceof Error) {
158
189
  Object.defineProperty(values, i, {
159
190
  enumerable: true,
160
- get: () => { throw value; }
191
+ get: () => {
192
+ throw value;
193
+ },
161
194
  });
162
195
  }
163
196
  }
@@ -165,14 +198,13 @@ export function unpack(reader: Reader, coders: Array<Coder>): Result {
165
198
  return Object.freeze(values);
166
199
  }
167
200
 
168
-
169
201
  export class ArrayCoder extends Coder {
170
202
  readonly coder: Coder;
171
203
  readonly length: number;
172
204
 
173
205
  constructor(coder: Coder, length: number, localName: string) {
174
- const type = (coder.type + "[" + (length >= 0 ? length: "") + "]");
175
- const dynamic = (length === -1 || coder.dynamic);
206
+ const type = coder.type + "[" + (length >= 0 ? length : "") + "]";
207
+ const dynamic = length === -1 || coder.dynamic;
176
208
  super("array", type, localName, dynamic);
177
209
 
178
210
  this.coder = coder;
@@ -202,10 +234,16 @@ export class ArrayCoder extends Coder {
202
234
  writer.writeValue(value.length);
203
235
  }
204
236
 
205
- logger.checkArgumentCount(value.length, count, "coder array" + (this.localName? (" "+ this.localName): ""));
237
+ logger.checkArgumentCount(
238
+ value.length,
239
+ count,
240
+ "coder array" + (this.localName ? " " + this.localName : ""),
241
+ );
206
242
 
207
243
  let coders = [];
208
- for (let i = 0; i < value.length; i++) { coders.push(this.coder); }
244
+ for (let i = 0; i < value.length; i++) {
245
+ coders.push(this.coder);
246
+ }
209
247
 
210
248
  return pack(writer, coders, value);
211
249
  }
@@ -221,16 +259,21 @@ export class ArrayCoder extends Coder {
221
259
  // bytes as a link to the data). This could use a much
222
260
  // tighter bound, but we are erroring on the side of safety.
223
261
  if (count * 32 > reader._data.length) {
224
- logger.throwError("insufficient data length", Logger.errors.BUFFER_OVERRUN, {
225
- length: reader._data.length,
226
- count: count
227
- });
262
+ logger.throwError(
263
+ "insufficient data length",
264
+ Logger.errors.BUFFER_OVERRUN,
265
+ {
266
+ length: reader._data.length,
267
+ count: count,
268
+ },
269
+ );
228
270
  }
229
271
  }
230
272
  let coders = [];
231
- for (let i = 0; i < count; i++) { coders.push(new AnonymousCoder(this.coder)); }
273
+ for (let i = 0; i < count; i++) {
274
+ coders.push(new AnonymousCoder(this.coder));
275
+ }
232
276
 
233
277
  return reader.coerce(this.name, unpack(reader, coders));
234
278
  }
235
279
  }
236
-
@@ -3,7 +3,6 @@
3
3
  import { Coder, Reader, Writer } from "./abstract-coder";
4
4
 
5
5
  export class BooleanCoder extends Coder {
6
-
7
6
  constructor(localName: string) {
8
7
  super("bool", "bool", localName, false);
9
8
  }
@@ -13,11 +12,10 @@ export class BooleanCoder extends Coder {
13
12
  }
14
13
 
15
14
  encode(writer: Writer, value: boolean): number {
16
- return writer.writeValue(value ? 1: 0);
15
+ return writer.writeValue(value ? 1 : 0);
17
16
  }
18
17
 
19
18
  decode(reader: Reader): any {
20
19
  return reader.coerce(this.type, !reader.readValue().isZero());
21
20
  }
22
21
  }
23
-
@@ -6,7 +6,7 @@ import { Coder, Reader, Writer } from "./abstract-coder";
6
6
 
7
7
  export class DynamicBytesCoder extends Coder {
8
8
  constructor(type: string, localName: string) {
9
- super(type, type, localName, true);
9
+ super(type, type, localName, true);
10
10
  }
11
11
 
12
12
  defaultValue(): string {
@@ -34,5 +34,3 @@ export class BytesCoder extends DynamicBytesCoder {
34
34
  return reader.coerce(this.name, hexlify(super.decode(reader)));
35
35
  }
36
36
  }
37
-
38
-
@@ -15,12 +15,17 @@ export class FixedBytesCoder extends Coder {
15
15
  }
16
16
 
17
17
  defaultValue(): string {
18
- return ("0x0000000000000000000000000000000000000000000000000000000000000000").substring(0, 2 + this.size * 2);
18
+ return "0x0000000000000000000000000000000000000000000000000000000000000000".substring(
19
+ 0,
20
+ 2 + this.size * 2,
21
+ );
19
22
  }
20
23
 
21
24
  encode(writer: Writer, value: BytesLike): number {
22
25
  let data = arrayify(value);
23
- if (data.length !== this.size) { this._throwError("incorrect data length", value); }
26
+ if (data.length !== this.size) {
27
+ this._throwError("incorrect data length", value);
28
+ }
24
29
  return writer.writeBytes(data);
25
30
  }
26
31
 
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+
3
+ import { hexZeroPad } from "@qevm/bytes";
4
+ import { getAddress } from "@qevm/address";
5
+
6
+ import { Coder, Reader, Writer } from "./abstract-coder";
7
+
8
+ export class FunctionCoder extends Coder {
9
+ constructor(localName: string) {
10
+ // type "function" is NOT dynamic, occupies 64 bytes (2 words)
11
+ super("function", "function", localName, false);
12
+ }
13
+
14
+ defaultValue(): string {
15
+ // 32-byte zero address + 4-byte zero selector = 72 hex chars
16
+ return "0x" + "00".repeat(32) + "00000000";
17
+ }
18
+
19
+ encode(writer: Writer, value: string): number {
20
+ // Expected format: "0x" + 64 hex (address) + 8 hex (selector)
21
+ // Total: 74 chars including "0x"
22
+ let hex = value;
23
+ if (hex.startsWith("0x")) {
24
+ hex = hex.substring(2);
25
+ }
26
+
27
+ if (hex.length !== 72) {
28
+ this._throwError(
29
+ "invalid function value (expected 72 hex chars after 0x)",
30
+ value,
31
+ );
32
+ }
33
+
34
+ const addressHex = "0x" + hex.substring(0, 64);
35
+ const selectorHex = "0x" + hex.substring(64, 72);
36
+
37
+ // Validate address
38
+ getAddress(addressHex);
39
+
40
+ // Word 0: full 32-byte address (right-aligned = as uint256)
41
+ writer.writeValue(addressHex);
42
+
43
+ // Word 1: 4-byte selector right-aligned in 32-byte word
44
+ writer.writeValue(selectorHex);
45
+
46
+ return writer.length;
47
+ }
48
+
49
+ decode(reader: Reader): any {
50
+ // Read 2 words (64 bytes)
51
+ const addressValue = reader.readValue(); // word 0: address
52
+ const selectorValue = reader.readValue(); // word 1: selector (masked to 4 bytes)
53
+
54
+ const addressHex = hexZeroPad(addressValue.toHexString(), 32).substring(
55
+ 2,
56
+ ); // 64 hex chars
57
+ const selectorHex = hexZeroPad(
58
+ selectorValue.mask(32).toHexString(),
59
+ 4,
60
+ ).substring(2); // 8 hex chars
61
+
62
+ return reader.coerce(this.name, "0x" + addressHex + selectorHex);
63
+ }
64
+ }
@@ -3,7 +3,6 @@
3
3
  import { Coder, Reader, Writer } from "./abstract-coder";
4
4
 
5
5
  export class NullCoder extends Coder {
6
-
7
6
  constructor(localName: string) {
8
7
  super("null", "", localName, false);
9
8
  }
@@ -13,8 +12,10 @@ export class NullCoder extends Coder {
13
12
  }
14
13
 
15
14
  encode(writer: Writer, value: any): number {
16
- if (value != null) { this._throwError("not null", value); }
17
- return writer.writeBytes([ ]);
15
+ if (value != null) {
16
+ this._throwError("not null", value);
17
+ }
18
+ return writer.writeBytes([]);
18
19
  }
19
20
 
20
21
  decode(reader: Reader): any {
@@ -10,7 +10,7 @@ export class NumberCoder extends Coder {
10
10
  readonly signed: boolean;
11
11
 
12
12
  constructor(size: number, signed: boolean, localName: string) {
13
- const name = ((signed ? "int": "uint") + (size * 8));
13
+ const name = (signed ? "int" : "uint") + size * 8;
14
14
  super(name, name, localName, false);
15
15
 
16
16
  this.size = size;
@@ -54,4 +54,3 @@ export class NumberCoder extends Coder {
54
54
  return reader.coerce(this.name, value);
55
55
  }
56
56
  }
57
-
@@ -1,12 +1,11 @@
1
1
  "use strict";
2
2
 
3
- import { toUtf8Bytes, toUtf8String } from "@ethersproject/strings";
3
+ import { toUtf8Bytes, toUtf8String } from "@qevm/strings";
4
4
 
5
5
  import { Reader, Writer } from "./abstract-coder";
6
6
  import { DynamicBytesCoder } from "./bytes";
7
7
 
8
8
  export class StringCoder extends DynamicBytesCoder {
9
-
10
9
  constructor(localName: string) {
11
10
  super("string", localName);
12
11
  }
@@ -10,39 +10,52 @@ export class TupleCoder extends Coder {
10
10
  let dynamic = false;
11
11
  const types: Array<string> = [];
12
12
  coders.forEach((coder) => {
13
- if (coder.dynamic) { dynamic = true; }
13
+ if (coder.dynamic) {
14
+ dynamic = true;
15
+ }
14
16
  types.push(coder.type);
15
17
  });
16
- const type = ("tuple(" + types.join(",") + ")");
18
+ const type = "tuple(" + types.join(",") + ")";
17
19
 
18
20
  super("tuple", type, localName, dynamic);
19
21
  this.coders = coders;
20
22
  }
21
23
 
22
24
  defaultValue(): any {
23
- const values: any = [ ];
25
+ const values: any = [];
24
26
  this.coders.forEach((coder) => {
25
27
  values.push(coder.defaultValue());
26
28
  });
27
29
 
28
30
  // We only output named properties for uniquely named coders
29
- const uniqueNames = this.coders.reduce((accum, coder) => {
30
- const name = coder.localName;
31
- if (name) {
32
- if (!accum[name]) { accum[name] = 0; }
33
- accum[name]++;
34
- }
35
- return accum;
36
- }, <{ [ name: string ]: number }>{ });
31
+ const uniqueNames = this.coders.reduce(
32
+ (accum, coder) => {
33
+ const name = coder.localName;
34
+ if (name) {
35
+ if (!accum[name]) {
36
+ accum[name] = 0;
37
+ }
38
+ accum[name]++;
39
+ }
40
+ return accum;
41
+ },
42
+ <{ [name: string]: number }>{},
43
+ );
37
44
 
38
45
  // Add named values
39
46
  this.coders.forEach((coder: Coder, index: number) => {
40
47
  let name = coder.localName;
41
- if (!name || uniqueNames[name] !== 1) { return; }
48
+ if (!name || uniqueNames[name] !== 1) {
49
+ return;
50
+ }
42
51
 
43
- if (name === "length") { name = "_length"; }
52
+ if (name === "length") {
53
+ name = "_length";
54
+ }
44
55
 
45
- if (values[name] != null) { return; }
56
+ if (values[name] != null) {
57
+ return;
58
+ }
46
59
 
47
60
  values[name] = values[index];
48
61
  });
@@ -50,7 +63,10 @@ export class TupleCoder extends Coder {
50
63
  return Object.freeze(values);
51
64
  }
52
65
 
53
- encode(writer: Writer, value: Array<any> | { [ name: string ]: any }): number {
66
+ encode(
67
+ writer: Writer,
68
+ value: Array<any> | { [name: string]: any },
69
+ ): number {
54
70
  return pack(writer, this.coders, value);
55
71
  }
56
72
 
@@ -58,4 +74,3 @@ export class TupleCoder extends Coder {
58
74
  return reader.coerce(this.name, unpack(reader, this.coders));
59
75
  }
60
76
  }
61
-