@subsquid/evm-codec 0.2.1 → 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 (79) hide show
  1. package/lib/codec.d.ts +59 -12
  2. package/lib/codec.d.ts.map +1 -1
  3. package/lib/codec.js.map +1 -1
  4. package/lib/codecs/array.d.ts +3 -3
  5. package/lib/codecs/array.d.ts.map +1 -1
  6. package/lib/codecs/array.js +13 -7
  7. package/lib/codecs/array.js.map +1 -1
  8. package/lib/codecs/primitives.d.ts +2 -16
  9. package/lib/codecs/primitives.d.ts.map +1 -1
  10. package/lib/codecs/primitives.js +52 -141
  11. package/lib/codecs/primitives.js.map +1 -1
  12. package/lib/codecs/struct.d.ts +17 -9
  13. package/lib/codecs/struct.d.ts.map +1 -1
  14. package/lib/codecs/struct.js +53 -39
  15. package/lib/codecs/struct.js.map +1 -1
  16. package/lib/dsl.d.ts +11 -0
  17. package/lib/dsl.d.ts.map +1 -0
  18. package/lib/dsl.js +33 -0
  19. package/lib/dsl.js.map +1 -0
  20. package/lib/index.d.ts +7 -4
  21. package/lib/index.d.ts.map +1 -1
  22. package/lib/index.js +7 -6
  23. package/lib/index.js.map +1 -1
  24. package/lib/sink/bounds.d.ts +21 -0
  25. package/lib/sink/bounds.d.ts.map +1 -0
  26. package/lib/sink/bounds.js +24 -0
  27. package/lib/sink/bounds.js.map +1 -0
  28. package/lib/sink/bytes.d.ts +41 -0
  29. package/lib/sink/bytes.d.ts.map +1 -0
  30. package/lib/sink/bytes.js +261 -0
  31. package/lib/sink/bytes.js.map +1 -0
  32. package/lib/sink/hex.d.ts +33 -0
  33. package/lib/sink/hex.d.ts.map +1 -0
  34. package/lib/sink/hex.js +289 -0
  35. package/lib/sink/hex.js.map +1 -0
  36. package/lib/{src.d.ts → src/bytes.d.ts} +7 -5
  37. package/lib/src/bytes.d.ts.map +1 -0
  38. package/lib/src/bytes.js +161 -0
  39. package/lib/src/bytes.js.map +1 -0
  40. package/lib/src/hex.d.ts +33 -0
  41. package/lib/src/hex.d.ts.map +1 -0
  42. package/lib/src/hex.js +164 -0
  43. package/lib/src/hex.js.map +1 -0
  44. package/lib/util.d.ts +6 -0
  45. package/lib/util.d.ts.map +1 -0
  46. package/lib/util.js +20 -0
  47. package/lib/util.js.map +1 -0
  48. package/package.json +6 -8
  49. package/src/codec.ts +67 -18
  50. package/src/codecs/array.test.ts +87 -0
  51. package/src/codecs/array.ts +9 -12
  52. package/src/codecs/primitives.test.ts +27 -0
  53. package/src/codecs/primitives.ts +87 -191
  54. package/src/codecs/struct.test.ts +69 -0
  55. package/src/codecs/struct.ts +80 -60
  56. package/src/dsl.ts +16 -0
  57. package/src/index.ts +7 -4
  58. package/src/sink/bounds.ts +26 -0
  59. package/src/sink/bytes.test.ts +92 -0
  60. package/src/sink/bytes.ts +290 -0
  61. package/src/sink/hex.ts +311 -0
  62. package/src/src/bytes.test.ts +114 -0
  63. package/src/src/bytes.ts +187 -0
  64. package/src/src/hex.ts +191 -0
  65. package/src/util.ts +19 -0
  66. package/lib/safeToNumber.d.ts +0 -2
  67. package/lib/safeToNumber.d.ts.map +0 -1
  68. package/lib/safeToNumber.js +0 -11
  69. package/lib/safeToNumber.js.map +0 -1
  70. package/lib/sink.d.ts +0 -43
  71. package/lib/sink.d.ts.map +0 -1
  72. package/lib/sink.js +0 -215
  73. package/lib/sink.js.map +0 -1
  74. package/lib/src.d.ts.map +0 -1
  75. package/lib/src.js +0 -141
  76. package/lib/src.js.map +0 -1
  77. package/src/safeToNumber.ts +0 -6
  78. package/src/sink.ts +0 -241
  79. package/src/src.ts +0 -158
@@ -0,0 +1,187 @@
1
+ import {WORD_SIZE, type Src} from '../codec'
2
+ import {toHex} from '@subsquid/util-internal-hex'
3
+
4
+ const I64_SIGN_BIT = 1n << 63n
5
+ const I64_RANGE = 1n << 64n
6
+ const I128_SIGN_BIT = 1n << 127n
7
+ const I128_RANGE = 1n << 128n
8
+ const I256_SIGN_BIT = 1n << 255n
9
+ const I256_RANGE = 1n << 256n
10
+
11
+ const TEXT_DECODER = new TextDecoder('utf-8')
12
+
13
+ export class BytesSrc implements Src {
14
+ private view: DataView
15
+ private pos = 0
16
+ private oldPos = 0
17
+
18
+ constructor(private buf: Uint8Array) {
19
+ this.view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength)
20
+ }
21
+
22
+ slice(start: number, end?: number): BytesSrc {
23
+ return new BytesSrc(this.buf.subarray(start, end))
24
+ }
25
+
26
+ u8(): number {
27
+ this.pos += WORD_SIZE - 1
28
+ let val = this.view.getUint8(this.pos)
29
+ this.pos += 1
30
+ return val
31
+ }
32
+
33
+ i8(): number {
34
+ return Number(this.i256())
35
+ }
36
+
37
+ u16(): number {
38
+ this.pos += WORD_SIZE - 2
39
+ let val = this.view.getUint16(this.pos, false)
40
+ this.pos += 2
41
+ return val
42
+ }
43
+
44
+ i16(): number {
45
+ return Number(this.i256())
46
+ }
47
+
48
+ u32(): number {
49
+ this.pos += WORD_SIZE - 4
50
+ let val = this.view.getUint32(this.pos, false)
51
+ this.pos += 4
52
+ return val
53
+ }
54
+
55
+ i32(): number {
56
+ return Number(this.i256())
57
+ }
58
+
59
+ u64(): bigint {
60
+ this.pos += WORD_SIZE - 8
61
+ return this.#u64()
62
+ }
63
+
64
+ #u64(): bigint {
65
+ let val = this.view.getBigUint64(this.pos, false)
66
+ this.pos += 8
67
+ return val
68
+ }
69
+
70
+ i64(): bigint {
71
+ this.pos += WORD_SIZE - 8
72
+ const raw = this.#u64()
73
+ return raw < I64_SIGN_BIT ? raw : raw - I64_RANGE
74
+ }
75
+
76
+ u128(): bigint {
77
+ this.pos += WORD_SIZE - 16
78
+ return this.#u128()
79
+ }
80
+
81
+ #u128(): bigint {
82
+ const hi = this.view.getBigUint64(this.pos, false)
83
+ const lo = this.view.getBigUint64(this.pos + 8, false)
84
+ this.pos += 16
85
+ return (hi << 64n) | lo
86
+ }
87
+
88
+ i128(): bigint {
89
+ this.pos += WORD_SIZE - 16
90
+ const raw = this.#u128()
91
+ return raw < I128_SIGN_BIT ? raw : raw - I128_RANGE
92
+ }
93
+
94
+ u256(): bigint {
95
+ const hi = this.#u128()
96
+ const lo = this.#u128()
97
+ return (hi << 128n) | lo
98
+ }
99
+
100
+ i256(): bigint {
101
+ const hi = this.#u128()
102
+ const lo = this.#u128()
103
+ const raw = (hi << 128n) | lo
104
+ return raw < I256_SIGN_BIT ? raw : raw - I256_RANGE
105
+ }
106
+
107
+ address(): string {
108
+ const start = this.pos + WORD_SIZE - 20
109
+ this.pos += WORD_SIZE
110
+ return toHex(this.buf, start, 20)
111
+ }
112
+
113
+ bytes(): Uint8Array {
114
+ const ptr = this.u32()
115
+ this.jump(ptr)
116
+ const len = Number(this.u256())
117
+ this.#assertLength(len, 'bytes')
118
+ const val = this.buf.subarray(this.pos, this.pos + len)
119
+ this.jumpBack()
120
+ return val
121
+ }
122
+
123
+ bytesHex(): string {
124
+ const ptr = this.u32()
125
+ this.jump(ptr)
126
+ const len = Number(this.u256())
127
+ this.#assertLength(len, 'bytes')
128
+ const val = toHex(this.buf, this.pos, len)
129
+ this.jumpBack()
130
+ return val
131
+ }
132
+
133
+ staticBytes(len: number): Uint8Array {
134
+ if (len > 32) {
135
+ throw new Error(`bytes${len} is not a valid type`)
136
+ }
137
+ const val = this.buf.subarray(this.pos, this.pos + len)
138
+ this.pos += WORD_SIZE
139
+ return val
140
+ }
141
+
142
+ staticBytesHex(len: number): string {
143
+ if (len > 32) {
144
+ throw new Error(`bytes${len} is not a valid type`)
145
+ }
146
+ const start = this.pos
147
+ this.pos += WORD_SIZE
148
+ return toHex(this.buf, start, len)
149
+ }
150
+
151
+ string(): string {
152
+ const ptr = this.u32()
153
+ this.jump(ptr, 'string')
154
+ const len = Number(this.u256())
155
+ this.#assertLength(len, 'string')
156
+ const val = TEXT_DECODER.decode(this.buf.subarray(this.pos, this.pos + len))
157
+ this.jumpBack()
158
+ return val
159
+ }
160
+
161
+ bool(): boolean {
162
+ return !!this.u8()
163
+ }
164
+
165
+ #assertLength(len: number, typeName: string): void {
166
+ if (this.buf.length - this.pos < len) {
167
+ throw new RangeError(
168
+ `Unexpected end of input. Attempting to read ${typeName} of length ${len} from ${toHex(this.buf)}`,
169
+ )
170
+ }
171
+ }
172
+
173
+ jump(pos: number, typeName?: string): void {
174
+ if (pos < 0 || pos >= this.buf.length) {
175
+ const what = typeName ? `${typeName} ` : ''
176
+ throw new RangeError(
177
+ `Unexpected pointer location: 0x${pos.toString(16)}. Attempting to read ${what}from ${toHex(this.buf)}`,
178
+ )
179
+ }
180
+ this.oldPos = this.pos
181
+ this.pos = pos
182
+ }
183
+
184
+ jumpBack(): void {
185
+ this.pos = this.oldPos
186
+ }
187
+ }
package/src/src/hex.ts ADDED
@@ -0,0 +1,191 @@
1
+ import {WORD_SIZE, type Src} from '../codec'
2
+
3
+ const HEX_BYTE = 2
4
+ const WORD_HEX = WORD_SIZE * HEX_BYTE
5
+
6
+ const I64_SIGN_BIT = 1n << 63n
7
+ const I64_RANGE = 1n << 64n
8
+ const I128_SIGN_BIT = 1n << 127n
9
+ const I128_RANGE = 1n << 128n
10
+ const I256_SIGN_BIT = 1n << 255n
11
+ const I256_RANGE = 1n << 256n
12
+
13
+ const TEXT_DECODER = new TextDecoder('utf-8')
14
+
15
+ export class HexSrc implements Src {
16
+ private readonly buf: string
17
+ private readonly base: number
18
+ private readonly endChar: number
19
+ private pos: number
20
+ private oldPos: number
21
+
22
+ constructor(hex: string, strOffset = 2, strEnd: number = hex.length) {
23
+ this.buf = hex
24
+ this.base = strOffset
25
+ this.endChar = strEnd
26
+ this.pos = strOffset
27
+ this.oldPos = strOffset
28
+ }
29
+
30
+ slice(start: number, end?: number): HexSrc {
31
+ const s = this.base + HEX_BYTE * start
32
+ const e = end == null ? this.endChar : this.base + HEX_BYTE * end
33
+ return new HexSrc(this.buf, s, e)
34
+ }
35
+
36
+ u8(): number {
37
+ const start = this.pos + WORD_HEX - 2
38
+ const val = Number.parseInt(this.buf.slice(start, start + 2), 16)
39
+ this.pos += WORD_HEX
40
+ return val
41
+ }
42
+
43
+ i8(): number {
44
+ return Number(this.i256())
45
+ }
46
+
47
+ u16(): number {
48
+ const start = this.pos + WORD_HEX - 4
49
+ const val = Number.parseInt(this.buf.slice(start, start + 4), 16)
50
+ this.pos += WORD_HEX
51
+ return val
52
+ }
53
+
54
+ i16(): number {
55
+ return Number(this.i256())
56
+ }
57
+
58
+ u32(): number {
59
+ const start = this.pos + WORD_HEX - 8
60
+ const val = Number.parseInt(this.buf.slice(start, start + 8), 16)
61
+ this.pos += WORD_HEX
62
+ return val
63
+ }
64
+
65
+ i32(): number {
66
+ return Number(this.i256())
67
+ }
68
+
69
+ u64(): bigint {
70
+ const start = this.pos + WORD_HEX - 16
71
+ const val = BigInt(`0x${this.buf.slice(start, start + 16)}`)
72
+ this.pos += WORD_HEX
73
+ return val
74
+ }
75
+
76
+ i64(): bigint {
77
+ const raw = this.u64()
78
+ return raw < I64_SIGN_BIT ? raw : raw - I64_RANGE
79
+ }
80
+
81
+ u128(): bigint {
82
+ const start = this.pos + WORD_HEX - 32
83
+ const val = BigInt(`0x${this.buf.slice(start, start + 32)}`)
84
+ this.pos += WORD_HEX
85
+ return val
86
+ }
87
+
88
+ i128(): bigint {
89
+ const raw = this.u128()
90
+ return raw < I128_SIGN_BIT ? raw : raw - I128_RANGE
91
+ }
92
+
93
+ u256(): bigint {
94
+ const val = BigInt(`0x${this.buf.slice(this.pos, this.pos + WORD_HEX)}`)
95
+ this.pos += WORD_HEX
96
+ return val
97
+ }
98
+
99
+ i256(): bigint {
100
+ const raw = this.u256()
101
+ return raw < I256_SIGN_BIT ? raw : raw - I256_RANGE
102
+ }
103
+
104
+ address(): string {
105
+ const start = this.pos + WORD_HEX - 40
106
+ const val = `0x${this.buf.slice(start, start + 40)}`
107
+ this.pos += WORD_HEX
108
+ return val
109
+ }
110
+
111
+ bytes(): Uint8Array {
112
+ const ptr = this.u32()
113
+ this.jump(ptr)
114
+ const len = Number(this.u256())
115
+ this.#assertLength(len, 'bytes')
116
+ const sub = this.buf.slice(this.pos, this.pos + HEX_BYTE * len)
117
+ const val = Buffer.from(sub, 'hex')
118
+ this.jumpBack()
119
+ return val
120
+ }
121
+
122
+ bytesHex(): string {
123
+ const ptr = this.u32()
124
+ this.jump(ptr)
125
+ const len = Number(this.u256())
126
+ this.#assertLength(len, 'bytes')
127
+ const val = `0x${this.buf.slice(this.pos, this.pos + HEX_BYTE * len)}`
128
+ this.jumpBack()
129
+ return val
130
+ }
131
+
132
+ staticBytes(len: number): Uint8Array {
133
+ if (len > 32) {
134
+ throw new Error(`bytes${len} is not a valid type`)
135
+ }
136
+ const sub = this.buf.slice(this.pos, this.pos + HEX_BYTE * len)
137
+ this.pos += WORD_HEX
138
+ return Buffer.from(sub, 'hex')
139
+ }
140
+
141
+ staticBytesHex(len: number): string {
142
+ if (len > 32) {
143
+ throw new Error(`bytes${len} is not a valid type`)
144
+ }
145
+ const val = `0x${this.buf.slice(this.pos, this.pos + HEX_BYTE * len)}`
146
+ this.pos += WORD_HEX
147
+ return val
148
+ }
149
+
150
+ string(): string {
151
+ const ptr = this.u32()
152
+ this.jump(ptr, 'string')
153
+ const len = Number(this.u256())
154
+ this.#assertLength(len, 'string')
155
+ const sub = this.buf.slice(this.pos, this.pos + HEX_BYTE * len)
156
+ const val = TEXT_DECODER.decode(Buffer.from(sub, 'hex'))
157
+ this.jumpBack()
158
+ return val
159
+ }
160
+
161
+ bool(): boolean {
162
+ const a = this.buf.charCodeAt(this.pos + WORD_HEX - 2)
163
+ const b = this.buf.charCodeAt(this.pos + WORD_HEX - 1)
164
+ this.pos += WORD_HEX
165
+ return a !== 48 /* '0' */ || b !== 48
166
+ }
167
+
168
+ #assertLength(len: number, typeName: string): void {
169
+ if (this.endChar - this.pos < HEX_BYTE * len) {
170
+ throw new RangeError(
171
+ `Unexpected end of input. Attempting to read ${typeName} of length ${len} from 0x${this.buf.slice(this.base, this.endChar)}`,
172
+ )
173
+ }
174
+ }
175
+
176
+ jump(pos: number, typeName?: string): void {
177
+ const target = this.base + HEX_BYTE * pos
178
+ if (pos < 0 || target >= this.endChar) {
179
+ const what = typeName ? `${typeName} ` : ''
180
+ throw new RangeError(
181
+ `Unexpected pointer location: 0x${pos.toString(16)}. Attempting to read ${what}from 0x${this.buf.slice(this.base, this.endChar)}`,
182
+ )
183
+ }
184
+ this.oldPos = this.pos
185
+ this.pos = target
186
+ }
187
+
188
+ jumpBack(): void {
189
+ this.pos = this.oldPos
190
+ }
191
+ }
package/src/util.ts ADDED
@@ -0,0 +1,19 @@
1
+ export type Pretty<T> = {[K in keyof T]: T[K]} & unknown
2
+
3
+ export function propName(prop: string): string {
4
+ if (isValidProperty(prop)) {
5
+ return prop
6
+ }
7
+ return `[${JSON.stringify(prop)}]`
8
+ }
9
+
10
+ export function propAccess(prop: string): string {
11
+ if (isValidProperty(prop)) {
12
+ return `.${prop}`
13
+ }
14
+ return `[${JSON.stringify(prop)}]`
15
+ }
16
+
17
+ function isValidProperty(s: string): boolean {
18
+ return /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(s)
19
+ }
@@ -1,2 +0,0 @@
1
- export declare function safeToNumber(value: number | bigint): number;
2
- //# sourceMappingURL=safeToNumber.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"safeToNumber.d.ts","sourceRoot":"","sources":["../src/safeToNumber.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAK3D"}
@@ -1,11 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.safeToNumber = void 0;
4
- function safeToNumber(value) {
5
- if (value < Number.MIN_SAFE_INTEGER || value > Number.MAX_SAFE_INTEGER) {
6
- throw new Error(`${value} is not a safe integer`);
7
- }
8
- return Number(value);
9
- }
10
- exports.safeToNumber = safeToNumber;
11
- //# sourceMappingURL=safeToNumber.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"safeToNumber.js","sourceRoot":"","sources":["../src/safeToNumber.ts"],"names":[],"mappings":";;;AAAA,SAAgB,YAAY,CAAC,KAAsB;IACjD,IAAK,KAAK,GAAG,MAAM,CAAC,gBAAgB,IAAI,KAAK,GAAG,MAAM,CAAC,gBAAgB,EAAE,CAAC;QACxE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,wBAAwB,CAAC,CAAA;IACnD,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;AACtB,CAAC;AALD,oCAKC"}
package/lib/sink.d.ts DELETED
@@ -1,43 +0,0 @@
1
- /// <reference types="node" />
2
- export declare class Sink {
3
- #private;
4
- private pos;
5
- private buf;
6
- private view;
7
- private stack;
8
- constructor(fields: number, capacity?: number);
9
- result(): Buffer;
10
- toString(): string;
11
- reserve(additional: number): void;
12
- size(): number;
13
- private _allocate;
14
- private checkNumberBounds;
15
- u8(val: number): void;
16
- i8(val: number): void;
17
- u16(val: number): void;
18
- i16(val: number): void;
19
- u32(val: number): void;
20
- i32(val: number): void;
21
- u64(val: bigint): void;
22
- i64(val: bigint): void;
23
- u128(val: bigint): void;
24
- i128(val: bigint): void;
25
- u256(val: bigint): void;
26
- i256(val: bigint): void;
27
- bytes(val: Uint8Array): void;
28
- staticBytes(len: number, val: Uint8Array): void;
29
- address(val: string): void;
30
- string(val: string): void;
31
- bool(val: boolean): void;
32
- /**
33
- * @example
34
- * @link [Solidity docs](https://docs.soliditylang.org/en/latest/abi-spec.html#use-of-dynamic-types)
35
- */
36
- newStaticDataArea(slotsCount?: number): void;
37
- newDynamicDataArea(slotsCount: number): void;
38
- private currentDataAreaStart;
39
- increaseCurrentDataAreaSize(amount: number): void;
40
- private pushDataArea;
41
- endCurrentDataArea(): void;
42
- }
43
- //# sourceMappingURL=sink.d.ts.map
package/lib/sink.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"sink.d.ts","sourceRoot":"","sources":["../src/sink.ts"],"names":[],"mappings":";AAGA,qBAAa,IAAI;;IACf,OAAO,CAAC,GAAG,CAAI;IACf,OAAO,CAAC,GAAG,CAAQ;IACnB,OAAO,CAAC,IAAI,CAAU;IACtB,OAAO,CAAC,KAAK,CAA6D;gBAC9D,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAa;IAUnD,MAAM,IAAI,MAAM;IAKhB,QAAQ;IAIR,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAMjC,IAAI;IAIJ,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,iBAAiB;IAMzB,EAAE,CAAC,GAAG,EAAE,MAAM;IAQd,EAAE,CAAC,GAAG,EAAE,MAAM;IAKd,GAAG,CAAC,GAAG,EAAE,MAAM;IAQf,GAAG,CAAC,GAAG,EAAE,MAAM;IAKf,GAAG,CAAC,GAAG,EAAE,MAAM;IAQf,GAAG,CAAC,GAAG,EAAE,MAAM;IAKf,GAAG,CAAC,GAAG,EAAE,MAAM;IAQf,GAAG,CAAC,GAAG,EAAE,MAAM;IAUf,IAAI,CAAC,GAAG,EAAE,MAAM;IAQhB,IAAI,CAAC,GAAG,EAAE,MAAM;IAWhB,IAAI,CAAC,GAAG,EAAE,MAAM;IAOhB,IAAI,CAAC,GAAG,EAAE,MAAM;IAiBhB,KAAK,CAAC,GAAG,EAAE,UAAU;IAWrB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU;IAaxC,OAAO,CAAC,GAAG,EAAE,MAAM;IAInB,MAAM,CAAC,GAAG,EAAE,MAAM;IAWlB,IAAI,CAAC,GAAG,EAAE,OAAO;IAIjB;;;OAGG;IACH,iBAAiB,CAAC,UAAU,SAAI;IAShC,kBAAkB,CAAC,UAAU,EAAE,MAAM;IASrC,OAAO,CAAC,oBAAoB;IAIrB,2BAA2B,CAAC,MAAM,EAAE,MAAM;IAIjD,OAAO,CAAC,YAAY;IAUb,kBAAkB;CAM1B"}
package/lib/sink.js DELETED
@@ -1,215 +0,0 @@
1
- "use strict";
2
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
4
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
- };
7
- var __importDefault = (this && this.__importDefault) || function (mod) {
8
- return (mod && mod.__esModule) ? mod : { "default": mod };
9
- };
10
- var _Sink_instances, _Sink_u64, _Sink_u128, _Sink_i256;
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.Sink = void 0;
13
- const node_assert_1 = __importDefault(require("node:assert"));
14
- const codec_1 = require("./codec");
15
- class Sink {
16
- constructor(fields, capacity = 1280) {
17
- _Sink_instances.add(this);
18
- this.pos = 0;
19
- this.stack = [];
20
- this.stack.push({
21
- start: 0,
22
- jumpBackPtr: 0,
23
- size: fields * codec_1.WORD_SIZE,
24
- });
25
- this.buf = Buffer.alloc(capacity);
26
- this.view = new DataView(this.buf.buffer, this.buf.byteOffset, this.buf.byteLength);
27
- }
28
- result() {
29
- (0, node_assert_1.default)(this.stack.length === 1, 'Cannot get result during dynamic encoding');
30
- return this.buf.subarray(0, this.size());
31
- }
32
- toString() {
33
- return '0x' + this.result().toString('hex');
34
- }
35
- reserve(additional) {
36
- if (this.buf.length - this.pos < additional) {
37
- this._allocate(this.pos + additional);
38
- }
39
- }
40
- size() {
41
- return this.stack[this.stack.length - 1].size;
42
- }
43
- _allocate(cap) {
44
- cap = Math.max(cap, this.buf.length * 2);
45
- let buf = Buffer.alloc(cap);
46
- buf.set(this.buf);
47
- this.buf = buf;
48
- this.view = new DataView(this.buf.buffer, this.buf.byteOffset, this.buf.byteLength);
49
- }
50
- checkNumberBounds(val, min, max, typeName) {
51
- if (val < min || val > max) {
52
- throw new Error(`${val} is out of bounds for ${typeName}[${min}, ${max}]`);
53
- }
54
- }
55
- u8(val) {
56
- this.checkNumberBounds(val, 0n, 255n, 'uint8');
57
- this.reserve(codec_1.WORD_SIZE);
58
- this.pos += codec_1.WORD_SIZE - 1;
59
- this.view.setUint8(this.pos, val);
60
- this.pos += 1;
61
- }
62
- i8(val) {
63
- this.checkNumberBounds(val, -128n, 127n, 'int8');
64
- __classPrivateFieldGet(this, _Sink_instances, "m", _Sink_i256).call(this, BigInt(val));
65
- }
66
- u16(val) {
67
- this.checkNumberBounds(val, 0n, 65535n, 'uint16');
68
- this.reserve(codec_1.WORD_SIZE);
69
- this.pos += codec_1.WORD_SIZE - 2;
70
- this.view.setUint16(this.pos, val, false);
71
- this.pos += 2;
72
- }
73
- i16(val) {
74
- this.checkNumberBounds(val, -32768n, 32767n, 'int16');
75
- __classPrivateFieldGet(this, _Sink_instances, "m", _Sink_i256).call(this, BigInt(val));
76
- }
77
- u32(val) {
78
- this.checkNumberBounds(val, 0n, 4294967295n, 'uint32');
79
- this.reserve(codec_1.WORD_SIZE);
80
- this.pos += codec_1.WORD_SIZE - 4;
81
- this.view.setUint32(this.pos, val, false);
82
- this.pos += 4;
83
- }
84
- i32(val) {
85
- this.checkNumberBounds(val, -2147483648n, 2147483647n, 'int32');
86
- __classPrivateFieldGet(this, _Sink_instances, "m", _Sink_i256).call(this, BigInt(val));
87
- }
88
- u64(val) {
89
- this.checkNumberBounds(val, 0n, 18446744073709551615n, 'uint64');
90
- this.reserve(codec_1.WORD_SIZE);
91
- this.pos += codec_1.WORD_SIZE - 8;
92
- this.view.setBigUint64(this.pos, val, false);
93
- this.pos += 8;
94
- }
95
- i64(val) {
96
- this.checkNumberBounds(val, -9223372036854775808n, 9223372036854775807n, 'int64');
97
- __classPrivateFieldGet(this, _Sink_instances, "m", _Sink_i256).call(this, val);
98
- }
99
- u128(val) {
100
- this.checkNumberBounds(val, 0n, 340282366920938463463374607431768211455n, 'uint128');
101
- this.reserve(codec_1.WORD_SIZE);
102
- this.pos += codec_1.WORD_SIZE - 16;
103
- __classPrivateFieldGet(this, _Sink_instances, "m", _Sink_u64).call(this, val & 0xffffffffffffffffn);
104
- __classPrivateFieldGet(this, _Sink_instances, "m", _Sink_u64).call(this, val >> 64n);
105
- }
106
- i128(val) {
107
- this.checkNumberBounds(val, -170141183460469231731687303715884105728n, 170141183460469231731687303715884105727n, 'int128');
108
- __classPrivateFieldGet(this, _Sink_instances, "m", _Sink_i256).call(this, val);
109
- }
110
- u256(val) {
111
- this.checkNumberBounds(val, 0n, 115792089237316195423570985008687907853269984665640564039457584007913129639935n, 'uint256');
112
- this.reserve(codec_1.WORD_SIZE);
113
- __classPrivateFieldGet(this, _Sink_instances, "m", _Sink_u128).call(this, val >> 128n);
114
- __classPrivateFieldGet(this, _Sink_instances, "m", _Sink_u128).call(this, val & (2n ** 128n - 1n));
115
- }
116
- i256(val) {
117
- this.checkNumberBounds(val, -57896044618658097711785492504343953926634992332820282019728792003956564819968n, 57896044618658097711785492504343953926634992332820282019728792003956564819967n, 'int256');
118
- __classPrivateFieldGet(this, _Sink_instances, "m", _Sink_i256).call(this, val);
119
- }
120
- bytes(val) {
121
- const size = Buffer.byteLength(val);
122
- this.u32(size);
123
- const wordsCount = Math.ceil(size / codec_1.WORD_SIZE);
124
- const reservedSize = codec_1.WORD_SIZE * wordsCount;
125
- this.reserve(reservedSize);
126
- this.buf.set(val, this.pos);
127
- this.pos += reservedSize;
128
- this.increaseCurrentDataAreaSize(reservedSize + codec_1.WORD_SIZE);
129
- }
130
- staticBytes(len, val) {
131
- if (len > 32) {
132
- throw new Error(`bytes${len} is not a valid type`);
133
- }
134
- const size = Buffer.byteLength(val);
135
- if (size > len) {
136
- throw new Error(`invalid data size for bytes${len}`);
137
- }
138
- this.reserve(codec_1.WORD_SIZE);
139
- this.buf.set(val, this.pos);
140
- this.pos += codec_1.WORD_SIZE;
141
- }
142
- address(val) {
143
- this.u256(BigInt(val));
144
- }
145
- string(val) {
146
- const size = Buffer.byteLength(val);
147
- this.u32(size);
148
- const wordsCount = Math.ceil(size / codec_1.WORD_SIZE);
149
- const reservedSize = codec_1.WORD_SIZE * wordsCount;
150
- this.reserve(reservedSize);
151
- this.buf.write(val, this.pos);
152
- this.pos += reservedSize;
153
- this.increaseCurrentDataAreaSize(reservedSize + codec_1.WORD_SIZE);
154
- }
155
- bool(val) {
156
- this.u8(val ? 1 : 0);
157
- }
158
- /**
159
- * @example
160
- * @link [Solidity docs](https://docs.soliditylang.org/en/latest/abi-spec.html#use-of-dynamic-types)
161
- */
162
- newStaticDataArea(slotsCount = 0) {
163
- const offset = this.size();
164
- this.u32(offset);
165
- const dataAreaStart = this.currentDataAreaStart();
166
- this.pushDataArea(dataAreaStart + offset, slotsCount);
167
- this.pos = dataAreaStart + offset;
168
- }
169
- // Adds elements count before the data area in an additional slot
170
- newDynamicDataArea(slotsCount) {
171
- const offset = this.size();
172
- this.u32(offset);
173
- const dataAreaStart = this.currentDataAreaStart();
174
- this.pushDataArea(dataAreaStart + offset + codec_1.WORD_SIZE, slotsCount);
175
- this.pos = dataAreaStart + offset;
176
- this.u32(slotsCount);
177
- }
178
- currentDataAreaStart() {
179
- return this.stack[this.stack.length - 1].start;
180
- }
181
- increaseCurrentDataAreaSize(amount) {
182
- this.stack[this.stack.length - 1].size += amount;
183
- }
184
- pushDataArea(dataAreaStart, slotsCount) {
185
- const size = slotsCount * codec_1.WORD_SIZE;
186
- this.reserve(dataAreaStart + size);
187
- this.stack.push({
188
- start: dataAreaStart,
189
- jumpBackPtr: this.pos,
190
- size,
191
- });
192
- }
193
- endCurrentDataArea() {
194
- (0, node_assert_1.default)(this.stack.length > 1, 'No dynamic encoding started');
195
- const { jumpBackPtr, size } = this.stack.pop();
196
- this.increaseCurrentDataAreaSize(size);
197
- this.pos = jumpBackPtr;
198
- }
199
- }
200
- exports.Sink = Sink;
201
- _Sink_instances = new WeakSet(), _Sink_u64 = function _Sink_u64(val) {
202
- this.view.setBigUint64(this.pos, val, false);
203
- this.pos += 8;
204
- }, _Sink_u128 = function _Sink_u128(val) {
205
- this.reserve(codec_1.WORD_SIZE);
206
- __classPrivateFieldGet(this, _Sink_instances, "m", _Sink_u64).call(this, val >> 64n);
207
- __classPrivateFieldGet(this, _Sink_instances, "m", _Sink_u64).call(this, val & 0xffffffffffffffffn);
208
- }, _Sink_i256 = function _Sink_i256(val) {
209
- let base = 2n ** 256n;
210
- const uval = (val + base) % base;
211
- this.reserve(codec_1.WORD_SIZE);
212
- __classPrivateFieldGet(this, _Sink_instances, "m", _Sink_u128).call(this, uval >> 128n);
213
- __classPrivateFieldGet(this, _Sink_instances, "m", _Sink_u128).call(this, uval & (2n ** 128n - 1n));
214
- };
215
- //# sourceMappingURL=sink.js.map