/
tunnel.js
executable file
·46 lines (36 loc) · 1.77 KB
/
tunnel.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import {Foundry, to_address} from '@adraffy/blocksmith';
import {EZCCIP, serve} from '@resolverworks/ezccip';
import {ethers} from 'ethers';
import {test, after} from 'node:test';
import assert from 'node:assert/strict';
test('it works', async () => {
// launch an anvil testnet
let foundry = await Foundry.launch();
after(() => foundry.shutdown());
// define an interface for ccip
let abi = new ethers.Interface([
'function f(uint256, uint256) returns (uint256)'
]);
// create ccip-handler for f() define it below, in js
let ezccip = new EZCCIP();
// (assocate the single-function-abi with the supplied implementation)
let [{frag: {selector}}] = ezccip.register(abi, ([a, b]) => [a * 1000n + b]);
// deploy trustless tunnel-contract
let tunnel = await foundry.deploy({file: 'OffchainTunnel'});
// create a ccip-server for answering wrappable-questions from tunnel-contract
// (which has a randomly generated private key)
let ccip = await serve(ezccip, {resolver: to_address(tunnel)});
after(() => ccip.http.close());
// claim interface of f() on tunnel thats "tunnels" to our ccip-server that signs responses
// last argument 0 => save (signer, endpoint) under (sender, 0)
// (selector) => (sender, index) => (signer, endpoint)
await foundry.confirm(tunnel.claimAndSetContext(selector, ccip.signer, ccip.endpoint, 0));
// print the owner and server info for f()
console.log(await tunnel.getSelector(selector));
// call f() on tunnel, which via fallback() and selector registry,
// reverts for ccip using our ccip-endpoint,
// then verifies our response was signed by the registered signer,
// and returns the result of f()
let contract = new ethers.Contract(tunnel, abi, foundry.provider);
assert(69420n, await contract.f.staticCall(69, 420, {enableCcipRead: true}));
});