@@ -17,10 +17,10 @@ const defaultOpts = {
17
17
18
18
const sleuthDeployer = process . env [ 'SLEUTH_DEPLOYER' ] ?? '0x84C3e20985d9E7aEc46F80d2EB52b731D8CC40F8' ;
19
19
20
- interface Query < T > {
20
+ interface Query < T , A extends any [ ] = [ ] > {
21
21
bytecode : string ,
22
22
callargs ?: string ,
23
- abi : ReadonlyArray < ParamType >
23
+ fn : FunctionFragment
24
24
}
25
25
26
26
interface Source {
@@ -84,16 +84,18 @@ export class Sleuth {
84
84
version : number ;
85
85
sleuthAddr : string ;
86
86
sources : Source [ ] ;
87
+ coder : AbiCoder ;
87
88
88
89
constructor ( provider : Provider , opts : Opts = { } ) {
89
90
this . provider = provider ;
90
91
this . network = opts . network ?? defaultOpts . network ;
91
92
this . version = opts . version ?? defaultOpts . version ;
92
93
this . sleuthAddr = getContractAddress ( { from : sleuthDeployer , nonce : this . version - 1 } ) ;
93
94
this . sources = [ ] ;
95
+ this . coder = new AbiCoder ( ) ;
94
96
}
95
97
96
- query < T > ( q : string ) : Query < T > {
98
+ query < T > ( q : string ) : Query < T , [ ] > {
97
99
let registrations = this . sources . map ( ( source ) => {
98
100
let iface = JSON . stringify ( source . iface . format ( FormatTypes . full ) ) ;
99
101
return `REGISTER CONTRACT ${ source . name } AT ${ source . address } WITH INTERFACE ${ iface } ;`
@@ -132,11 +134,17 @@ export class Sleuth {
132
134
133
135
return {
134
136
bytecode : bytecode ,
135
- abi : ParamType . from ( tuple ) . components
137
+ fn : FunctionFragment . from ( {
138
+ name : 'query' ,
139
+ inputs : [ ] ,
140
+ outputs : ParamType . from ( tuple ) . components ,
141
+ stateMutability : 'pure' ,
142
+ type : 'function'
143
+ } )
136
144
} ;
137
145
}
138
146
139
- static querySol < T > ( q : string | object , opts : SolidityQueryOpts = { } ) : Query < T > {
147
+ static querySol < T , A extends any [ ] = [ ] > ( q : string | object , opts : SolidityQueryOpts = { } ) : Query < T , A > {
140
148
if ( typeof ( q ) === 'string' ) {
141
149
let r ;
142
150
try {
@@ -159,7 +167,7 @@ export class Sleuth {
159
167
}
160
168
}
161
169
162
- static querySolOutput < T > ( c : SolcContract , opts : SolidityQueryOpts = { } ) : Query < T > {
170
+ static querySolOutput < T , A extends any [ ] = [ ] > ( c : SolcContract , opts : SolidityQueryOpts = { } ) : Query < T , A > {
163
171
let queryFunctionName = opts . queryFunctionName ?? 'query' ;
164
172
let b = c . evm ?. bytecode ?. object ?? c . bytecode ?. object ;
165
173
if ( ! b ) {
@@ -173,11 +181,11 @@ export class Sleuth {
173
181
174
182
return {
175
183
bytecode : b ,
176
- abi : ( queryAbi as FunctionFragment ) . outputs ?? [ ]
184
+ fn : queryAbi as FunctionFragment
177
185
} ;
178
186
}
179
187
180
- static querySolSource < T > ( q : string , opts : SolidityQueryOpts = { } ) : Query < T > {
188
+ static querySolSource < T , A extends any [ ] = [ ] > ( q : string , opts : SolidityQueryOpts = { } ) : Query < T , A > {
181
189
let fnName = opts . queryFunctionName ?? 'query' ;
182
190
let input = {
183
191
language : 'Solidity' ,
@@ -219,12 +227,16 @@ export class Sleuth {
219
227
this . sources . push ( { name, address, iface} ) ;
220
228
}
221
229
222
- async fetch < T > ( q : Query < T > ) : Promise < T > {
223
- let sleuthCtx = new Contract ( this . sleuthAddr , [ 'function query(bytes) public view returns (bytes)' ] , this . provider ) ;
224
- let queryResult = await sleuthCtx . query ( hexify ( q . bytecode ) ) ;
225
- console . log ( q . abi ) ;
230
+ async fetch < T , A extends any [ ] = [ ] > ( q : Query < T , A > , args ?: A ) : Promise < T > {
231
+ let sleuthCtx = new Contract ( this . sleuthAddr , [
232
+ 'function query(bytes,bytes) public view returns (bytes)'
233
+ ] , this . provider ) ;
234
+ let iface = new Interface ( [ q . fn ] ) ;
235
+ let argsCoded = iface . encodeFunctionData ( q . fn . name , args ?? [ ] ) ;
236
+ let queryResult = await sleuthCtx . query ( hexify ( q . bytecode ) , argsCoded ) ;
237
+ console . log ( q . fn ) ;
226
238
console . log ( queryResult ) ;
227
- let r = new AbiCoder ( ) . decode ( q . abi , queryResult ) as unknown ;
239
+ let r = this . coder . decode ( q . fn . outputs ?? [ ] , queryResult ) as unknown ;
228
240
if ( Array . isArray ( r ) && r . length === 1 ) {
229
241
return r [ 0 ] as T ;
230
242
} else {
@@ -234,6 +246,6 @@ export class Sleuth {
234
246
235
247
async fetchSql < T > ( q : string ) : Promise < T > {
236
248
let query = this . query < T > ( q ) ;
237
- return this . fetch < T > ( query ) ;
249
+ return this . fetch < T , [ ] > ( query , [ ] ) ;
238
250
}
239
251
}
0 commit comments