feat(tmpnetjs): SDK ergonomics — relayer in artifacts, chain-time helpers, library linking, expectRevert#5
Merged
Conversation
…nking, expectRevert
Gaps hit while building a real third-party-contract validation on tmpnet:
- network.json / addresses.ts / .env now include the relayer EOA
(relayer.address, RELAYER, RELAYER_ADDRESS), and DEFAULT_RELAYER_ADDRESS
/ DEFAULT_RELAYER_KEY are exported from the package. Anyone testing
Teleporter allowedRelayerAddresses needs this and previously had to
hardcode the Anvil[0] address. Also fixes the constant's EIP-55
checksum (cfFFb -> cffFb), which viem 2.50+ rejects, and drops the
getAddress() workaround it forced in commands.ts.
- sdk/chain-time.ts: mineBlock + waitForChainTime. Local chains mint
blocks on demand, so block.timestamp stays frozen between txs and gas
estimation rejects any time-guarded call (timelocks, vesting) forever
even after wall-clock time has passed. waitForChainTime sleeps to the
target, then nudges empty blocks until the head is stamped past it.
- loadArtifact(name, { dir }) loads artifacts from an explicit directory
(forge nested or flat layout) instead of only contracts/out, returns
linkReferences, and the new linkLibraries() splices deployed library
addresses over solc's __$hash$__ placeholders using those references.
- sdk/expect.ts: expectRevert — simulate a call and assert it reverts
with the expected custom error / reason, via eth_call (no gas, no
on-chain trace).
- Repairs the package test script (node --test cannot import a bare
directory) and adds unit tests for loadArtifact/linkLibraries.
- README: note that the deployed icm-contracts v1.0.9 Teleporter stack
interoperates with contracts compiled against newer icm-services
releases (wire protocol + registry ABI are stable).
ashucoder9
approved these changes
Jun 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Gaps hit while building an e2e validation of third-party ICTT contracts on tmpnet — each required hand-rolling something the SDK should provide:
network.jsonor exported, so testing TeleporterallowedRelayerAddressesmeans hardcoding the Anvil[0] addressblock.timestampfreezes between txs and gas estimation rejects any time-guarded call (timelocks, vesting) forever — even after wall-clock time has passedloadArtifactonly readscontracts/out/, and there's no way to deploy contracts that link external libraries (solc__$hash$__placeholders)Changes
network.jsongainsrelayer.address,addresses.tsgainsRELAYER,.envgainsRELAYER_ADDRESS;DEFAULT_RELAYER_ADDRESS/DEFAULT_RELAYER_KEYexported from the package. Also fixes the constant's EIP-55 checksum (cfFFb→cffFb) — viem 2.50+ rejects the old casing — and drops thegetAddress()workaround that bug forced incommands.ts.sdk/chain-time.ts:mineBlock(clients)(zero-value self-transfer to mint a fresh block) andwaitForChainTime(clients, targetUnixSeconds)(sleep to target wall-clock, then nudge blocks until the head is stamped past it).loadArtifact(name, { dir }): load artifacts from an explicit directory (forge nested or flat layout); returnslinkReferences. NewlinkLibraries(artifact, { LibName: address })splices deployed library addresses over solc placeholders, validating nothing unresolved remains.sdk/expect.ts:expectRevert(publicClient, call, expectedError)— eth_call simulation, asserts the decoded revert matches; throws with the original error text when it doesn't.testscript (node --testcan't import a bare directory — it was broken since it was added) and adds 8 unit tests forloadArtifact/linkLibraries.Verification
pnpm --filter tmpnetjs test: 8/8 passmineBlock/waitForChainTime/expectRevertexercised against a live local network (block advance, chain-time catch-up past a future target, revert capture)buildArtifactDocemits the relayer block with the corrected checksum