@resolverworks/ezccip

0.0.22 • Public • Published

ezccip.js

Turnkey EIP-3668: CCIP-Read Handler for ENS and arbitrary functions.

npm i @resolverworks/ezccip

Demo

  1. npm run start — starts a CCIP-Read server for TOR protocol using serve()
  2. check Postman ← change to http://localhost:8016
  3. choose a TOR:
    1. TOR on Mainnet or Sepolia
    2. DNSTORWithENSProtocol on Mainnet or Sepolia
  4. setup Context: 0xd00d726b2aD6C81E894DC6B87BE6Ce9c5572D2cd http://localhost:8016

Examples

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
  • context carries useful information about the incoming request
  • history collects 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

  • ⚠️ sender may not be the originating contract
  • Best Solution: embed origin into the endpoint as a path component:
    1. http://my.server/.../0xABCD/...
    2. origin = 0xABCD
  • or, use parseOrigin(path: string) => string to extract origin from an arbitrary path
  • or, supply a fallback origin
  • if origin is 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']);

Dependencies (1)

Dev Dependencies (1)

Package Sidebar

Install

npm i @resolverworks/ezccip

Weekly Downloads

12

Version

0.0.22

License

MIT

Unpacked Size

44.5 kB

Total Files

11

Last publish

Collaborators

  • dsinghbailey
  • adraffy
  • slobodnik