1
1
import assert from "assert" ;
2
2
3
- import {
4
- FetchRequest ,
5
- OtterscanProvider ,
6
- JsonRpcProvider ,
7
- } from "../index.js" ;
3
+ import { FetchRequest , OtterscanProvider , JsonRpcProvider } from "../index.js" ;
8
4
9
5
import type {
10
6
OtsInternalOp ,
11
7
OtsBlockDetails ,
12
- OtsBlockTxPage ,
13
- OtsSearchResult ,
14
- OtsContractCreator ,
8
+ OtsBlockTransactionsPage ,
9
+ OtsAddressTransactionsPage ,
10
+ OtsContractCreator
15
11
} from "../providers/provider-otterscan.js" ;
16
12
17
- describe ( "Test Otterscan Provider" , function ( ) {
13
+ describe ( "Test Otterscan Provider" , function ( ) {
18
14
// Mock OTS responses for testing
19
15
function createMockOtsProvider ( ) {
20
16
const req = new FetchRequest ( "http://localhost:8545/" ) ;
21
-
17
+
22
18
req . getUrlFunc = async ( _req , signal ) => {
23
- const bodyStr = typeof _req . body === "string" ? _req . body : new TextDecoder ( ) . decode ( _req . body || new Uint8Array ( ) ) ;
19
+ const bodyStr =
20
+ typeof _req . body === "string" ? _req . body : new TextDecoder ( ) . decode ( _req . body || new Uint8Array ( ) ) ;
24
21
const request = JSON . parse ( bodyStr || "{}" ) ;
25
-
22
+
26
23
let result : any ;
27
-
24
+
28
25
switch ( request . method ) {
29
26
case "ots_getApiLevel" :
30
27
result = 8 ;
@@ -34,12 +31,14 @@ describe("Test Otterscan Provider", function() {
34
31
result = request . params [ 0 ] !== "0x0000000000000000000000000000000000000000" ;
35
32
break ;
36
33
case "ots_getInternalOperations" :
37
- result = [ {
38
- type : 0 ,
39
- from : "0x1234567890123456789012345678901234567890" ,
40
- to : "0x0987654321098765432109876543210987654321" ,
41
- value : "0x1000000000000000000"
42
- } ] ;
34
+ result = [
35
+ {
36
+ type : 0 ,
37
+ from : "0x1234567890123456789012345678901234567890" ,
38
+ to : "0x0987654321098765432109876543210987654321" ,
39
+ value : "0x1000000000000000000"
40
+ }
41
+ ] ;
43
42
break ;
44
43
case "ots_getTransactionError" :
45
44
result = "0x" ;
@@ -51,36 +50,86 @@ describe("Test Otterscan Provider", function() {
51
50
result = {
52
51
block : {
53
52
hash : "0x123abc" ,
54
- number : "0x1000"
53
+ number : "0x1000" ,
54
+ timestamp : "0x499602d2" ,
55
+ parentHash : "0x000abc" ,
56
+ nonce : "0x0" ,
57
+ difficulty : "0x0" ,
58
+ gasLimit : "0x1c9c380" ,
59
+ gasUsed : "0x5208" ,
60
+ miner : "0x0000000000000000000000000000000000000000" ,
61
+ extraData : "0x" ,
62
+ baseFeePerGas : "0x0" ,
63
+ logsBloom : null
55
64
} ,
56
- transactionCount : 5 ,
57
65
totalFees : "0x5000000000000000"
58
66
} ;
59
67
break ;
60
68
case "ots_getBlockTransactions" :
61
69
result = {
62
- transactions : [ {
63
- hash : "0x456def" ,
64
- from : "0x1111111111111111111111111111111111111111" ,
65
- to : "0x2222222222222222222222222222222222222222" ,
66
- value : "0x1000000000000000000"
67
- } ] ,
68
- receipts : [ {
69
- status : "0x1" ,
70
- gasUsed : "0x5208"
71
- } ]
70
+ transactions : [
71
+ {
72
+ hash : "0x456def" ,
73
+ from : "0x1111111111111111111111111111111111111111" ,
74
+ to : "0x2222222222222222222222222222222222222222" ,
75
+ value : "0x1000000000000000000"
76
+ }
77
+ ] ,
78
+ receipts : [
79
+ {
80
+ status : "0x1" ,
81
+ gasUsed : "0x5208"
82
+ }
83
+ ]
72
84
} ;
73
85
break ;
74
86
case "ots_searchTransactionsBefore" :
75
87
case "ots_searchTransactionsAfter" :
76
88
result = {
77
- txs : [ {
78
- hash : "0x789ghi" ,
79
- blockNumber : "0x1000"
80
- } ] ,
81
- receipts : [ {
82
- status : "0x1"
83
- } ] ,
89
+ txs : [
90
+ {
91
+ blockHash : "0x5adc8e4d5d8eee95a3b390e9cbed9f1633f94dae073b70f2c890d419b7bb7ca0" ,
92
+ blockNumber : "0x121e890" ,
93
+ from : "0x17076a2bdff9db26544a9201faad098b76b51b31" ,
94
+ gas : "0x5208" ,
95
+ gasPrice : "0x44721f210" ,
96
+ maxPriorityFeePerGas : "0x5f5e100" ,
97
+ maxFeePerGas : "0x5e2b132fb" ,
98
+ hash : "0xe689a340d805b0e6d5f26a4498caecec81752003b9352bb5802819641baaf9a9" ,
99
+ input : "0x" ,
100
+ nonce : "0x1f" ,
101
+ to : "0xd8da6bf26964af9d7eed9e03e53415d37aa96045" ,
102
+ transactionIndex : "0x11" ,
103
+ value : "0x38d7ea4c68000" ,
104
+ type : "0x2" ,
105
+ accessList : [ ] ,
106
+ chainId : "0x1" ,
107
+ v : "0x0" ,
108
+ yParity : "0x0" ,
109
+ r : "0xd3ecccab74bc708d2ead0d913c38990870c31f3f3eee3c7354752c1fdd826b19" ,
110
+ s : "0x275c7656704d35da38b197d3365ef73388d42a8ca2304ce849547ce2348b087"
111
+ }
112
+ ] ,
113
+ receipts : [
114
+ {
115
+ blockHash : "0x5adc8e4d5d8eee95a3b390e9cbed9f1633f94dae073b70f2c890d419b7bb7ca0" ,
116
+ blockNumber : "0x121e890" ,
117
+ contractAddress : null ,
118
+ cumulativeGasUsed : "0x2654c4" ,
119
+ effectiveGasPrice : "0x44721f210" ,
120
+ from : "0x17076a2bdff9db26544a9201faad098b76b51b31" ,
121
+ gasUsed : "0x5208" ,
122
+ logs : [ ] ,
123
+ logsBloom :
124
+ "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" ,
125
+ status : "0x1" ,
126
+ timestamp : 1705166675 ,
127
+ to : "0xd8da6bf26964af9d7eed9e03e53415d37aa96045" ,
128
+ transactionHash : "0xe689a340d805b0e6d5f26a4498caecec81752003b9352bb5802819641baaf9a9" ,
129
+ transactionIndex : "0x11" ,
130
+ type : "0x2"
131
+ }
132
+ ] ,
84
133
firstPage : true ,
85
134
lastPage : false
86
135
} ;
@@ -103,138 +152,146 @@ describe("Test Otterscan Provider", function() {
103
152
default :
104
153
throw new Error ( `Unsupported method: ${ request . method } ` ) ;
105
154
}
106
-
155
+
107
156
const response = {
108
157
id : request . id ,
109
158
jsonrpc : "2.0" ,
110
159
result
111
160
} ;
112
-
161
+
113
162
return {
114
163
statusCode : 200 ,
115
164
statusMessage : "OK" ,
116
165
headers : { "content-type" : "application/json" } ,
117
166
body : new TextEncoder ( ) . encode ( JSON . stringify ( response ) )
118
167
} ;
119
168
} ;
120
-
169
+
121
170
return new OtterscanProvider ( req , 1 , { staticNetwork : true } ) ;
122
171
}
123
172
124
- it ( "should extend JsonRpcProvider" , function ( ) {
173
+ it ( "should extend JsonRpcProvider" , function ( ) {
125
174
const provider = createMockOtsProvider ( ) ;
126
175
assert ( provider instanceof OtterscanProvider , "should be OtterscanProvider instance" ) ;
127
176
assert ( provider instanceof JsonRpcProvider , "should extend JsonRpcProvider" ) ;
128
177
} ) ;
129
178
130
- it ( "should get OTS API level" , async function ( ) {
179
+ it ( "should get OTS API level" , async function ( ) {
131
180
const provider = createMockOtsProvider ( ) ;
132
181
const apiLevel = await provider . otsApiLevel ( ) ;
133
182
assert . strictEqual ( apiLevel , 8 , "should return API level 8" ) ;
134
183
} ) ;
135
184
136
- it ( "should check if address has code" , async function ( ) {
185
+ it ( "should check if address has code" , async function ( ) {
137
186
const provider = createMockOtsProvider ( ) ;
138
-
187
+
139
188
const hasCodeTrue = await provider . hasCode ( "0x1234567890123456789012345678901234567890" ) ;
140
189
assert . strictEqual ( hasCodeTrue , true , "should return true for non-zero address" ) ;
141
-
190
+
142
191
const hasCodeFalse = await provider . hasCode ( "0x0000000000000000000000000000000000000000" ) ;
143
192
assert . strictEqual ( hasCodeFalse , false , "should return false for zero address" ) ;
144
193
} ) ;
145
194
146
- it ( "should get internal operations" , async function ( ) {
195
+ it ( "should get internal operations" , async function ( ) {
147
196
const provider = createMockOtsProvider ( ) ;
148
197
const internalOps = await provider . getInternalOperations ( "0x123" ) ;
149
-
198
+
150
199
assert ( Array . isArray ( internalOps ) , "should return array" ) ;
151
200
assert . strictEqual ( internalOps . length , 1 , "should have one operation" ) ;
152
-
201
+
153
202
const op = internalOps [ 0 ] ;
154
203
assert . strictEqual ( op . type , 0 , "should have type 0" ) ;
155
204
assert . strictEqual ( op . from , "0x1234567890123456789012345678901234567890" , "should have correct from" ) ;
156
205
assert . strictEqual ( op . to , "0x0987654321098765432109876543210987654321" , "should have correct to" ) ;
157
206
assert . strictEqual ( op . value , "0x1000000000000000000" , "should have correct value" ) ;
158
207
} ) ;
159
208
160
- it ( "should get transaction error data" , async function ( ) {
209
+ it ( "should get transaction error data" , async function ( ) {
161
210
const provider = createMockOtsProvider ( ) ;
162
211
const errorData = await provider . getTransactionErrorData ( "0x123" ) ;
163
212
assert . strictEqual ( errorData , "0x" , "should return empty error data" ) ;
164
213
} ) ;
165
214
166
- it ( "should get transaction revert reason" , async function ( ) {
215
+ it ( "should get transaction revert reason" , async function ( ) {
167
216
const provider = createMockOtsProvider ( ) ;
168
217
const revertReason = await provider . getTransactionRevertReason ( "0x123" ) ;
169
218
assert . strictEqual ( revertReason , null , "should return null for no error" ) ;
170
219
} ) ;
171
220
172
- it ( "should trace transaction" , async function ( ) {
221
+ it ( "should trace transaction" , async function ( ) {
173
222
const provider = createMockOtsProvider ( ) ;
174
223
const trace = await provider . traceTransaction ( "0x123" ) ;
175
224
assert ( typeof trace === "object" , "should return trace object" ) ;
176
225
assert ( Array . isArray ( trace . calls ) , "should have calls array" ) ;
177
226
} ) ;
178
227
179
- it ( "should get block details" , async function ( ) {
228
+ it ( "should get block details" , async function ( ) {
180
229
const provider = createMockOtsProvider ( ) ;
181
230
const blockDetails = await provider . getBlockDetails ( 4096 ) ;
182
-
231
+
183
232
assert ( typeof blockDetails === "object" , "should return object" ) ;
184
- assert . strictEqual ( blockDetails . transactionCount , 5 , "should have transaction count" ) ;
233
+ assert . strictEqual (
234
+ blockDetails . block . logsBloom ,
235
+ null ,
236
+ "should have null logsBloom (removed for efficiency)"
237
+ ) ;
185
238
assert . strictEqual ( blockDetails . totalFees , "0x5000000000000000" , "should have total fees" ) ;
186
239
assert ( blockDetails . block , "should have block data" ) ;
187
240
} ) ;
188
241
189
- it ( "should get block transactions" , async function ( ) {
242
+ it ( "should get block transactions" , async function ( ) {
190
243
const provider = createMockOtsProvider ( ) ;
191
244
const blockTxs = await provider . getBlockTransactions ( 4096 , 0 , 10 ) ;
192
-
245
+
193
246
assert ( Array . isArray ( blockTxs . transactions ) , "should have transactions array" ) ;
194
247
assert ( Array . isArray ( blockTxs . receipts ) , "should have receipts array" ) ;
195
248
assert . strictEqual ( blockTxs . transactions . length , 1 , "should have one transaction" ) ;
196
249
assert . strictEqual ( blockTxs . receipts . length , 1 , "should have one receipt" ) ;
197
250
} ) ;
198
251
199
- it ( "should search transactions before" , async function ( ) {
252
+ it ( "should search transactions before" , async function ( ) {
200
253
const provider = createMockOtsProvider ( ) ;
201
254
const searchResults = await provider . searchTransactionsBefore ( "0x123" , 4096 , 10 ) ;
202
-
255
+
203
256
assert ( Array . isArray ( searchResults . txs ) , "should have txs array" ) ;
204
257
assert ( Array . isArray ( searchResults . receipts ) , "should have receipts array" ) ;
205
258
assert . strictEqual ( searchResults . firstPage , true , "should be first page" ) ;
206
259
assert . strictEqual ( searchResults . lastPage , false , "should not be last page" ) ;
207
260
} ) ;
208
261
209
- it ( "should search transactions after" , async function ( ) {
262
+ it ( "should search transactions after" , async function ( ) {
210
263
const provider = createMockOtsProvider ( ) ;
211
264
const searchResults = await provider . searchTransactionsAfter ( "0x123" , 4096 , 10 ) ;
212
-
265
+
213
266
assert ( Array . isArray ( searchResults . txs ) , "should have txs array" ) ;
214
267
assert ( Array . isArray ( searchResults . receipts ) , "should have receipts array" ) ;
215
268
} ) ;
216
269
217
- it ( "should get transaction by sender and nonce" , async function ( ) {
270
+ it ( "should get transaction by sender and nonce" , async function ( ) {
218
271
const provider = createMockOtsProvider ( ) ;
219
272
const txHash = await provider . getTransactionBySenderAndNonce ( "0x123" , 0 ) ;
220
273
assert . strictEqual ( txHash , "0xabcdef123456789" , "should return transaction hash" ) ;
221
274
} ) ;
222
275
223
- it ( "should get contract creator" , async function ( ) {
276
+ it ( "should get contract creator" , async function ( ) {
224
277
const provider = createMockOtsProvider ( ) ;
225
278
const creator = await provider . getContractCreator ( "0x123" ) ;
226
-
279
+
227
280
assert ( typeof creator === "object" , "should return object" ) ;
228
281
assert . strictEqual ( creator ?. hash , "0x987654321" , "should have creation hash" ) ;
229
- assert . strictEqual ( creator ?. creator , "0x1111111111111111111111111111111111111111" , "should have creator address" ) ;
282
+ assert . strictEqual (
283
+ creator ?. creator ,
284
+ "0x1111111111111111111111111111111111111111" ,
285
+ "should have creator address"
286
+ ) ;
230
287
} ) ;
231
288
232
- it ( "should ensure OTS capability" , async function ( ) {
289
+ it ( "should ensure OTS capability" , async function ( ) {
233
290
const provider = createMockOtsProvider ( ) ;
234
-
291
+
235
292
// Should not throw
236
293
await provider . ensureOts ( 8 ) ;
237
-
294
+
238
295
// Should throw for higher requirement
239
296
try {
240
297
await provider . ensureOts ( 10 ) ;
@@ -245,25 +302,25 @@ describe("Test Otterscan Provider", function() {
245
302
}
246
303
} ) ;
247
304
248
- it ( "should have async iterator for address history" , function ( ) {
305
+ it ( "should have async iterator for address history" , function ( ) {
249
306
const provider = createMockOtsProvider ( ) ;
250
307
const iterator = provider . iterateAddressHistory ( "0x123" , "before" , 4096 ) ;
251
-
308
+
252
309
assert ( typeof iterator [ Symbol . asyncIterator ] === "function" , "should be async iterable" ) ;
253
310
} ) ;
254
311
255
- it ( "should properly type return values" , async function ( ) {
312
+ it ( "should properly type return values" , async function ( ) {
256
313
const provider = createMockOtsProvider ( ) ;
257
-
314
+
258
315
// Test TypeScript typing works correctly
259
316
const apiLevel : number = await provider . otsApiLevel ( ) ;
260
317
const hasCode : boolean = await provider . hasCode ( "0x123" ) ;
261
318
const internalOps : OtsInternalOp [ ] = await provider . getInternalOperations ( "0x123" ) ;
262
319
const blockDetails : OtsBlockDetails = await provider . getBlockDetails ( 4096 ) ;
263
- const blockTxs : OtsBlockTxPage = await provider . getBlockTransactions ( 4096 , 0 , 10 ) ;
264
- const searchResults : OtsSearchResult = await provider . searchTransactionsBefore ( "0x123" , 4096 , 10 ) ;
320
+ const blockTxs : OtsBlockTransactionsPage = await provider . getBlockTransactions ( 4096 , 0 , 10 ) ;
321
+ const searchResults : OtsAddressTransactionsPage = await provider . searchTransactionsBefore ( "0x123" , 4096 , 10 ) ;
265
322
const creator : OtsContractCreator | null = await provider . getContractCreator ( "0x123" ) ;
266
-
323
+
267
324
// Basic type assertions
268
325
assert . strictEqual ( typeof apiLevel , "number" ) ;
269
326
assert . strictEqual ( typeof hasCode , "boolean" ) ;
@@ -273,4 +330,4 @@ describe("Test Otterscan Provider", function() {
273
330
assert ( typeof searchResults === "object" && Array . isArray ( searchResults . txs ) ) ;
274
331
assert ( creator === null || typeof creator === "object" ) ;
275
332
} ) ;
276
- } ) ;
333
+ } ) ;
0 commit comments