@subsquid/evm-codec 0.3.0 → 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 +57 -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 +1 -3
  5. package/lib/codecs/array.d.ts.map +1 -1
  6. package/lib/codecs/array.js +13 -9
  7. package/lib/codecs/array.js.map +1 -1
  8. package/lib/codecs/primitives.d.ts +2 -17
  9. package/lib/codecs/primitives.d.ts.map +1 -1
  10. package/lib/codecs/primitives.js +46 -152
  11. package/lib/codecs/primitives.js.map +1 -1
  12. package/lib/codecs/struct.d.ts +16 -9
  13. package/lib/codecs/struct.d.ts.map +1 -1
  14. package/lib/codecs/struct.js +53 -40
  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 +65 -19
  50. package/src/codecs/array.test.ts +87 -0
  51. package/src/codecs/array.ts +6 -11
  52. package/src/codecs/primitives.test.ts +27 -0
  53. package/src/codecs/primitives.ts +87 -208
  54. package/src/codecs/struct.test.ts +69 -0
  55. package/src/codecs/struct.ts +80 -61
  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
@@ -1,201 +1,93 @@
1
- import { decodeHex, isHex, toHex } from '@subsquid/util-internal-hex'
2
- import { Codec } from '../codec'
3
- import { Sink } from '../sink'
4
- import { Src } from '../src'
5
- import { ArrayCodec, FixedSizeArrayCodec } from './array'
6
- import { StructCodec } from './struct'
7
- import { safeToNumber } from '../safeToNumber'
1
+ import type {Codec, Sink, Src} from '../codec'
8
2
 
9
- type Numberish = number | bigint
10
-
11
- export const bool: Codec<boolean> = {
12
- encode: function (sink: Sink, val: boolean) {
13
- sink.bool(val)
14
- },
15
- decode(src: Src): boolean {
16
- return src.bool()
17
- },
18
- isDynamic: false,
19
- baseType: 'bool',
20
- }
21
-
22
- export const uint8: Codec<Numberish, number> = {
23
- encode(sink: Sink, val: Numberish) {
24
- sink.u8(safeToNumber(val))
25
- },
26
- decode(src: Src): number {
27
- return src.u8()
28
- },
29
- isDynamic: false,
30
- baseType: 'int',
31
- }
32
-
33
- export const int8: Codec<Numberish, number> = {
34
- encode(sink: Sink, val: Numberish) {
35
- sink.i8(safeToNumber(val))
36
- },
37
- decode(src: Src): number {
38
- return src.i8()
39
- },
40
- isDynamic: false,
41
- baseType: 'int',
42
- }
43
-
44
- export const uint16: Codec<Numberish, number> = {
45
- encode(sink: Sink, val: Numberish) {
46
- sink.u16(safeToNumber(val))
47
- },
48
- decode(src: Src): number {
49
- return src.u16()
50
- },
51
- isDynamic: false,
52
- baseType: 'int',
3
+ function safeToNumber(value: number | bigint): number {
4
+ if (value < Number.MIN_SAFE_INTEGER || value > Number.MAX_SAFE_INTEGER) {
5
+ throw new Error(`${value} is not a safe integer`)
6
+ }
7
+ return Number(value)
53
8
  }
54
9
 
55
- export const int16: Codec<Numberish, number> = {
56
- encode(sink: Sink, val: Numberish) {
57
- sink.i16(safeToNumber(val))
58
- },
59
- decode(src: Src): number {
60
- return src.i16()
61
- },
62
- isDynamic: false,
63
- baseType: 'int',
64
- }
65
-
66
- export const uint32: Codec<Numberish, number> = {
67
- encode(sink: Sink, val: Numberish) {
68
- sink.u32(safeToNumber(val))
69
- },
70
- decode(src: Src): number {
71
- return src.u32()
72
- },
73
- isDynamic: false,
74
- baseType: 'int',
75
- }
76
-
77
- export const int32: Codec<Numberish, number> = {
78
- encode(sink: Sink, val: Numberish) {
79
- sink.i32(safeToNumber(val))
80
- },
81
- decode(src: Src): number {
82
- return src.i32()
83
- },
84
- isDynamic: false,
85
- baseType: 'int',
86
- }
87
-
88
- export const uint64: Codec<Numberish, bigint> = {
89
- encode(sink: Sink, val: Numberish) {
90
- sink.u64(BigInt(val))
91
- },
92
- decode(src: Src): bigint {
93
- return src.u64()
94
- },
95
- isDynamic: false,
96
- baseType: 'int',
97
- }
98
-
99
- export const int64: Codec<Numberish, bigint> = {
100
- encode(sink: Sink, val: Numberish) {
101
- sink.i64(BigInt(val))
102
- },
103
- decode(src: Src): bigint {
104
- return src.i64()
105
- },
106
- isDynamic: false,
107
- baseType: 'int',
108
- }
109
-
110
- export const uint128: Codec<Numberish, bigint> = {
111
- encode(sink: Sink, val: Numberish) {
112
- sink.u128(BigInt(val))
113
- },
114
- decode(src: Src): bigint {
115
- return src.u128()
116
- },
117
- isDynamic: false,
118
- baseType: 'int',
119
- }
120
-
121
- export const int128: Codec<Numberish, bigint> = {
122
- encode(sink: Sink, val: Numberish) {
123
- sink.i128(BigInt(val))
124
- },
125
- decode(src: Src): bigint {
126
- return src.i128()
127
- },
128
- isDynamic: false,
129
- baseType: 'int',
130
- }
131
-
132
- export const uint256: Codec<Numberish, bigint> = {
133
- encode(sink: Sink, val: Numberish) {
134
- sink.u256(BigInt(val))
135
- },
136
- decode(src: Src): bigint {
137
- return src.u256()
138
- },
139
- isDynamic: false,
140
- baseType: 'int',
141
- }
142
-
143
- export const int256: Codec<Numberish, bigint> = {
144
- encode(sink: Sink, val: Numberish) {
145
- sink.i256(BigInt(val))
146
- },
147
- decode(src: Src): bigint {
148
- return src.i256()
149
- },
150
- isDynamic: false,
151
- baseType: 'int',
152
- }
10
+ type Numberish = number | bigint
11
+ type NumberType = 'u8' | 'i8' | 'u16' | 'i16' | 'u32' | 'i32'
12
+ type BigIntType = 'u64' | 'i64' | 'u128' | 'i128' | 'u256' | 'i256'
153
13
 
154
- export const string = <const>{
155
- encode(sink: Sink, val: string) {
156
- sink.newStaticDataArea()
157
- sink.string(val)
158
- sink.endCurrentDataArea()
159
- },
160
- decode(src: Src): string {
161
- return src.string()
162
- },
163
- isDynamic: true,
164
- baseType: 'string',
14
+ function numberCodec(method: NumberType): Codec<Numberish, number> {
15
+ return {
16
+ encode: (sink, val) => sink[method](safeToNumber(val)),
17
+ decode: (src) => src[method](),
18
+ isDynamic: false,
19
+ baseType: 'int',
20
+ }
165
21
  }
166
22
 
167
- function toBuffer(val: Uint8Array | string): Uint8Array {
168
- if (val instanceof Uint8Array) {
169
- return val
170
- }
171
- if (!isHex(val)) {
172
- throw new Error(`Expected hex string or buffer, got: ${val}`)
173
- }
174
- return decodeHex(val)
23
+ function bigintCodec(method: BigIntType): Codec<Numberish, bigint> {
24
+ return {
25
+ encode: (sink, val) => sink[method](BigInt(val)),
26
+ decode: (src) => src[method](),
27
+ isDynamic: false,
28
+ baseType: 'int',
29
+ }
175
30
  }
176
31
 
177
- export const bytes: Codec<Uint8Array | string, string> = <const>{
178
- encode(sink: Sink, val: Uint8Array | string) {
179
- sink.newStaticDataArea()
180
- sink.bytes(toBuffer(val))
181
- sink.endCurrentDataArea()
182
- },
183
- decode(src: Src): string {
184
- return toHex(src.bytes())
185
- },
186
- isDynamic: true,
187
- baseType: 'bytes',
32
+ export const bool: Codec<boolean> = {
33
+ encode(sink: Sink, val: boolean) {
34
+ sink.bool(val)
35
+ },
36
+ decode(src: Src): boolean {
37
+ return src.bool()
38
+ },
39
+ isDynamic: false,
40
+ baseType: 'bool',
41
+ }
42
+
43
+ export const uint8 = numberCodec('u8')
44
+ export const int8 = numberCodec('i8')
45
+ export const uint16 = numberCodec('u16')
46
+ export const int16 = numberCodec('i16')
47
+ export const uint32 = numberCodec('u32')
48
+ export const int32 = numberCodec('i32')
49
+ export const uint64 = bigintCodec('u64')
50
+ export const int64 = bigintCodec('i64')
51
+ export const uint128 = bigintCodec('u128')
52
+ export const int128 = bigintCodec('i128')
53
+ export const uint256 = bigintCodec('u256')
54
+ export const int256 = bigintCodec('i256')
55
+
56
+ export const string: Codec<string> = {
57
+ encode(sink: Sink, val: string) {
58
+ sink.openTail()
59
+ sink.string(val)
60
+ sink.closeTail()
61
+ },
62
+ decode(src: Src): string {
63
+ return src.string()
64
+ },
65
+ isDynamic: true,
66
+ baseType: 'string',
67
+ }
68
+
69
+ export const bytes: Codec<Uint8Array | string, string> = {
70
+ encode(sink: Sink, val: Uint8Array | string) {
71
+ sink.openTail()
72
+ sink.bytes(val)
73
+ sink.closeTail()
74
+ },
75
+ decode(src: Src): string {
76
+ return src.bytesHex()
77
+ },
78
+ isDynamic: true,
79
+ baseType: 'bytes',
188
80
  }
189
81
 
190
82
  const bytesN = (size: number): Codec<Uint8Array | string, string> => ({
191
- encode(sink: Sink, val: Uint8Array | string) {
192
- sink.staticBytes(size, toBuffer(val))
193
- },
194
- decode(src: Src): string {
195
- return toHex(src.staticBytes(size))
196
- },
197
- isDynamic: false,
198
- baseType: 'bytes',
83
+ encode(sink: Sink, val: Uint8Array | string) {
84
+ sink.staticBytes(size, val)
85
+ },
86
+ decode(src: Src): string {
87
+ return src.staticBytesHex(size)
88
+ },
89
+ isDynamic: false,
90
+ baseType: 'bytes',
199
91
  })
200
92
 
201
93
  export const bytes0 = bytesN(0)
@@ -233,28 +125,16 @@ export const bytes31 = bytesN(31)
233
125
  export const bytes32 = bytesN(32)
234
126
 
235
127
  export const address: Codec<string> = {
236
- encode(sink: Sink, val: string) {
237
- sink.address(val)
238
- },
239
- decode(src: Src): string {
240
- return src.address()
241
- },
242
- isDynamic: false,
243
- baseType: 'address',
244
- }
245
-
246
- export const fixedSizeArray = <TIn, TOut>(item: Codec<TIn, TOut>, size: number): Codec<TIn[], TOut[]> => new FixedSizeArrayCodec(item, size)
247
-
248
- export const array = <TIn, TOut>(item: Codec<TIn, TOut>): Codec<TIn[], TOut[]> => new ArrayCodec(item)
249
-
250
- type Struct = {
251
- [key: string]: Codec<any>
128
+ encode(sink: Sink, val: string) {
129
+ sink.address(val)
130
+ },
131
+ decode(src: Src): string {
132
+ return src.address()
133
+ },
134
+ isDynamic: false,
135
+ baseType: 'address',
252
136
  }
253
137
 
254
- export const struct = <const T extends Struct>(components: T) => new StructCodec<T>(components)
255
-
256
- export const tuple = struct
257
-
258
138
  export const uint24 = uint32
259
139
  export const int24 = int32
260
140
  export const uint40 = uint64
@@ -307,4 +187,3 @@ export const uint240 = uint256
307
187
  export const int240 = int256
308
188
  export const uint248 = uint256
309
189
  export const int248 = int256
310
-
@@ -0,0 +1,69 @@
1
+ import {describe, expect, it} from 'vitest'
2
+ import {address, array, bytes4, int8, BytesSink, BytesSrc, struct, uint256} from '..'
3
+
4
+ function roundtrip<T>(codec: {encode: (s: BytesSink, v: T) => void; decode: (s: BytesSrc) => T; slotsCount?: number}, value: T) {
5
+ const sink = new BytesSink(codec.slotsCount ?? 1)
6
+ codec.encode(sink, value)
7
+ expect(codec.decode(new BytesSrc(sink.result()))).toStrictEqual(value)
8
+ }
9
+
10
+ describe('StructCodec', () => {
11
+ it('static tuple', () => {
12
+ roundtrip(
13
+ struct({
14
+ a: int8,
15
+ b: uint256,
16
+ c: struct({e: address}),
17
+ }),
18
+ {
19
+ a: 1,
20
+ b: 2n,
21
+ c: {e: '0x1234567890123456789012345678901234567890'},
22
+ },
23
+ )
24
+ })
25
+
26
+ it('dynamic tuple', () => {
27
+ roundtrip(
28
+ struct({
29
+ a: array(uint256),
30
+ b: uint256,
31
+ c: struct({d: array(uint256), e: address}),
32
+ }),
33
+ {
34
+ a: [100n, 1n, 123n],
35
+ b: 2n,
36
+ c: {
37
+ d: [3n, 4n],
38
+ e: '0x1234567890123456789012345678901234567890',
39
+ },
40
+ },
41
+ )
42
+ })
43
+
44
+ it('dynamic tuple with bytes4', () => {
45
+ const s = struct({
46
+ foo: uint256,
47
+ bar: array(uint256),
48
+ str: struct({foo: uint256, bar: bytes4}),
49
+ })
50
+ const value = {
51
+ foo: 100n,
52
+ bar: [1n, 2n, 3n],
53
+ str: {
54
+ foo: 123n,
55
+ bar: '0x12345678',
56
+ },
57
+ }
58
+ const sink = new BytesSink(1)
59
+ // `bytes4` accepts either `Uint8Array` or the `0x…`-prefixed hex form
60
+ // on the encode side but always returns the hex form on decode — check
61
+ // both input paths explicitly.
62
+ s.encode(sink, {
63
+ ...value,
64
+ str: {...value.str, bar: Uint8Array.from([0x12, 0x34, 0x56, 0x78])},
65
+ })
66
+ expect(s.decode(new BytesSrc(sink.result()))).toStrictEqual(value)
67
+ roundtrip(s, value)
68
+ })
69
+ })
@@ -1,75 +1,94 @@
1
- import {Codec, Struct, DecodedStruct, EncodedStruct} from '../codec'
2
- import { Sink } from '../sink'
3
- import { Src } from '../src'
1
+ import type {Codec, Sink, Src, Struct} from '../codec'
2
+ import {type Pretty, propAccess, propName} from '../util'
3
+
4
+ export type DecodedStruct<T extends Struct> = Pretty<{
5
+ [K in keyof T]: T[K] extends Codec<any, infer U> ? U : never
6
+ }>
7
+
8
+ export type EncodedStruct<T extends Struct> = Pretty<{
9
+ [K in keyof T]: T[K] extends Codec<infer U, any> ? U : never
10
+ }>
4
11
 
5
12
  function slotsCount(codecs: readonly Codec<any>[]) {
6
- let count = 0
7
- for (const codec of codecs) {
8
- count += codec.slotsCount ?? 1
9
- }
10
- return count
13
+ let count = 0
14
+ for (const codec of codecs) {
15
+ count += codec.slotsCount ?? 1
16
+ }
17
+ return count
11
18
  }
12
19
 
13
20
  export class StructCodec<const T extends Struct> implements Codec<EncodedStruct<T>, DecodedStruct<T>> {
14
- public readonly baseType = 'struct'
15
- public readonly isDynamic: boolean
16
- public readonly slotsCount: number
17
- private readonly childrenSlotsCount: number
18
- private readonly components: T
21
+ public readonly baseType = 'struct'
22
+ public readonly isDynamic: boolean
23
+ public readonly slotsCount: number
24
+ public readonly childrenSlotsCount: number
25
+ public readonly components: T
19
26
 
20
- constructor(components: T) {
21
- this.components = components
22
- const codecs = Object.values(components)
23
- this.isDynamic = codecs.some((codec) => codec.isDynamic)
24
- this.childrenSlotsCount = slotsCount(codecs)
25
- if (this.isDynamic) {
26
- this.slotsCount = 1
27
- } else {
28
- this.slotsCount = this.childrenSlotsCount
29
- }
30
- }
27
+ readonly encodeInline: (sink: Sink, val: EncodedStruct<T>) => void
28
+ readonly decodeInline: (src: Src) => DecodedStruct<T>
31
29
 
32
- public encode(sink: Sink, val: EncodedStruct<T>): void {
33
- if (this.isDynamic) {
34
- this.encodeDynamic(sink, val)
35
- return
36
- }
37
- for (let i in this.components) {
38
- let prop = this.components[i]
39
- prop.encode(sink, val[i])
40
- }
41
- }
30
+ readonly encode: (sink: Sink, val: EncodedStruct<T>) => void
31
+ readonly decode: (src: Src) => DecodedStruct<T>
42
32
 
43
- private encodeDynamic(sink: Sink, val: EncodedStruct<T>): void {
44
- sink.newStaticDataArea(this.childrenSlotsCount)
45
- for (let i in this.components) {
46
- let prop = this.components[i]
47
- prop.encode(sink, val[i])
48
- }
49
- sink.endCurrentDataArea()
50
- }
33
+ constructor(components: T) {
34
+ this.components = components
35
+ const entries = Object.entries(components) as Array<[string, Codec<any>]>
36
+ const codecs = entries.map(([, c]) => c)
37
+ this.isDynamic = codecs.some((codec) => codec.isDynamic)
38
+ this.childrenSlotsCount = slotsCount(codecs)
39
+ this.slotsCount = this.isDynamic ? 1 : this.childrenSlotsCount
51
40
 
52
- public decode(src: Src): DecodedStruct<T> {
53
- if (this.isDynamic) {
54
- return this.decodeDynamic(src)
41
+ this.encodeInline = this.createEncode(entries, false)
42
+ this.decodeInline = this.createDecode(entries, false)
43
+ this.encode = this.isDynamic ? this.createEncode(entries, true) : this.encodeInline
44
+ this.decode = this.isDynamic ? this.createDecode(entries, true) : this.decodeInline
55
45
  }
56
- let result: any = {}
57
- for (let i in this.components) {
58
- let prop = this.components[i]
59
- result[i] = prop.decode(src)
60
- }
61
- return result
62
- }
63
46
 
64
- private decodeDynamic(src: Src): DecodedStruct<T> {
65
- let result: any = {}
47
+ // JIT-generates a straight-line encode function. Each child's encode is bound once
48
+ // at construction time to avoid property lookups on the hot path. When wrap=true
49
+ // and the struct is dynamic, openTail/closeTail bracket the field writes so the
50
+ // function can be used as a nested ABI field.
51
+ private createEncode(
52
+ entries: Array<[string, Codec<any>]>,
53
+ wrap: boolean,
54
+ ): (sink: Sink, val: EncodedStruct<T>) => void {
55
+ const closureNames: string[] = []
56
+ const closureValues: any[] = []
57
+ let body = ''
58
+ if (wrap && this.isDynamic) {
59
+ body += `sink.openTail(${this.childrenSlotsCount});`
60
+ }
61
+ for (let i = 0; i < entries.length; i++) {
62
+ const [key, child] = entries[i]
63
+ const name = `__e${i}`
64
+ closureNames.push(name)
65
+ closureValues.push(child.encode.bind(child))
66
+ body += `${name}(sink, val${propAccess(key)});`
67
+ }
68
+ if (wrap && this.isDynamic) {
69
+ body += 'sink.closeTail();'
70
+ }
71
+ const fn = new Function(...closureNames, 'sink', 'val', body)
72
+ return fn.bind(null, ...closureValues)
73
+ }
66
74
 
67
- const offset = src.u32()
68
- const tmpSrc = src.slice(offset)
69
- for (let i in this.components) {
70
- let prop = this.components[i]
71
- result[i] = prop.decode(tmpSrc)
75
+ private createDecode(entries: Array<[string, Codec<any>]>, wrap: boolean): (src: Src) => DecodedStruct<T> {
76
+ const closureNames: string[] = []
77
+ const closureValues: any[] = []
78
+ let body = ''
79
+ if (wrap && this.isDynamic) {
80
+ body += 'src = src.slice(src.u32());'
81
+ }
82
+ const fields: string[] = []
83
+ for (let i = 0; i < entries.length; i++) {
84
+ const [key, child] = entries[i]
85
+ const name = `__d${i}`
86
+ closureNames.push(name)
87
+ closureValues.push(child.decode.bind(child))
88
+ fields.push(`${propName(key)}:${name}(src)`)
89
+ }
90
+ body += `return {${fields.join(',')}};`
91
+ const fn = new Function(...closureNames, 'src', body)
92
+ return fn.bind(null, ...closureValues)
72
93
  }
73
- return result
74
- }
75
94
  }
package/src/dsl.ts ADDED
@@ -0,0 +1,16 @@
1
+ import type {Codec, Struct} from './codec'
2
+ import {ArrayCodec, FixedSizeArrayCodec} from './codecs/array'
3
+ import {StructCodec} from './codecs/struct'
4
+
5
+ export * from './codecs/primitives'
6
+ export {ArrayCodec, FixedSizeArrayCodec} from './codecs/array'
7
+ export {StructCodec, type DecodedStruct, type EncodedStruct} from './codecs/struct'
8
+
9
+ export const fixedSizeArray = <TIn, TOut>(item: Codec<TIn, TOut>, size: number): FixedSizeArrayCodec<TIn, TOut> =>
10
+ new FixedSizeArrayCodec(item, size)
11
+
12
+ export const array = <TIn, TOut>(item: Codec<TIn, TOut>): ArrayCodec<TIn, TOut> => new ArrayCodec(item)
13
+
14
+ export const struct = <const T extends Struct>(components: T): StructCodec<T> => new StructCodec<T>(components)
15
+
16
+ export const tuple = struct
package/src/index.ts CHANGED
@@ -1,4 +1,7 @@
1
- export { Src } from './src'
2
- export { Sink } from './sink'
3
- export type { Codec, Struct, DecodedStruct, EncodedStruct, BaseType } from './codec'
4
- export * from './codecs/primitives'
1
+ export * from './codec'
2
+ export * from './dsl'
3
+ export * from './sink/bytes'
4
+ export * from './sink/hex'
5
+ export * from './src/bytes'
6
+ export * from './src/hex'
7
+ export * from './util'
@@ -0,0 +1,26 @@
1
+ export const TEXT_ENCODER = new TextEncoder()
2
+
3
+ export const U256_BASE = 1n << 256n
4
+
5
+ export const U8_MAX = 0xff
6
+ export const U16_MAX = 0xffff
7
+ export const U32_MAX = 0xffffffff
8
+
9
+ export const I8_MIN = -0x80
10
+ export const I8_MAX = 0x7f
11
+ export const I16_MIN = -0x8000
12
+ export const I16_MAX = 0x7fff
13
+ export const I32_MIN = -0x80000000
14
+ export const I32_MAX = 0x7fffffff
15
+
16
+ export const U64_MAX_BI = 0xffffffffffffffffn
17
+ export const I64_MIN_BI = -0x8000000000000000n
18
+ export const I64_MAX_BI = 0x7ffffffffffffffen
19
+
20
+ export const U128_MAX_BI = 0xffffffffffffffffffffffffffffffffn
21
+ export const I128_MIN_BI = -0x80000000000000000000000000000000n
22
+ export const I128_MAX_BI = 0x7fffffffffffffffffffffffffffffffn
23
+
24
+ export const U256_MAX_BI = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn
25
+ export const I256_MIN_BI = -0x8000000000000000000000000000000000000000000000000000000000000000n
26
+ export const I256_MAX_BI = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn