@@ -232,6 +232,84 @@ def test_rest_requires_env_and_path_map():
232232 _ok (f"ValueError correctly raised for unknown method: { e } " )
233233
234234
235+ # ─────────────────────────────────────────────────────────────────────────────
236+ # Test 8 (S3-A): JsonRpc new formats — block_number / block_number_int /
237+ # transaction_hash / eth_call_object_latest / object_single
238+ # ─────────────────────────────────────────────────────────────────────────────
239+ def test_jsonrpc_s3a_new_formats ():
240+ print ("\n [8] JsonRpc S3-A new formats (5 EVM-compat chains)" )
241+ a = get_adapter ("arbitrum" ) # any jsonrpc chain works
242+ url = "http://x"
243+
244+ # block_number → ["latest", false]
245+ t = a .build_vegeta_target ("eth_getBlockByNumber" , "0xabc" , url , "block_number" )
246+ body = json .loads (base64 .b64decode (t ["body" ]))
247+ assert body ["params" ] == ["latest" , False ], f"block_number wrong: { body ['params' ]} "
248+ _ok (f"block_number → { body ['params' ]} " )
249+
250+ # block_number_int → [<int>]
251+ t = a .build_vegeta_target ("zks_getBlockDetails" , "60100000" , url , "block_number_int" )
252+ body = json .loads (base64 .b64decode (t ["body" ]))
253+ assert body ["params" ] == [60100000 ], f"block_number_int wrong: { body ['params' ]} "
254+ _ok (f"block_number_int (int address) → { body ['params' ]} " )
255+ # fallback when address not int-parseable
256+ t = a .build_vegeta_target ("zks_getBlockDetails" , "not_an_int" , url , "block_number_int" )
257+ body = json .loads (base64 .b64decode (t ["body" ]))
258+ assert body ["params" ] == [1 ], f"block_number_int fallback wrong: { body ['params' ]} "
259+ _ok (f"block_number_int (bad address) → fallback { body ['params' ]} " )
260+
261+ # transaction_hash → [<tx_hash>]
262+ # with valid 0x + 64-hex address-as-hash:
263+ fake_hash = "0x" + "ab" * 32
264+ t = a .build_vegeta_target ("eth_getTransactionReceipt" , fake_hash , url , "transaction_hash" )
265+ body = json .loads (base64 .b64decode (t ["body" ]))
266+ assert body ["params" ] == [fake_hash ], f"transaction_hash wrong: { body ['params' ]} "
267+ _ok (f"transaction_hash (valid) → { body ['params' ][0 ][:18 ]} ..." )
268+ # fallback when address is not a tx hash shape:
269+ t = a .build_vegeta_target ("eth_getTransactionReceipt" , "0xshort" , url , "transaction_hash" )
270+ body = json .loads (base64 .b64decode (t ["body" ]))
271+ assert body ["params" ] == ["0x" + "0" * 64 ], f"transaction_hash fallback wrong: { body ['params' ]} "
272+ _ok (f"transaction_hash (short addr) → fallback { body ['params' ][0 ][:18 ]} ..." )
273+
274+ # eth_call_object_latest → [{to, data}, "latest"]
275+ t = a .build_vegeta_target ("eth_call" , "0xc0ffee" , url , "eth_call_object_latest" )
276+ body = json .loads (base64 .b64decode (t ["body" ]))
277+ assert body ["params" ][1 ] == "latest" , f"eth_call missing latest: { body ['params' ]} "
278+ assert body ["params" ][0 ]["to" ] == "0xc0ffee" , f"eth_call to wrong: { body ['params' ]} "
279+ assert body ["params" ][0 ]["data" ].startswith ("0x70a08231" ), f"data missing balanceOf selector: { body ['params' ]} "
280+ _ok (f"eth_call_object_latest → [{{to,data}}, latest]" )
281+
282+ # object_single → [{from, to, value}]
283+ t = a .build_vegeta_target ("linea_estimateGas" , "0xc0ffee" , url , "object_single" )
284+ body = json .loads (base64 .b64decode (t ["body" ]))
285+ assert isinstance (body ["params" ], list ) and len (body ["params" ]) == 1
286+ assert body ["params" ][0 ]["from" ] == "0xc0ffee"
287+ assert body ["params" ][0 ]["value" ] == "0x1"
288+ _ok (f"object_single → [{{from,to,value}}] single-elem list" )
289+
290+
291+ # ─────────────────────────────────────────────────────────────────────────────
292+ # Test 9 (S3-A): 5 EVM-compat chains have only standard-enum param_formats
293+ # ─────────────────────────────────────────────────────────────────────────────
294+ def test_evm_compat_5chains_standard_enum ():
295+ print ("\n [9] EVM-compat 5 chains: param_formats ⊂ adapter standard enum" )
296+ STANDARD = {
297+ "no_params" , "single_address" , "address_latest" , "latest_address" ,
298+ "address_storage_latest" , "address_key_latest" , "address_with_options" ,
299+ "block_number" , "block_number_int" , "transaction_hash" ,
300+ "eth_call_object_latest" , "object_single" ,
301+ }
302+ EVM_COMPAT = ["arbitrum" , "optimism" , "zksync-era" , "linea" , "avalanche-c" ]
303+ for chain in EVM_COMPAT :
304+ p = REPO / "config" / "chains" / f"{ chain } .json"
305+ data = json .loads (p .read_text ())
306+ pf = data .get ("param_formats" , {})
307+ bad = {m : f for m , f in pf .items () if f not in STANDARD }
308+ if bad :
309+ _fail (f"{ chain } has nonstandard formats: { bad } " )
310+ _ok (f"{ chain } : { len (pf )} formats all standard" )
311+
312+
235313# ─────────────────────────────────────────────────────────────────────────────
236314# Main
237315# ─────────────────────────────────────────────────────────────────────────────
@@ -244,6 +322,8 @@ def main():
244322 test_health_check_requests ,
245323 test_bitcoin_auth ,
246324 test_rest_requires_env_and_path_map ,
325+ test_jsonrpc_s3a_new_formats ,
326+ test_evm_compat_5chains_standard_enum ,
247327 ]
248328 print (f"Running { len (tests )} test groups for chain_adapters" )
249329 for t in tests :
0 commit comments