0.0.22 • Published 1 year ago
@resolverworks/ezccip v0.0.22
ezccip.js
Turnkey EIP-3668: CCIP-Read Handler for ENS and arbitrary functions.
npm i @resolverworks/ezccip ✓
- see types / uses ethers
- works with any server infrastructure * uses minimal imports for serverless
- implements multiple protocols:
"tor"— resolverworks/TheOffchainResolver.sol"ens"— ensdomains/offchain-resolver and ccip.tools *"raw"— raw response (EVM Gateway, testing, etc.) - used by resolverworks/TheOffchainGateway.js
enableENSIP10()drop-in support for resolverworks/enson.js Record-type- supports Multicall-over-CCIP-Read
resolve(name, multicall([...]))multicall([resolve(name, ...), ...])*multicall([resolve(name, multicall([...])), ...]) - use
serve()to quickly launch a server - CCIP Postman ⭐️ * directly debug any CCIP-Read server (no RPC)
Demo
npm run start— starts a CCIP-Read server for TOR protocol usingserve()- check Postman ← change to
http://localhost:8016 - choose a TOR:
- setup Context:
0xd00d726b2aD6C81E894DC6B87BE6Ce9c5572D2cd http://localhost:8016
Examples
- DNS (using
"tor"protocol on Mainnet):ezccip.raffy.xyzResolver:0x7CE6Cf740075B5AF6b1681d67136B84431B43AbDContext:0xd00d726b2aD6C81E894DC6B87BE6Ce9c5572D2cd https://raffy.xyz/ezccip/0x7CE6Cf740075B5AF6b1681d67136B84431B43AbD - ENS (using
"tor"protocol on Sepolia):ezccip.ethResolver:0x3c187BAb6dC2C94790d4dA5308672e6F799DcEC3Context:0xd00d726b2aD6C81E894DC6B87BE6Ce9c5572D2cd https://raffy.xyz/ezccip/0x3c187BAb6dC2C94790d4dA5308672e6F799DcEC3 - DNS (using
"ens"protocol on Mainnet)ens.ezccip.raffy.xyzResolver: 0x3CA097Edd180Ea2C2436BD30c021Ca20869087a0 Contect:0xd00d726b2aD6C81E894DC6B87BE6Ce9c5572D2cd https://raffy.xyz/ezccip/0x3CA097Edd180Ea2C2436BD30c021Ca20869087a0
Usage
Create an instance and register some handlers.
import {EZCCIP} from '@resolverworks/ezccip';
let ezccip = new EZCCIP();
// implement an arbitrary function
ezccip.register('add(uint256, uint256) returns (uint256)', ([a, b]) => [a + b]);
// implement a wildcard ENSIP-10 resolver
// which handles resolve() automatically
ezccip.enableENSIP10(async (name, context) => {
return {
async text(key) {
switch (key) {
case 'name': return 'Raffy';
case 'avatar': return 'https://raffy.antistupid.com/ens.jpg';
}
},
};
});
// more complicated example
let abi = new ethers.Interface([
'function f(bytes32 x) returns (string)',
'function g(uint256 a, uint256 b) returns (uint256)',
]);
ezccip.register(abi, { // register multiple functions at once using existing ABI
async ['f(bytes32)']([x], context, history) { // match function by signature
history.show = [context.sender]; // replace arguments of f(...) in logger
history.name = 'Chonk'; // rename f() to Chonk() in logger
return [context.calldata]; // echo incoming calldata
},
async ['0xe2179b8e']([a, b], context) { // match by selector
context.protocol = "tor"; // override signing protocol
return ethers.toBeHex(1337n, 32); // return raw encoded result
}
});When your server has a request for CCIP-Read, use EZCCIP to produce a response.
let {sender, data: calldata} = JSON.parse(req.body); // ABI-encoded request in JSON from EIP-3668
let {data, history} = await ezccip.handleRead(sender, calldata, {
protocol: 'tor', // default, tor requires signingKey + resolver
signingKey, // your private key
});
reply.json({data}); // ABI-encoded response in JSON for EIP-3668
console.log(history.toString()); // description of response- implement via
GET,POST, or query directly contextcarries useful information about the incoming requesthistorycollects information as the response is generated
serve()
Start a simple server for an EZCCIP instance or a function representing the enableENSIP10() handler.
import {serve} from '@resolverworks/ezccip/serve';
let ccip = await serve(ezccip); // see types for more configuration
// ...
await ccip.shutdown();
// minimal example:
// return fixed text() for any name
await serve(() => { text: () => 'Raffy' });Sender vs Origin
- ⚠️
sendermay not be the originating contract * see: recursive CCIP-Read - Best Solution: embed
origininto the endpoint as a path component: 1.http://my.server/.../0xABCD/...1.origin = 0xABCD - or, use
parseOrigin(path: string) => stringto extractoriginfrom an arbitrary path - or, supply a fallback
origin - if
originis not detected,origin = sender
processENSIP10()
Apply ENSIP-10 calldata to a Record-object and generate the corresponding ABI-encoded response. This is a free-function.
let record = {
text(key) { if (key == 'name') return 'raffy'; }
addr(type) { if (type == 60) return '0x1234'; }
};
let calldata = '0x...'; // encodeFunctionData('text', ['name']);
let res = await processENSIP10(record, calldata); // encodeFunctionResult('text', ['raffy']);0.0.22
1 year ago
0.0.21
1 year ago
0.0.20
1 year ago
0.0.16
1 year ago
0.0.17
1 year ago
0.0.18
1 year ago
0.0.19
1 year ago
0.0.15
1 year ago
0.0.12
2 years ago
0.0.13
1 year ago
0.0.14
1 year ago
0.0.11
2 years ago
0.0.10
2 years ago
0.0.9
2 years ago
0.0.8
2 years ago
0.0.7
2 years ago
0.0.5
2 years ago
0.0.6
2 years ago
0.0.3
2 years ago
0.0.4
2 years ago
0.0.2
2 years ago
0.0.1
2 years ago