diff --git a/packages/linea-ccip-gateway/package.json b/packages/linea-ccip-gateway/package.json index cbaf3a6a1..161dbe3a8 100644 --- a/packages/linea-ccip-gateway/package.json +++ b/packages/linea-ccip-gateway/package.json @@ -4,31 +4,13 @@ "main": "dist/index.js", "author": "Consensys", "license": "Apache-2.0", - "typings": "dist/index.d.ts", - "files": [ - "dist", - "src" - ], "scripts": { "start": "node dist/server.js", "build": "tsc --project tsconfig.json --module commonjs --skipLibCheck true --outDir ./dist", - "size": "size-limit", - "analyze": "size-limit --why", "clean": "rm -fr node_modules dist", - "test": "mocha test/testVerifier.spec.ts --timeout 10000 --exit", + "test": "hardhat compile && mocha test/testVerifier.spec.ts --timeout 10000 --exit", "compile": "hardhat compile" }, - "module": "dist/linea-ccip-gateway.esm.js", - "size-limit": [ - { - "path": "dist/linea-ccip-gateway.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/linea-ccip-gateway.esm.js", - "limit": "10 KB" - } - ], "dependencies": { "@chainlink/ccip-read-server": "^0.2.1", "@ethersproject/abi": "^5.4.7", diff --git a/packages/linea-ccip-gateway/src/ccip-server/index.ts b/packages/linea-ccip-gateway/src/ccip-server/index.ts deleted file mode 100644 index 8ed370a85..000000000 --- a/packages/linea-ccip-gateway/src/ccip-server/index.ts +++ /dev/null @@ -1,194 +0,0 @@ -import cors from "cors"; -import { ethers, BytesLike, ParamType, isAddress, isBytesLike } from "ethers"; -import { - Fragment, - FunctionFragment, - Interface, - JsonFragment, -} from "@ethersproject/abi"; -import { hexlify } from "@ethersproject/bytes"; -import express from "express"; - -export interface RPCCall { - to: BytesLike; - data: BytesLike; -} - -export interface RPCResponse { - status: number; - body: any; -} - -export type HandlerFunc = ( - args: ethers.Result, - req: RPCCall -) => Promise> | Array; - -interface Handler { - type: FunctionFragment; - func: HandlerFunc; -} - -function toInterface( - abi: string | readonly (string | Fragment | JsonFragment)[] | Interface -) { - if (Interface.isInterface(abi)) { - return abi; - } - return new Interface(abi); -} - -export interface HandlerDescription { - type: string; - func: HandlerFunc; -} - -/** - * Implements a CCIP-Read gateway service using express.js. - * - * Example usage: - * ```javascript - * const ccipread = require('@chainlink/ccip-read-server'); - * const server = new ccipread.Server(); - * const abi = [ - * 'function getSignedBalance(address addr) public view returns(uint256 balance, bytes memory sig)', - * ]; - * server.add(abi, [ - * { - * type: 'getSignedBalance', - * func: async (contractAddress, [addr]) => { - * const balance = getBalance(addr); - * const sig = signMessage([addr, balance]); - * return [balance, sig]; - * } - * } - * ]); - * const app = server.makeApp(); - * app.listen(8080); - * ``` - */ -export class Server { - /** @ignore */ - readonly handlers: { [selector: string]: Handler }; - - /** - * Constructs a new CCIP-Read gateway server instance. - */ - constructor() { - this.handlers = {}; - } - - /** - * Adds an interface to the gateway server, with handlers to handle some or all of its functions. - * @param abi The contract ABI to use. This can be in any format that ethers.js recognises, including - * a 'Human Readable ABI', a JSON-format ABI, or an Ethers `Interface` object. - * @param handlers An array of handlers to register against this interface. - */ - add( - abi: string | readonly (string | Fragment | JsonFragment)[] | Interface, - handlers: Array - ) { - const abiInterface = toInterface(abi); - - for (const handler of handlers) { - const fn = abiInterface.getFunction(handler.type); - this.handlers[Interface.getSighash(fn)] = { - type: fn, - func: handler.func, - }; - } - } - - /** - * Convenience function to construct an `express` application object for the gateway. - * Example usage: - * ```javascript - * const ccipread = require('ccip-read'); - * const server = new ccipread.Server(); - * // set up server object here - * const app = server.makeApp('/'); - * app.serve(8080); - * ``` - * The path prefix to `makeApp` will have sender and callData arguments appended. - * If your server is on example.com and configured as above, the URL template to use - * in a smart contract would be "https://example.com/{sender}/{callData}.json". - * @returns An `express.Application` object configured to serve as a CCIP read gateway. - */ - makeApp(prefix: string): express.Application { - const app = express(); - app.use(cors()); - app.use(express.json() as express.RequestHandler); - app.get(`${prefix}:sender/:callData.json`, this.handleRequest.bind(this)); - app.post(prefix, this.handleRequest.bind(this)); - return app; - } - - async handleRequest(req: express.Request, res: express.Response) { - let sender: string; - let callData: string; - - if (req.method === "GET") { - sender = req.params.sender; - callData = req.params.callData; - } else { - sender = req.body.sender; - callData = req.body.data; - } - - if (!isAddress(sender) || !isBytesLike(callData)) { - res.status(400).json({ - message: "Invalid request format", - }); - return; - } - - try { - const response = await this.call({ to: sender, data: callData }); - res.status(response.status).json(response.body); - } catch (e) { - res.status(500).json({ - message: `Internal server error: ${(e as any).toString()}`, - }); - } - } - - async call(call: RPCCall): Promise { - const calldata = hexlify(call.data); - const selector = calldata.slice(0, 10).toLowerCase(); - - // Find a function handler for this selector - const handler = this.handlers[selector]; - if (!handler) { - return { - status: 404, - body: { - message: `No implementation for function with selector ${selector}`, - }, - }; - } - - // Decode function arguments - const args = ethers.AbiCoder.defaultAbiCoder().decode( - handler.type.inputs as unknown as ParamType[], - "0x" + calldata.slice(10) - ); - - // Call the handler - const result = await handler.func(args, call); - - // Encode return data - return { - status: 200, - body: { - data: handler.type.outputs - ? hexlify( - ethers.AbiCoder.defaultAbiCoder().encode( - handler.type.outputs as unknown as ParamType[], - result - ) - ) - : "0x", - }, - }; - } -} diff --git a/packages/linea-ccip-gateway/src/server.ts b/packages/linea-ccip-gateway/src/server.ts index 041ac2317..d8c60997b 100644 --- a/packages/linea-ccip-gateway/src/server.ts +++ b/packages/linea-ccip-gateway/src/server.ts @@ -2,7 +2,7 @@ import { EVMGateway } from "./evm-gateway"; import { ethers } from "ethers"; import { L2ProofService } from "./L2ProofService"; import "dotenv/config"; -import { Server } from "./ccip-server"; +import { Server } from "@chainlink/ccip-read-server"; import { logError } from "./utils"; const l1ProviderUrl = process.env.L1_PROVIDER_URL; diff --git a/packages/linea-ens-contracts/README.md b/packages/linea-ens-contracts/README.md index 25573cdb0..c742a9748 100644 --- a/packages/linea-ens-contracts/README.md +++ b/packages/linea-ens-contracts/README.md @@ -1,6 +1,15 @@ # linea-ens-contracts -Friendly forked from https://github.com/ensdomains/ens-contracts +ENS contracts deployed on Linea to support "linea.eth" subdomain registration on Linea. +Its implementation has started with a fork from official ENS's repo https://github.com/ensdomains/ens-contracts + +A few specifities: + +- Supports 3 levels domain registration +- A POH linked to the account registering is needed to be able to register +- Registration is free using POH +- One registration by account using POH is allowed +- Is supported on L1 resolution thanks to [linea-state-verifier](https://github.com/Consensys/linea-resolver/tree/main/packages/linea-state-verifier) ## Contracts @@ -46,15 +55,13 @@ This separation of concerns provides name owners strong guarantees over continue ### EthRegistrarController -EthRegistrarController is the first implementation of a registration controller for the new registrar. This contract implements the following functionality: +EthRegistrarController is taken from the official ENS's [registration controller](https://github.com/ensdomains/ens-contracts/blob/staging/contracts/ethregistrar/ETHRegistrarController.sol) with some changes: -- The owner of the registrar may set a price oracle contract, which determines the cost of registrations and renewals based on the name and the desired registration or renewal duration. -- The owner of the registrar may withdraw any collected funds to their account. - The owner of the registrar can register a domain for any address that has not been registered yet for free. - Users can register a new name using a commit/reveal process and if they have completed of Proof of humanity process. - Users can renew a name 6 month before the expiration date. -The commit/reveal process is used to avoid frontrunning, and operates as follows: +It has the same the commit/reveal process is used to avoid frontrunning, and operates as follows: 1. A user commits to a hash, the preimage of which contains the name to be registered and a secret value. 2. After a minimum delay period and before the commitment expires, the user calls the register function with the name to register and the secret value from the commitment. If a valid commitment is found and the other preconditions are met, the name is registered. @@ -74,13 +81,10 @@ PohVerifier is the contract responsible for checking the signature of the privat - The owner of PohVerifier can set the signer address responsible for aknowledging a POH -### SimplePriceOracle - -SimplePriceOracle is a trivial implementation of the pricing oracle for the EthRegistrarController that always returns a fixed price per domain per year, determined by the contract owner. +### FixedPriceOracle -### StablePriceOracle - -StablePriceOracle is a price oracle implementation that allows the contract owner to specify pricing based on the length of a name, and uses a fiat currency oracle to set a fixed price in fiat per name. +FixedPriceOracle is a price oracle implementation that always return the same price. +It is used to make the original register function very expensive making it almost impossible to use and to force users to use the registration with POH. ## Resolvers @@ -99,10 +103,6 @@ PublicResolver includes the following profiles that implements different EIPs. ## Developer guide -### Prettier pre-commit hook - -This repo runs a husky precommit to prettify all contract files to keep them consistent. Add new folder/files to `prettier format` script in package.json. If you need to add other tasks to the pre-commit script, add them to `.husky/pre-commit` - ### How to setup ``` diff --git a/packages/linea-ens-resolver/package.json b/packages/linea-ens-resolver/package.json index 734d4997e..4c4f8a87b 100644 --- a/packages/linea-ens-resolver/package.json +++ b/packages/linea-ens-resolver/package.json @@ -1,8 +1,7 @@ { "name": "linea-ens-resolver", "version": "1.0.0", - "description": "", - "main": "index.js", + "description": "L1 contracts to resolve Linea ENS domains stored on Linea from L1", "scripts": { "test": "hardhat compile && cd ../linea-ccip-gateway && npm run build && cd ../linea-ens-resolver && mocha test/testL1Resolver.spec.ts --timeout 10000 --exit", "compile": "hardhat compile", diff --git a/packages/poh-signer-api/README.md b/packages/poh-signer-api/README.md index 2b0ed6f03..377432c3d 100644 --- a/packages/poh-signer-api/README.md +++ b/packages/poh-signer-api/README.md @@ -1,6 +1,7 @@ # Linea ENS POH -API responsible for signing a message aknowledging an address has passed the POH process. +A NestJS API responsible for returning a signature aknowledging an address has passed the POH process. +Uses the [POH api](https://linea-xp-poh-api.linea.build) to check if an address has a POH. ## Installation @@ -33,17 +34,3 @@ $ pnpm run test:e2e # test coverage $ pnpm run test:cov ``` - -## Support - -Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support). - -## Stay in touch - -- Author - [Kamil Myƛliwiec](https://kamilmysliwiec.com) -- Website - [https://nestjs.com](https://nestjs.com/) -- Twitter - [@nestframework](https://twitter.com/nestframework) - -## License - -Nest is [MIT licensed](LICENSE). diff --git a/packages/poh-signer-api/package.json b/packages/poh-signer-api/package.json index 09898418d..520c94e64 100644 --- a/packages/poh-signer-api/package.json +++ b/packages/poh-signer-api/package.json @@ -1,7 +1,7 @@ { "name": "poh-signer-api", "version": "1.0.0", - "description": "", + "description": "API to get a signature for an address that has a POH", "author": "Consensys", "private": true, "license": "Apache-2.0",