@subsquid/evm-typegen 4.5.1 → 5.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.
package/src/typegen.ts CHANGED
@@ -1,254 +1,303 @@
1
- import { Logger } from '@subsquid/logger'
2
- import { def } from '@subsquid/util-internal'
3
- import { keccak256 } from '@subsquid/evm-abi'
4
- import { getType } from './util/types'
5
- import type { Abi, AbiEvent, AbiFunction, AbiParameter } from 'abitype'
6
- import { FileOutput, OutDir } from '@subsquid/util-internal-code-printer'
1
+ import type {Logger} from '@subsquid/logger'
2
+ import {FileOutput, type OutDir} from '@subsquid/util-internal-code-printer'
3
+ import type {Abi} from 'abitype'
4
+ import * as fs from 'node:fs'
5
+ import {type ContractDef, type DocDef, type EventDef, type FieldDef, type FunctionDef, type NatSpec, type TypeDef, describe} from './description'
6
+
7
+ type Import = {name: string; alias?: string; type?: boolean}
7
8
 
8
9
  export class Typegen {
9
- private out: FileOutput
10
-
11
- constructor(
12
- dest: OutDir,
13
- private abi: Abi,
14
- basename: string,
15
- private log: Logger,
16
- ) {
17
- this.out = dest.file(basename + '.ts')
18
- }
19
-
20
- async generate() {
21
- this.out.line(`import * as p from '@subsquid/evm-codec'`)
22
- this.out.line(
23
- `import { event, fun, viewFun, indexed, ContractBase } from '@subsquid/evm-abi'`,
24
- )
25
- this.out.line(
26
- `import type { EventParams as EParams, FunctionArguments, FunctionReturn } from '@subsquid/evm-abi'`,
27
- )
28
-
29
- this.generateEvents()
30
- this.generateFunctions()
31
- this.generateContract()
32
- this.generateEventTypes()
33
- this.generateFunctionTypes()
34
-
35
- await this.out.write()
36
- this.log.info(`saved ${this.out.file}`)
37
- }
38
-
39
- private generateEvents() {
40
- let events = this.getEvents()
41
- if (events.length == 0) {
42
- return
43
- }
44
- this.out.line()
45
- this.out.block(`export const events =`, () => {
46
- for (let e of events) {
47
- this.out.line(
48
- `${this.getPropName(e)}: event("${this.topic0(e)}", "${this.signature(e)}", {${this.toTypes(
49
- e.inputs,
50
- )}}),`,
51
- )
52
- }
53
- })
54
- }
55
-
56
- private topic0(e: AbiEvent): string {
57
- return `0x${keccak256(this.signature(e)).toString('hex')}`
58
- }
59
-
60
- private toTypes(inputs: readonly AbiParameter[]): string {
61
- return inputs.map((input, idx) => getType(input, idx)).join(', ')
62
- }
63
-
64
- private generateFunctions() {
65
- let functions = this.getFunctions()
66
- if (functions.length == 0) {
67
- return
10
+ private dest: OutDir
11
+ private contract: ContractDef
12
+ private modules = new Set<'events' | 'functions'>()
13
+
14
+ constructor(
15
+ dest: OutDir,
16
+ abi: Abi,
17
+ basename: string,
18
+ private log: Logger,
19
+ natspec?: NatSpec,
20
+ ) {
21
+ // Earlier versions of typegen emitted a single `${basename}.ts` file
22
+ // alongside the output dir. The current layout is a directory
23
+ // (`${basename}/index.ts` etc.). When TypeScript resolves
24
+ // `import './abi/foo'` it prefers `foo.ts` over `foo/index.ts`, so
25
+ // a stale legacy file would silently shadow the freshly generated
26
+ // module — builds keep passing against the old contents. Detect and
27
+ // remove the legacy file before we lay down the new directory.
28
+ const legacy = dest.path(`${basename}.ts`)
29
+ if (fs.existsSync(legacy) && fs.statSync(legacy).isFile()) {
30
+ log.warn(`removing stale ${legacy} from a previous typegen layout`)
31
+ fs.unlinkSync(legacy)
32
+ }
33
+ this.dest = dest.child(basename)
34
+ this.contract = describe(abi, natspec)
68
35
  }
69
- this.out.line()
70
- this.out.block(`export const functions =`, () => {
71
- for (let f of functions) {
72
- let returnType = ''
73
- if (f.outputs?.length === 1) {
74
- returnType = getType({ ...f.outputs[0], name: undefined })
36
+
37
+ async generate(): Promise<void> {
38
+ if (this.contract.events.length > 0) {
39
+ this.generateEvents()
40
+ this.modules.add('events')
75
41
  }
76
- if (f.outputs?.length > 1) {
77
- returnType = `{${this.toTypes(f.outputs)}}`
42
+ if (this.contract.functions.length > 0) {
43
+ this.generateFunctions()
44
+ this.modules.add('functions')
78
45
  }
79
- const funType = f.stateMutability === 'view' || f.stateMutability === 'pure' ? 'viewFun' : 'fun'
80
- this.out.line(
81
- `${this.getPropName(f)}: ${funType}("${this.functionSelector(
82
- f,
83
- )}", "${this.signature(f)}", {${this.toTypes(f.inputs)}}, ${returnType}),`,
84
- )
85
- }
86
- })
87
- }
88
-
89
- private functionSelector(f: AbiFunction): string {
90
- const sighash = this.signature(f)
91
- return `0x${keccak256(sighash).slice(0, 4).toString('hex')}`
92
- }
93
-
94
- private generateContract() {
95
- this.out.line()
96
- this.out.block(`export class Contract extends ContractBase`, () => {
97
- let functions = this.getFunctions()
98
- for (let f of functions) {
99
- if ((f.stateMutability === 'pure' || f.stateMutability === 'view') &&
100
- f.outputs?.length
101
- ) {
102
- this.out.line()
103
- let argNames = f.inputs.map((a, idx) => a.name || `_${idx}`)
104
- const ref = this.getPropNameGetter(f)
105
- const [argsType] = this.toFunctionTypes(f)
106
- let args = f.inputs
107
- .map(
108
- (a, idx) =>
109
- `${argNames[idx]}: ${argsType}["${argNames[idx]}"]`,
110
- )
111
- .join(', ')
112
- this.out.block(`${this.getPropName(f)}(${args})`, () => {
113
- this.out.line(
114
- `return this.eth_call(functions${ref}, {${argNames.join(', ')}})`,
115
- )
116
- })
46
+ this.generateContract()
47
+ this.writeIndex()
48
+ }
49
+
50
+ private generateEvents(): void {
51
+ const out = new TypeModuleOutput(this.dest.path('events.ts'))
52
+ out.import('support', 'event')
53
+ out.import('support', 'EventParams', 'EParams', true)
54
+
55
+ for (let i = 0; i < this.contract.events.length; i++) {
56
+ if (i > 0) out.line()
57
+ out.printEvent(this.contract.events[i])
117
58
  }
118
- }
119
- })
120
- }
121
59
 
122
- private canonicalType(param: AbiParameter): string {
123
- if (!param.type.startsWith('tuple')) {
124
- return param.type
60
+ out.write()
61
+ this.log.info(`saved ${out.file}`)
125
62
  }
126
- const arrayBrackets = param.type.slice(5)
127
- return `(${(param as any).components.map((param: AbiParameter) =>
128
- this.canonicalType(param),
129
- )})${arrayBrackets}`
130
- }
131
-
132
- private signature(item: AbiEvent | AbiFunction): string {
133
- return `${item.name}(${item.inputs
134
- .map((param) => this.canonicalType(param))
135
- .join(',')})`
136
- }
137
-
138
- private getPropName(item: AbiEvent | AbiFunction): string {
139
- if (this.getOverloads(item) == 1) {
140
- return item.name
141
- } else if (item.type === 'function') {
142
- return `'${this.signature(item)}'`
143
- } else {
144
- return `'${item.name}(${item.inputs
145
- .map((param) => this.canonicalType(param) + (param.indexed ? ` indexed` : ``))
146
- .join(',')})'`
63
+
64
+ private generateFunctions(): void {
65
+ const out = new TypeModuleOutput(this.dest.path('functions.ts'))
66
+ out.import('support', 'FunctionArguments', undefined, true)
67
+ out.import('support', 'FunctionReturn', undefined, true)
68
+
69
+ for (let i = 0; i < this.contract.functions.length; i++) {
70
+ if (i > 0) out.line()
71
+ out.printFunction(this.contract.functions[i])
72
+ }
73
+
74
+ out.write()
75
+ this.log.info(`saved ${out.file}`)
147
76
  }
148
- }
149
77
 
150
- private getPropNameGetter(item: AbiEvent | AbiFunction): string {
151
- if (this.getOverloads(item) == 1) {
152
- return '.' + item.name
153
- } else{
154
- return `[${this.getPropName(item)}]`
78
+ private generateContract(): void {
79
+ const viewFns = this.contract.functions.filter((f) => f.outputs.length > 0)
80
+
81
+ const out = new TypeModuleOutput(this.dest.path('contract.ts'))
82
+ out.import('support', 'ContractBase')
83
+
84
+ for (const f of viewFns) {
85
+ out.importFrom('./functions.js', {name: f.key})
86
+ if (f.inputs.length > 0) {
87
+ out.importFrom('./functions.js', {name: f.paramsTypeName, type: true})
88
+ }
89
+ }
90
+
91
+ out.line('export class Contract extends ContractBase {')
92
+ out.indentation(() => {
93
+ for (let i = 0; i < viewFns.length; i++) {
94
+ const f = viewFns[i]
95
+ if (i > 0) out.line()
96
+ const argNames = f.inputs.map((a) => a.name)
97
+ const argList = f.inputs
98
+ .map((a) => `${a.name}: ${f.paramsTypeName}[${JSON.stringify(a.name)}]`)
99
+ .join(', ')
100
+ out.line(`${f.key}(${argList}) {`)
101
+ out.indentation(() => {
102
+ const argsObj = argNames.length === 0 ? '{}' : `{${argNames.join(', ')}}`
103
+ out.line(`return this.eth_call(${f.key}, ${argsObj})`)
104
+ })
105
+ out.line('}')
106
+ }
107
+ })
108
+ out.line('}')
109
+
110
+ out.write()
111
+ this.log.info(`saved ${out.file}`)
155
112
  }
156
- }
157
113
 
158
- private getOverloads(item: AbiEvent | AbiFunction): number {
159
- if (item.type === 'event') {
160
- return this.eventOverloads()[item.name]
161
- } else {
162
- return this.functionOverloads()[item.name]
114
+ private writeIndex(): void {
115
+ const out = new FileOutput(this.dest.path('index.ts'))
116
+ for (const m of this.modules) {
117
+ out.line(`export * as ${m} from './${m}.js'`)
118
+ }
119
+ out.line()
120
+ out.line(`export { Contract } from './contract.js'`)
121
+ out.write()
122
+ this.log.info(`saved ${out.file}`)
163
123
  }
164
- }
124
+ }
125
+
126
+ const EVM_CODEC_MODULE = '@subsquid/evm-codec'
127
+ const SUPPORT_MODULE = '../abi.support.js'
165
128
 
166
- private capitalize(s: string): string {
167
- return s.charAt(0).toUpperCase() + s.slice(1)
168
- }
129
+ const BUCKETS = {
130
+ evmCodec: EVM_CODEC_MODULE,
131
+ support: SUPPORT_MODULE,
132
+ } as const
169
133
 
170
- private getOverloadIndex(item: AbiEvent | AbiFunction): number {
171
- const abi = [...this.getEvents(), ...this.getFunctions()]
172
- const overloads = abi.filter((x) => x.name === item.name)
173
- return overloads.findIndex((x) => x === item)
174
- }
134
+ class TypeModuleOutput extends FileOutput {
135
+ // Seeded so evm-codec + abi.support always appear first in the output.
136
+ private imports = new Map<string, Import[]>([
137
+ [EVM_CODEC_MODULE, []],
138
+ [SUPPORT_MODULE, []],
139
+ ])
175
140
 
176
- private toEventType(e: AbiEvent): string {
177
- if (this.getOverloads(e) === 1) {
178
- return `${this.capitalize(e.name)}EventArgs`
141
+ constructor(file: string) {
142
+ super(file)
143
+ this.lazy(() => {
144
+ let printed = 0
145
+ for (const [from, imps] of this.imports) {
146
+ printed += this.printImports(from, imps)
147
+ }
148
+ if (printed > 0) this.line()
149
+ })
179
150
  }
180
- const index = this.getOverloadIndex(e)
181
- return `${this.capitalize(e.name)}EventArgs_${index}`
182
- }
183
-
184
- private generateEventTypes() {
185
- const events = this.getEvents()
186
- if (events.length == 0) {
187
- return
151
+
152
+ import(bucket: keyof typeof BUCKETS, name: string, alias?: string, type = false): void {
153
+ this.importFrom(BUCKETS[bucket], {name, alias, type})
188
154
  }
189
- this.out.line()
190
- this.out.line(`/// Event types`)
191
- for (let e of events) {
192
- const propName = this.getPropNameGetter(e)
193
- this.out.line(
194
- `export type ${this.toEventType(e)} = EParams<typeof events${propName}>`,
195
- )
155
+
156
+ importFrom(from: string, imp: Import): void {
157
+ let list = this.imports.get(from)
158
+ if (!list) {
159
+ list = []
160
+ this.imports.set(from, list)
161
+ }
162
+ list.push(imp)
196
163
  }
197
- }
198
164
 
199
- private toFunctionTypes(f: AbiFunction): [string, string] {
200
- if (this.getOverloads(f) === 1) {
201
- return [`${this.capitalize(f.name)}Params`, `${this.capitalize(f.name)}Return`]
165
+ private printImports(from: string, imports: Import[]): number {
166
+ if (imports.length === 0) return 0
167
+ const seen = new Set<string>()
168
+ const values: Import[] = []
169
+ const types: Import[] = []
170
+ for (const imp of imports) {
171
+ const key = `${imp.type ? 't' : 'v'}:${imp.name}:${imp.alias || ''}`
172
+ if (seen.has(key)) continue
173
+ seen.add(key)
174
+ ;(imp.type ? types : values).push(imp)
175
+ }
176
+ const fmt = (list: Import[]) =>
177
+ list
178
+ .map((i) => (i.alias ? `${i.name} as ${i.alias}` : i.name))
179
+ .sort()
180
+ .join(', ')
181
+ if (values.length > 0) this.line(`import { ${fmt(values)} } from '${from}'`)
182
+ if (types.length > 0) this.line(`import type { ${fmt(types)} } from '${from}'`)
183
+ return (values.length > 0 ? 1 : 0) + (types.length > 0 ? 1 : 0)
202
184
  }
203
- const index = this.getOverloadIndex(f)
204
- return [`${this.capitalize(f.name)}Params_${index}`, `${this.capitalize(f.name)}Return_${index}`]
205
- }
206
-
207
- private generateFunctionTypes() {
208
- let functions = this.getFunctions()
209
- if (functions.length == 0) {
210
- return
185
+
186
+ printDoc(signature: string, docs: DocDef | undefined): void {
187
+ const docLines: string[] = []
188
+ if (docs?.notice) docLines.push(docs.notice)
189
+ if (docs?.dev) docLines.push(`@dev ${docs.dev}`)
190
+ if (docLines.length === 0) {
191
+ this.line(`/** ${signature} */`)
192
+ } else {
193
+ this.line('/**')
194
+ this.line(` * ${signature}`)
195
+ this.line(' *')
196
+ for (const l of docLines) this.line(` * ${l}`)
197
+ this.line(' */')
198
+ }
211
199
  }
212
- this.out.line()
213
- this.out.line(`/// Function types`)
214
- for (let f of functions) {
215
- const propName = this.getPropNameGetter(f)
216
- const [args, ret] = this.toFunctionTypes(f)
217
- this.out.line(
218
- `export type ${args} = FunctionArguments<typeof functions${propName}>`,
219
- )
220
- this.out.line(
221
- `export type ${ret} = FunctionReturn<typeof functions${propName}>`,
222
- )
223
- this.out.line()
200
+
201
+ printEvent(e: EventDef): void {
202
+ this.printDoc(e.signature, e.docs)
203
+ if (e.inputs.length === 0) {
204
+ this.line(`export const ${e.key} = event('${e.topic}', {})`)
205
+ } else {
206
+ this.line(`export const ${e.key} = event('${e.topic}', {`)
207
+ this.indentation(() => {
208
+ for (const f of e.inputs) this.printFieldDsl(f, ',')
209
+ })
210
+ this.line('})')
211
+ }
212
+ this.line(`export type ${e.typeName} = EParams<typeof ${e.key}>`)
224
213
  }
225
- }
226
214
 
227
- @def
228
- private functionOverloads(): Record<string, number> {
229
- let overloads: Record<string, number> = {}
230
- for (let item of this.getFunctions()) {
231
- overloads[item.name] = (overloads[item.name] || 0) + 1
215
+ printFunction(f: FunctionDef): void {
216
+ this.import('support', 'func')
217
+
218
+ this.printDoc(f.signature, f.docs)
219
+ const prefix = `export const ${f.key} = func('${f.selector}', `
220
+ const hasInputs = f.inputs.length > 0
221
+ const hasOutputs = f.outputs.length > 0
222
+ const singleReturn = f.outputs.length === 1
223
+
224
+ if (!hasInputs && !hasOutputs) {
225
+ this.line(`${prefix}{})`)
226
+ } else if (!hasInputs && singleReturn) {
227
+ this.printTypeDsl(`${prefix}{}, `, f.outputs[0].type, ')')
228
+ } else if (!hasInputs) {
229
+ this.import('evmCodec', 'struct')
230
+ this.line(`${prefix}{}, struct({`)
231
+ this.indentation(() => {
232
+ for (const o of f.outputs) this.printFieldDsl(o, ',')
233
+ })
234
+ this.line('}))')
235
+ } else {
236
+ this.line(`${prefix}{`)
237
+ this.indentation(() => {
238
+ for (const inp of f.inputs) this.printFieldDsl(inp, ',')
239
+ })
240
+ if (!hasOutputs) {
241
+ this.line('})')
242
+ } else if (singleReturn) {
243
+ this.printTypeDsl('}, ', f.outputs[0].type, ')')
244
+ } else {
245
+ this.import('evmCodec', 'struct')
246
+ this.line('}, struct({')
247
+ this.indentation(() => {
248
+ for (const o of f.outputs) this.printFieldDsl(o, ',')
249
+ })
250
+ this.line('}))')
251
+ }
252
+ }
253
+
254
+ this.line(`export type ${f.paramsTypeName} = FunctionArguments<typeof ${f.key}>`)
255
+ this.line(`export type ${f.returnTypeName} = FunctionReturn<typeof ${f.key}>`)
232
256
  }
233
- return overloads
234
- }
235
-
236
- @def
237
- private eventOverloads(): Record<string, number> {
238
- let overloads: Record<string, number> = {}
239
- for (let item of this.getEvents()) {
240
- overloads[item.name] = (overloads[item.name] || 0) + 1
257
+
258
+ private printFieldDsl(f: FieldDef, end: string): void {
259
+ if (f.doc) this.line(`/** ${f.doc} */`)
260
+ const start = `${propKey(f.name)}: `
261
+ if (f.indexed) {
262
+ this.import('support', 'indexed')
263
+ this.printTypeDsl(`${start}indexed(`, f.type, `)${end}`)
264
+ return
265
+ }
266
+ this.printTypeDsl(start, f.type, end)
241
267
  }
242
- return overloads
243
- }
244
-
245
- @def
246
- private getFunctions(): AbiFunction[] {
247
- return this.abi.filter((f) => f.type === 'function') as AbiFunction[]
248
- }
249
-
250
- @def
251
- private getEvents(): AbiEvent[] {
252
- return this.abi.filter((f) => f.type === 'event') as AbiEvent[]
253
- }
268
+
269
+ private printTypeDsl(start: string, type: TypeDef, end: string): void {
270
+ switch (type.kind) {
271
+ case 'primitive':
272
+ this.import('evmCodec', type.name)
273
+ this.line(start + type.name + end)
274
+ return
275
+ case 'array':
276
+ this.import('evmCodec', 'array')
277
+ this.printTypeDsl(`${start}array(`, type.item, `)${end}`)
278
+ return
279
+ case 'fixedArray':
280
+ this.import('evmCodec', 'fixedSizeArray')
281
+ this.printTypeDsl(`${start}fixedSizeArray(`, type.item, `, ${type.size})${end}`)
282
+ return
283
+ case 'tuple': {
284
+ this.import('evmCodec', 'struct')
285
+ if (type.fields.length === 0) {
286
+ this.line(`${start}struct({})${end}`)
287
+ return
288
+ }
289
+ this.line(`${start}struct({`)
290
+ this.indentation(() => {
291
+ for (const f of type.fields) this.printFieldDsl(f, ',')
292
+ })
293
+ this.line(`})${end}`)
294
+ return
295
+ }
296
+ }
297
+ }
298
+ }
299
+
300
+ function propKey(name: string): string {
301
+ if (/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) return name
302
+ return JSON.stringify(name)
254
303
  }
@@ -1,3 +0,0 @@
1
- import type { AbiEventParameter } from 'abitype';
2
- export declare function getType(param: AbiEventParameter, index?: number): string;
3
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/util/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAkBhD,wBAAgB,OAAO,CAAC,KAAK,EAAE,iBAAiB,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAmCxE"}
package/lib/util/types.js DELETED
@@ -1,46 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getType = getType;
4
- function isStaticArray(param) {
5
- return param.type.match(/\[\d+]$/);
6
- }
7
- function isDynamicArray(param) {
8
- return param.type.endsWith('[]');
9
- }
10
- function elementsCount(param) {
11
- return Number(param.type.match(/\[(\d+)]$/)?.[1] ?? 0);
12
- }
13
- function arrayChildType(param) {
14
- return param.type.replace(/\[\d*]$/, '');
15
- }
16
- function getType(param, index) {
17
- const { name, ...namelessParam } = param;
18
- if (name) {
19
- return `"${name}": ${getType(namelessParam)}`;
20
- }
21
- if (index !== undefined) {
22
- return `"_${index}": ${getType(namelessParam)}`;
23
- }
24
- const { indexed, ...indexlessParam } = param;
25
- if (indexed) {
26
- return `indexed(${getType(indexlessParam)})`;
27
- }
28
- if (isStaticArray(param)) {
29
- const elements = elementsCount(param);
30
- return `p.fixedSizeArray(${getType({
31
- ...param,
32
- type: arrayChildType(param),
33
- })}, ${elements})`;
34
- }
35
- if (isDynamicArray(param)) {
36
- return `p.array(${getType({
37
- ...param,
38
- type: arrayChildType(param),
39
- })})`;
40
- }
41
- if (param.type === 'tuple') {
42
- return `p.struct({${param.components.map((type, idx) => getType(type, idx)).join(', ')}})`;
43
- }
44
- return `p.${param.type}`;
45
- }
46
- //# sourceMappingURL=types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/util/types.ts"],"names":[],"mappings":";;AAkBA,0BAmCC;AAnDD,SAAS,aAAa,CAAC,KAAwB;IAC7C,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;AACpC,CAAC;AAED,SAAS,cAAc,CAAC,KAAwB;IAC9C,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;AAClC,CAAC;AAED,SAAS,aAAa,CAAC,KAAwB;IAC7C,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;AACxD,CAAC;AAED,SAAS,cAAc,CAAC,KAAwB;IAC9C,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA;AAC1C,CAAC;AAED,SAAgB,OAAO,CAAC,KAAwB,EAAE,KAAc;IAC9D,MAAM,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,GAAG,KAAK,CAAA;IAExC,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,IAAI,IAAI,MAAM,OAAO,CAAC,aAAoB,CAAC,EAAE,CAAA;IACtD,CAAC;IAED,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC,aAAa,CAAC,EAAE,CAAA;IACjD,CAAC;IAED,MAAM,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,GAAG,KAAK,CAAA;IAC5C,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,WAAW,OAAO,CAAC,cAAqB,CAAC,GAAG,CAAA;IACrD,CAAC;IACD,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,CAAC,CAAA;QACrC,OAAO,oBAAoB,OAAO,CAAC;YACjC,GAAG,KAAK;YACR,IAAI,EAAE,cAAc,CAAC,KAAK,CAAC;SAC5B,CAAC,KAAK,QAAQ,GAAG,CAAA;IACpB,CAAC;IAED,IAAI,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,WAAW,OAAO,CAAC;YACxB,GAAG,KAAK;YACR,IAAI,EAAE,cAAc,CAAC,KAAK,CAAC;SAC5B,CAAC,GAAG,CAAA;IACP,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC3B,OAAO,aAAc,KAAa,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAuB,EAAE,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAA;IAChI,CAAC;IAED,OAAO,KAAK,KAAK,CAAC,IAAI,EAAE,CAAA;AAC1B,CAAC"}
package/src/util/types.ts DELETED
@@ -1,54 +0,0 @@
1
- import type { AbiEventParameter } from 'abitype'
2
-
3
- function isStaticArray(param: AbiEventParameter) {
4
- return param.type.match(/\[\d+]$/)
5
- }
6
-
7
- function isDynamicArray(param: AbiEventParameter) {
8
- return param.type.endsWith('[]')
9
- }
10
-
11
- function elementsCount(param: AbiEventParameter) {
12
- return Number(param.type.match(/\[(\d+)]$/)?.[1] ?? 0)
13
- }
14
-
15
- function arrayChildType(param: AbiEventParameter) {
16
- return param.type.replace(/\[\d*]$/, '')
17
- }
18
-
19
- export function getType(param: AbiEventParameter, index?: number): string {
20
- const { name, ...namelessParam } = param
21
-
22
- if (name) {
23
- return `"${name}": ${getType(namelessParam as any)}`
24
- }
25
-
26
- if (index !== undefined) {
27
- return `"_${index}": ${getType(namelessParam)}`
28
- }
29
-
30
- const { indexed, ...indexlessParam } = param
31
- if (indexed) {
32
- return `indexed(${getType(indexlessParam as any)})`
33
- }
34
- if (isStaticArray(param)) {
35
- const elements = elementsCount(param)
36
- return `p.fixedSizeArray(${getType({
37
- ...param,
38
- type: arrayChildType(param),
39
- })}, ${elements})`
40
- }
41
-
42
- if (isDynamicArray(param)) {
43
- return `p.array(${getType({
44
- ...param,
45
- type: arrayChildType(param),
46
- })})`
47
- }
48
-
49
- if (param.type === 'tuple') {
50
- return `p.struct({${(param as any).components.map((type: AbiEventParameter, idx: number) => getType(type, idx)).join(', ')}})`
51
- }
52
-
53
- return `p.${param.type}`
54
- }