├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .prettierrc ├── .solcover.ts ├── .solhint.json ├── LICENSE ├── README.md ├── components └── Contracts.ts ├── contracts ├── Common.sol ├── EAS.sol ├── IEAS.sol ├── ISchemaRegistry.sol ├── ISemver.sol ├── Indexer.sol ├── SchemaRegistry.sol ├── Semver.sol ├── eip1271 │ └── EIP1271Verifier.sol ├── eip712 │ └── proxy │ │ ├── EIP712Proxy.sol │ │ └── examples │ │ └── PermissionedEIP712Proxy.sol ├── resolver │ ├── ISchemaResolver.sol │ ├── SchemaResolver.sol │ └── examples │ │ ├── AttestationResolver.sol │ │ ├── AttesterResolver.sol │ │ ├── DataResolver.sol │ │ ├── ExpirationTimeResolver.sol │ │ ├── PayingResolver.sol │ │ ├── RecipientResolver.sol │ │ ├── RevocationResolver.sol │ │ ├── TokenResolver.sol │ │ └── ValueResolver.sol └── tests │ ├── TestEAS.sol │ ├── TestERC20Token.sol │ ├── TestSchemaResolver.sol │ ├── eip1271 │ ├── TestEIP1271Signer.sol │ └── TestEIP1271Verifier.sol │ └── eip712 │ └── proxy │ └── TestEIP712Proxy.sol ├── deployments ├── arbitrum-nova │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── EIP712Proxy.json │ ├── Indexer.json │ ├── SchemaRegistry.json │ └── types │ │ ├── contracts │ │ ├── EAS.ts │ │ ├── Indexer.ts │ │ ├── SchemaRegistry.ts │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy.ts │ │ └── factories │ │ └── contracts │ │ ├── EAS__factory.ts │ │ ├── Indexer__factory.ts │ │ ├── SchemaRegistry__factory.ts │ │ └── eip712 │ │ └── proxy │ │ └── EIP712Proxy__factory.ts ├── arbitrum-one │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── SchemaRegistry.json │ └── types │ │ ├── contracts │ │ ├── EAS.ts │ │ └── SchemaRegistry.ts │ │ └── factories │ │ └── contracts │ │ ├── EAS__factory.ts │ │ └── SchemaRegistry__factory.ts ├── arbitrum-sepolia │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── EIP712Proxy.json │ ├── Indexer.json │ ├── SchemaRegistry.json │ └── types │ │ ├── @ethereum-attestation-service │ │ └── eas-contracts │ │ │ └── contracts │ │ │ ├── EAS.ts │ │ │ ├── Indexer.ts │ │ │ ├── SchemaRegistry.ts │ │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy.ts │ │ └── factories │ │ └── @ethereum-attestation-service │ │ └── eas-contracts │ │ └── contracts │ │ ├── EAS__factory.ts │ │ ├── Indexer__factory.ts │ │ ├── SchemaRegistry__factory.ts │ │ └── eip712 │ │ └── proxy │ │ └── EIP712Proxy__factory.ts ├── base-goerli │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── EIP712Proxy.json │ ├── Indexer.json │ ├── SchemaRegistry.json │ └── types │ │ ├── contracts │ │ ├── EAS.ts │ │ ├── Indexer.ts │ │ ├── SchemaRegistry.ts │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy.ts │ │ └── factories │ │ └── contracts │ │ ├── EAS__factory.ts │ │ ├── Indexer__factory.ts │ │ ├── SchemaRegistry__factory.ts │ │ └── eip712 │ │ └── proxy │ │ └── EIP712Proxy__factory.ts ├── base-sepolia │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── EIP712Proxy.json │ ├── Indexer.json │ ├── SchemaRegistry.json │ └── types │ │ ├── contracts │ │ ├── EAS.ts │ │ ├── Indexer.ts │ │ ├── SchemaRegistry.ts │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy.ts │ │ └── factories │ │ └── contracts │ │ ├── EAS__factory.ts │ │ ├── Indexer__factory.ts │ │ ├── SchemaRegistry__factory.ts │ │ └── eip712 │ │ └── proxy │ │ └── EIP712Proxy__factory.ts ├── base │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── EIP712Proxy.json │ ├── Indexer.json │ ├── SchemaRegistry.json │ └── types │ │ ├── contracts │ │ ├── Indexer.ts │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy.ts │ │ └── factories │ │ └── contracts │ │ ├── Indexer__factory.ts │ │ └── eip712 │ │ └── proxy │ │ └── EIP712Proxy__factory.ts ├── celo │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── EIP712Proxy.json │ ├── Indexer.json │ ├── SchemaRegistry.json │ └── types │ │ ├── contracts │ │ ├── EAS.ts │ │ ├── Indexer.ts │ │ ├── SchemaRegistry.ts │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy.ts │ │ └── factories │ │ └── contracts │ │ ├── EAS__factory.ts │ │ ├── Indexer__factory.ts │ │ ├── SchemaRegistry__factory.ts │ │ └── eip712 │ │ └── proxy │ │ └── EIP712Proxy__factory.ts ├── hardhat │ └── .chainId ├── ink-sepolia │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── EIP712Proxy.json │ ├── Indexer.json │ ├── SchemaRegistry.json │ ├── solcInputs │ │ └── ab2e55c92b39ec3be86af0608f634927.json │ └── types │ │ ├── @ethereum-attestation-service │ │ └── eas-contracts │ │ │ └── contracts │ │ │ ├── Indexer.ts │ │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy.ts │ │ ├── contracts │ │ ├── EAS.ts │ │ ├── Indexer.ts │ │ ├── SchemaRegistry.ts │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy.ts │ │ └── factories │ │ ├── @ethereum-attestation-service │ │ └── eas-contracts │ │ │ └── contracts │ │ │ ├── Indexer__factory.ts │ │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy__factory.ts │ │ └── contracts │ │ ├── EAS__factory.ts │ │ ├── Indexer__factory.ts │ │ ├── SchemaRegistry__factory.ts │ │ └── eip712 │ │ └── proxy │ │ └── EIP712Proxy__factory.ts ├── ink │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── EIP712Proxy.json │ ├── Indexer.json │ ├── SchemaRegistry.json │ └── types │ │ ├── @ethereum-attestation-service │ │ └── eas-contracts │ │ │ └── contracts │ │ │ ├── Indexer.ts │ │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy.ts │ │ └── factories │ │ └── @ethereum-attestation-service │ │ └── eas-contracts │ │ └── contracts │ │ ├── Indexer__factory.ts │ │ └── eip712 │ │ └── proxy │ │ └── EIP712Proxy__factory.ts ├── linea-goerli │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── EIP712Proxy.json │ ├── SchemaRegistry.json │ └── types │ │ ├── contracts │ │ ├── EAS.ts │ │ ├── SchemaRegistry.ts │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy.ts │ │ └── factories │ │ └── contracts │ │ ├── EAS__factory.ts │ │ ├── SchemaRegistry__factory.ts │ │ └── eip712 │ │ └── proxy │ │ └── EIP712Proxy__factory.ts ├── linea │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── EIP712Proxy.json │ ├── SchemaRegistry.json │ └── types │ │ ├── contracts │ │ ├── EAS.ts │ │ ├── SchemaRegistry.ts │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy.ts │ │ └── factories │ │ └── contracts │ │ ├── EAS__factory.ts │ │ ├── SchemaRegistry__factory.ts │ │ └── eip712 │ │ └── proxy │ │ └── EIP712Proxy__factory.ts ├── mainnet │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── SchemaRegistry.json │ └── types │ │ ├── contracts │ │ ├── EAS.ts │ │ └── SchemaRegistry.ts │ │ └── factories │ │ └── contracts │ │ ├── EAS__factory.ts │ │ └── SchemaRegistry__factory.ts ├── optimism-goerli │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── EIP712Proxy.json │ ├── Indexer.json │ ├── SchemaRegistry.json │ └── types │ │ ├── contracts │ │ ├── EAS.ts │ │ ├── Indexer.ts │ │ ├── SchemaRegistry.ts │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy.ts │ │ └── factories │ │ └── contracts │ │ ├── EAS__factory.ts │ │ ├── Indexer__factory.ts │ │ ├── SchemaRegistry__factory.ts │ │ └── eip712 │ │ └── proxy │ │ └── EIP712Proxy__factory.ts ├── optimism-sepolia │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── EIP712Proxy.json │ ├── Indexer.json │ ├── SchemaRegistry.json │ └── types │ │ ├── contracts │ │ ├── EAS.ts │ │ ├── Indexer.ts │ │ ├── SchemaRegistry.ts │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy.ts │ │ └── factories │ │ └── contracts │ │ ├── EAS__factory.ts │ │ ├── Indexer__factory.ts │ │ ├── SchemaRegistry__factory.ts │ │ └── eip712 │ │ └── proxy │ │ └── EIP712Proxy__factory.ts ├── optimism │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── EIP712Proxy.json │ ├── Indexer.json │ ├── SchemaRegistry.json │ └── types │ │ ├── contracts │ │ ├── Indexer.ts │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy.ts │ │ └── factories │ │ └── contracts │ │ ├── Indexer__factory.ts │ │ └── eip712 │ │ └── proxy │ │ └── EIP712Proxy__factory.ts ├── polygon-amoy │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── EIP712Proxy.json │ ├── Indexer.json │ ├── SchemaRegistry.json │ └── types │ │ ├── contracts │ │ ├── EAS.ts │ │ ├── Indexer.ts │ │ ├── SchemaRegistry.ts │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy.ts │ │ └── factories │ │ └── contracts │ │ ├── EAS__factory.ts │ │ ├── Indexer__factory.ts │ │ ├── SchemaRegistry__factory.ts │ │ └── eip712 │ │ └── proxy │ │ └── EIP712Proxy__factory.ts ├── polygon │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── EIP712Proxy.json │ ├── Indexer.json │ ├── SchemaRegistry.json │ └── types │ │ ├── contracts │ │ ├── EAS.ts │ │ ├── Indexer.ts │ │ ├── SchemaRegistry.ts │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy.ts │ │ └── factories │ │ └── contracts │ │ ├── EAS__factory.ts │ │ ├── Indexer__factory.ts │ │ ├── SchemaRegistry__factory.ts │ │ └── eip712 │ │ └── proxy │ │ └── EIP712Proxy__factory.ts ├── scroll-sepolia │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── EIP712Proxy.json │ ├── Indexer.json │ ├── SchemaRegistry.json │ └── types │ │ ├── contracts │ │ ├── EAS.ts │ │ ├── Indexer.ts │ │ ├── SchemaRegistry.ts │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy.ts │ │ └── factories │ │ └── contracts │ │ ├── EAS__factory.ts │ │ ├── Indexer__factory.ts │ │ ├── SchemaRegistry__factory.ts │ │ └── eip712 │ │ └── proxy │ │ └── EIP712Proxy__factory.ts ├── scroll │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── EIP712Proxy.json │ ├── Indexer.json │ ├── SchemaRegistry.json │ └── types │ │ ├── contracts │ │ ├── EAS.ts │ │ ├── Indexer.ts │ │ ├── SchemaRegistry.ts │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy.ts │ │ └── factories │ │ └── contracts │ │ ├── EAS__factory.ts │ │ ├── Indexer__factory.ts │ │ ├── SchemaRegistry__factory.ts │ │ └── eip712 │ │ └── proxy │ │ └── EIP712Proxy__factory.ts ├── sepolia │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── EIP712Proxy.json │ ├── Indexer.json │ ├── SchemaRegistry.json │ └── types │ │ ├── contracts │ │ ├── EAS.ts │ │ ├── Indexer.ts │ │ ├── SchemaRegistry.ts │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy.ts │ │ └── factories │ │ └── contracts │ │ ├── EAS__factory.ts │ │ ├── Indexer__factory.ts │ │ ├── SchemaRegistry__factory.ts │ │ └── eip712 │ │ └── proxy │ │ └── EIP712Proxy__factory.ts ├── soneium │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── EIP712Proxy.json │ ├── Indexer.json │ ├── SchemaRegistry.json │ ├── solcInputs │ │ └── ab2e55c92b39ec3be86af0608f634927.json │ └── types │ │ ├── @ethereum-attestation-service │ │ └── eas-contracts │ │ │ └── contracts │ │ │ ├── Indexer.ts │ │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy.ts │ │ ├── contracts │ │ ├── Indexer.ts │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy.ts │ │ └── factories │ │ ├── @ethereum-attestation-service │ │ └── eas-contracts │ │ │ └── contracts │ │ │ ├── Indexer__factory.ts │ │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy__factory.ts │ │ └── contracts │ │ ├── Indexer__factory.ts │ │ └── eip712 │ │ └── proxy │ │ └── EIP712Proxy__factory.ts ├── telos │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── EIP712Proxy.json │ ├── Indexer.json │ ├── SchemaRegistry.json │ ├── solcInputs │ │ └── ab2e55c92b39ec3be86af0608f634927.json │ └── types │ │ ├── @ethereum-attestation-service │ │ └── eas-contracts │ │ │ └── contracts │ │ │ ├── EAS.ts │ │ │ ├── Indexer.ts │ │ │ ├── SchemaRegistry.ts │ │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy.ts │ │ └── factories │ │ └── @ethereum-attestation-service │ │ └── eas-contracts │ │ └── contracts │ │ ├── EAS__factory.ts │ │ ├── Indexer__factory.ts │ │ ├── SchemaRegistry__factory.ts │ │ └── eip712 │ │ └── proxy │ │ └── EIP712Proxy__factory.ts ├── unichain │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── EIP712Proxy.json │ ├── Indexer.json │ ├── SchemaRegistry.json │ └── types │ │ ├── @ethereum-attestation-service │ │ └── eas-contracts │ │ │ └── contracts │ │ │ ├── Indexer.ts │ │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy.ts │ │ ├── contracts │ │ ├── EAS.ts │ │ └── SchemaRegistry.ts │ │ └── factories │ │ ├── @ethereum-attestation-service │ │ └── eas-contracts │ │ │ └── contracts │ │ │ ├── Indexer__factory.ts │ │ │ └── eip712 │ │ │ └── proxy │ │ │ └── EIP712Proxy__factory.ts │ │ └── contracts │ │ ├── EAS__factory.ts │ │ └── SchemaRegistry__factory.ts └── zksync │ ├── .chainId │ ├── .migrations.json │ ├── EAS.json │ ├── EIP712Proxy.json │ ├── Indexer.json │ ├── SchemaRegistry.json │ └── types │ ├── contracts │ ├── EAS.ts │ ├── Indexer.ts │ ├── SchemaRegistry.ts │ └── eip712 │ │ └── proxy │ │ └── EIP712Proxy.ts │ └── factories │ └── contracts │ ├── EAS__factory.ts │ ├── Indexer__factory.ts │ ├── SchemaRegistry__factory.ts │ └── eip712 │ └── proxy │ └── EIP712Proxy__factory.ts ├── eslint.config.mjs ├── foundry.toml ├── funding.json ├── hardhat.config.ts ├── package.json ├── pnpm-lock.yaml ├── test ├── EAS.ts ├── Indexer.ts ├── SchemaRegistry.ts ├── eip1271 │ └── EIP1271Verifier.ts ├── eip712 │ └── proxy │ │ ├── EIP712Proxy.ts │ │ └── PermissionedEIP712Proxy.ts ├── helpers │ ├── Chai.ts │ ├── EAS.ts │ ├── EIP712ProxyUtils.ts │ ├── EIP712Utils.ts │ ├── Time.ts │ ├── Transaction.ts │ └── Wallet.ts └── resolver │ ├── AttestationResolver.ts │ ├── AttesterResolver.ts │ ├── DataResolver.ts │ ├── ExpirationTimeResolver.ts │ ├── PayingResolver.ts │ ├── RecipientResolver.ts │ ├── RevocationResolver.ts │ ├── SchemaResolver.ts │ ├── TokenResolver.ts │ └── ValueResoler.ts ├── tsconfig.json ├── tsconfig.release.json └── utils ├── Constants.ts ├── EAS.ts ├── Logger.ts └── Time.ts /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - master 8 | pull_request: 9 | 10 | jobs: 11 | test: 12 | name: Test 13 | 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - name: Check out the Repository 18 | uses: actions/checkout@v4 19 | 20 | - name: Install Packages 21 | run: sudo apt-get update && sudo apt-get -y install pkg-config libusb-1.0 libudev-dev 22 | 23 | - name: Install PNPM 24 | uses: pnpm/action-setup@v4 25 | id: pnpm-install 26 | with: 27 | version: 8 28 | run_install: false 29 | 30 | - name: Install Node.js 31 | uses: actions/setup-node@v4 32 | with: 33 | node-version: 20 34 | cache: 'pnpm' 35 | 36 | - name: Install Dependencies 37 | run: pnpm install 38 | 39 | - name: Install Foundry 40 | uses: foundry-rs/foundry-toolchain@v1 41 | with: 42 | version: nightly 43 | 44 | - name: Lint 45 | run: pnpm lint 46 | 47 | - name: Compile (Hardhat) 48 | run: pnpm compile 49 | 50 | - name: Test 51 | run: pnpm test 52 | 53 | - name: Compile (Foundry) 54 | run: forge build 55 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .vscode/ 3 | */**/.DS_Store 4 | 5 | /node_modules 6 | 7 | dist 8 | cache 9 | artifacts 10 | typechain-types 11 | cache-zk 12 | artifacts-zk 13 | deployments-zk 14 | 15 | deployments/mainnet/solcInputs/* 16 | deployments/optimism/solcInputs/* 17 | deployments/base/solcInputs/* 18 | deployments/arbitrum-one/solcInputs/* 19 | deployments/arbitrum-nova/solcInputs/* 20 | deployments/polygon/solcInputs/* 21 | deployments/scroll/solcInputs/* 22 | deployments/zksync/solcInputs/* 23 | deployments/celo/solcInputs/* 24 | deployments/linea/solcInputs/* 25 | deployments/telos/solcInputs/* 26 | deployments/soneium/solcInputs/* 27 | deployments/ink/solcInputs/* 28 | deployments/unichain/solcInputs/* 29 | deployments/sepolia/solcInputs/* 30 | deployments/optimism-sepolia/solcInputs/* 31 | deployments/optimism-goerli/solcInputs/* 32 | deployments/base-sepolia/solcInputs/* 33 | deployments/base-goerli/solcInputs/* 34 | deployments/arbitrum-sepolia/solcInputs/* 35 | deployments/polygon-amoy/solcInputs/* 36 | deployments/scroll-sepolia/solcInputs/* 37 | deployments/linea-goerli/solcInputs/* 38 | deployments/hardhat/* 39 | !deployments/hardhat/.chainId 40 | 41 | .coverage_artifacts 42 | .coverage_contracts 43 | /coverage 44 | /coverage.json 45 | allFiredEvents 46 | scTopics 47 | 48 | .env* 49 | !.env.template 50 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["@ianvs/prettier-plugin-sort-imports", "prettier-package-json", "prettier-plugin-solidity"], 3 | "overrides": [ 4 | { 5 | "files": "*.sol", 6 | "options": { 7 | "tabWidth": 4, 8 | "singleQuote": false 9 | } 10 | } 11 | ], 12 | "printWidth": 120, 13 | "tabWidth": 2, 14 | "useTabs": false, 15 | "semi": true, 16 | "singleQuote": true, 17 | "trailingComma": "none", 18 | "arrowParens": "always", 19 | "bracketSpacing": true, 20 | "importOrderTypeScriptVersion": "5.0.0" 21 | } 22 | -------------------------------------------------------------------------------- /.solcover.ts: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | skipFiles: ['tests'] 3 | }; 4 | -------------------------------------------------------------------------------- /.solhint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "solhint:recommended", 3 | "rules": { 4 | "avoid-throw": "off", 5 | "avoid-suicide": "error", 6 | "avoid-sha3": "warn", 7 | "not-rely-on-time": "off", 8 | "no-empty-blocks": "off", 9 | "mark-callable-contracts": "off", 10 | "func-visibility": ["error", { "ignoreConstructors": true }], 11 | "func-named-parameters": "off", 12 | "immutable-vars-naming": "off", 13 | "compiler-version": ["error", "^0.8.0"], 14 | "imports-order": "warn" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Leonid Beder 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /components/Contracts.ts: -------------------------------------------------------------------------------- 1 | import { ContractFactory, Signer } from 'ethers'; 2 | import { ethers } from 'hardhat'; 3 | import { 4 | AttestationResolver__factory, 5 | AttesterResolver__factory, 6 | DataResolver__factory, 7 | EAS__factory, 8 | ExpirationTimeResolver__factory, 9 | Indexer__factory, 10 | PayingResolver__factory, 11 | PermissionedEIP712Proxy__factory, 12 | RecipientResolver__factory, 13 | RevocationResolver__factory, 14 | SchemaRegistry__factory, 15 | TestEAS__factory, 16 | TestEIP712Proxy__factory, 17 | TestEIP1271Signer__factory, 18 | TestEIP1271Verifier__factory, 19 | TestERC20Token__factory, 20 | TestSchemaResolver__factory, 21 | TokenResolver__factory, 22 | ValueResolver__factory 23 | } from '../typechain-types'; 24 | 25 | export * from '../typechain-types'; 26 | 27 | type AsyncReturnType any> = T extends (...args: any) => Promise 28 | ? U 29 | : T extends (...args: any) => infer U 30 | ? U 31 | : any; 32 | 33 | type Contract = AsyncReturnType; 34 | 35 | export interface ContractBuilder { 36 | metadata: { 37 | bytecode: string; 38 | }; 39 | deploy(...args: Parameters): Promise>; 40 | attach(address: string, passedSigner?: Signer): Promise>; 41 | } 42 | 43 | export type FactoryConstructor = { 44 | new (signer?: Signer): F; 45 | abi: unknown; 46 | bytecode: string; 47 | }; 48 | 49 | export const deployOrAttach = ( 50 | FactoryConstructor: FactoryConstructor, 51 | initialSigner?: Signer 52 | ): ContractBuilder => { 53 | return { 54 | metadata: { 55 | bytecode: FactoryConstructor.bytecode 56 | }, 57 | deploy: async (...args: Parameters): Promise> => { 58 | const defaultSigner = initialSigner ?? ((await ethers.getSigners())[0] as any as Signer); 59 | 60 | return new FactoryConstructor(defaultSigner).deploy(...(args || [])) as Promise>; 61 | }, 62 | attach: attachOnly(FactoryConstructor, initialSigner).attach 63 | }; 64 | }; 65 | 66 | export const attachOnly = ( 67 | FactoryConstructor: FactoryConstructor, 68 | initialSigner?: Signer 69 | ) => { 70 | return { 71 | attach: async (address: string, signer?: Signer): Promise> => { 72 | const defaultSigner = initialSigner ?? ((await ethers.getSigners())[0] as any as Signer); 73 | return new FactoryConstructor(signer ?? defaultSigner).attach(address) as Contract; 74 | } 75 | }; 76 | }; 77 | 78 | const getContracts = (signer?: Signer) => ({ 79 | connect: (signer: Signer) => getContracts(signer), 80 | 81 | AttestationResolver: deployOrAttach(AttestationResolver__factory, signer), 82 | AttesterResolver: deployOrAttach(AttesterResolver__factory, signer), 83 | DataResolver: deployOrAttach(DataResolver__factory, signer), 84 | EAS: deployOrAttach(EAS__factory, signer), 85 | ExpirationTimeResolver: deployOrAttach(ExpirationTimeResolver__factory, signer), 86 | Indexer: deployOrAttach(Indexer__factory, signer), 87 | PayingResolver: deployOrAttach(PayingResolver__factory, signer), 88 | PermissionedEIP712Proxy: deployOrAttach(PermissionedEIP712Proxy__factory, signer), 89 | RecipientResolver: deployOrAttach(RecipientResolver__factory, signer), 90 | RevocationResolver: deployOrAttach(RevocationResolver__factory, signer), 91 | SchemaRegistry: deployOrAttach(SchemaRegistry__factory, signer), 92 | TestEAS: deployOrAttach(TestEAS__factory, signer), 93 | TestEIP712Proxy: deployOrAttach(TestEIP712Proxy__factory, signer), 94 | TestEIP1271Signer: deployOrAttach(TestEIP1271Signer__factory, signer), 95 | TestEIP1271Verifier: deployOrAttach(TestEIP1271Verifier__factory, signer), 96 | TestERC20Token: deployOrAttach(TestERC20Token__factory, signer), 97 | TestSchemaResolver: deployOrAttach(TestSchemaResolver__factory, signer), 98 | TokenResolver: deployOrAttach(TokenResolver__factory, signer), 99 | ValueResolver: deployOrAttach(ValueResolver__factory, signer) 100 | }); 101 | 102 | export default getContracts(); 103 | -------------------------------------------------------------------------------- /contracts/Common.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | // A representation of an empty/uninitialized UID. 6 | bytes32 constant EMPTY_UID = 0; 7 | 8 | // A zero expiration represents an non-expiring attestation. 9 | uint64 constant NO_EXPIRATION_TIME = 0; 10 | 11 | error AccessDenied(); 12 | error DeadlineExpired(); 13 | error InvalidEAS(); 14 | error InvalidLength(); 15 | error InvalidSignature(); 16 | error NotFound(); 17 | 18 | /// @notice A struct representing ECDSA signature data. 19 | struct Signature { 20 | uint8 v; // The recovery ID. 21 | bytes32 r; // The x-coordinate of the nonce R. 22 | bytes32 s; // The signature data. 23 | } 24 | 25 | /// @notice A struct representing a single attestation. 26 | struct Attestation { 27 | bytes32 uid; // A unique identifier of the attestation. 28 | bytes32 schema; // The unique identifier of the schema. 29 | uint64 time; // The time when the attestation was created (Unix timestamp). 30 | uint64 expirationTime; // The time when the attestation expires (Unix timestamp). 31 | uint64 revocationTime; // The time when the attestation was revoked (Unix timestamp). 32 | bytes32 refUID; // The UID of the related attestation. 33 | address recipient; // The recipient of the attestation. 34 | address attester; // The attester/sender of the attestation. 35 | bool revocable; // Whether the attestation is revocable. 36 | bytes data; // Custom attestation data. 37 | } 38 | -------------------------------------------------------------------------------- /contracts/ISchemaRegistry.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | import { ISemver } from "./ISemver.sol"; 6 | 7 | import { ISchemaResolver } from "./resolver/ISchemaResolver.sol"; 8 | 9 | /// @notice A struct representing a record for a submitted schema. 10 | struct SchemaRecord { 11 | bytes32 uid; // The unique identifier of the schema. 12 | ISchemaResolver resolver; // Optional schema resolver. 13 | bool revocable; // Whether the schema allows revocations explicitly. 14 | string schema; // Custom specification of the schema (e.g., an ABI). 15 | } 16 | 17 | /// @title ISchemaRegistry 18 | /// @notice The interface of global attestation schemas for the Ethereum Attestation Service protocol. 19 | interface ISchemaRegistry is ISemver { 20 | /// @notice Emitted when a new schema has been registered 21 | /// @param uid The schema UID. 22 | /// @param registerer The address of the account used to register the schema. 23 | /// @param schema The schema data. 24 | event Registered(bytes32 indexed uid, address indexed registerer, SchemaRecord schema); 25 | 26 | /// @notice Submits and reserves a new schema 27 | /// @param schema The schema data schema. 28 | /// @param resolver An optional schema resolver. 29 | /// @param revocable Whether the schema allows revocations explicitly. 30 | /// @return The UID of the new schema. 31 | function register(string calldata schema, ISchemaResolver resolver, bool revocable) external returns (bytes32); 32 | 33 | /// @notice Returns an existing schema by UID 34 | /// @param uid The UID of the schema to retrieve. 35 | /// @return The schema data members. 36 | function getSchema(bytes32 uid) external view returns (SchemaRecord memory); 37 | } 38 | -------------------------------------------------------------------------------- /contracts/ISemver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | /// @title ISemver 6 | /// @notice A semver interface. 7 | interface ISemver { 8 | /// @notice Returns the full semver contract version. 9 | /// @return Semver contract version as a string. 10 | function version() external view returns (string memory); 11 | } 12 | -------------------------------------------------------------------------------- /contracts/SchemaRegistry.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.8.28; 4 | 5 | import { ISchemaResolver } from "./resolver/ISchemaResolver.sol"; 6 | 7 | import { EMPTY_UID } from "./Common.sol"; 8 | import { Semver } from "./Semver.sol"; 9 | import { ISchemaRegistry, SchemaRecord } from "./ISchemaRegistry.sol"; 10 | 11 | /// @title SchemaRegistry 12 | /// @notice The global schema registry. 13 | contract SchemaRegistry is ISchemaRegistry, Semver { 14 | error AlreadyExists(); 15 | 16 | // The global mapping between schema records and their IDs. 17 | mapping(bytes32 uid => SchemaRecord schemaRecord) private _registry; 18 | 19 | /// @dev Creates a new SchemaRegistry instance. 20 | constructor() Semver(1, 4, 0) {} 21 | 22 | /// @inheritdoc ISchemaRegistry 23 | function register(string calldata schema, ISchemaResolver resolver, bool revocable) external returns (bytes32) { 24 | SchemaRecord memory schemaRecord = SchemaRecord({ 25 | uid: EMPTY_UID, 26 | schema: schema, 27 | resolver: resolver, 28 | revocable: revocable 29 | }); 30 | 31 | bytes32 uid = _getUID(schemaRecord); 32 | if (_registry[uid].uid != EMPTY_UID) { 33 | revert AlreadyExists(); 34 | } 35 | 36 | schemaRecord.uid = uid; 37 | _registry[uid] = schemaRecord; 38 | 39 | emit Registered(uid, msg.sender, schemaRecord); 40 | 41 | return uid; 42 | } 43 | 44 | /// @inheritdoc ISchemaRegistry 45 | function getSchema(bytes32 uid) external view returns (SchemaRecord memory) { 46 | return _registry[uid]; 47 | } 48 | 49 | /// @dev Calculates a UID for a given schema. 50 | /// @param schemaRecord The input schema. 51 | /// @return schema UID. 52 | function _getUID(SchemaRecord memory schemaRecord) private pure returns (bytes32) { 53 | return keccak256(abi.encodePacked(schemaRecord.schema, schemaRecord.resolver, schemaRecord.revocable)); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /contracts/Semver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.4; 4 | 5 | import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; 6 | 7 | import { ISemver } from "./ISemver.sol"; 8 | 9 | /// @title Semver 10 | /// @notice A simple contract for managing contract versions. 11 | contract Semver is ISemver { 12 | // Contract's major version number. 13 | uint256 private immutable _major; 14 | 15 | // Contract's minor version number. 16 | uint256 private immutable _minor; 17 | 18 | // Contract's patch version number. 19 | uint256 private immutable _patch; 20 | 21 | /// @dev Create a new Semver instance. 22 | /// @param major Major version number. 23 | /// @param minor Minor version number. 24 | /// @param patch Patch version number. 25 | constructor(uint256 major, uint256 minor, uint256 patch) { 26 | _major = major; 27 | _minor = minor; 28 | _patch = patch; 29 | } 30 | 31 | /// @notice Returns the full semver contract version. 32 | /// @return Semver contract version as a string. 33 | function version() external view returns (string memory) { 34 | return 35 | string( 36 | abi.encodePacked(Strings.toString(_major), ".", Strings.toString(_minor), ".", Strings.toString(_patch)) 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /contracts/eip712/proxy/examples/PermissionedEIP712Proxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.8.28; 4 | 5 | import { Ownable, Ownable2Step } from "@openzeppelin/contracts/access/Ownable2Step.sol"; 6 | 7 | // prettier-ignore 8 | import { 9 | EIP712Proxy, 10 | DelegatedProxyAttestationRequest, 11 | DelegatedProxyRevocationRequest, 12 | MultiDelegatedProxyAttestationRequest, 13 | MultiDelegatedProxyRevocationRequest 14 | } from "../EIP712Proxy.sol"; 15 | 16 | import { IEAS } from "../../../IEAS.sol"; 17 | 18 | import { AccessDenied } from "../../../Common.sol"; 19 | 20 | /// @title PermissionedEIP712Proxy 21 | /// @notice A sample EIP712 proxy that allows only a specific address to attest. 22 | contract PermissionedEIP712Proxy is EIP712Proxy, Ownable2Step { 23 | /// @dev Creates a new PermissionedEIP712Proxy instance. 24 | /// @param eas The address of the global EAS contract. 25 | /// @param name The user readable name of the signing domain. 26 | constructor(IEAS eas, string memory name) Ownable(msg.sender) EIP712Proxy(eas, name) {} 27 | 28 | /// @inheritdoc EIP712Proxy 29 | function attestByDelegation( 30 | DelegatedProxyAttestationRequest calldata delegatedRequest 31 | ) public payable override returns (bytes32) { 32 | // Ensure that only the owner is allowed to delegate attestations. 33 | _verifyAttester(delegatedRequest.attester); 34 | 35 | return super.attestByDelegation(delegatedRequest); 36 | } 37 | 38 | /// @inheritdoc EIP712Proxy 39 | function multiAttestByDelegation( 40 | MultiDelegatedProxyAttestationRequest[] calldata multiDelegatedRequests 41 | ) public payable override returns (bytes32[] memory) { 42 | uint256 length = multiDelegatedRequests.length; 43 | for (uint256 i = 0; i < length; ++i) { 44 | // Ensure that only the owner is allowed to delegate attestations. 45 | _verifyAttester(multiDelegatedRequests[i].attester); 46 | } 47 | 48 | return super.multiAttestByDelegation(multiDelegatedRequests); 49 | } 50 | 51 | /// @inheritdoc EIP712Proxy 52 | function revokeByDelegation(DelegatedProxyRevocationRequest calldata delegatedRequest) public payable override { 53 | // Ensure that only the owner is allowed to delegate revocations. 54 | _verifyAttester(delegatedRequest.revoker); 55 | 56 | super.revokeByDelegation(delegatedRequest); 57 | } 58 | 59 | /// @inheritdoc EIP712Proxy 60 | function multiRevokeByDelegation( 61 | MultiDelegatedProxyRevocationRequest[] calldata multiDelegatedRequests 62 | ) public payable override { 63 | uint256 length = multiDelegatedRequests.length; 64 | for (uint256 i = 0; i < length; ++i) { 65 | // Ensure that only the owner is allowed to delegate revocations. 66 | _verifyAttester(multiDelegatedRequests[i].revoker); 67 | } 68 | 69 | super.multiRevokeByDelegation(multiDelegatedRequests); 70 | } 71 | 72 | /// @dev Ensures that only the allowed attester can attest. 73 | /// @param attester The attester to verify. 74 | function _verifyAttester(address attester) private view { 75 | if (attester != owner()) { 76 | revert AccessDenied(); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /contracts/resolver/ISchemaResolver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | import { Attestation } from "./../Common.sol"; 6 | import { ISemver } from "./../ISemver.sol"; 7 | 8 | /// @title ISchemaResolver 9 | /// @notice The interface of an optional schema resolver. 10 | interface ISchemaResolver is ISemver { 11 | /// @notice Checks if the resolver can be sent ETH. 12 | /// @return Whether the resolver supports ETH transfers. 13 | function isPayable() external pure returns (bool); 14 | 15 | /// @notice Processes an attestation and verifies whether it's valid. 16 | /// @param attestation The new attestation. 17 | /// @return Whether the attestation is valid. 18 | function attest(Attestation calldata attestation) external payable returns (bool); 19 | 20 | /// @notice Processes multiple attestations and verifies whether they are valid. 21 | /// @param attestations The new attestations. 22 | /// @param values Explicit ETH amounts which were sent with each attestation. 23 | /// @return Whether all the attestations are valid. 24 | function multiAttest( 25 | Attestation[] calldata attestations, 26 | uint256[] calldata values 27 | ) external payable returns (bool); 28 | 29 | /// @notice Processes an attestation revocation and verifies if it can be revoked. 30 | /// @param attestation The existing attestation to be revoked. 31 | /// @return Whether the attestation can be revoked. 32 | function revoke(Attestation calldata attestation) external payable returns (bool); 33 | 34 | /// @notice Processes revocation of multiple attestation and verifies they can be revoked. 35 | /// @param attestations The existing attestations to be revoked. 36 | /// @param values Explicit ETH amounts which were sent with each revocation. 37 | /// @return Whether the attestations can be revoked. 38 | function multiRevoke( 39 | Attestation[] calldata attestations, 40 | uint256[] calldata values 41 | ) external payable returns (bool); 42 | } 43 | -------------------------------------------------------------------------------- /contracts/resolver/examples/AttestationResolver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.8.28; 4 | 5 | import { SchemaResolver } from "../SchemaResolver.sol"; 6 | 7 | import { IEAS, Attestation } from "../../IEAS.sol"; 8 | 9 | /// @title AttestationResolver 10 | /// @notice A sample schema resolver that checks whether an attestations attest to an existing attestation with a 11 | // specific data field. 12 | contract AttestationResolver is SchemaResolver { 13 | error OutOfBounds(); 14 | 15 | bytes32 private constant MAGIC_DATA = "EA5EA5EA5EA5EA5EA5EA5EA5EA5EA5"; 16 | 17 | constructor(IEAS eas) SchemaResolver(eas) {} 18 | 19 | function onAttest(Attestation calldata attestation, uint256 /*value*/) internal view override returns (bool) { 20 | bytes32 uid = _toBytes32(attestation.data, 0); 21 | Attestation memory targetAttestation = _eas.getAttestation(uid); 22 | 23 | // Make sure that the encoded data is an attestation with the magic data. 24 | return targetAttestation.data.length == MAGIC_DATA.length && bytes32(targetAttestation.data) == MAGIC_DATA; 25 | } 26 | 27 | function onRevoke(Attestation calldata /*attestation*/, uint256 /*value*/) internal pure override returns (bool) { 28 | return true; 29 | } 30 | 31 | function toBytes32(bytes memory data, uint256 start) external pure returns (bytes32) { 32 | return _toBytes32(data, start); 33 | } 34 | 35 | function _toBytes32(bytes memory data, uint256 start) private pure returns (bytes32) { 36 | unchecked { 37 | if (data.length < start + 32) { 38 | revert OutOfBounds(); 39 | } 40 | } 41 | 42 | bytes32 tempBytes32; 43 | 44 | // solhint-disable-next-line no-inline-assembly 45 | assembly { 46 | tempBytes32 := mload(add(add(data, 0x20), start)) 47 | } 48 | 49 | return tempBytes32; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /contracts/resolver/examples/AttesterResolver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.8.28; 4 | 5 | import { SchemaResolver } from "../SchemaResolver.sol"; 6 | 7 | import { IEAS, Attestation } from "../../IEAS.sol"; 8 | 9 | /// @title AttesterResolver 10 | /// @notice A sample schema resolver that checks whether the attestation is from a specific attester. 11 | contract AttesterResolver is SchemaResolver { 12 | address private immutable _targetAttester; 13 | 14 | constructor(IEAS eas, address targetAttester) SchemaResolver(eas) { 15 | _targetAttester = targetAttester; 16 | } 17 | 18 | function onAttest(Attestation calldata attestation, uint256 /*value*/) internal view override returns (bool) { 19 | return attestation.attester == _targetAttester; 20 | } 21 | 22 | function onRevoke(Attestation calldata /*attestation*/, uint256 /*value*/) internal pure override returns (bool) { 23 | return true; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /contracts/resolver/examples/DataResolver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.8.28; 4 | 5 | import { SchemaResolver } from "../SchemaResolver.sol"; 6 | 7 | import { IEAS, Attestation } from "../../IEAS.sol"; 8 | 9 | /// @title DataResolver 10 | /// @notice A sample schema resolver that checks whether an attestation data is either \x00 or \x01. 11 | contract DataResolver is SchemaResolver { 12 | bytes1 private constant DATA1 = "\x00"; 13 | bytes1 private constant DATA2 = "\x01"; 14 | 15 | constructor(IEAS eas) SchemaResolver(eas) {} 16 | 17 | function onAttest(Attestation calldata attestation, uint256 /*value*/) internal pure override returns (bool) { 18 | // Verifies that the data is either 0 or 1. 19 | return attestation.data.length == 1 && (attestation.data[0] == DATA1 || attestation.data[0] == DATA2); 20 | } 21 | 22 | function onRevoke(Attestation calldata /*attestation*/, uint256 /*value*/) internal pure override returns (bool) { 23 | return true; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /contracts/resolver/examples/ExpirationTimeResolver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.8.28; 4 | 5 | import { SchemaResolver } from "../SchemaResolver.sol"; 6 | 7 | import { IEAS, Attestation } from "../../IEAS.sol"; 8 | 9 | /// @title ExpirationTimeResolver 10 | /// @notice A sample schema resolver that checks whether the expiration time is later than a specific timestamp. 11 | contract ExpirationTimeResolver is SchemaResolver { 12 | uint256 private immutable _validAfter; 13 | 14 | constructor(IEAS eas, uint256 validAfter) SchemaResolver(eas) { 15 | _validAfter = validAfter; 16 | } 17 | 18 | function onAttest(Attestation calldata attestation, uint256 /*value*/) internal view override returns (bool) { 19 | return attestation.expirationTime >= _validAfter; 20 | } 21 | 22 | function onRevoke(Attestation calldata /*attestation*/, uint256 /*value*/) internal pure override returns (bool) { 23 | return true; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /contracts/resolver/examples/PayingResolver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.8.28; 4 | 5 | import { Address } from "@openzeppelin/contracts/utils/Address.sol"; 6 | 7 | import { SchemaResolver } from "../SchemaResolver.sol"; 8 | 9 | import { IEAS, Attestation } from "../../IEAS.sol"; 10 | 11 | /// @title PayingResolver 12 | /// @notice A sample schema resolver that pays attesters (and expects the payment to be returned during revocations). 13 | contract PayingResolver is SchemaResolver { 14 | using Address for address payable; 15 | 16 | error InvalidValue(); 17 | 18 | uint256 private immutable _incentive; 19 | 20 | constructor(IEAS eas, uint256 incentive) SchemaResolver(eas) { 21 | _incentive = incentive; 22 | } 23 | 24 | function isPayable() public pure override returns (bool) { 25 | return true; 26 | } 27 | 28 | function onAttest(Attestation calldata attestation, uint256 value) internal override returns (bool) { 29 | if (value > 0) { 30 | return false; 31 | } 32 | 33 | payable(attestation.attester).transfer(_incentive); 34 | 35 | return true; 36 | } 37 | 38 | function onRevoke(Attestation calldata attestation, uint256 value) internal override returns (bool) { 39 | if (value < _incentive) { 40 | return false; 41 | } 42 | 43 | if (value > _incentive) { 44 | payable(address(attestation.attester)).sendValue(value - _incentive); 45 | } 46 | 47 | return true; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /contracts/resolver/examples/RecipientResolver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.8.28; 4 | 5 | import { SchemaResolver } from "../SchemaResolver.sol"; 6 | 7 | import { IEAS, Attestation } from "../../IEAS.sol"; 8 | 9 | /// @title RecipientResolver 10 | /// @notice A sample schema resolver that checks whether the attestation is to a specific recipient. 11 | contract RecipientResolver is SchemaResolver { 12 | address private immutable _targetRecipient; 13 | 14 | constructor(IEAS eas, address targetRecipient) SchemaResolver(eas) { 15 | _targetRecipient = targetRecipient; 16 | } 17 | 18 | function onAttest(Attestation calldata attestation, uint256 /*value*/) internal view override returns (bool) { 19 | return attestation.recipient == _targetRecipient; 20 | } 21 | 22 | function onRevoke(Attestation calldata /*attestation*/, uint256 /*value*/) internal pure override returns (bool) { 23 | return true; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /contracts/resolver/examples/RevocationResolver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.8.28; 4 | 5 | import { SchemaResolver } from "../SchemaResolver.sol"; 6 | 7 | import { IEAS, Attestation } from "../../IEAS.sol"; 8 | 9 | /// @title RevocationResolver 10 | /// @notice A sample schema resolver that controls revocations. 11 | contract RevocationResolver is SchemaResolver { 12 | bool private _revocation; 13 | 14 | constructor(IEAS eas) SchemaResolver(eas) {} 15 | 16 | function setRevocation(bool status) external { 17 | _revocation = status; 18 | } 19 | 20 | function onAttest(Attestation calldata /*attestation)*/, uint256 /*value*/) internal pure override returns (bool) { 21 | return true; 22 | } 23 | 24 | function onRevoke(Attestation calldata /*attestation*/, uint256 /*value*/) internal view override returns (bool) { 25 | return _revocation; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /contracts/resolver/examples/TokenResolver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.8.28; 4 | 5 | import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 6 | import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; 7 | 8 | import { SchemaResolver } from "../SchemaResolver.sol"; 9 | 10 | import { IEAS, Attestation } from "../../IEAS.sol"; 11 | 12 | /// @title TokenResolver 13 | /// @notice A sample schema resolver that checks whether a specific amount of tokens was approved to be included in an attestation. 14 | contract TokenResolver is SchemaResolver { 15 | using SafeERC20 for IERC20; 16 | 17 | error InvalidAllowance(); 18 | 19 | IERC20 private immutable _targetToken; 20 | uint256 private immutable _targetAmount; 21 | 22 | constructor(IEAS eas, IERC20 targetToken, uint256 targetAmount) SchemaResolver(eas) { 23 | _targetToken = targetToken; 24 | _targetAmount = targetAmount; 25 | } 26 | 27 | function onAttest(Attestation calldata attestation, uint256 /*value*/) internal view override returns (bool) { 28 | if (_targetToken.allowance(attestation.attester, address(this)) < _targetAmount) { 29 | revert InvalidAllowance(); 30 | } 31 | 32 | return true; 33 | } 34 | 35 | function onRevoke(Attestation calldata /*attestation*/, uint256 /*value*/) internal pure override returns (bool) { 36 | return true; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /contracts/resolver/examples/ValueResolver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.8.28; 4 | 5 | import { SchemaResolver } from "../SchemaResolver.sol"; 6 | 7 | import { IEAS, Attestation } from "../../IEAS.sol"; 8 | 9 | /// @title ValueResolver 10 | /// @notice A sample schema resolver that checks whether a specific amount of ETH was sent with an attestation. 11 | contract ValueResolver is SchemaResolver { 12 | uint256 private immutable _targetValue; 13 | 14 | constructor(IEAS eas, uint256 targetValue) SchemaResolver(eas) { 15 | _targetValue = targetValue; 16 | } 17 | 18 | function isPayable() public pure override returns (bool) { 19 | return true; 20 | } 21 | 22 | function onAttest(Attestation calldata /*attestation*/, uint256 value) internal view override returns (bool) { 23 | return value == _targetValue; 24 | } 25 | 26 | function onRevoke(Attestation calldata /*attestation*/, uint256 /*value*/) internal pure override returns (bool) { 27 | return true; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /contracts/tests/TestEAS.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.8.28; 4 | 5 | import { EAS } from "../EAS.sol"; 6 | 7 | import { ISchemaRegistry } from "../ISchemaRegistry.sol"; 8 | 9 | contract TestEAS is EAS { 10 | uint64 private constant INITIAL_TIME = 0; 11 | 12 | uint64 private _currentTime = INITIAL_TIME; 13 | 14 | constructor(ISchemaRegistry registry) EAS(registry) {} 15 | 16 | function setTime(uint64 newTime) external { 17 | _currentTime = newTime; 18 | } 19 | 20 | function getTime() external view returns (uint64) { 21 | return _time(); 22 | } 23 | 24 | function _time() internal view override returns (uint64) { 25 | return _currentTime == INITIAL_TIME ? super._time() : _currentTime; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /contracts/tests/TestERC20Token.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.8.28; 4 | 5 | import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 6 | 7 | contract TestERC20Token is ERC20 { 8 | constructor(string memory name, string memory symbol, uint256 totalSupply) ERC20(name, symbol) { 9 | _mint(msg.sender, totalSupply); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /contracts/tests/TestSchemaResolver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.8.28; 4 | 5 | import { IEAS, Attestation } from "./../IEAS.sol"; 6 | import { SchemaResolver } from "./../resolver/SchemaResolver.sol"; 7 | 8 | contract TestSchemaResolver is SchemaResolver { 9 | constructor(IEAS eas) SchemaResolver(eas) {} 10 | 11 | function onAttest(Attestation calldata /*attestation*/, uint256 /*value*/) internal pure override returns (bool) { 12 | return true; 13 | } 14 | 15 | function onRevoke(Attestation calldata /*attestation*/, uint256 /*value*/) internal pure override returns (bool) { 16 | return true; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /contracts/tests/eip1271/TestEIP1271Signer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.8.28; 4 | 5 | import { IERC1271 } from "@openzeppelin/contracts/interfaces/IERC1271.sol"; 6 | 7 | contract TestEIP1271Signer is IERC1271 { 8 | bytes4 private constant EIP1271_INVALID_MAGIC_VALUE = 0xffffffff; 9 | 10 | mapping(bytes32 hash => bytes signature) private _validSignatures; 11 | 12 | function mockSignature(bytes32 hash, bytes calldata signature) external { 13 | _validSignatures[hash] = signature; 14 | } 15 | 16 | function isValidSignature(bytes32 hash, bytes calldata signature) external view returns (bytes4 magicValue) { 17 | bytes memory storedSignature = _validSignatures[hash]; 18 | if (storedSignature.length == signature.length && keccak256(storedSignature) == keccak256(signature)) { 19 | return IERC1271.isValidSignature.selector; 20 | } 21 | 22 | return EIP1271_INVALID_MAGIC_VALUE; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /contracts/tests/eip1271/TestEIP1271Verifier.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.8.28; 4 | 5 | import { EIP1271Verifier } from "../../eip1271/EIP1271Verifier.sol"; 6 | import { DelegatedAttestationRequest, DelegatedRevocationRequest } from "../../IEAS.sol"; 7 | import { Semver } from "../../Semver.sol"; 8 | 9 | contract TestEIP1271Verifier is Semver, EIP1271Verifier { 10 | constructor(string memory name) Semver(1, 4, 0) EIP1271Verifier(name, "1.4.0") {} 11 | 12 | function verifyAttest(DelegatedAttestationRequest memory request) external { 13 | _verifyAttest(request); 14 | } 15 | 16 | function verifyRevoke(DelegatedRevocationRequest memory request) external { 17 | _verifyRevoke(request); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /contracts/tests/eip712/proxy/TestEIP712Proxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.8.28; 4 | 5 | import { IEAS } from "../../../IEAS.sol"; 6 | import { EIP712Proxy, DelegatedProxyAttestationRequest, DelegatedProxyRevocationRequest } from "../../../eip712/proxy/EIP712Proxy.sol"; 7 | 8 | contract TestEIP712Proxy is EIP712Proxy { 9 | constructor(IEAS eas, string memory name) EIP712Proxy(eas, name) {} 10 | 11 | function verifyAttest(DelegatedProxyAttestationRequest memory request) external { 12 | _verifyAttest(request); 13 | } 14 | 15 | function verifyRevoke(DelegatedProxyRevocationRequest memory request) external { 16 | _verifyRevoke(request); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /deployments/arbitrum-nova/.chainId: -------------------------------------------------------------------------------- 1 | 42170 2 | -------------------------------------------------------------------------------- /deployments/arbitrum-nova/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1706812884, 3 | "000002-eas": 1706812886, 4 | "000003-register-initial-schemas": 1706812965, 5 | "000004-name-initial-schemas": 1706813044, 6 | "000005-eip712-proxy": 1706813046, 7 | "000006-indexer": 1706813048 8 | } -------------------------------------------------------------------------------- /deployments/arbitrum-nova/types/contracts/SchemaRegistry.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type { 5 | BaseContract, 6 | BytesLike, 7 | FunctionFragment, 8 | Result, 9 | Interface, 10 | EventFragment, 11 | AddressLike, 12 | ContractRunner, 13 | ContractMethod, 14 | Listener, 15 | } from "ethers"; 16 | import type { 17 | TypedContractEvent, 18 | TypedDeferredTopicFilter, 19 | TypedEventLog, 20 | TypedLogDescription, 21 | TypedListener, 22 | TypedContractMethod, 23 | } from "../common"; 24 | 25 | export type SchemaRecordStruct = { 26 | uid: BytesLike; 27 | resolver: AddressLike; 28 | revocable: boolean; 29 | schema: string; 30 | }; 31 | 32 | export type SchemaRecordStructOutput = [ 33 | uid: string, 34 | resolver: string, 35 | revocable: boolean, 36 | schema: string 37 | ] & { uid: string; resolver: string; revocable: boolean; schema: string }; 38 | 39 | export interface SchemaRegistryInterface extends Interface { 40 | getFunction( 41 | nameOrSignature: "getSchema" | "register" | "version" 42 | ): FunctionFragment; 43 | 44 | getEvent(nameOrSignatureOrTopic: "Registered"): EventFragment; 45 | 46 | encodeFunctionData( 47 | functionFragment: "getSchema", 48 | values: [BytesLike] 49 | ): string; 50 | encodeFunctionData( 51 | functionFragment: "register", 52 | values: [string, AddressLike, boolean] 53 | ): string; 54 | encodeFunctionData(functionFragment: "version", values?: undefined): string; 55 | 56 | decodeFunctionResult(functionFragment: "getSchema", data: BytesLike): Result; 57 | decodeFunctionResult(functionFragment: "register", data: BytesLike): Result; 58 | decodeFunctionResult(functionFragment: "version", data: BytesLike): Result; 59 | } 60 | 61 | export namespace RegisteredEvent { 62 | export type InputTuple = [ 63 | uid: BytesLike, 64 | registerer: AddressLike, 65 | schema: SchemaRecordStruct 66 | ]; 67 | export type OutputTuple = [ 68 | uid: string, 69 | registerer: string, 70 | schema: SchemaRecordStructOutput 71 | ]; 72 | export interface OutputObject { 73 | uid: string; 74 | registerer: string; 75 | schema: SchemaRecordStructOutput; 76 | } 77 | export type Event = TypedContractEvent; 78 | export type Filter = TypedDeferredTopicFilter; 79 | export type Log = TypedEventLog; 80 | export type LogDescription = TypedLogDescription; 81 | } 82 | 83 | export interface SchemaRegistry extends BaseContract { 84 | connect(runner?: ContractRunner | null): SchemaRegistry; 85 | waitForDeployment(): Promise; 86 | 87 | interface: SchemaRegistryInterface; 88 | 89 | queryFilter( 90 | event: TCEvent, 91 | fromBlockOrBlockhash?: string | number | undefined, 92 | toBlock?: string | number | undefined 93 | ): Promise>>; 94 | queryFilter( 95 | filter: TypedDeferredTopicFilter, 96 | fromBlockOrBlockhash?: string | number | undefined, 97 | toBlock?: string | number | undefined 98 | ): Promise>>; 99 | 100 | on( 101 | event: TCEvent, 102 | listener: TypedListener 103 | ): Promise; 104 | on( 105 | filter: TypedDeferredTopicFilter, 106 | listener: TypedListener 107 | ): Promise; 108 | 109 | once( 110 | event: TCEvent, 111 | listener: TypedListener 112 | ): Promise; 113 | once( 114 | filter: TypedDeferredTopicFilter, 115 | listener: TypedListener 116 | ): Promise; 117 | 118 | listeners( 119 | event: TCEvent 120 | ): Promise>>; 121 | listeners(eventName?: string): Promise>; 122 | removeAllListeners( 123 | event?: TCEvent 124 | ): Promise; 125 | 126 | getSchema: TypedContractMethod< 127 | [uid: BytesLike], 128 | [SchemaRecordStructOutput], 129 | "view" 130 | >; 131 | 132 | register: TypedContractMethod< 133 | [schema: string, resolver: AddressLike, revocable: boolean], 134 | [string], 135 | "nonpayable" 136 | >; 137 | 138 | version: TypedContractMethod<[], [string], "view">; 139 | 140 | getFunction( 141 | key: string | FunctionFragment 142 | ): T; 143 | 144 | getFunction( 145 | nameOrSignature: "getSchema" 146 | ): TypedContractMethod<[uid: BytesLike], [SchemaRecordStructOutput], "view">; 147 | getFunction( 148 | nameOrSignature: "register" 149 | ): TypedContractMethod< 150 | [schema: string, resolver: AddressLike, revocable: boolean], 151 | [string], 152 | "nonpayable" 153 | >; 154 | getFunction( 155 | nameOrSignature: "version" 156 | ): TypedContractMethod<[], [string], "view">; 157 | 158 | getEvent( 159 | key: "Registered" 160 | ): TypedContractEvent< 161 | RegisteredEvent.InputTuple, 162 | RegisteredEvent.OutputTuple, 163 | RegisteredEvent.OutputObject 164 | >; 165 | 166 | filters: { 167 | "Registered(bytes32,address,tuple)": TypedContractEvent< 168 | RegisteredEvent.InputTuple, 169 | RegisteredEvent.OutputTuple, 170 | RegisteredEvent.OutputObject 171 | >; 172 | Registered: TypedContractEvent< 173 | RegisteredEvent.InputTuple, 174 | RegisteredEvent.OutputTuple, 175 | RegisteredEvent.OutputObject 176 | >; 177 | }; 178 | } 179 | -------------------------------------------------------------------------------- /deployments/arbitrum-one/.chainId: -------------------------------------------------------------------------------- 1 | 42161 2 | -------------------------------------------------------------------------------- /deployments/arbitrum-one/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1677352373, 3 | "000002-eas": 1677352375, 4 | "000003-register-initial-schemas": 1677352432, 5 | "000004-name-initial-schemas": 1677352617 6 | } -------------------------------------------------------------------------------- /deployments/arbitrum-sepolia/.chainId: -------------------------------------------------------------------------------- 1 | 421614 2 | -------------------------------------------------------------------------------- /deployments/arbitrum-sepolia/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1737155407, 3 | "000002-eas": 1737155413, 4 | "000003-register-initial-schemas": 1737155813 5 | } -------------------------------------------------------------------------------- /deployments/arbitrum-sepolia/types/@ethereum-attestation-service/eas-contracts/contracts/SchemaRegistry.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type { 5 | BaseContract, 6 | BytesLike, 7 | FunctionFragment, 8 | Result, 9 | Interface, 10 | EventFragment, 11 | AddressLike, 12 | ContractRunner, 13 | ContractMethod, 14 | Listener, 15 | } from "ethers"; 16 | import type { 17 | TypedContractEvent, 18 | TypedDeferredTopicFilter, 19 | TypedEventLog, 20 | TypedLogDescription, 21 | TypedListener, 22 | TypedContractMethod, 23 | } from "../../../common"; 24 | 25 | export type SchemaRecordStruct = { 26 | uid: BytesLike; 27 | resolver: AddressLike; 28 | revocable: boolean; 29 | schema: string; 30 | }; 31 | 32 | export type SchemaRecordStructOutput = [ 33 | uid: string, 34 | resolver: string, 35 | revocable: boolean, 36 | schema: string 37 | ] & { uid: string; resolver: string; revocable: boolean; schema: string }; 38 | 39 | export interface SchemaRegistryInterface extends Interface { 40 | getFunction( 41 | nameOrSignature: "getSchema" | "register" | "version" 42 | ): FunctionFragment; 43 | 44 | getEvent(nameOrSignatureOrTopic: "Registered"): EventFragment; 45 | 46 | encodeFunctionData( 47 | functionFragment: "getSchema", 48 | values: [BytesLike] 49 | ): string; 50 | encodeFunctionData( 51 | functionFragment: "register", 52 | values: [string, AddressLike, boolean] 53 | ): string; 54 | encodeFunctionData(functionFragment: "version", values?: undefined): string; 55 | 56 | decodeFunctionResult(functionFragment: "getSchema", data: BytesLike): Result; 57 | decodeFunctionResult(functionFragment: "register", data: BytesLike): Result; 58 | decodeFunctionResult(functionFragment: "version", data: BytesLike): Result; 59 | } 60 | 61 | export namespace RegisteredEvent { 62 | export type InputTuple = [ 63 | uid: BytesLike, 64 | registerer: AddressLike, 65 | schema: SchemaRecordStruct 66 | ]; 67 | export type OutputTuple = [ 68 | uid: string, 69 | registerer: string, 70 | schema: SchemaRecordStructOutput 71 | ]; 72 | export interface OutputObject { 73 | uid: string; 74 | registerer: string; 75 | schema: SchemaRecordStructOutput; 76 | } 77 | export type Event = TypedContractEvent; 78 | export type Filter = TypedDeferredTopicFilter; 79 | export type Log = TypedEventLog; 80 | export type LogDescription = TypedLogDescription; 81 | } 82 | 83 | export interface SchemaRegistry extends BaseContract { 84 | connect(runner?: ContractRunner | null): SchemaRegistry; 85 | waitForDeployment(): Promise; 86 | 87 | interface: SchemaRegistryInterface; 88 | 89 | queryFilter( 90 | event: TCEvent, 91 | fromBlockOrBlockhash?: string | number | undefined, 92 | toBlock?: string | number | undefined 93 | ): Promise>>; 94 | queryFilter( 95 | filter: TypedDeferredTopicFilter, 96 | fromBlockOrBlockhash?: string | number | undefined, 97 | toBlock?: string | number | undefined 98 | ): Promise>>; 99 | 100 | on( 101 | event: TCEvent, 102 | listener: TypedListener 103 | ): Promise; 104 | on( 105 | filter: TypedDeferredTopicFilter, 106 | listener: TypedListener 107 | ): Promise; 108 | 109 | once( 110 | event: TCEvent, 111 | listener: TypedListener 112 | ): Promise; 113 | once( 114 | filter: TypedDeferredTopicFilter, 115 | listener: TypedListener 116 | ): Promise; 117 | 118 | listeners( 119 | event: TCEvent 120 | ): Promise>>; 121 | listeners(eventName?: string): Promise>; 122 | removeAllListeners( 123 | event?: TCEvent 124 | ): Promise; 125 | 126 | getSchema: TypedContractMethod< 127 | [uid: BytesLike], 128 | [SchemaRecordStructOutput], 129 | "view" 130 | >; 131 | 132 | register: TypedContractMethod< 133 | [schema: string, resolver: AddressLike, revocable: boolean], 134 | [string], 135 | "nonpayable" 136 | >; 137 | 138 | version: TypedContractMethod<[], [string], "view">; 139 | 140 | getFunction( 141 | key: string | FunctionFragment 142 | ): T; 143 | 144 | getFunction( 145 | nameOrSignature: "getSchema" 146 | ): TypedContractMethod<[uid: BytesLike], [SchemaRecordStructOutput], "view">; 147 | getFunction( 148 | nameOrSignature: "register" 149 | ): TypedContractMethod< 150 | [schema: string, resolver: AddressLike, revocable: boolean], 151 | [string], 152 | "nonpayable" 153 | >; 154 | getFunction( 155 | nameOrSignature: "version" 156 | ): TypedContractMethod<[], [string], "view">; 157 | 158 | getEvent( 159 | key: "Registered" 160 | ): TypedContractEvent< 161 | RegisteredEvent.InputTuple, 162 | RegisteredEvent.OutputTuple, 163 | RegisteredEvent.OutputObject 164 | >; 165 | 166 | filters: { 167 | "Registered(bytes32,address,tuple)": TypedContractEvent< 168 | RegisteredEvent.InputTuple, 169 | RegisteredEvent.OutputTuple, 170 | RegisteredEvent.OutputObject 171 | >; 172 | Registered: TypedContractEvent< 173 | RegisteredEvent.InputTuple, 174 | RegisteredEvent.OutputTuple, 175 | RegisteredEvent.OutputObject 176 | >; 177 | }; 178 | } 179 | -------------------------------------------------------------------------------- /deployments/base-goerli/.chainId: -------------------------------------------------------------------------------- 1 | 84531 -------------------------------------------------------------------------------- /deployments/base-goerli/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1684880484, 3 | "000002-eas": 1684880493, 4 | "000003-register-initial-schemas": 1697138912, 5 | "000004-name-initial-schemas": 1697139184, 6 | "000005-eip712-proxy": 1697139190, 7 | "000006-indexer": 1698798154, 8 | "000100-test-seed": 1697229391 9 | } 10 | -------------------------------------------------------------------------------- /deployments/base-goerli/SchemaRegistry.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "0x4200000000000000000000000000000000000020", 3 | "abi": [ 4 | { 5 | "inputs": [], 6 | "stateMutability": "nonpayable", 7 | "type": "constructor" 8 | }, 9 | { 10 | "inputs": [], 11 | "name": "AlreadyExists", 12 | "type": "error" 13 | }, 14 | { 15 | "anonymous": false, 16 | "inputs": [ 17 | { 18 | "indexed": true, 19 | "internalType": "bytes32", 20 | "name": "uid", 21 | "type": "bytes32" 22 | }, 23 | { 24 | "indexed": true, 25 | "internalType": "address", 26 | "name": "registerer", 27 | "type": "address" 28 | }, 29 | { 30 | "components": [ 31 | { 32 | "internalType": "bytes32", 33 | "name": "uid", 34 | "type": "bytes32" 35 | }, 36 | { 37 | "internalType": "contract ISchemaResolver", 38 | "name": "resolver", 39 | "type": "address" 40 | }, 41 | { 42 | "internalType": "bool", 43 | "name": "revocable", 44 | "type": "bool" 45 | }, 46 | { 47 | "internalType": "string", 48 | "name": "schema", 49 | "type": "string" 50 | } 51 | ], 52 | "indexed": false, 53 | "internalType": "struct SchemaRecord", 54 | "name": "schema", 55 | "type": "tuple" 56 | } 57 | ], 58 | "name": "Registered", 59 | "type": "event" 60 | }, 61 | { 62 | "inputs": [ 63 | { 64 | "internalType": "bytes32", 65 | "name": "uid", 66 | "type": "bytes32" 67 | } 68 | ], 69 | "name": "getSchema", 70 | "outputs": [ 71 | { 72 | "components": [ 73 | { 74 | "internalType": "bytes32", 75 | "name": "uid", 76 | "type": "bytes32" 77 | }, 78 | { 79 | "internalType": "contract ISchemaResolver", 80 | "name": "resolver", 81 | "type": "address" 82 | }, 83 | { 84 | "internalType": "bool", 85 | "name": "revocable", 86 | "type": "bool" 87 | }, 88 | { 89 | "internalType": "string", 90 | "name": "schema", 91 | "type": "string" 92 | } 93 | ], 94 | "internalType": "struct SchemaRecord", 95 | "name": "", 96 | "type": "tuple" 97 | } 98 | ], 99 | "stateMutability": "view", 100 | "type": "function" 101 | }, 102 | { 103 | "inputs": [ 104 | { 105 | "internalType": "string", 106 | "name": "schema", 107 | "type": "string" 108 | }, 109 | { 110 | "internalType": "contract ISchemaResolver", 111 | "name": "resolver", 112 | "type": "address" 113 | }, 114 | { 115 | "internalType": "bool", 116 | "name": "revocable", 117 | "type": "bool" 118 | } 119 | ], 120 | "name": "register", 121 | "outputs": [ 122 | { 123 | "internalType": "bytes32", 124 | "name": "", 125 | "type": "bytes32" 126 | } 127 | ], 128 | "stateMutability": "nonpayable", 129 | "type": "function" 130 | }, 131 | { 132 | "inputs": [], 133 | "name": "version", 134 | "outputs": [ 135 | { 136 | "internalType": "string", 137 | "name": "", 138 | "type": "string" 139 | } 140 | ], 141 | "stateMutability": "view", 142 | "type": "function" 143 | } 144 | ] 145 | } 146 | -------------------------------------------------------------------------------- /deployments/base-sepolia/.chainId: -------------------------------------------------------------------------------- 1 | 84532 2 | -------------------------------------------------------------------------------- /deployments/base-sepolia/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1684880484, 3 | "000002-eas": 1684880493, 4 | "000003-register-initial-schemas": 1706273944, 5 | "000004-name-initial-schemas": 1706274209, 6 | "000005-eip712-proxy": 1706274215, 7 | "000006-indexer": 1706274220, 8 | "000100-test-seed": 1706274304 9 | } -------------------------------------------------------------------------------- /deployments/base-sepolia/SchemaRegistry.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "0x4200000000000000000000000000000000000020", 3 | "abi": [ 4 | { 5 | "inputs": [], 6 | "stateMutability": "nonpayable", 7 | "type": "constructor" 8 | }, 9 | { 10 | "inputs": [], 11 | "name": "AlreadyExists", 12 | "type": "error" 13 | }, 14 | { 15 | "anonymous": false, 16 | "inputs": [ 17 | { 18 | "indexed": true, 19 | "internalType": "bytes32", 20 | "name": "uid", 21 | "type": "bytes32" 22 | }, 23 | { 24 | "indexed": true, 25 | "internalType": "address", 26 | "name": "registerer", 27 | "type": "address" 28 | }, 29 | { 30 | "components": [ 31 | { 32 | "internalType": "bytes32", 33 | "name": "uid", 34 | "type": "bytes32" 35 | }, 36 | { 37 | "internalType": "contract ISchemaResolver", 38 | "name": "resolver", 39 | "type": "address" 40 | }, 41 | { 42 | "internalType": "bool", 43 | "name": "revocable", 44 | "type": "bool" 45 | }, 46 | { 47 | "internalType": "string", 48 | "name": "schema", 49 | "type": "string" 50 | } 51 | ], 52 | "indexed": false, 53 | "internalType": "struct SchemaRecord", 54 | "name": "schema", 55 | "type": "tuple" 56 | } 57 | ], 58 | "name": "Registered", 59 | "type": "event" 60 | }, 61 | { 62 | "inputs": [ 63 | { 64 | "internalType": "bytes32", 65 | "name": "uid", 66 | "type": "bytes32" 67 | } 68 | ], 69 | "name": "getSchema", 70 | "outputs": [ 71 | { 72 | "components": [ 73 | { 74 | "internalType": "bytes32", 75 | "name": "uid", 76 | "type": "bytes32" 77 | }, 78 | { 79 | "internalType": "contract ISchemaResolver", 80 | "name": "resolver", 81 | "type": "address" 82 | }, 83 | { 84 | "internalType": "bool", 85 | "name": "revocable", 86 | "type": "bool" 87 | }, 88 | { 89 | "internalType": "string", 90 | "name": "schema", 91 | "type": "string" 92 | } 93 | ], 94 | "internalType": "struct SchemaRecord", 95 | "name": "", 96 | "type": "tuple" 97 | } 98 | ], 99 | "stateMutability": "view", 100 | "type": "function" 101 | }, 102 | { 103 | "inputs": [ 104 | { 105 | "internalType": "string", 106 | "name": "schema", 107 | "type": "string" 108 | }, 109 | { 110 | "internalType": "contract ISchemaResolver", 111 | "name": "resolver", 112 | "type": "address" 113 | }, 114 | { 115 | "internalType": "bool", 116 | "name": "revocable", 117 | "type": "bool" 118 | } 119 | ], 120 | "name": "register", 121 | "outputs": [ 122 | { 123 | "internalType": "bytes32", 124 | "name": "", 125 | "type": "bytes32" 126 | } 127 | ], 128 | "stateMutability": "nonpayable", 129 | "type": "function" 130 | }, 131 | { 132 | "inputs": [], 133 | "name": "version", 134 | "outputs": [ 135 | { 136 | "internalType": "string", 137 | "name": "", 138 | "type": "string" 139 | } 140 | ], 141 | "stateMutability": "view", 142 | "type": "function" 143 | } 144 | ] 145 | } 146 | -------------------------------------------------------------------------------- /deployments/base/.chainId: -------------------------------------------------------------------------------- 1 | 8453 2 | -------------------------------------------------------------------------------- /deployments/base/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1682454805, 3 | "000002-eas": 1682454812, 4 | "000003-register-initial-schemas": 1694192651, 5 | "000004-name-initial-schemas": 1694192936, 6 | "000005-eip712-proxy": 1698793201, 7 | "000006-indexer": 1698793220 8 | } -------------------------------------------------------------------------------- /deployments/base/SchemaRegistry.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "0x4200000000000000000000000000000000000020", 3 | "abi": [ 4 | { 5 | "inputs": [], 6 | "stateMutability": "nonpayable", 7 | "type": "constructor" 8 | }, 9 | { 10 | "inputs": [], 11 | "name": "AlreadyExists", 12 | "type": "error" 13 | }, 14 | { 15 | "anonymous": false, 16 | "inputs": [ 17 | { 18 | "indexed": true, 19 | "internalType": "bytes32", 20 | "name": "uid", 21 | "type": "bytes32" 22 | }, 23 | { 24 | "indexed": true, 25 | "internalType": "address", 26 | "name": "registerer", 27 | "type": "address" 28 | }, 29 | { 30 | "components": [ 31 | { 32 | "internalType": "bytes32", 33 | "name": "uid", 34 | "type": "bytes32" 35 | }, 36 | { 37 | "internalType": "contract ISchemaResolver", 38 | "name": "resolver", 39 | "type": "address" 40 | }, 41 | { 42 | "internalType": "bool", 43 | "name": "revocable", 44 | "type": "bool" 45 | }, 46 | { 47 | "internalType": "string", 48 | "name": "schema", 49 | "type": "string" 50 | } 51 | ], 52 | "indexed": false, 53 | "internalType": "struct SchemaRecord", 54 | "name": "schema", 55 | "type": "tuple" 56 | } 57 | ], 58 | "name": "Registered", 59 | "type": "event" 60 | }, 61 | { 62 | "inputs": [ 63 | { 64 | "internalType": "bytes32", 65 | "name": "uid", 66 | "type": "bytes32" 67 | } 68 | ], 69 | "name": "getSchema", 70 | "outputs": [ 71 | { 72 | "components": [ 73 | { 74 | "internalType": "bytes32", 75 | "name": "uid", 76 | "type": "bytes32" 77 | }, 78 | { 79 | "internalType": "contract ISchemaResolver", 80 | "name": "resolver", 81 | "type": "address" 82 | }, 83 | { 84 | "internalType": "bool", 85 | "name": "revocable", 86 | "type": "bool" 87 | }, 88 | { 89 | "internalType": "string", 90 | "name": "schema", 91 | "type": "string" 92 | } 93 | ], 94 | "internalType": "struct SchemaRecord", 95 | "name": "", 96 | "type": "tuple" 97 | } 98 | ], 99 | "stateMutability": "view", 100 | "type": "function" 101 | }, 102 | { 103 | "inputs": [ 104 | { 105 | "internalType": "string", 106 | "name": "schema", 107 | "type": "string" 108 | }, 109 | { 110 | "internalType": "contract ISchemaResolver", 111 | "name": "resolver", 112 | "type": "address" 113 | }, 114 | { 115 | "internalType": "bool", 116 | "name": "revocable", 117 | "type": "bool" 118 | } 119 | ], 120 | "name": "register", 121 | "outputs": [ 122 | { 123 | "internalType": "bytes32", 124 | "name": "", 125 | "type": "bytes32" 126 | } 127 | ], 128 | "stateMutability": "nonpayable", 129 | "type": "function" 130 | }, 131 | { 132 | "inputs": [], 133 | "name": "version", 134 | "outputs": [ 135 | { 136 | "internalType": "string", 137 | "name": "", 138 | "type": "string" 139 | } 140 | ], 141 | "stateMutability": "view", 142 | "type": "function" 143 | } 144 | ] 145 | } 146 | -------------------------------------------------------------------------------- /deployments/celo/.chainId: -------------------------------------------------------------------------------- 1 | 42220 -------------------------------------------------------------------------------- /deployments/celo/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1710900693, 3 | "000002-eas": 1710900707, 4 | "000003-register-initial-schemas": 1710901215, 5 | "000004-name-initial-schemas": 1710901734, 6 | "000005-eip712-proxy": 1710901744, 7 | "000006-indexer": 1710901754 8 | } -------------------------------------------------------------------------------- /deployments/celo/types/contracts/SchemaRegistry.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type { 5 | BaseContract, 6 | BytesLike, 7 | FunctionFragment, 8 | Result, 9 | Interface, 10 | EventFragment, 11 | AddressLike, 12 | ContractRunner, 13 | ContractMethod, 14 | Listener, 15 | } from "ethers"; 16 | import type { 17 | TypedContractEvent, 18 | TypedDeferredTopicFilter, 19 | TypedEventLog, 20 | TypedLogDescription, 21 | TypedListener, 22 | TypedContractMethod, 23 | } from "../common"; 24 | 25 | export type SchemaRecordStruct = { 26 | uid: BytesLike; 27 | resolver: AddressLike; 28 | revocable: boolean; 29 | schema: string; 30 | }; 31 | 32 | export type SchemaRecordStructOutput = [ 33 | uid: string, 34 | resolver: string, 35 | revocable: boolean, 36 | schema: string 37 | ] & { uid: string; resolver: string; revocable: boolean; schema: string }; 38 | 39 | export interface SchemaRegistryInterface extends Interface { 40 | getFunction( 41 | nameOrSignature: "getSchema" | "register" | "version" 42 | ): FunctionFragment; 43 | 44 | getEvent(nameOrSignatureOrTopic: "Registered"): EventFragment; 45 | 46 | encodeFunctionData( 47 | functionFragment: "getSchema", 48 | values: [BytesLike] 49 | ): string; 50 | encodeFunctionData( 51 | functionFragment: "register", 52 | values: [string, AddressLike, boolean] 53 | ): string; 54 | encodeFunctionData(functionFragment: "version", values?: undefined): string; 55 | 56 | decodeFunctionResult(functionFragment: "getSchema", data: BytesLike): Result; 57 | decodeFunctionResult(functionFragment: "register", data: BytesLike): Result; 58 | decodeFunctionResult(functionFragment: "version", data: BytesLike): Result; 59 | } 60 | 61 | export namespace RegisteredEvent { 62 | export type InputTuple = [ 63 | uid: BytesLike, 64 | registerer: AddressLike, 65 | schema: SchemaRecordStruct 66 | ]; 67 | export type OutputTuple = [ 68 | uid: string, 69 | registerer: string, 70 | schema: SchemaRecordStructOutput 71 | ]; 72 | export interface OutputObject { 73 | uid: string; 74 | registerer: string; 75 | schema: SchemaRecordStructOutput; 76 | } 77 | export type Event = TypedContractEvent; 78 | export type Filter = TypedDeferredTopicFilter; 79 | export type Log = TypedEventLog; 80 | export type LogDescription = TypedLogDescription; 81 | } 82 | 83 | export interface SchemaRegistry extends BaseContract { 84 | connect(runner?: ContractRunner | null): SchemaRegistry; 85 | waitForDeployment(): Promise; 86 | 87 | interface: SchemaRegistryInterface; 88 | 89 | queryFilter( 90 | event: TCEvent, 91 | fromBlockOrBlockhash?: string | number | undefined, 92 | toBlock?: string | number | undefined 93 | ): Promise>>; 94 | queryFilter( 95 | filter: TypedDeferredTopicFilter, 96 | fromBlockOrBlockhash?: string | number | undefined, 97 | toBlock?: string | number | undefined 98 | ): Promise>>; 99 | 100 | on( 101 | event: TCEvent, 102 | listener: TypedListener 103 | ): Promise; 104 | on( 105 | filter: TypedDeferredTopicFilter, 106 | listener: TypedListener 107 | ): Promise; 108 | 109 | once( 110 | event: TCEvent, 111 | listener: TypedListener 112 | ): Promise; 113 | once( 114 | filter: TypedDeferredTopicFilter, 115 | listener: TypedListener 116 | ): Promise; 117 | 118 | listeners( 119 | event: TCEvent 120 | ): Promise>>; 121 | listeners(eventName?: string): Promise>; 122 | removeAllListeners( 123 | event?: TCEvent 124 | ): Promise; 125 | 126 | getSchema: TypedContractMethod< 127 | [uid: BytesLike], 128 | [SchemaRecordStructOutput], 129 | "view" 130 | >; 131 | 132 | register: TypedContractMethod< 133 | [schema: string, resolver: AddressLike, revocable: boolean], 134 | [string], 135 | "nonpayable" 136 | >; 137 | 138 | version: TypedContractMethod<[], [string], "view">; 139 | 140 | getFunction( 141 | key: string | FunctionFragment 142 | ): T; 143 | 144 | getFunction( 145 | nameOrSignature: "getSchema" 146 | ): TypedContractMethod<[uid: BytesLike], [SchemaRecordStructOutput], "view">; 147 | getFunction( 148 | nameOrSignature: "register" 149 | ): TypedContractMethod< 150 | [schema: string, resolver: AddressLike, revocable: boolean], 151 | [string], 152 | "nonpayable" 153 | >; 154 | getFunction( 155 | nameOrSignature: "version" 156 | ): TypedContractMethod<[], [string], "view">; 157 | 158 | getEvent( 159 | key: "Registered" 160 | ): TypedContractEvent< 161 | RegisteredEvent.InputTuple, 162 | RegisteredEvent.OutputTuple, 163 | RegisteredEvent.OutputObject 164 | >; 165 | 166 | filters: { 167 | "Registered(bytes32,address,tuple)": TypedContractEvent< 168 | RegisteredEvent.InputTuple, 169 | RegisteredEvent.OutputTuple, 170 | RegisteredEvent.OutputObject 171 | >; 172 | Registered: TypedContractEvent< 173 | RegisteredEvent.InputTuple, 174 | RegisteredEvent.OutputTuple, 175 | RegisteredEvent.OutputObject 176 | >; 177 | }; 178 | } 179 | -------------------------------------------------------------------------------- /deployments/hardhat/.chainId: -------------------------------------------------------------------------------- 1 | 31337 2 | -------------------------------------------------------------------------------- /deployments/ink-sepolia/.chainId: -------------------------------------------------------------------------------- 1 | 763373 2 | -------------------------------------------------------------------------------- /deployments/ink-sepolia/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1682454805, 3 | "000002-eas": 1682454812, 4 | "000003-register-initial-schemas": 1732802675, 5 | "000004-name-initial-schemas": 1732802681, 6 | "000005-eip712-proxy": 1732802997, 7 | "000006-indexer": 1732803300, 8 | "000100-test-seed": 1732813635 9 | } 10 | -------------------------------------------------------------------------------- /deployments/ink-sepolia/SchemaRegistry.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "0x4200000000000000000000000000000000000020", 3 | "abi": [ 4 | { 5 | "inputs": [], 6 | "stateMutability": "nonpayable", 7 | "type": "constructor" 8 | }, 9 | { 10 | "inputs": [], 11 | "name": "AlreadyExists", 12 | "type": "error" 13 | }, 14 | { 15 | "anonymous": false, 16 | "inputs": [ 17 | { 18 | "indexed": true, 19 | "internalType": "bytes32", 20 | "name": "uid", 21 | "type": "bytes32" 22 | }, 23 | { 24 | "indexed": false, 25 | "internalType": "address", 26 | "name": "registerer", 27 | "type": "address" 28 | } 29 | ], 30 | "name": "Registered", 31 | "type": "event" 32 | }, 33 | { 34 | "inputs": [ 35 | { 36 | "internalType": "bytes32", 37 | "name": "uid", 38 | "type": "bytes32" 39 | } 40 | ], 41 | "name": "getSchema", 42 | "outputs": [ 43 | { 44 | "components": [ 45 | { 46 | "internalType": "bytes32", 47 | "name": "uid", 48 | "type": "bytes32" 49 | }, 50 | { 51 | "internalType": "contract ISchemaResolver", 52 | "name": "resolver", 53 | "type": "address" 54 | }, 55 | { 56 | "internalType": "bool", 57 | "name": "revocable", 58 | "type": "bool" 59 | }, 60 | { 61 | "internalType": "string", 62 | "name": "schema", 63 | "type": "string" 64 | } 65 | ], 66 | "internalType": "struct SchemaRecord", 67 | "name": "", 68 | "type": "tuple" 69 | } 70 | ], 71 | "stateMutability": "view", 72 | "type": "function" 73 | }, 74 | { 75 | "inputs": [ 76 | { 77 | "internalType": "string", 78 | "name": "schema", 79 | "type": "string" 80 | }, 81 | { 82 | "internalType": "contract ISchemaResolver", 83 | "name": "resolver", 84 | "type": "address" 85 | }, 86 | { 87 | "internalType": "bool", 88 | "name": "revocable", 89 | "type": "bool" 90 | } 91 | ], 92 | "name": "register", 93 | "outputs": [ 94 | { 95 | "internalType": "bytes32", 96 | "name": "", 97 | "type": "bytes32" 98 | } 99 | ], 100 | "stateMutability": "nonpayable", 101 | "type": "function" 102 | }, 103 | { 104 | "inputs": [], 105 | "name": "version", 106 | "outputs": [ 107 | { 108 | "internalType": "string", 109 | "name": "", 110 | "type": "string" 111 | } 112 | ], 113 | "stateMutability": "view", 114 | "type": "function" 115 | } 116 | ] 117 | } 118 | -------------------------------------------------------------------------------- /deployments/ink/.chainId: -------------------------------------------------------------------------------- 1 | 57073 2 | -------------------------------------------------------------------------------- /deployments/ink/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1682454805, 3 | "000002-eas": 1682454812, 4 | "000003-register-initial-schemas": 1739761699, 5 | "000004-name-initial-schemas": 1739762014, 6 | "000005-eip712-proxy": 1739762227, 7 | "000006-indexer": 1739762232 8 | } -------------------------------------------------------------------------------- /deployments/ink/SchemaRegistry.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "0x4200000000000000000000000000000000000020", 3 | "abi": [ 4 | { 5 | "inputs": [], 6 | "stateMutability": "nonpayable", 7 | "type": "constructor" 8 | }, 9 | { 10 | "inputs": [], 11 | "name": "AlreadyExists", 12 | "type": "error" 13 | }, 14 | { 15 | "anonymous": false, 16 | "inputs": [ 17 | { 18 | "indexed": true, 19 | "internalType": "bytes32", 20 | "name": "uid", 21 | "type": "bytes32" 22 | }, 23 | { 24 | "indexed": false, 25 | "internalType": "address", 26 | "name": "registerer", 27 | "type": "address" 28 | } 29 | ], 30 | "name": "Registered", 31 | "type": "event" 32 | }, 33 | { 34 | "inputs": [ 35 | { 36 | "internalType": "bytes32", 37 | "name": "uid", 38 | "type": "bytes32" 39 | } 40 | ], 41 | "name": "getSchema", 42 | "outputs": [ 43 | { 44 | "components": [ 45 | { 46 | "internalType": "bytes32", 47 | "name": "uid", 48 | "type": "bytes32" 49 | }, 50 | { 51 | "internalType": "contract ISchemaResolver", 52 | "name": "resolver", 53 | "type": "address" 54 | }, 55 | { 56 | "internalType": "bool", 57 | "name": "revocable", 58 | "type": "bool" 59 | }, 60 | { 61 | "internalType": "string", 62 | "name": "schema", 63 | "type": "string" 64 | } 65 | ], 66 | "internalType": "struct SchemaRecord", 67 | "name": "", 68 | "type": "tuple" 69 | } 70 | ], 71 | "stateMutability": "view", 72 | "type": "function" 73 | }, 74 | { 75 | "inputs": [ 76 | { 77 | "internalType": "string", 78 | "name": "schema", 79 | "type": "string" 80 | }, 81 | { 82 | "internalType": "contract ISchemaResolver", 83 | "name": "resolver", 84 | "type": "address" 85 | }, 86 | { 87 | "internalType": "bool", 88 | "name": "revocable", 89 | "type": "bool" 90 | } 91 | ], 92 | "name": "register", 93 | "outputs": [ 94 | { 95 | "internalType": "bytes32", 96 | "name": "", 97 | "type": "bytes32" 98 | } 99 | ], 100 | "stateMutability": "nonpayable", 101 | "type": "function" 102 | }, 103 | { 104 | "inputs": [], 105 | "name": "version", 106 | "outputs": [ 107 | { 108 | "internalType": "string", 109 | "name": "", 110 | "type": "string" 111 | } 112 | ], 113 | "stateMutability": "view", 114 | "type": "function" 115 | } 116 | ] 117 | } 118 | -------------------------------------------------------------------------------- /deployments/linea-goerli/.chainId: -------------------------------------------------------------------------------- 1 | 59140 -------------------------------------------------------------------------------- /deployments/linea-goerli/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1693926089, 3 | "000002-eas": 1693926148, 4 | "000003-register-initial-schemas": 1693927856, 5 | "000004-name-initial-schemas": 1693929568, 6 | "000005-eip712-proxy": 1693929627 7 | } -------------------------------------------------------------------------------- /deployments/linea-goerli/types/contracts/SchemaRegistry.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type { 5 | BaseContract, 6 | BytesLike, 7 | FunctionFragment, 8 | Result, 9 | Interface, 10 | EventFragment, 11 | AddressLike, 12 | ContractRunner, 13 | ContractMethod, 14 | Listener, 15 | } from "ethers"; 16 | import type { 17 | TypedContractEvent, 18 | TypedDeferredTopicFilter, 19 | TypedEventLog, 20 | TypedLogDescription, 21 | TypedListener, 22 | TypedContractMethod, 23 | } from "../common"; 24 | 25 | export type SchemaRecordStruct = { 26 | uid: BytesLike; 27 | resolver: AddressLike; 28 | revocable: boolean; 29 | schema: string; 30 | }; 31 | 32 | export type SchemaRecordStructOutput = [ 33 | uid: string, 34 | resolver: string, 35 | revocable: boolean, 36 | schema: string 37 | ] & { uid: string; resolver: string; revocable: boolean; schema: string }; 38 | 39 | export interface SchemaRegistryInterface extends Interface { 40 | getFunction( 41 | nameOrSignature: "getSchema" | "register" | "version" 42 | ): FunctionFragment; 43 | 44 | getEvent(nameOrSignatureOrTopic: "Registered"): EventFragment; 45 | 46 | encodeFunctionData( 47 | functionFragment: "getSchema", 48 | values: [BytesLike] 49 | ): string; 50 | encodeFunctionData( 51 | functionFragment: "register", 52 | values: [string, AddressLike, boolean] 53 | ): string; 54 | encodeFunctionData(functionFragment: "version", values?: undefined): string; 55 | 56 | decodeFunctionResult(functionFragment: "getSchema", data: BytesLike): Result; 57 | decodeFunctionResult(functionFragment: "register", data: BytesLike): Result; 58 | decodeFunctionResult(functionFragment: "version", data: BytesLike): Result; 59 | } 60 | 61 | export namespace RegisteredEvent { 62 | export type InputTuple = [ 63 | uid: BytesLike, 64 | registerer: AddressLike, 65 | schema: SchemaRecordStruct 66 | ]; 67 | export type OutputTuple = [ 68 | uid: string, 69 | registerer: string, 70 | schema: SchemaRecordStructOutput 71 | ]; 72 | export interface OutputObject { 73 | uid: string; 74 | registerer: string; 75 | schema: SchemaRecordStructOutput; 76 | } 77 | export type Event = TypedContractEvent; 78 | export type Filter = TypedDeferredTopicFilter; 79 | export type Log = TypedEventLog; 80 | export type LogDescription = TypedLogDescription; 81 | } 82 | 83 | export interface SchemaRegistry extends BaseContract { 84 | connect(runner?: ContractRunner | null): SchemaRegistry; 85 | waitForDeployment(): Promise; 86 | 87 | interface: SchemaRegistryInterface; 88 | 89 | queryFilter( 90 | event: TCEvent, 91 | fromBlockOrBlockhash?: string | number | undefined, 92 | toBlock?: string | number | undefined 93 | ): Promise>>; 94 | queryFilter( 95 | filter: TypedDeferredTopicFilter, 96 | fromBlockOrBlockhash?: string | number | undefined, 97 | toBlock?: string | number | undefined 98 | ): Promise>>; 99 | 100 | on( 101 | event: TCEvent, 102 | listener: TypedListener 103 | ): Promise; 104 | on( 105 | filter: TypedDeferredTopicFilter, 106 | listener: TypedListener 107 | ): Promise; 108 | 109 | once( 110 | event: TCEvent, 111 | listener: TypedListener 112 | ): Promise; 113 | once( 114 | filter: TypedDeferredTopicFilter, 115 | listener: TypedListener 116 | ): Promise; 117 | 118 | listeners( 119 | event: TCEvent 120 | ): Promise>>; 121 | listeners(eventName?: string): Promise>; 122 | removeAllListeners( 123 | event?: TCEvent 124 | ): Promise; 125 | 126 | getSchema: TypedContractMethod< 127 | [uid: BytesLike], 128 | [SchemaRecordStructOutput], 129 | "view" 130 | >; 131 | 132 | register: TypedContractMethod< 133 | [schema: string, resolver: AddressLike, revocable: boolean], 134 | [string], 135 | "nonpayable" 136 | >; 137 | 138 | version: TypedContractMethod<[], [string], "view">; 139 | 140 | getFunction( 141 | key: string | FunctionFragment 142 | ): T; 143 | 144 | getFunction( 145 | nameOrSignature: "getSchema" 146 | ): TypedContractMethod<[uid: BytesLike], [SchemaRecordStructOutput], "view">; 147 | getFunction( 148 | nameOrSignature: "register" 149 | ): TypedContractMethod< 150 | [schema: string, resolver: AddressLike, revocable: boolean], 151 | [string], 152 | "nonpayable" 153 | >; 154 | getFunction( 155 | nameOrSignature: "version" 156 | ): TypedContractMethod<[], [string], "view">; 157 | 158 | getEvent( 159 | key: "Registered" 160 | ): TypedContractEvent< 161 | RegisteredEvent.InputTuple, 162 | RegisteredEvent.OutputTuple, 163 | RegisteredEvent.OutputObject 164 | >; 165 | 166 | filters: { 167 | "Registered(bytes32,address,tuple)": TypedContractEvent< 168 | RegisteredEvent.InputTuple, 169 | RegisteredEvent.OutputTuple, 170 | RegisteredEvent.OutputObject 171 | >; 172 | Registered: TypedContractEvent< 173 | RegisteredEvent.InputTuple, 174 | RegisteredEvent.OutputTuple, 175 | RegisteredEvent.OutputObject 176 | >; 177 | }; 178 | } 179 | -------------------------------------------------------------------------------- /deployments/linea/.chainId: -------------------------------------------------------------------------------- 1 | 59144 2 | -------------------------------------------------------------------------------- /deployments/linea/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1694032880, 3 | "000002-eas": 1694032891, 4 | "000003-register-initial-schemas": 1694033445, 5 | "000004-name-initial-schemas": 1694033997, 6 | "000005-eip712-proxy": 1694034008 7 | } -------------------------------------------------------------------------------- /deployments/linea/types/contracts/SchemaRegistry.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type { 5 | BaseContract, 6 | BytesLike, 7 | FunctionFragment, 8 | Result, 9 | Interface, 10 | EventFragment, 11 | AddressLike, 12 | ContractRunner, 13 | ContractMethod, 14 | Listener, 15 | } from "ethers"; 16 | import type { 17 | TypedContractEvent, 18 | TypedDeferredTopicFilter, 19 | TypedEventLog, 20 | TypedLogDescription, 21 | TypedListener, 22 | TypedContractMethod, 23 | } from "../common"; 24 | 25 | export type SchemaRecordStruct = { 26 | uid: BytesLike; 27 | resolver: AddressLike; 28 | revocable: boolean; 29 | schema: string; 30 | }; 31 | 32 | export type SchemaRecordStructOutput = [ 33 | uid: string, 34 | resolver: string, 35 | revocable: boolean, 36 | schema: string 37 | ] & { uid: string; resolver: string; revocable: boolean; schema: string }; 38 | 39 | export interface SchemaRegistryInterface extends Interface { 40 | getFunction( 41 | nameOrSignature: "getSchema" | "register" | "version" 42 | ): FunctionFragment; 43 | 44 | getEvent(nameOrSignatureOrTopic: "Registered"): EventFragment; 45 | 46 | encodeFunctionData( 47 | functionFragment: "getSchema", 48 | values: [BytesLike] 49 | ): string; 50 | encodeFunctionData( 51 | functionFragment: "register", 52 | values: [string, AddressLike, boolean] 53 | ): string; 54 | encodeFunctionData(functionFragment: "version", values?: undefined): string; 55 | 56 | decodeFunctionResult(functionFragment: "getSchema", data: BytesLike): Result; 57 | decodeFunctionResult(functionFragment: "register", data: BytesLike): Result; 58 | decodeFunctionResult(functionFragment: "version", data: BytesLike): Result; 59 | } 60 | 61 | export namespace RegisteredEvent { 62 | export type InputTuple = [ 63 | uid: BytesLike, 64 | registerer: AddressLike, 65 | schema: SchemaRecordStruct 66 | ]; 67 | export type OutputTuple = [ 68 | uid: string, 69 | registerer: string, 70 | schema: SchemaRecordStructOutput 71 | ]; 72 | export interface OutputObject { 73 | uid: string; 74 | registerer: string; 75 | schema: SchemaRecordStructOutput; 76 | } 77 | export type Event = TypedContractEvent; 78 | export type Filter = TypedDeferredTopicFilter; 79 | export type Log = TypedEventLog; 80 | export type LogDescription = TypedLogDescription; 81 | } 82 | 83 | export interface SchemaRegistry extends BaseContract { 84 | connect(runner?: ContractRunner | null): SchemaRegistry; 85 | waitForDeployment(): Promise; 86 | 87 | interface: SchemaRegistryInterface; 88 | 89 | queryFilter( 90 | event: TCEvent, 91 | fromBlockOrBlockhash?: string | number | undefined, 92 | toBlock?: string | number | undefined 93 | ): Promise>>; 94 | queryFilter( 95 | filter: TypedDeferredTopicFilter, 96 | fromBlockOrBlockhash?: string | number | undefined, 97 | toBlock?: string | number | undefined 98 | ): Promise>>; 99 | 100 | on( 101 | event: TCEvent, 102 | listener: TypedListener 103 | ): Promise; 104 | on( 105 | filter: TypedDeferredTopicFilter, 106 | listener: TypedListener 107 | ): Promise; 108 | 109 | once( 110 | event: TCEvent, 111 | listener: TypedListener 112 | ): Promise; 113 | once( 114 | filter: TypedDeferredTopicFilter, 115 | listener: TypedListener 116 | ): Promise; 117 | 118 | listeners( 119 | event: TCEvent 120 | ): Promise>>; 121 | listeners(eventName?: string): Promise>; 122 | removeAllListeners( 123 | event?: TCEvent 124 | ): Promise; 125 | 126 | getSchema: TypedContractMethod< 127 | [uid: BytesLike], 128 | [SchemaRecordStructOutput], 129 | "view" 130 | >; 131 | 132 | register: TypedContractMethod< 133 | [schema: string, resolver: AddressLike, revocable: boolean], 134 | [string], 135 | "nonpayable" 136 | >; 137 | 138 | version: TypedContractMethod<[], [string], "view">; 139 | 140 | getFunction( 141 | key: string | FunctionFragment 142 | ): T; 143 | 144 | getFunction( 145 | nameOrSignature: "getSchema" 146 | ): TypedContractMethod<[uid: BytesLike], [SchemaRecordStructOutput], "view">; 147 | getFunction( 148 | nameOrSignature: "register" 149 | ): TypedContractMethod< 150 | [schema: string, resolver: AddressLike, revocable: boolean], 151 | [string], 152 | "nonpayable" 153 | >; 154 | getFunction( 155 | nameOrSignature: "version" 156 | ): TypedContractMethod<[], [string], "view">; 157 | 158 | getEvent( 159 | key: "Registered" 160 | ): TypedContractEvent< 161 | RegisteredEvent.InputTuple, 162 | RegisteredEvent.OutputTuple, 163 | RegisteredEvent.OutputObject 164 | >; 165 | 166 | filters: { 167 | "Registered(bytes32,address,tuple)": TypedContractEvent< 168 | RegisteredEvent.InputTuple, 169 | RegisteredEvent.OutputTuple, 170 | RegisteredEvent.OutputObject 171 | >; 172 | Registered: TypedContractEvent< 173 | RegisteredEvent.InputTuple, 174 | RegisteredEvent.OutputTuple, 175 | RegisteredEvent.OutputObject 176 | >; 177 | }; 178 | } 179 | -------------------------------------------------------------------------------- /deployments/mainnet/.chainId: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /deployments/mainnet/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1677952935, 3 | "000002-eas": 1677952957, 4 | "000003-register-initial-schemas": 1677953511, 5 | "000004-name-initial-schemas": 1677954017 6 | } -------------------------------------------------------------------------------- /deployments/mainnet/types/contracts/SchemaRegistry.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type { 5 | BaseContract, 6 | BigNumber, 7 | BytesLike, 8 | CallOverrides, 9 | ContractTransaction, 10 | Overrides, 11 | PopulatedTransaction, 12 | Signer, 13 | utils, 14 | } from "ethers"; 15 | import type { 16 | FunctionFragment, 17 | Result, 18 | EventFragment, 19 | } from "@ethersproject/abi"; 20 | import type { Listener, Provider } from "@ethersproject/providers"; 21 | import type { 22 | TypedEventFilter, 23 | TypedEvent, 24 | TypedListener, 25 | OnEvent, 26 | PromiseOrValue, 27 | } from "../common"; 28 | 29 | export type SchemaRecordStruct = { 30 | uid: PromiseOrValue; 31 | resolver: PromiseOrValue; 32 | revocable: PromiseOrValue; 33 | schema: PromiseOrValue; 34 | }; 35 | 36 | export type SchemaRecordStructOutput = [string, string, boolean, string] & { 37 | uid: string; 38 | resolver: string; 39 | revocable: boolean; 40 | schema: string; 41 | }; 42 | 43 | export interface SchemaRegistryInterface extends utils.Interface { 44 | functions: { 45 | "VERSION()": FunctionFragment; 46 | "getSchema(bytes32)": FunctionFragment; 47 | "register(string,address,bool)": FunctionFragment; 48 | }; 49 | 50 | getFunction( 51 | nameOrSignatureOrTopic: "VERSION" | "getSchema" | "register" 52 | ): FunctionFragment; 53 | 54 | encodeFunctionData(functionFragment: "VERSION", values?: undefined): string; 55 | encodeFunctionData( 56 | functionFragment: "getSchema", 57 | values: [PromiseOrValue] 58 | ): string; 59 | encodeFunctionData( 60 | functionFragment: "register", 61 | values: [ 62 | PromiseOrValue, 63 | PromiseOrValue, 64 | PromiseOrValue 65 | ] 66 | ): string; 67 | 68 | decodeFunctionResult(functionFragment: "VERSION", data: BytesLike): Result; 69 | decodeFunctionResult(functionFragment: "getSchema", data: BytesLike): Result; 70 | decodeFunctionResult(functionFragment: "register", data: BytesLike): Result; 71 | 72 | events: { 73 | "Registered(bytes32,address)": EventFragment; 74 | }; 75 | 76 | getEvent(nameOrSignatureOrTopic: "Registered"): EventFragment; 77 | } 78 | 79 | export interface RegisteredEventObject { 80 | uid: string; 81 | registerer: string; 82 | } 83 | export type RegisteredEvent = TypedEvent< 84 | [string, string], 85 | RegisteredEventObject 86 | >; 87 | 88 | export type RegisteredEventFilter = TypedEventFilter; 89 | 90 | export interface SchemaRegistry extends BaseContract { 91 | connect(signerOrProvider: Signer | Provider | string): this; 92 | attach(addressOrName: string): this; 93 | deployed(): Promise; 94 | 95 | interface: SchemaRegistryInterface; 96 | 97 | queryFilter( 98 | event: TypedEventFilter, 99 | fromBlockOrBlockhash?: string | number | undefined, 100 | toBlock?: string | number | undefined 101 | ): Promise>; 102 | 103 | listeners( 104 | eventFilter?: TypedEventFilter 105 | ): Array>; 106 | listeners(eventName?: string): Array; 107 | removeAllListeners( 108 | eventFilter: TypedEventFilter 109 | ): this; 110 | removeAllListeners(eventName?: string): this; 111 | off: OnEvent; 112 | on: OnEvent; 113 | once: OnEvent; 114 | removeListener: OnEvent; 115 | 116 | functions: { 117 | VERSION(overrides?: CallOverrides): Promise<[string]>; 118 | 119 | getSchema( 120 | uid: PromiseOrValue, 121 | overrides?: CallOverrides 122 | ): Promise<[SchemaRecordStructOutput]>; 123 | 124 | register( 125 | schema: PromiseOrValue, 126 | resolver: PromiseOrValue, 127 | revocable: PromiseOrValue, 128 | overrides?: Overrides & { from?: PromiseOrValue } 129 | ): Promise; 130 | }; 131 | 132 | VERSION(overrides?: CallOverrides): Promise; 133 | 134 | getSchema( 135 | uid: PromiseOrValue, 136 | overrides?: CallOverrides 137 | ): Promise; 138 | 139 | register( 140 | schema: PromiseOrValue, 141 | resolver: PromiseOrValue, 142 | revocable: PromiseOrValue, 143 | overrides?: Overrides & { from?: PromiseOrValue } 144 | ): Promise; 145 | 146 | callStatic: { 147 | VERSION(overrides?: CallOverrides): Promise; 148 | 149 | getSchema( 150 | uid: PromiseOrValue, 151 | overrides?: CallOverrides 152 | ): Promise; 153 | 154 | register( 155 | schema: PromiseOrValue, 156 | resolver: PromiseOrValue, 157 | revocable: PromiseOrValue, 158 | overrides?: CallOverrides 159 | ): Promise; 160 | }; 161 | 162 | filters: { 163 | "Registered(bytes32,address)"( 164 | uid?: PromiseOrValue | null, 165 | registerer?: null 166 | ): RegisteredEventFilter; 167 | Registered( 168 | uid?: PromiseOrValue | null, 169 | registerer?: null 170 | ): RegisteredEventFilter; 171 | }; 172 | 173 | estimateGas: { 174 | VERSION(overrides?: CallOverrides): Promise; 175 | 176 | getSchema( 177 | uid: PromiseOrValue, 178 | overrides?: CallOverrides 179 | ): Promise; 180 | 181 | register( 182 | schema: PromiseOrValue, 183 | resolver: PromiseOrValue, 184 | revocable: PromiseOrValue, 185 | overrides?: Overrides & { from?: PromiseOrValue } 186 | ): Promise; 187 | }; 188 | 189 | populateTransaction: { 190 | VERSION(overrides?: CallOverrides): Promise; 191 | 192 | getSchema( 193 | uid: PromiseOrValue, 194 | overrides?: CallOverrides 195 | ): Promise; 196 | 197 | register( 198 | schema: PromiseOrValue, 199 | resolver: PromiseOrValue, 200 | revocable: PromiseOrValue, 201 | overrides?: Overrides & { from?: PromiseOrValue } 202 | ): Promise; 203 | }; 204 | } 205 | -------------------------------------------------------------------------------- /deployments/optimism-goerli/.chainId: -------------------------------------------------------------------------------- 1 | 420 -------------------------------------------------------------------------------- /deployments/optimism-goerli/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1682454805, 3 | "000002-eas": 1682454812, 4 | "000003-register-initial-schemas": 1690031840, 5 | "000004-name-initial-schemas": 1690109514, 6 | "000005-eip712-proxy": 1698798073, 7 | "000006-indexer": 1698797914, 8 | "000100-test-seed": 1690109807 9 | } 10 | -------------------------------------------------------------------------------- /deployments/optimism-goerli/SchemaRegistry.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "0x4200000000000000000000000000000000000020", 3 | "abi": [ 4 | { 5 | "inputs": [], 6 | "stateMutability": "nonpayable", 7 | "type": "constructor" 8 | }, 9 | { 10 | "inputs": [], 11 | "name": "AlreadyExists", 12 | "type": "error" 13 | }, 14 | { 15 | "anonymous": false, 16 | "inputs": [ 17 | { 18 | "indexed": true, 19 | "internalType": "bytes32", 20 | "name": "uid", 21 | "type": "bytes32" 22 | }, 23 | { 24 | "indexed": false, 25 | "internalType": "address", 26 | "name": "registerer", 27 | "type": "address" 28 | } 29 | ], 30 | "name": "Registered", 31 | "type": "event" 32 | }, 33 | { 34 | "inputs": [ 35 | { 36 | "internalType": "bytes32", 37 | "name": "uid", 38 | "type": "bytes32" 39 | } 40 | ], 41 | "name": "getSchema", 42 | "outputs": [ 43 | { 44 | "components": [ 45 | { 46 | "internalType": "bytes32", 47 | "name": "uid", 48 | "type": "bytes32" 49 | }, 50 | { 51 | "internalType": "contract ISchemaResolver", 52 | "name": "resolver", 53 | "type": "address" 54 | }, 55 | { 56 | "internalType": "bool", 57 | "name": "revocable", 58 | "type": "bool" 59 | }, 60 | { 61 | "internalType": "string", 62 | "name": "schema", 63 | "type": "string" 64 | } 65 | ], 66 | "internalType": "struct SchemaRecord", 67 | "name": "", 68 | "type": "tuple" 69 | } 70 | ], 71 | "stateMutability": "view", 72 | "type": "function" 73 | }, 74 | { 75 | "inputs": [ 76 | { 77 | "internalType": "string", 78 | "name": "schema", 79 | "type": "string" 80 | }, 81 | { 82 | "internalType": "contract ISchemaResolver", 83 | "name": "resolver", 84 | "type": "address" 85 | }, 86 | { 87 | "internalType": "bool", 88 | "name": "revocable", 89 | "type": "bool" 90 | } 91 | ], 92 | "name": "register", 93 | "outputs": [ 94 | { 95 | "internalType": "bytes32", 96 | "name": "", 97 | "type": "bytes32" 98 | } 99 | ], 100 | "stateMutability": "nonpayable", 101 | "type": "function" 102 | }, 103 | { 104 | "inputs": [], 105 | "name": "version", 106 | "outputs": [ 107 | { 108 | "internalType": "string", 109 | "name": "", 110 | "type": "string" 111 | } 112 | ], 113 | "stateMutability": "view", 114 | "type": "function" 115 | } 116 | ] 117 | } 118 | -------------------------------------------------------------------------------- /deployments/optimism-sepolia/.chainId: -------------------------------------------------------------------------------- 1 | 11155420 2 | -------------------------------------------------------------------------------- /deployments/optimism-sepolia/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1682454805, 3 | "000002-eas": 1682454812, 4 | "000003-register-initial-schemas": 1701559674, 5 | "000004-name-initial-schemas": 1701559939, 6 | "000005-eip712-proxy": 1701559947, 7 | "000006-indexer": 1701559957, 8 | "000100-test-seed": 1701560054 9 | } -------------------------------------------------------------------------------- /deployments/optimism-sepolia/SchemaRegistry.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "0x4200000000000000000000000000000000000020", 3 | "abi": [ 4 | { 5 | "inputs": [], 6 | "stateMutability": "nonpayable", 7 | "type": "constructor" 8 | }, 9 | { 10 | "inputs": [], 11 | "name": "AlreadyExists", 12 | "type": "error" 13 | }, 14 | { 15 | "anonymous": false, 16 | "inputs": [ 17 | { 18 | "indexed": true, 19 | "internalType": "bytes32", 20 | "name": "uid", 21 | "type": "bytes32" 22 | }, 23 | { 24 | "indexed": false, 25 | "internalType": "address", 26 | "name": "registerer", 27 | "type": "address" 28 | } 29 | ], 30 | "name": "Registered", 31 | "type": "event" 32 | }, 33 | { 34 | "inputs": [ 35 | { 36 | "internalType": "bytes32", 37 | "name": "uid", 38 | "type": "bytes32" 39 | } 40 | ], 41 | "name": "getSchema", 42 | "outputs": [ 43 | { 44 | "components": [ 45 | { 46 | "internalType": "bytes32", 47 | "name": "uid", 48 | "type": "bytes32" 49 | }, 50 | { 51 | "internalType": "contract ISchemaResolver", 52 | "name": "resolver", 53 | "type": "address" 54 | }, 55 | { 56 | "internalType": "bool", 57 | "name": "revocable", 58 | "type": "bool" 59 | }, 60 | { 61 | "internalType": "string", 62 | "name": "schema", 63 | "type": "string" 64 | } 65 | ], 66 | "internalType": "struct SchemaRecord", 67 | "name": "", 68 | "type": "tuple" 69 | } 70 | ], 71 | "stateMutability": "view", 72 | "type": "function" 73 | }, 74 | { 75 | "inputs": [ 76 | { 77 | "internalType": "string", 78 | "name": "schema", 79 | "type": "string" 80 | }, 81 | { 82 | "internalType": "contract ISchemaResolver", 83 | "name": "resolver", 84 | "type": "address" 85 | }, 86 | { 87 | "internalType": "bool", 88 | "name": "revocable", 89 | "type": "bool" 90 | } 91 | ], 92 | "name": "register", 93 | "outputs": [ 94 | { 95 | "internalType": "bytes32", 96 | "name": "", 97 | "type": "bytes32" 98 | } 99 | ], 100 | "stateMutability": "nonpayable", 101 | "type": "function" 102 | }, 103 | { 104 | "inputs": [], 105 | "name": "version", 106 | "outputs": [ 107 | { 108 | "internalType": "string", 109 | "name": "", 110 | "type": "string" 111 | } 112 | ], 113 | "stateMutability": "view", 114 | "type": "function" 115 | } 116 | ] 117 | } 118 | -------------------------------------------------------------------------------- /deployments/optimism/.chainId: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /deployments/optimism/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1682454805, 3 | "000002-eas": 1682454812, 4 | "000003-register-initial-schemas": 1690557621, 5 | "000004-name-initial-schemas": 1690558187, 6 | "000005-eip712-proxy": 1698793560, 7 | "000006-indexer": 1698793569 8 | } -------------------------------------------------------------------------------- /deployments/optimism/SchemaRegistry.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "0x4200000000000000000000000000000000000020", 3 | "abi": [ 4 | { 5 | "inputs": [], 6 | "stateMutability": "nonpayable", 7 | "type": "constructor" 8 | }, 9 | { 10 | "inputs": [], 11 | "name": "AlreadyExists", 12 | "type": "error" 13 | }, 14 | { 15 | "anonymous": false, 16 | "inputs": [ 17 | { 18 | "indexed": true, 19 | "internalType": "bytes32", 20 | "name": "uid", 21 | "type": "bytes32" 22 | }, 23 | { 24 | "indexed": false, 25 | "internalType": "address", 26 | "name": "registerer", 27 | "type": "address" 28 | } 29 | ], 30 | "name": "Registered", 31 | "type": "event" 32 | }, 33 | { 34 | "inputs": [ 35 | { 36 | "internalType": "bytes32", 37 | "name": "uid", 38 | "type": "bytes32" 39 | } 40 | ], 41 | "name": "getSchema", 42 | "outputs": [ 43 | { 44 | "components": [ 45 | { 46 | "internalType": "bytes32", 47 | "name": "uid", 48 | "type": "bytes32" 49 | }, 50 | { 51 | "internalType": "contract ISchemaResolver", 52 | "name": "resolver", 53 | "type": "address" 54 | }, 55 | { 56 | "internalType": "bool", 57 | "name": "revocable", 58 | "type": "bool" 59 | }, 60 | { 61 | "internalType": "string", 62 | "name": "schema", 63 | "type": "string" 64 | } 65 | ], 66 | "internalType": "struct SchemaRecord", 67 | "name": "", 68 | "type": "tuple" 69 | } 70 | ], 71 | "stateMutability": "view", 72 | "type": "function" 73 | }, 74 | { 75 | "inputs": [ 76 | { 77 | "internalType": "string", 78 | "name": "schema", 79 | "type": "string" 80 | }, 81 | { 82 | "internalType": "contract ISchemaResolver", 83 | "name": "resolver", 84 | "type": "address" 85 | }, 86 | { 87 | "internalType": "bool", 88 | "name": "revocable", 89 | "type": "bool" 90 | } 91 | ], 92 | "name": "register", 93 | "outputs": [ 94 | { 95 | "internalType": "bytes32", 96 | "name": "", 97 | "type": "bytes32" 98 | } 99 | ], 100 | "stateMutability": "nonpayable", 101 | "type": "function" 102 | }, 103 | { 104 | "inputs": [], 105 | "name": "version", 106 | "outputs": [ 107 | { 108 | "internalType": "string", 109 | "name": "", 110 | "type": "string" 111 | } 112 | ], 113 | "stateMutability": "view", 114 | "type": "function" 115 | } 116 | ] 117 | } 118 | -------------------------------------------------------------------------------- /deployments/polygon-amoy/.chainId: -------------------------------------------------------------------------------- 1 | 80002 2 | -------------------------------------------------------------------------------- /deployments/polygon-amoy/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1716415922, 3 | "000002-eas": 1716415937, 4 | "000003-register-initial-schemas": 1716416376, 5 | "000004-name-initial-schemas": 1716416816, 6 | "000005-eip712-proxy": 1716416827, 7 | "000006-indexer": 1716416838, 8 | "000100-test-seed": 1716416977 9 | } -------------------------------------------------------------------------------- /deployments/polygon-amoy/types/contracts/SchemaRegistry.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type { 5 | BaseContract, 6 | BytesLike, 7 | FunctionFragment, 8 | Result, 9 | Interface, 10 | EventFragment, 11 | AddressLike, 12 | ContractRunner, 13 | ContractMethod, 14 | Listener, 15 | } from "ethers"; 16 | import type { 17 | TypedContractEvent, 18 | TypedDeferredTopicFilter, 19 | TypedEventLog, 20 | TypedLogDescription, 21 | TypedListener, 22 | TypedContractMethod, 23 | } from "../common"; 24 | 25 | export type SchemaRecordStruct = { 26 | uid: BytesLike; 27 | resolver: AddressLike; 28 | revocable: boolean; 29 | schema: string; 30 | }; 31 | 32 | export type SchemaRecordStructOutput = [ 33 | uid: string, 34 | resolver: string, 35 | revocable: boolean, 36 | schema: string 37 | ] & { uid: string; resolver: string; revocable: boolean; schema: string }; 38 | 39 | export interface SchemaRegistryInterface extends Interface { 40 | getFunction( 41 | nameOrSignature: "getSchema" | "register" | "version" 42 | ): FunctionFragment; 43 | 44 | getEvent(nameOrSignatureOrTopic: "Registered"): EventFragment; 45 | 46 | encodeFunctionData( 47 | functionFragment: "getSchema", 48 | values: [BytesLike] 49 | ): string; 50 | encodeFunctionData( 51 | functionFragment: "register", 52 | values: [string, AddressLike, boolean] 53 | ): string; 54 | encodeFunctionData(functionFragment: "version", values?: undefined): string; 55 | 56 | decodeFunctionResult(functionFragment: "getSchema", data: BytesLike): Result; 57 | decodeFunctionResult(functionFragment: "register", data: BytesLike): Result; 58 | decodeFunctionResult(functionFragment: "version", data: BytesLike): Result; 59 | } 60 | 61 | export namespace RegisteredEvent { 62 | export type InputTuple = [ 63 | uid: BytesLike, 64 | registerer: AddressLike, 65 | schema: SchemaRecordStruct 66 | ]; 67 | export type OutputTuple = [ 68 | uid: string, 69 | registerer: string, 70 | schema: SchemaRecordStructOutput 71 | ]; 72 | export interface OutputObject { 73 | uid: string; 74 | registerer: string; 75 | schema: SchemaRecordStructOutput; 76 | } 77 | export type Event = TypedContractEvent; 78 | export type Filter = TypedDeferredTopicFilter; 79 | export type Log = TypedEventLog; 80 | export type LogDescription = TypedLogDescription; 81 | } 82 | 83 | export interface SchemaRegistry extends BaseContract { 84 | connect(runner?: ContractRunner | null): SchemaRegistry; 85 | waitForDeployment(): Promise; 86 | 87 | interface: SchemaRegistryInterface; 88 | 89 | queryFilter( 90 | event: TCEvent, 91 | fromBlockOrBlockhash?: string | number | undefined, 92 | toBlock?: string | number | undefined 93 | ): Promise>>; 94 | queryFilter( 95 | filter: TypedDeferredTopicFilter, 96 | fromBlockOrBlockhash?: string | number | undefined, 97 | toBlock?: string | number | undefined 98 | ): Promise>>; 99 | 100 | on( 101 | event: TCEvent, 102 | listener: TypedListener 103 | ): Promise; 104 | on( 105 | filter: TypedDeferredTopicFilter, 106 | listener: TypedListener 107 | ): Promise; 108 | 109 | once( 110 | event: TCEvent, 111 | listener: TypedListener 112 | ): Promise; 113 | once( 114 | filter: TypedDeferredTopicFilter, 115 | listener: TypedListener 116 | ): Promise; 117 | 118 | listeners( 119 | event: TCEvent 120 | ): Promise>>; 121 | listeners(eventName?: string): Promise>; 122 | removeAllListeners( 123 | event?: TCEvent 124 | ): Promise; 125 | 126 | getSchema: TypedContractMethod< 127 | [uid: BytesLike], 128 | [SchemaRecordStructOutput], 129 | "view" 130 | >; 131 | 132 | register: TypedContractMethod< 133 | [schema: string, resolver: AddressLike, revocable: boolean], 134 | [string], 135 | "nonpayable" 136 | >; 137 | 138 | version: TypedContractMethod<[], [string], "view">; 139 | 140 | getFunction( 141 | key: string | FunctionFragment 142 | ): T; 143 | 144 | getFunction( 145 | nameOrSignature: "getSchema" 146 | ): TypedContractMethod<[uid: BytesLike], [SchemaRecordStructOutput], "view">; 147 | getFunction( 148 | nameOrSignature: "register" 149 | ): TypedContractMethod< 150 | [schema: string, resolver: AddressLike, revocable: boolean], 151 | [string], 152 | "nonpayable" 153 | >; 154 | getFunction( 155 | nameOrSignature: "version" 156 | ): TypedContractMethod<[], [string], "view">; 157 | 158 | getEvent( 159 | key: "Registered" 160 | ): TypedContractEvent< 161 | RegisteredEvent.InputTuple, 162 | RegisteredEvent.OutputTuple, 163 | RegisteredEvent.OutputObject 164 | >; 165 | 166 | filters: { 167 | "Registered(bytes32,address,tuple)": TypedContractEvent< 168 | RegisteredEvent.InputTuple, 169 | RegisteredEvent.OutputTuple, 170 | RegisteredEvent.OutputObject 171 | >; 172 | Registered: TypedContractEvent< 173 | RegisteredEvent.InputTuple, 174 | RegisteredEvent.OutputTuple, 175 | RegisteredEvent.OutputObject 176 | >; 177 | }; 178 | } 179 | -------------------------------------------------------------------------------- /deployments/polygon/.chainId: -------------------------------------------------------------------------------- 1 | 137 2 | -------------------------------------------------------------------------------- /deployments/polygon/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1702921022, 3 | "000002-eas": 1702921037, 4 | "000003-register-initial-schemas": 1702964641, 5 | "000004-name-initial-schemas": 1703017795, 6 | "000005-eip712-proxy": 1703018283, 7 | "000006-indexer": 1703018290 8 | } -------------------------------------------------------------------------------- /deployments/polygon/types/contracts/SchemaRegistry.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type { 5 | BaseContract, 6 | BytesLike, 7 | FunctionFragment, 8 | Result, 9 | Interface, 10 | EventFragment, 11 | AddressLike, 12 | ContractRunner, 13 | ContractMethod, 14 | Listener, 15 | } from "ethers"; 16 | import type { 17 | TypedContractEvent, 18 | TypedDeferredTopicFilter, 19 | TypedEventLog, 20 | TypedLogDescription, 21 | TypedListener, 22 | TypedContractMethod, 23 | } from "../common"; 24 | 25 | export type SchemaRecordStruct = { 26 | uid: BytesLike; 27 | resolver: AddressLike; 28 | revocable: boolean; 29 | schema: string; 30 | }; 31 | 32 | export type SchemaRecordStructOutput = [ 33 | uid: string, 34 | resolver: string, 35 | revocable: boolean, 36 | schema: string 37 | ] & { uid: string; resolver: string; revocable: boolean; schema: string }; 38 | 39 | export interface SchemaRegistryInterface extends Interface { 40 | getFunction( 41 | nameOrSignature: "getSchema" | "register" | "version" 42 | ): FunctionFragment; 43 | 44 | getEvent(nameOrSignatureOrTopic: "Registered"): EventFragment; 45 | 46 | encodeFunctionData( 47 | functionFragment: "getSchema", 48 | values: [BytesLike] 49 | ): string; 50 | encodeFunctionData( 51 | functionFragment: "register", 52 | values: [string, AddressLike, boolean] 53 | ): string; 54 | encodeFunctionData(functionFragment: "version", values?: undefined): string; 55 | 56 | decodeFunctionResult(functionFragment: "getSchema", data: BytesLike): Result; 57 | decodeFunctionResult(functionFragment: "register", data: BytesLike): Result; 58 | decodeFunctionResult(functionFragment: "version", data: BytesLike): Result; 59 | } 60 | 61 | export namespace RegisteredEvent { 62 | export type InputTuple = [ 63 | uid: BytesLike, 64 | registerer: AddressLike, 65 | schema: SchemaRecordStruct 66 | ]; 67 | export type OutputTuple = [ 68 | uid: string, 69 | registerer: string, 70 | schema: SchemaRecordStructOutput 71 | ]; 72 | export interface OutputObject { 73 | uid: string; 74 | registerer: string; 75 | schema: SchemaRecordStructOutput; 76 | } 77 | export type Event = TypedContractEvent; 78 | export type Filter = TypedDeferredTopicFilter; 79 | export type Log = TypedEventLog; 80 | export type LogDescription = TypedLogDescription; 81 | } 82 | 83 | export interface SchemaRegistry extends BaseContract { 84 | connect(runner?: ContractRunner | null): SchemaRegistry; 85 | waitForDeployment(): Promise; 86 | 87 | interface: SchemaRegistryInterface; 88 | 89 | queryFilter( 90 | event: TCEvent, 91 | fromBlockOrBlockhash?: string | number | undefined, 92 | toBlock?: string | number | undefined 93 | ): Promise>>; 94 | queryFilter( 95 | filter: TypedDeferredTopicFilter, 96 | fromBlockOrBlockhash?: string | number | undefined, 97 | toBlock?: string | number | undefined 98 | ): Promise>>; 99 | 100 | on( 101 | event: TCEvent, 102 | listener: TypedListener 103 | ): Promise; 104 | on( 105 | filter: TypedDeferredTopicFilter, 106 | listener: TypedListener 107 | ): Promise; 108 | 109 | once( 110 | event: TCEvent, 111 | listener: TypedListener 112 | ): Promise; 113 | once( 114 | filter: TypedDeferredTopicFilter, 115 | listener: TypedListener 116 | ): Promise; 117 | 118 | listeners( 119 | event: TCEvent 120 | ): Promise>>; 121 | listeners(eventName?: string): Promise>; 122 | removeAllListeners( 123 | event?: TCEvent 124 | ): Promise; 125 | 126 | getSchema: TypedContractMethod< 127 | [uid: BytesLike], 128 | [SchemaRecordStructOutput], 129 | "view" 130 | >; 131 | 132 | register: TypedContractMethod< 133 | [schema: string, resolver: AddressLike, revocable: boolean], 134 | [string], 135 | "nonpayable" 136 | >; 137 | 138 | version: TypedContractMethod<[], [string], "view">; 139 | 140 | getFunction( 141 | key: string | FunctionFragment 142 | ): T; 143 | 144 | getFunction( 145 | nameOrSignature: "getSchema" 146 | ): TypedContractMethod<[uid: BytesLike], [SchemaRecordStructOutput], "view">; 147 | getFunction( 148 | nameOrSignature: "register" 149 | ): TypedContractMethod< 150 | [schema: string, resolver: AddressLike, revocable: boolean], 151 | [string], 152 | "nonpayable" 153 | >; 154 | getFunction( 155 | nameOrSignature: "version" 156 | ): TypedContractMethod<[], [string], "view">; 157 | 158 | getEvent( 159 | key: "Registered" 160 | ): TypedContractEvent< 161 | RegisteredEvent.InputTuple, 162 | RegisteredEvent.OutputTuple, 163 | RegisteredEvent.OutputObject 164 | >; 165 | 166 | filters: { 167 | "Registered(bytes32,address,tuple)": TypedContractEvent< 168 | RegisteredEvent.InputTuple, 169 | RegisteredEvent.OutputTuple, 170 | RegisteredEvent.OutputObject 171 | >; 172 | Registered: TypedContractEvent< 173 | RegisteredEvent.InputTuple, 174 | RegisteredEvent.OutputTuple, 175 | RegisteredEvent.OutputObject 176 | >; 177 | }; 178 | } 179 | -------------------------------------------------------------------------------- /deployments/scroll-sepolia/.chainId: -------------------------------------------------------------------------------- 1 | 534351 2 | -------------------------------------------------------------------------------- /deployments/scroll-sepolia/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1701365148, 3 | "000002-eas": 1701365159, 4 | "000003-register-initial-schemas": 1701365446, 5 | "000004-name-initial-schemas": 1701365734, 6 | "000005-eip712-proxy": 1701365744, 7 | "000006-indexer": 1701365771, 8 | "000100-test-seed": 1701365890 9 | } -------------------------------------------------------------------------------- /deployments/scroll-sepolia/types/contracts/SchemaRegistry.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type { 5 | BaseContract, 6 | BytesLike, 7 | FunctionFragment, 8 | Result, 9 | Interface, 10 | EventFragment, 11 | AddressLike, 12 | ContractRunner, 13 | ContractMethod, 14 | Listener, 15 | } from "ethers"; 16 | import type { 17 | TypedContractEvent, 18 | TypedDeferredTopicFilter, 19 | TypedEventLog, 20 | TypedLogDescription, 21 | TypedListener, 22 | TypedContractMethod, 23 | } from "../common"; 24 | 25 | export type SchemaRecordStruct = { 26 | uid: BytesLike; 27 | resolver: AddressLike; 28 | revocable: boolean; 29 | schema: string; 30 | }; 31 | 32 | export type SchemaRecordStructOutput = [ 33 | uid: string, 34 | resolver: string, 35 | revocable: boolean, 36 | schema: string 37 | ] & { uid: string; resolver: string; revocable: boolean; schema: string }; 38 | 39 | export interface SchemaRegistryInterface extends Interface { 40 | getFunction( 41 | nameOrSignature: "getSchema" | "register" | "version" 42 | ): FunctionFragment; 43 | 44 | getEvent(nameOrSignatureOrTopic: "Registered"): EventFragment; 45 | 46 | encodeFunctionData( 47 | functionFragment: "getSchema", 48 | values: [BytesLike] 49 | ): string; 50 | encodeFunctionData( 51 | functionFragment: "register", 52 | values: [string, AddressLike, boolean] 53 | ): string; 54 | encodeFunctionData(functionFragment: "version", values?: undefined): string; 55 | 56 | decodeFunctionResult(functionFragment: "getSchema", data: BytesLike): Result; 57 | decodeFunctionResult(functionFragment: "register", data: BytesLike): Result; 58 | decodeFunctionResult(functionFragment: "version", data: BytesLike): Result; 59 | } 60 | 61 | export namespace RegisteredEvent { 62 | export type InputTuple = [ 63 | uid: BytesLike, 64 | registerer: AddressLike, 65 | schema: SchemaRecordStruct 66 | ]; 67 | export type OutputTuple = [ 68 | uid: string, 69 | registerer: string, 70 | schema: SchemaRecordStructOutput 71 | ]; 72 | export interface OutputObject { 73 | uid: string; 74 | registerer: string; 75 | schema: SchemaRecordStructOutput; 76 | } 77 | export type Event = TypedContractEvent; 78 | export type Filter = TypedDeferredTopicFilter; 79 | export type Log = TypedEventLog; 80 | export type LogDescription = TypedLogDescription; 81 | } 82 | 83 | export interface SchemaRegistry extends BaseContract { 84 | connect(runner?: ContractRunner | null): SchemaRegistry; 85 | waitForDeployment(): Promise; 86 | 87 | interface: SchemaRegistryInterface; 88 | 89 | queryFilter( 90 | event: TCEvent, 91 | fromBlockOrBlockhash?: string | number | undefined, 92 | toBlock?: string | number | undefined 93 | ): Promise>>; 94 | queryFilter( 95 | filter: TypedDeferredTopicFilter, 96 | fromBlockOrBlockhash?: string | number | undefined, 97 | toBlock?: string | number | undefined 98 | ): Promise>>; 99 | 100 | on( 101 | event: TCEvent, 102 | listener: TypedListener 103 | ): Promise; 104 | on( 105 | filter: TypedDeferredTopicFilter, 106 | listener: TypedListener 107 | ): Promise; 108 | 109 | once( 110 | event: TCEvent, 111 | listener: TypedListener 112 | ): Promise; 113 | once( 114 | filter: TypedDeferredTopicFilter, 115 | listener: TypedListener 116 | ): Promise; 117 | 118 | listeners( 119 | event: TCEvent 120 | ): Promise>>; 121 | listeners(eventName?: string): Promise>; 122 | removeAllListeners( 123 | event?: TCEvent 124 | ): Promise; 125 | 126 | getSchema: TypedContractMethod< 127 | [uid: BytesLike], 128 | [SchemaRecordStructOutput], 129 | "view" 130 | >; 131 | 132 | register: TypedContractMethod< 133 | [schema: string, resolver: AddressLike, revocable: boolean], 134 | [string], 135 | "nonpayable" 136 | >; 137 | 138 | version: TypedContractMethod<[], [string], "view">; 139 | 140 | getFunction( 141 | key: string | FunctionFragment 142 | ): T; 143 | 144 | getFunction( 145 | nameOrSignature: "getSchema" 146 | ): TypedContractMethod<[uid: BytesLike], [SchemaRecordStructOutput], "view">; 147 | getFunction( 148 | nameOrSignature: "register" 149 | ): TypedContractMethod< 150 | [schema: string, resolver: AddressLike, revocable: boolean], 151 | [string], 152 | "nonpayable" 153 | >; 154 | getFunction( 155 | nameOrSignature: "version" 156 | ): TypedContractMethod<[], [string], "view">; 157 | 158 | getEvent( 159 | key: "Registered" 160 | ): TypedContractEvent< 161 | RegisteredEvent.InputTuple, 162 | RegisteredEvent.OutputTuple, 163 | RegisteredEvent.OutputObject 164 | >; 165 | 166 | filters: { 167 | "Registered(bytes32,address,tuple)": TypedContractEvent< 168 | RegisteredEvent.InputTuple, 169 | RegisteredEvent.OutputTuple, 170 | RegisteredEvent.OutputObject 171 | >; 172 | Registered: TypedContractEvent< 173 | RegisteredEvent.InputTuple, 174 | RegisteredEvent.OutputTuple, 175 | RegisteredEvent.OutputObject 176 | >; 177 | }; 178 | } 179 | -------------------------------------------------------------------------------- /deployments/scroll/.chainId: -------------------------------------------------------------------------------- 1 | 534352 2 | -------------------------------------------------------------------------------- /deployments/scroll/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1701717190, 3 | "000002-eas": 1701717198, 4 | "000003-register-initial-schemas": 1701717560, 5 | "000004-name-initial-schemas": 1701717948, 6 | "000005-eip712-proxy": 1701717959, 7 | "000006-indexer": 1701717967 8 | } -------------------------------------------------------------------------------- /deployments/scroll/types/contracts/SchemaRegistry.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type { 5 | BaseContract, 6 | BytesLike, 7 | FunctionFragment, 8 | Result, 9 | Interface, 10 | EventFragment, 11 | AddressLike, 12 | ContractRunner, 13 | ContractMethod, 14 | Listener, 15 | } from "ethers"; 16 | import type { 17 | TypedContractEvent, 18 | TypedDeferredTopicFilter, 19 | TypedEventLog, 20 | TypedLogDescription, 21 | TypedListener, 22 | TypedContractMethod, 23 | } from "../common"; 24 | 25 | export type SchemaRecordStruct = { 26 | uid: BytesLike; 27 | resolver: AddressLike; 28 | revocable: boolean; 29 | schema: string; 30 | }; 31 | 32 | export type SchemaRecordStructOutput = [ 33 | uid: string, 34 | resolver: string, 35 | revocable: boolean, 36 | schema: string 37 | ] & { uid: string; resolver: string; revocable: boolean; schema: string }; 38 | 39 | export interface SchemaRegistryInterface extends Interface { 40 | getFunction( 41 | nameOrSignature: "getSchema" | "register" | "version" 42 | ): FunctionFragment; 43 | 44 | getEvent(nameOrSignatureOrTopic: "Registered"): EventFragment; 45 | 46 | encodeFunctionData( 47 | functionFragment: "getSchema", 48 | values: [BytesLike] 49 | ): string; 50 | encodeFunctionData( 51 | functionFragment: "register", 52 | values: [string, AddressLike, boolean] 53 | ): string; 54 | encodeFunctionData(functionFragment: "version", values?: undefined): string; 55 | 56 | decodeFunctionResult(functionFragment: "getSchema", data: BytesLike): Result; 57 | decodeFunctionResult(functionFragment: "register", data: BytesLike): Result; 58 | decodeFunctionResult(functionFragment: "version", data: BytesLike): Result; 59 | } 60 | 61 | export namespace RegisteredEvent { 62 | export type InputTuple = [ 63 | uid: BytesLike, 64 | registerer: AddressLike, 65 | schema: SchemaRecordStruct 66 | ]; 67 | export type OutputTuple = [ 68 | uid: string, 69 | registerer: string, 70 | schema: SchemaRecordStructOutput 71 | ]; 72 | export interface OutputObject { 73 | uid: string; 74 | registerer: string; 75 | schema: SchemaRecordStructOutput; 76 | } 77 | export type Event = TypedContractEvent; 78 | export type Filter = TypedDeferredTopicFilter; 79 | export type Log = TypedEventLog; 80 | export type LogDescription = TypedLogDescription; 81 | } 82 | 83 | export interface SchemaRegistry extends BaseContract { 84 | connect(runner?: ContractRunner | null): SchemaRegistry; 85 | waitForDeployment(): Promise; 86 | 87 | interface: SchemaRegistryInterface; 88 | 89 | queryFilter( 90 | event: TCEvent, 91 | fromBlockOrBlockhash?: string | number | undefined, 92 | toBlock?: string | number | undefined 93 | ): Promise>>; 94 | queryFilter( 95 | filter: TypedDeferredTopicFilter, 96 | fromBlockOrBlockhash?: string | number | undefined, 97 | toBlock?: string | number | undefined 98 | ): Promise>>; 99 | 100 | on( 101 | event: TCEvent, 102 | listener: TypedListener 103 | ): Promise; 104 | on( 105 | filter: TypedDeferredTopicFilter, 106 | listener: TypedListener 107 | ): Promise; 108 | 109 | once( 110 | event: TCEvent, 111 | listener: TypedListener 112 | ): Promise; 113 | once( 114 | filter: TypedDeferredTopicFilter, 115 | listener: TypedListener 116 | ): Promise; 117 | 118 | listeners( 119 | event: TCEvent 120 | ): Promise>>; 121 | listeners(eventName?: string): Promise>; 122 | removeAllListeners( 123 | event?: TCEvent 124 | ): Promise; 125 | 126 | getSchema: TypedContractMethod< 127 | [uid: BytesLike], 128 | [SchemaRecordStructOutput], 129 | "view" 130 | >; 131 | 132 | register: TypedContractMethod< 133 | [schema: string, resolver: AddressLike, revocable: boolean], 134 | [string], 135 | "nonpayable" 136 | >; 137 | 138 | version: TypedContractMethod<[], [string], "view">; 139 | 140 | getFunction( 141 | key: string | FunctionFragment 142 | ): T; 143 | 144 | getFunction( 145 | nameOrSignature: "getSchema" 146 | ): TypedContractMethod<[uid: BytesLike], [SchemaRecordStructOutput], "view">; 147 | getFunction( 148 | nameOrSignature: "register" 149 | ): TypedContractMethod< 150 | [schema: string, resolver: AddressLike, revocable: boolean], 151 | [string], 152 | "nonpayable" 153 | >; 154 | getFunction( 155 | nameOrSignature: "version" 156 | ): TypedContractMethod<[], [string], "view">; 157 | 158 | getEvent( 159 | key: "Registered" 160 | ): TypedContractEvent< 161 | RegisteredEvent.InputTuple, 162 | RegisteredEvent.OutputTuple, 163 | RegisteredEvent.OutputObject 164 | >; 165 | 166 | filters: { 167 | "Registered(bytes32,address,tuple)": TypedContractEvent< 168 | RegisteredEvent.InputTuple, 169 | RegisteredEvent.OutputTuple, 170 | RegisteredEvent.OutputObject 171 | >; 172 | Registered: TypedContractEvent< 173 | RegisteredEvent.InputTuple, 174 | RegisteredEvent.OutputTuple, 175 | RegisteredEvent.OutputObject 176 | >; 177 | }; 178 | } 179 | -------------------------------------------------------------------------------- /deployments/sepolia/.chainId: -------------------------------------------------------------------------------- 1 | 11155111 2 | -------------------------------------------------------------------------------- /deployments/sepolia/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1677138964, 3 | "000002-eas": 1677138984, 4 | "000003-register-initial-schemas": 1677139251, 5 | "000004-name-initial-schemas": 1677139550, 6 | "000005-eip712-proxy": 1698797280, 7 | "000006-indexer": 1698792410, 8 | "000100-test-seed": 1677139824 9 | } 10 | -------------------------------------------------------------------------------- /deployments/sepolia/types/contracts/SchemaRegistry.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type { 5 | BaseContract, 6 | BigNumber, 7 | BytesLike, 8 | CallOverrides, 9 | ContractTransaction, 10 | Overrides, 11 | PopulatedTransaction, 12 | Signer, 13 | utils, 14 | } from "ethers"; 15 | import type { 16 | FunctionFragment, 17 | Result, 18 | EventFragment, 19 | } from "@ethersproject/abi"; 20 | import type { Listener, Provider } from "@ethersproject/providers"; 21 | import type { 22 | TypedEventFilter, 23 | TypedEvent, 24 | TypedListener, 25 | OnEvent, 26 | PromiseOrValue, 27 | } from "../common"; 28 | 29 | export type SchemaRecordStruct = { 30 | uid: PromiseOrValue; 31 | resolver: PromiseOrValue; 32 | revocable: PromiseOrValue; 33 | schema: PromiseOrValue; 34 | }; 35 | 36 | export type SchemaRecordStructOutput = [string, string, boolean, string] & { 37 | uid: string; 38 | resolver: string; 39 | revocable: boolean; 40 | schema: string; 41 | }; 42 | 43 | export interface SchemaRegistryInterface extends utils.Interface { 44 | functions: { 45 | "VERSION()": FunctionFragment; 46 | "getSchema(bytes32)": FunctionFragment; 47 | "register(string,address,bool)": FunctionFragment; 48 | }; 49 | 50 | getFunction( 51 | nameOrSignatureOrTopic: "VERSION" | "getSchema" | "register" 52 | ): FunctionFragment; 53 | 54 | encodeFunctionData(functionFragment: "VERSION", values?: undefined): string; 55 | encodeFunctionData( 56 | functionFragment: "getSchema", 57 | values: [PromiseOrValue] 58 | ): string; 59 | encodeFunctionData( 60 | functionFragment: "register", 61 | values: [ 62 | PromiseOrValue, 63 | PromiseOrValue, 64 | PromiseOrValue 65 | ] 66 | ): string; 67 | 68 | decodeFunctionResult(functionFragment: "VERSION", data: BytesLike): Result; 69 | decodeFunctionResult(functionFragment: "getSchema", data: BytesLike): Result; 70 | decodeFunctionResult(functionFragment: "register", data: BytesLike): Result; 71 | 72 | events: { 73 | "Registered(bytes32,address)": EventFragment; 74 | }; 75 | 76 | getEvent(nameOrSignatureOrTopic: "Registered"): EventFragment; 77 | } 78 | 79 | export interface RegisteredEventObject { 80 | uid: string; 81 | registerer: string; 82 | } 83 | export type RegisteredEvent = TypedEvent< 84 | [string, string], 85 | RegisteredEventObject 86 | >; 87 | 88 | export type RegisteredEventFilter = TypedEventFilter; 89 | 90 | export interface SchemaRegistry extends BaseContract { 91 | connect(signerOrProvider: Signer | Provider | string): this; 92 | attach(addressOrName: string): this; 93 | deployed(): Promise; 94 | 95 | interface: SchemaRegistryInterface; 96 | 97 | queryFilter( 98 | event: TypedEventFilter, 99 | fromBlockOrBlockhash?: string | number | undefined, 100 | toBlock?: string | number | undefined 101 | ): Promise>; 102 | 103 | listeners( 104 | eventFilter?: TypedEventFilter 105 | ): Array>; 106 | listeners(eventName?: string): Array; 107 | removeAllListeners( 108 | eventFilter: TypedEventFilter 109 | ): this; 110 | removeAllListeners(eventName?: string): this; 111 | off: OnEvent; 112 | on: OnEvent; 113 | once: OnEvent; 114 | removeListener: OnEvent; 115 | 116 | functions: { 117 | VERSION(overrides?: CallOverrides): Promise<[string]>; 118 | 119 | getSchema( 120 | uid: PromiseOrValue, 121 | overrides?: CallOverrides 122 | ): Promise<[SchemaRecordStructOutput]>; 123 | 124 | register( 125 | schema: PromiseOrValue, 126 | resolver: PromiseOrValue, 127 | revocable: PromiseOrValue, 128 | overrides?: Overrides & { from?: PromiseOrValue } 129 | ): Promise; 130 | }; 131 | 132 | VERSION(overrides?: CallOverrides): Promise; 133 | 134 | getSchema( 135 | uid: PromiseOrValue, 136 | overrides?: CallOverrides 137 | ): Promise; 138 | 139 | register( 140 | schema: PromiseOrValue, 141 | resolver: PromiseOrValue, 142 | revocable: PromiseOrValue, 143 | overrides?: Overrides & { from?: PromiseOrValue } 144 | ): Promise; 145 | 146 | callStatic: { 147 | VERSION(overrides?: CallOverrides): Promise; 148 | 149 | getSchema( 150 | uid: PromiseOrValue, 151 | overrides?: CallOverrides 152 | ): Promise; 153 | 154 | register( 155 | schema: PromiseOrValue, 156 | resolver: PromiseOrValue, 157 | revocable: PromiseOrValue, 158 | overrides?: CallOverrides 159 | ): Promise; 160 | }; 161 | 162 | filters: { 163 | "Registered(bytes32,address)"( 164 | uid?: PromiseOrValue | null, 165 | registerer?: null 166 | ): RegisteredEventFilter; 167 | Registered( 168 | uid?: PromiseOrValue | null, 169 | registerer?: null 170 | ): RegisteredEventFilter; 171 | }; 172 | 173 | estimateGas: { 174 | VERSION(overrides?: CallOverrides): Promise; 175 | 176 | getSchema( 177 | uid: PromiseOrValue, 178 | overrides?: CallOverrides 179 | ): Promise; 180 | 181 | register( 182 | schema: PromiseOrValue, 183 | resolver: PromiseOrValue, 184 | revocable: PromiseOrValue, 185 | overrides?: Overrides & { from?: PromiseOrValue } 186 | ): Promise; 187 | }; 188 | 189 | populateTransaction: { 190 | VERSION(overrides?: CallOverrides): Promise; 191 | 192 | getSchema( 193 | uid: PromiseOrValue, 194 | overrides?: CallOverrides 195 | ): Promise; 196 | 197 | register( 198 | schema: PromiseOrValue, 199 | resolver: PromiseOrValue, 200 | revocable: PromiseOrValue, 201 | overrides?: Overrides & { from?: PromiseOrValue } 202 | ): Promise; 203 | }; 204 | } 205 | -------------------------------------------------------------------------------- /deployments/soneium/.chainId: -------------------------------------------------------------------------------- 1 | 1868 2 | -------------------------------------------------------------------------------- /deployments/soneium/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1682454805, 3 | "000002-eas": 1682454812, 4 | "000003-register-initial-schemas": 1736905397, 5 | "000004-name-initial-schemas": 1736905858, 6 | "000005-eip712-proxy": 1736905868, 7 | "000006-indexer": 1736905878 8 | } -------------------------------------------------------------------------------- /deployments/soneium/SchemaRegistry.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "0x4200000000000000000000000000000000000020", 3 | "abi": [ 4 | { 5 | "inputs": [], 6 | "stateMutability": "nonpayable", 7 | "type": "constructor" 8 | }, 9 | { 10 | "inputs": [], 11 | "name": "AlreadyExists", 12 | "type": "error" 13 | }, 14 | { 15 | "anonymous": false, 16 | "inputs": [ 17 | { 18 | "indexed": true, 19 | "internalType": "bytes32", 20 | "name": "uid", 21 | "type": "bytes32" 22 | }, 23 | { 24 | "indexed": false, 25 | "internalType": "address", 26 | "name": "registerer", 27 | "type": "address" 28 | } 29 | ], 30 | "name": "Registered", 31 | "type": "event" 32 | }, 33 | { 34 | "inputs": [ 35 | { 36 | "internalType": "bytes32", 37 | "name": "uid", 38 | "type": "bytes32" 39 | } 40 | ], 41 | "name": "getSchema", 42 | "outputs": [ 43 | { 44 | "components": [ 45 | { 46 | "internalType": "bytes32", 47 | "name": "uid", 48 | "type": "bytes32" 49 | }, 50 | { 51 | "internalType": "contract ISchemaResolver", 52 | "name": "resolver", 53 | "type": "address" 54 | }, 55 | { 56 | "internalType": "bool", 57 | "name": "revocable", 58 | "type": "bool" 59 | }, 60 | { 61 | "internalType": "string", 62 | "name": "schema", 63 | "type": "string" 64 | } 65 | ], 66 | "internalType": "struct SchemaRecord", 67 | "name": "", 68 | "type": "tuple" 69 | } 70 | ], 71 | "stateMutability": "view", 72 | "type": "function" 73 | }, 74 | { 75 | "inputs": [ 76 | { 77 | "internalType": "string", 78 | "name": "schema", 79 | "type": "string" 80 | }, 81 | { 82 | "internalType": "contract ISchemaResolver", 83 | "name": "resolver", 84 | "type": "address" 85 | }, 86 | { 87 | "internalType": "bool", 88 | "name": "revocable", 89 | "type": "bool" 90 | } 91 | ], 92 | "name": "register", 93 | "outputs": [ 94 | { 95 | "internalType": "bytes32", 96 | "name": "", 97 | "type": "bytes32" 98 | } 99 | ], 100 | "stateMutability": "nonpayable", 101 | "type": "function" 102 | }, 103 | { 104 | "inputs": [], 105 | "name": "version", 106 | "outputs": [ 107 | { 108 | "internalType": "string", 109 | "name": "", 110 | "type": "string" 111 | } 112 | ], 113 | "stateMutability": "view", 114 | "type": "function" 115 | } 116 | ] 117 | } 118 | -------------------------------------------------------------------------------- /deployments/telos/.chainId: -------------------------------------------------------------------------------- 1 | 40 2 | -------------------------------------------------------------------------------- /deployments/telos/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1732315140, 3 | "000002-eas": 1732315151, 4 | "000003-register-initial-schemas": 1732315795, 5 | "000004-name-initial-schemas": 1732316219, 6 | "000005-eip712-proxy": 1732316245, 7 | "000006-indexer": 1732316254 8 | } -------------------------------------------------------------------------------- /deployments/telos/types/@ethereum-attestation-service/eas-contracts/contracts/SchemaRegistry.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type { 5 | BaseContract, 6 | BytesLike, 7 | FunctionFragment, 8 | Result, 9 | Interface, 10 | EventFragment, 11 | AddressLike, 12 | ContractRunner, 13 | ContractMethod, 14 | Listener, 15 | } from "ethers"; 16 | import type { 17 | TypedContractEvent, 18 | TypedDeferredTopicFilter, 19 | TypedEventLog, 20 | TypedLogDescription, 21 | TypedListener, 22 | TypedContractMethod, 23 | } from "../../../common"; 24 | 25 | export type SchemaRecordStruct = { 26 | uid: BytesLike; 27 | resolver: AddressLike; 28 | revocable: boolean; 29 | schema: string; 30 | }; 31 | 32 | export type SchemaRecordStructOutput = [ 33 | uid: string, 34 | resolver: string, 35 | revocable: boolean, 36 | schema: string 37 | ] & { uid: string; resolver: string; revocable: boolean; schema: string }; 38 | 39 | export interface SchemaRegistryInterface extends Interface { 40 | getFunction( 41 | nameOrSignature: "getSchema" | "register" | "version" 42 | ): FunctionFragment; 43 | 44 | getEvent(nameOrSignatureOrTopic: "Registered"): EventFragment; 45 | 46 | encodeFunctionData( 47 | functionFragment: "getSchema", 48 | values: [BytesLike] 49 | ): string; 50 | encodeFunctionData( 51 | functionFragment: "register", 52 | values: [string, AddressLike, boolean] 53 | ): string; 54 | encodeFunctionData(functionFragment: "version", values?: undefined): string; 55 | 56 | decodeFunctionResult(functionFragment: "getSchema", data: BytesLike): Result; 57 | decodeFunctionResult(functionFragment: "register", data: BytesLike): Result; 58 | decodeFunctionResult(functionFragment: "version", data: BytesLike): Result; 59 | } 60 | 61 | export namespace RegisteredEvent { 62 | export type InputTuple = [ 63 | uid: BytesLike, 64 | registerer: AddressLike, 65 | schema: SchemaRecordStruct 66 | ]; 67 | export type OutputTuple = [ 68 | uid: string, 69 | registerer: string, 70 | schema: SchemaRecordStructOutput 71 | ]; 72 | export interface OutputObject { 73 | uid: string; 74 | registerer: string; 75 | schema: SchemaRecordStructOutput; 76 | } 77 | export type Event = TypedContractEvent; 78 | export type Filter = TypedDeferredTopicFilter; 79 | export type Log = TypedEventLog; 80 | export type LogDescription = TypedLogDescription; 81 | } 82 | 83 | export interface SchemaRegistry extends BaseContract { 84 | connect(runner?: ContractRunner | null): SchemaRegistry; 85 | waitForDeployment(): Promise; 86 | 87 | interface: SchemaRegistryInterface; 88 | 89 | queryFilter( 90 | event: TCEvent, 91 | fromBlockOrBlockhash?: string | number | undefined, 92 | toBlock?: string | number | undefined 93 | ): Promise>>; 94 | queryFilter( 95 | filter: TypedDeferredTopicFilter, 96 | fromBlockOrBlockhash?: string | number | undefined, 97 | toBlock?: string | number | undefined 98 | ): Promise>>; 99 | 100 | on( 101 | event: TCEvent, 102 | listener: TypedListener 103 | ): Promise; 104 | on( 105 | filter: TypedDeferredTopicFilter, 106 | listener: TypedListener 107 | ): Promise; 108 | 109 | once( 110 | event: TCEvent, 111 | listener: TypedListener 112 | ): Promise; 113 | once( 114 | filter: TypedDeferredTopicFilter, 115 | listener: TypedListener 116 | ): Promise; 117 | 118 | listeners( 119 | event: TCEvent 120 | ): Promise>>; 121 | listeners(eventName?: string): Promise>; 122 | removeAllListeners( 123 | event?: TCEvent 124 | ): Promise; 125 | 126 | getSchema: TypedContractMethod< 127 | [uid: BytesLike], 128 | [SchemaRecordStructOutput], 129 | "view" 130 | >; 131 | 132 | register: TypedContractMethod< 133 | [schema: string, resolver: AddressLike, revocable: boolean], 134 | [string], 135 | "nonpayable" 136 | >; 137 | 138 | version: TypedContractMethod<[], [string], "view">; 139 | 140 | getFunction( 141 | key: string | FunctionFragment 142 | ): T; 143 | 144 | getFunction( 145 | nameOrSignature: "getSchema" 146 | ): TypedContractMethod<[uid: BytesLike], [SchemaRecordStructOutput], "view">; 147 | getFunction( 148 | nameOrSignature: "register" 149 | ): TypedContractMethod< 150 | [schema: string, resolver: AddressLike, revocable: boolean], 151 | [string], 152 | "nonpayable" 153 | >; 154 | getFunction( 155 | nameOrSignature: "version" 156 | ): TypedContractMethod<[], [string], "view">; 157 | 158 | getEvent( 159 | key: "Registered" 160 | ): TypedContractEvent< 161 | RegisteredEvent.InputTuple, 162 | RegisteredEvent.OutputTuple, 163 | RegisteredEvent.OutputObject 164 | >; 165 | 166 | filters: { 167 | "Registered(bytes32,address,tuple)": TypedContractEvent< 168 | RegisteredEvent.InputTuple, 169 | RegisteredEvent.OutputTuple, 170 | RegisteredEvent.OutputObject 171 | >; 172 | Registered: TypedContractEvent< 173 | RegisteredEvent.InputTuple, 174 | RegisteredEvent.OutputTuple, 175 | RegisteredEvent.OutputObject 176 | >; 177 | }; 178 | } 179 | -------------------------------------------------------------------------------- /deployments/unichain/.chainId: -------------------------------------------------------------------------------- 1 | 130 2 | -------------------------------------------------------------------------------- /deployments/unichain/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1682454805, 3 | "000002-eas": 1682454812, 4 | "000003-register-initial-schemas": 1739372915, 5 | "000004-name-initial-schemas": 1739373612, 6 | "000005-eip712-proxy": 1739374161, 7 | "000006-indexer": 1739374173 8 | } -------------------------------------------------------------------------------- /deployments/unichain/SchemaRegistry.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "0x4200000000000000000000000000000000000020", 3 | "abi": [ 4 | { 5 | "inputs": [], 6 | "stateMutability": "nonpayable", 7 | "type": "constructor" 8 | }, 9 | { 10 | "inputs": [], 11 | "name": "AlreadyExists", 12 | "type": "error" 13 | }, 14 | { 15 | "anonymous": false, 16 | "inputs": [ 17 | { 18 | "indexed": true, 19 | "internalType": "bytes32", 20 | "name": "uid", 21 | "type": "bytes32" 22 | }, 23 | { 24 | "indexed": false, 25 | "internalType": "address", 26 | "name": "registerer", 27 | "type": "address" 28 | } 29 | ], 30 | "name": "Registered", 31 | "type": "event" 32 | }, 33 | { 34 | "inputs": [ 35 | { 36 | "internalType": "bytes32", 37 | "name": "uid", 38 | "type": "bytes32" 39 | } 40 | ], 41 | "name": "getSchema", 42 | "outputs": [ 43 | { 44 | "components": [ 45 | { 46 | "internalType": "bytes32", 47 | "name": "uid", 48 | "type": "bytes32" 49 | }, 50 | { 51 | "internalType": "contract ISchemaResolver", 52 | "name": "resolver", 53 | "type": "address" 54 | }, 55 | { 56 | "internalType": "bool", 57 | "name": "revocable", 58 | "type": "bool" 59 | }, 60 | { 61 | "internalType": "string", 62 | "name": "schema", 63 | "type": "string" 64 | } 65 | ], 66 | "internalType": "struct SchemaRecord", 67 | "name": "", 68 | "type": "tuple" 69 | } 70 | ], 71 | "stateMutability": "view", 72 | "type": "function" 73 | }, 74 | { 75 | "inputs": [ 76 | { 77 | "internalType": "string", 78 | "name": "schema", 79 | "type": "string" 80 | }, 81 | { 82 | "internalType": "contract ISchemaResolver", 83 | "name": "resolver", 84 | "type": "address" 85 | }, 86 | { 87 | "internalType": "bool", 88 | "name": "revocable", 89 | "type": "bool" 90 | } 91 | ], 92 | "name": "register", 93 | "outputs": [ 94 | { 95 | "internalType": "bytes32", 96 | "name": "", 97 | "type": "bytes32" 98 | } 99 | ], 100 | "stateMutability": "nonpayable", 101 | "type": "function" 102 | }, 103 | { 104 | "inputs": [], 105 | "name": "version", 106 | "outputs": [ 107 | { 108 | "internalType": "string", 109 | "name": "", 110 | "type": "string" 111 | } 112 | ], 113 | "stateMutability": "view", 114 | "type": "function" 115 | } 116 | ] 117 | } 118 | -------------------------------------------------------------------------------- /deployments/unichain/types/contracts/SchemaRegistry.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type { 5 | BaseContract, 6 | BigNumber, 7 | BytesLike, 8 | CallOverrides, 9 | ContractTransaction, 10 | Overrides, 11 | PopulatedTransaction, 12 | Signer, 13 | utils, 14 | } from "ethers"; 15 | import type { 16 | FunctionFragment, 17 | Result, 18 | EventFragment, 19 | } from "@ethersproject/abi"; 20 | import type { Listener, Provider } from "@ethersproject/providers"; 21 | import type { 22 | TypedEventFilter, 23 | TypedEvent, 24 | TypedListener, 25 | OnEvent, 26 | PromiseOrValue, 27 | } from "../common"; 28 | 29 | export type SchemaRecordStruct = { 30 | uid: PromiseOrValue; 31 | resolver: PromiseOrValue; 32 | revocable: PromiseOrValue; 33 | schema: PromiseOrValue; 34 | }; 35 | 36 | export type SchemaRecordStructOutput = [string, string, boolean, string] & { 37 | uid: string; 38 | resolver: string; 39 | revocable: boolean; 40 | schema: string; 41 | }; 42 | 43 | export interface SchemaRegistryInterface extends utils.Interface { 44 | functions: { 45 | "VERSION()": FunctionFragment; 46 | "getSchema(bytes32)": FunctionFragment; 47 | "register(string,address,bool)": FunctionFragment; 48 | }; 49 | 50 | getFunction( 51 | nameOrSignatureOrTopic: "VERSION" | "getSchema" | "register" 52 | ): FunctionFragment; 53 | 54 | encodeFunctionData(functionFragment: "VERSION", values?: undefined): string; 55 | encodeFunctionData( 56 | functionFragment: "getSchema", 57 | values: [PromiseOrValue] 58 | ): string; 59 | encodeFunctionData( 60 | functionFragment: "register", 61 | values: [ 62 | PromiseOrValue, 63 | PromiseOrValue, 64 | PromiseOrValue 65 | ] 66 | ): string; 67 | 68 | decodeFunctionResult(functionFragment: "VERSION", data: BytesLike): Result; 69 | decodeFunctionResult(functionFragment: "getSchema", data: BytesLike): Result; 70 | decodeFunctionResult(functionFragment: "register", data: BytesLike): Result; 71 | 72 | events: { 73 | "Registered(bytes32,address)": EventFragment; 74 | }; 75 | 76 | getEvent(nameOrSignatureOrTopic: "Registered"): EventFragment; 77 | } 78 | 79 | export interface RegisteredEventObject { 80 | uid: string; 81 | registerer: string; 82 | } 83 | export type RegisteredEvent = TypedEvent< 84 | [string, string], 85 | RegisteredEventObject 86 | >; 87 | 88 | export type RegisteredEventFilter = TypedEventFilter; 89 | 90 | export interface SchemaRegistry extends BaseContract { 91 | connect(signerOrProvider: Signer | Provider | string): this; 92 | attach(addressOrName: string): this; 93 | deployed(): Promise; 94 | 95 | interface: SchemaRegistryInterface; 96 | 97 | queryFilter( 98 | event: TypedEventFilter, 99 | fromBlockOrBlockhash?: string | number | undefined, 100 | toBlock?: string | number | undefined 101 | ): Promise>; 102 | 103 | listeners( 104 | eventFilter?: TypedEventFilter 105 | ): Array>; 106 | listeners(eventName?: string): Array; 107 | removeAllListeners( 108 | eventFilter: TypedEventFilter 109 | ): this; 110 | removeAllListeners(eventName?: string): this; 111 | off: OnEvent; 112 | on: OnEvent; 113 | once: OnEvent; 114 | removeListener: OnEvent; 115 | 116 | functions: { 117 | VERSION(overrides?: CallOverrides): Promise<[string]>; 118 | 119 | getSchema( 120 | uid: PromiseOrValue, 121 | overrides?: CallOverrides 122 | ): Promise<[SchemaRecordStructOutput]>; 123 | 124 | register( 125 | schema: PromiseOrValue, 126 | resolver: PromiseOrValue, 127 | revocable: PromiseOrValue, 128 | overrides?: Overrides & { from?: PromiseOrValue } 129 | ): Promise; 130 | }; 131 | 132 | VERSION(overrides?: CallOverrides): Promise; 133 | 134 | getSchema( 135 | uid: PromiseOrValue, 136 | overrides?: CallOverrides 137 | ): Promise; 138 | 139 | register( 140 | schema: PromiseOrValue, 141 | resolver: PromiseOrValue, 142 | revocable: PromiseOrValue, 143 | overrides?: Overrides & { from?: PromiseOrValue } 144 | ): Promise; 145 | 146 | callStatic: { 147 | VERSION(overrides?: CallOverrides): Promise; 148 | 149 | getSchema( 150 | uid: PromiseOrValue, 151 | overrides?: CallOverrides 152 | ): Promise; 153 | 154 | register( 155 | schema: PromiseOrValue, 156 | resolver: PromiseOrValue, 157 | revocable: PromiseOrValue, 158 | overrides?: CallOverrides 159 | ): Promise; 160 | }; 161 | 162 | filters: { 163 | "Registered(bytes32,address)"( 164 | uid?: PromiseOrValue | null, 165 | registerer?: null 166 | ): RegisteredEventFilter; 167 | Registered( 168 | uid?: PromiseOrValue | null, 169 | registerer?: null 170 | ): RegisteredEventFilter; 171 | }; 172 | 173 | estimateGas: { 174 | VERSION(overrides?: CallOverrides): Promise; 175 | 176 | getSchema( 177 | uid: PromiseOrValue, 178 | overrides?: CallOverrides 179 | ): Promise; 180 | 181 | register( 182 | schema: PromiseOrValue, 183 | resolver: PromiseOrValue, 184 | revocable: PromiseOrValue, 185 | overrides?: Overrides & { from?: PromiseOrValue } 186 | ): Promise; 187 | }; 188 | 189 | populateTransaction: { 190 | VERSION(overrides?: CallOverrides): Promise; 191 | 192 | getSchema( 193 | uid: PromiseOrValue, 194 | overrides?: CallOverrides 195 | ): Promise; 196 | 197 | register( 198 | schema: PromiseOrValue, 199 | resolver: PromiseOrValue, 200 | revocable: PromiseOrValue, 201 | overrides?: Overrides & { from?: PromiseOrValue } 202 | ): Promise; 203 | }; 204 | } 205 | -------------------------------------------------------------------------------- /deployments/zksync/.chainId: -------------------------------------------------------------------------------- 1 | 324 2 | -------------------------------------------------------------------------------- /deployments/zksync/.migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "000001-registry": 1714515518, 3 | "000002-eas": 1714515524, 4 | "000003-register-initial-schemas": 1714515978, 5 | "000004-name-initial-schemas": 1714516445, 6 | "000005-eip712-proxy": 1714516451, 7 | "000006-indexer": 1714516456 8 | } -------------------------------------------------------------------------------- /deployments/zksync/types/contracts/SchemaRegistry.ts: -------------------------------------------------------------------------------- 1 | /* Autogenerated file. Do not edit manually. */ 2 | /* tslint:disable */ 3 | /* eslint-disable */ 4 | import type { 5 | BaseContract, 6 | BytesLike, 7 | FunctionFragment, 8 | Result, 9 | Interface, 10 | EventFragment, 11 | AddressLike, 12 | ContractRunner, 13 | ContractMethod, 14 | Listener, 15 | } from "ethers"; 16 | import type { 17 | TypedContractEvent, 18 | TypedDeferredTopicFilter, 19 | TypedEventLog, 20 | TypedLogDescription, 21 | TypedListener, 22 | TypedContractMethod, 23 | } from "../common"; 24 | 25 | export type SchemaRecordStruct = { 26 | uid: BytesLike; 27 | resolver: AddressLike; 28 | revocable: boolean; 29 | schema: string; 30 | }; 31 | 32 | export type SchemaRecordStructOutput = [ 33 | uid: string, 34 | resolver: string, 35 | revocable: boolean, 36 | schema: string 37 | ] & { uid: string; resolver: string; revocable: boolean; schema: string }; 38 | 39 | export interface SchemaRegistryInterface extends Interface { 40 | getFunction( 41 | nameOrSignature: "getSchema" | "register" | "version" 42 | ): FunctionFragment; 43 | 44 | getEvent(nameOrSignatureOrTopic: "Registered"): EventFragment; 45 | 46 | encodeFunctionData( 47 | functionFragment: "getSchema", 48 | values: [BytesLike] 49 | ): string; 50 | encodeFunctionData( 51 | functionFragment: "register", 52 | values: [string, AddressLike, boolean] 53 | ): string; 54 | encodeFunctionData(functionFragment: "version", values?: undefined): string; 55 | 56 | decodeFunctionResult(functionFragment: "getSchema", data: BytesLike): Result; 57 | decodeFunctionResult(functionFragment: "register", data: BytesLike): Result; 58 | decodeFunctionResult(functionFragment: "version", data: BytesLike): Result; 59 | } 60 | 61 | export namespace RegisteredEvent { 62 | export type InputTuple = [ 63 | uid: BytesLike, 64 | registerer: AddressLike, 65 | schema: SchemaRecordStruct 66 | ]; 67 | export type OutputTuple = [ 68 | uid: string, 69 | registerer: string, 70 | schema: SchemaRecordStructOutput 71 | ]; 72 | export interface OutputObject { 73 | uid: string; 74 | registerer: string; 75 | schema: SchemaRecordStructOutput; 76 | } 77 | export type Event = TypedContractEvent; 78 | export type Filter = TypedDeferredTopicFilter; 79 | export type Log = TypedEventLog; 80 | export type LogDescription = TypedLogDescription; 81 | } 82 | 83 | export interface SchemaRegistry extends BaseContract { 84 | connect(runner?: ContractRunner | null): SchemaRegistry; 85 | waitForDeployment(): Promise; 86 | 87 | interface: SchemaRegistryInterface; 88 | 89 | queryFilter( 90 | event: TCEvent, 91 | fromBlockOrBlockhash?: string | number | undefined, 92 | toBlock?: string | number | undefined 93 | ): Promise>>; 94 | queryFilter( 95 | filter: TypedDeferredTopicFilter, 96 | fromBlockOrBlockhash?: string | number | undefined, 97 | toBlock?: string | number | undefined 98 | ): Promise>>; 99 | 100 | on( 101 | event: TCEvent, 102 | listener: TypedListener 103 | ): Promise; 104 | on( 105 | filter: TypedDeferredTopicFilter, 106 | listener: TypedListener 107 | ): Promise; 108 | 109 | once( 110 | event: TCEvent, 111 | listener: TypedListener 112 | ): Promise; 113 | once( 114 | filter: TypedDeferredTopicFilter, 115 | listener: TypedListener 116 | ): Promise; 117 | 118 | listeners( 119 | event: TCEvent 120 | ): Promise>>; 121 | listeners(eventName?: string): Promise>; 122 | removeAllListeners( 123 | event?: TCEvent 124 | ): Promise; 125 | 126 | getSchema: TypedContractMethod< 127 | [uid: BytesLike], 128 | [SchemaRecordStructOutput], 129 | "view" 130 | >; 131 | 132 | register: TypedContractMethod< 133 | [schema: string, resolver: AddressLike, revocable: boolean], 134 | [string], 135 | "nonpayable" 136 | >; 137 | 138 | version: TypedContractMethod<[], [string], "view">; 139 | 140 | getFunction( 141 | key: string | FunctionFragment 142 | ): T; 143 | 144 | getFunction( 145 | nameOrSignature: "getSchema" 146 | ): TypedContractMethod<[uid: BytesLike], [SchemaRecordStructOutput], "view">; 147 | getFunction( 148 | nameOrSignature: "register" 149 | ): TypedContractMethod< 150 | [schema: string, resolver: AddressLike, revocable: boolean], 151 | [string], 152 | "nonpayable" 153 | >; 154 | getFunction( 155 | nameOrSignature: "version" 156 | ): TypedContractMethod<[], [string], "view">; 157 | 158 | getEvent( 159 | key: "Registered" 160 | ): TypedContractEvent< 161 | RegisteredEvent.InputTuple, 162 | RegisteredEvent.OutputTuple, 163 | RegisteredEvent.OutputObject 164 | >; 165 | 166 | filters: { 167 | "Registered(bytes32,address,tuple)": TypedContractEvent< 168 | RegisteredEvent.InputTuple, 169 | RegisteredEvent.OutputTuple, 170 | RegisteredEvent.OutputObject 171 | >; 172 | Registered: TypedContractEvent< 173 | RegisteredEvent.InputTuple, 174 | RegisteredEvent.OutputTuple, 175 | RegisteredEvent.OutputObject 176 | >; 177 | }; 178 | } 179 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import prettier from 'eslint-config-prettier'; 2 | import chaiFriendly from 'eslint-plugin-chai-friendly'; 3 | import tseslint from 'typescript-eslint'; 4 | 5 | export default [ 6 | ...tseslint.configs.recommended, 7 | prettier, 8 | chaiFriendly.configs.recommendedFlat, 9 | { 10 | files: ['**/*.ts'], 11 | rules: { 12 | 'max-len': ['error', 150, 2], 13 | camelcase: [ 14 | 'error', 15 | { 16 | ignoreImports: true 17 | } 18 | ], 19 | indent: [ 20 | 'error', 21 | 2, 22 | { 23 | SwitchCase: 1 24 | } 25 | ], 26 | semi: ['error', 'always'], 27 | quotes: ['error', 'single', { avoidEscape: true }], 28 | 'no-plusplus': 'off', 29 | 'no-await-in-loop': 'off', 30 | 'no-restricted-syntax': 'off', 31 | 'no-continue': 'off', 32 | 'arrow-body-style': 'off', 33 | 'no-loop-func': 'off', 34 | 'no-unused-expressions': 'off', 35 | 'chai-friendly/no-unused-expressions': 'error', 36 | 'require-await': 'error', 37 | 'no-return-await': 'error', 38 | '@typescript-eslint/explicit-module-boundary-types': 'off', 39 | '@typescript-eslint/no-explicit-any': 'off', 40 | '@typescript-eslint/no-non-null-assertion': 'off', 41 | '@typescript-eslint/no-unused-expressions': 'off' 42 | }, 43 | languageOptions: { 44 | globals: { 45 | assert: true, 46 | expect: true, 47 | artifacts: true, 48 | contract: true 49 | } 50 | } 51 | } 52 | ]; 53 | -------------------------------------------------------------------------------- /foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | solc = "0.8.28" 3 | bytecode_hash = "none" 4 | optimizer = true 5 | optimizer_runs = 1000000 6 | remappings = ["@openzeppelin/contracts=node_modules/@openzeppelin/contracts/"] 7 | -------------------------------------------------------------------------------- /funding.json: -------------------------------------------------------------------------------- 1 | { 2 | "opRetro": { 3 | "projectId": "0xa88844cea135382e3484e39c3172033437121b35ca0bc8b10b9b8253984876b5" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import '@nomicfoundation/hardhat-toolbox'; 2 | import '@nomiclabs/hardhat-solhint'; 3 | import 'hardhat-contract-sizer'; 4 | import { HardhatUserConfig } from 'hardhat/config'; 5 | import { MochaOptions } from 'mocha'; 6 | 7 | interface EnvOptions { 8 | PROFILE?: boolean; 9 | } 10 | 11 | const { PROFILE: isProfiling }: EnvOptions = process.env as any as EnvOptions; 12 | 13 | const mochaOptions = (): MochaOptions => { 14 | let timeout = 600000; 15 | let reporter; 16 | 17 | if (isProfiling) { 18 | timeout = 0; 19 | reporter = 'mocha-silent-reporter'; 20 | } 21 | 22 | return { 23 | timeout, 24 | color: true, 25 | bail: true, 26 | reporter 27 | }; 28 | }; 29 | 30 | const config: HardhatUserConfig = { 31 | networks: { 32 | hardhat: { 33 | accounts: { 34 | count: 20, 35 | accountsBalance: '10000000000000000000000000000000000000000000000' 36 | }, 37 | allowUnlimitedContractSize: true 38 | } 39 | }, 40 | 41 | solidity: { 42 | version: '0.8.28', 43 | settings: { 44 | optimizer: { 45 | enabled: true, 46 | runs: 1000000 47 | }, 48 | evmVersion: 'paris', // Prevent using the `PUSH0` opcode 49 | metadata: { 50 | bytecodeHash: 'none' // Remove the metadata hash from the bytecode 51 | } 52 | } 53 | }, 54 | 55 | typechain: { 56 | target: 'ethers-v6' 57 | }, 58 | 59 | contractSizer: { 60 | alphaSort: true, 61 | runOnCompile: false, 62 | disambiguatePaths: false 63 | }, 64 | 65 | gasReporter: { 66 | currency: 'USD', 67 | enabled: isProfiling 68 | }, 69 | 70 | mocha: mochaOptions() 71 | }; 72 | 73 | export default config; 74 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ethereum-attestation-service/eas-contracts", 3 | "version": "1.9.0", 4 | "description": "Ethereum Attestation Service", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/ethereum-attestation-service/eas-contracts" 8 | }, 9 | "author": "Leonid Beder ", 10 | "license": "MIT", 11 | "main": "dist/typechain-types/index.js", 12 | "types": "dist/typechain-types/index.d.ts", 13 | "files": [ 14 | "**/*.sol", 15 | "!/contracts/tests/**/*", 16 | "/artifacts/contracts", 17 | "!/artifacts/contracts/tests/**/*", 18 | "/dist/typechain-types", 19 | "!/dist/typechain-types/contracts/tests/**/*", 20 | "!/dist/typechain-types/factories/contracts/tests/**/*", 21 | "!/deployments/hardhat/**/*", 22 | "/deployments/mainnet/**/*", 23 | "/deployments/optimism/**/*", 24 | "/deployments/base/**/*", 25 | "/deployments/arbitrum-one/**/*", 26 | "/deployments/arbitrum-nova/**/*", 27 | "/deployments/polygon/**/*", 28 | "/deployments/scroll/**/*", 29 | "/deployments/zksync/**/*", 30 | "/deployments/celo/**/*", 31 | "/deployments/linea/**/*", 32 | "/deployments/telos/**/*", 33 | "/deployments/soneium/**/*", 34 | "/deployments/ink/**/*", 35 | "/deployments/unichain/**/*", 36 | "/deployments/sepolia/**/*", 37 | "/deployments/optimism-sepolia/**/*", 38 | "/deployments/optimism-goerli/**/*", 39 | "/deployments/base-sepolia/**/*", 40 | "/deployments/base-goerli/**/*", 41 | "/deployments/arbitrum-sepolia/**/*", 42 | "/deployments/polygon-amoy/**/*", 43 | "/deployments/scroll-sepolia/**/*", 44 | "/deployments/linea-goerli/**/*" 45 | ], 46 | "scripts": { 47 | "compile": "hardhat compile", 48 | "recompile": "pnpm clean && pnpm compile", 49 | "test": "hardhat test", 50 | "test:coverage": "hardhat coverage --solcoverjs .solcover.ts", 51 | "test:profile": "PROFILE=1 pnpm test", 52 | "lint": "pnpm lint:sol && pnpm lint:ts", 53 | "lint:sol": "solhint --max-warnings 0 contracts/**/*.sol", 54 | "lint:ts": "pnpm eslint components/**/*.ts test/**/*.ts utils/**/*.ts", 55 | "format": "prettier --check --write contracts/**/*.sol *.ts components/**/*.ts test/**/*.ts utils/**/*.ts --config .prettierrc", 56 | "size": "hardhat size-contracts", 57 | "verify": "hardhat verify", 58 | "flatten": "hardhat flatten", 59 | "clean": "rm -rf artifacts cache dist coverage typechain-types out artifacts-zk cache-zk", 60 | "prepare": "pnpm compile", 61 | "export-types": "pnpm delete-test-types && tsc -p tsconfig.release.json && copyfiles -u 1 \"typechain-types/**/*.d.ts\" dist/typechain-types && pnpm restore-test-types", 62 | "delete-test-types": "sed -i.bak '/tests/d' typechain-types/index.ts typechain-types/contracts/index.ts typechain-types/factories/contracts/index.ts && mv typechain-types/hardhat.d.ts typechain-types/hardhat.d.ts.bak", 63 | "restore-test-types": "mv typechain-types/index.ts.bak typechain-types/index.ts && mv typechain-types/contracts/index.ts.bak typechain-types/contracts/index.ts && mv typechain-types/factories/contracts/index.ts.bak typechain-types/factories/contracts/index.ts && mv typechain-types/hardhat.d.ts.bak typechain-types/hardhat.d.ts", 64 | "prepare:release": "pnpm prepare && pnpm export-types && pnpm lint && pnpm test" 65 | }, 66 | "dependencies": { 67 | "hardhat": "2.22.18" 68 | }, 69 | "devDependencies": { 70 | "@ianvs/prettier-plugin-sort-imports": "^4.4.1", 71 | "@nomicfoundation/hardhat-ethers": "^3.0.8", 72 | "@nomicfoundation/hardhat-toolbox": "^5.0.0", 73 | "@nomiclabs/hardhat-solhint": "^4.0.1", 74 | "@openzeppelin/contracts": "5.2.0", 75 | "@typechain/ethers-v6": "^0.5.1", 76 | "@types/chai": "^5.0.1", 77 | "@types/mocha": "^10.0.10", 78 | "@types/node": "^22.12.0", 79 | "chai-bigint": "^0.2.0", 80 | "copyfiles": "^2.4.1", 81 | "eslint": "^9.19.0", 82 | "eslint-config-prettier": "^10.0.1", 83 | "eslint-plugin-chai-friendly": "^1.0.1", 84 | "eslint-plugin-import": "^2.31.0", 85 | "ethereumjs-util": "^7.1.5", 86 | "ethers": "^6.13.5", 87 | "hardhat-contract-sizer": "^2.10.0", 88 | "mocha": "^11.1.0", 89 | "mocha-silent-reporter": "^1.0.0", 90 | "prettier": "^3.4.2", 91 | "prettier-package-json": "^2.8.0", 92 | "prettier-plugin-solidity": "^1.4.2", 93 | "solc": "0.8.28", 94 | "solhint": "^5.0.5", 95 | "ts-node": "^10.9.2", 96 | "typescript": "^5.7.3", 97 | "typescript-eslint": "^8.22.0" 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /test/SchemaRegistry.ts: -------------------------------------------------------------------------------- 1 | import { encodeBytes32String, Signer } from 'ethers'; 2 | import { ethers } from 'hardhat'; 3 | import Contracts from '../components/Contracts'; 4 | import { SchemaRegistry } from '../typechain-types'; 5 | import { ZERO_ADDRESS, ZERO_BYTES, ZERO_BYTES32 } from '../utils/Constants'; 6 | import { getSchemaUID } from '../utils/EAS'; 7 | import { expect } from './helpers/Chai'; 8 | 9 | describe('SchemaRegistry', () => { 10 | let accounts: Signer[]; 11 | 12 | let registry: SchemaRegistry; 13 | 14 | before(async () => { 15 | accounts = await ethers.getSigners(); 16 | }); 17 | 18 | beforeEach(async () => { 19 | registry = await Contracts.SchemaRegistry.deploy(); 20 | }); 21 | 22 | describe('construction', () => { 23 | it('should report a version', async () => { 24 | expect(await registry.version()).to.equal('1.4.0'); 25 | }); 26 | }); 27 | 28 | describe('registration', () => { 29 | const testRegister = async (schema: string, resolver: string | Signer, revocable: boolean) => { 30 | const resolverAddress = typeof resolver === 'string' ? resolver : await resolver.getAddress(); 31 | 32 | const uid = getSchemaUID(schema, resolverAddress, revocable); 33 | 34 | const retUID = await registry.register.staticCall(schema, resolverAddress, revocable); 35 | const res = await registry.register(schema, resolverAddress, revocable); 36 | expect(retUID).to.equal(uid); 37 | 38 | const schemaRecord = await registry.getSchema(uid); 39 | const sender = accounts[0]; 40 | 41 | await expect(res) 42 | .to.emit(registry, 'Registered') 43 | .withArgs(uid, await sender.getAddress(), schemaRecord); 44 | 45 | expect(schemaRecord.uid).to.equal(uid); 46 | expect(schemaRecord.schema).to.equal(schema); 47 | expect(schemaRecord.resolver).to.equal(resolverAddress); 48 | expect(schemaRecord.revocable).to.equal(revocable); 49 | }; 50 | 51 | it('should allow to register a schema', async () => { 52 | await testRegister('bool like', accounts[3], true); 53 | await testRegister('bytes32 proposalId, bool vote', accounts[3], false); 54 | }); 55 | 56 | it('should allow to register a schema without a schema', async () => { 57 | await testRegister(ZERO_BYTES, accounts[3], true); 58 | }); 59 | 60 | it('should allow to register a schema without a resolver', async () => { 61 | await testRegister('bool hasPhoneNumber, bytes32 phoneHash', ZERO_ADDRESS, true); 62 | }); 63 | 64 | it('should allow to register a schema without neither a schema or a resolver', async () => { 65 | await testRegister(ZERO_BYTES, ZERO_ADDRESS, true); 66 | }); 67 | 68 | it('should not allow to register the same schema and resolver twice', async () => { 69 | const schema = 'bool isFriend'; 70 | await registry.register(schema, ZERO_ADDRESS, true); 71 | await expect(registry.register(schema, ZERO_ADDRESS, true)).to.be.revertedWithCustomError( 72 | registry, 73 | 'AlreadyExists' 74 | ); 75 | }); 76 | }); 77 | 78 | describe('schema querying', () => { 79 | it('should return a schema', async () => { 80 | const schema = 'bool isFriend'; 81 | const resolver = accounts[5]; 82 | 83 | await registry.register(schema, await resolver.getAddress(), true); 84 | 85 | const uid = getSchemaUID(schema, await resolver.getAddress(), true); 86 | const schemaRecord = await registry.getSchema(uid); 87 | expect(schemaRecord.uid).to.equal(uid); 88 | expect(schemaRecord.schema).to.equal(schema); 89 | expect(schemaRecord.resolver).to.equal(await resolver.getAddress()); 90 | expect(schemaRecord.revocable).to.equal(true); 91 | }); 92 | 93 | it('should return an empty schema given non-existing id', async () => { 94 | const schemaRecord = await registry.getSchema(encodeBytes32String('BAD')); 95 | expect(schemaRecord.uid).to.equal(ZERO_BYTES32); 96 | expect(schemaRecord.schema).to.equal(''); 97 | expect(schemaRecord.resolver).to.equal(ZERO_ADDRESS); 98 | expect(schemaRecord.revocable).to.equal(false); 99 | }); 100 | }); 101 | }); 102 | -------------------------------------------------------------------------------- /test/helpers/Chai.ts: -------------------------------------------------------------------------------- 1 | import chai from 'chai'; 2 | import chaiBigInt from 'chai-bigint'; 3 | 4 | chai.use(chaiBigInt); 5 | 6 | export const { expect } = chai; 7 | 8 | export default chai; 9 | -------------------------------------------------------------------------------- /test/helpers/EIP712ProxyUtils.ts: -------------------------------------------------------------------------------- 1 | import { AbiCoder, keccak256, Signer, toUtf8Bytes } from 'ethers'; 2 | import { network } from 'hardhat'; 3 | import { EIP712Proxy } from '../../typechain-types'; 4 | import { 5 | DomainTypedData, 6 | EIP712_DOMAIN, 7 | EIP712AttestationParams, 8 | EIP712MessageTypes, 9 | EIP712Request, 10 | EIP712RevocationParams, 11 | EIP712Utils, 12 | TypedData, 13 | TypedDataConfig 14 | } from './EIP712Utils'; 15 | 16 | export const ATTEST_PROXY_TYPED_SIGNATURE = 17 | // eslint-disable-next-line max-len 18 | 'Attest(address attester,bytes32 schema,address recipient,uint64 expirationTime,bool revocable,bytes32 refUID,bytes data,uint256 value,uint64 deadline)'; 19 | export const REVOKE_PROXY_TYPED_SIGNATURE = 20 | 'Revoke(address revoker,bytes32 schema,bytes32 uid,uint256 value,uint64 deadline)'; 21 | export const ATTEST_PROXY_PRIMARY_TYPE = 'Attest'; 22 | export const REVOKE_PROXY_PRIMARY_TYPE = 'Revoke'; 23 | export const ATTEST_PROXY_TYPE: TypedData[] = [ 24 | { name: 'attester', type: 'address' }, 25 | { name: 'schema', type: 'bytes32' }, 26 | { name: 'recipient', type: 'address' }, 27 | { name: 'expirationTime', type: 'uint64' }, 28 | { name: 'revocable', type: 'bool' }, 29 | { name: 'refUID', type: 'bytes32' }, 30 | { name: 'data', type: 'bytes' }, 31 | { name: 'value', type: 'uint256' }, 32 | { name: 'deadline', type: 'uint64' } 33 | ]; 34 | export const REVOKE_PROXY_TYPE: TypedData[] = [ 35 | { name: 'revoker', type: 'address' }, 36 | { name: 'schema', type: 'bytes32' }, 37 | { name: 'uid', type: 'bytes32' }, 38 | { name: 'value', type: 'uint256' }, 39 | { name: 'deadline', type: 'uint64' } 40 | ]; 41 | 42 | export class EIP712ProxyUtils { 43 | public proxy: EIP712Proxy; 44 | private config?: TypedDataConfig; 45 | private name?: string; 46 | 47 | private constructor(proxy: EIP712Proxy) { 48 | this.proxy = proxy; 49 | } 50 | 51 | public static async fromProxy(verifier: EIP712Proxy) { 52 | const utils = new EIP712ProxyUtils(verifier); 53 | await utils.init(); 54 | 55 | return utils; 56 | } 57 | 58 | public async init() { 59 | this.config = { 60 | address: await this.proxy.getAddress(), 61 | version: await this.proxy.version(), 62 | chainId: network.config.chainId! 63 | }; 64 | 65 | this.name = await this.proxy.getName(); 66 | } 67 | 68 | public getDomainSeparator(name: string) { 69 | if (!this.config) { 70 | throw new Error("EIP712ProxyUtils wasn't initialized"); 71 | } 72 | 73 | return keccak256( 74 | AbiCoder.defaultAbiCoder().encode( 75 | ['bytes32', 'bytes32', 'bytes32', 'uint256', 'address'], 76 | [ 77 | keccak256(toUtf8Bytes(EIP712_DOMAIN)), 78 | keccak256(toUtf8Bytes(name)), 79 | keccak256(toUtf8Bytes(this.config.version)), 80 | this.config.chainId, 81 | this.config.address 82 | ] 83 | ) 84 | ); 85 | } 86 | 87 | public getDomainTypedData(): DomainTypedData { 88 | if (!this.config || !this.name) { 89 | throw new Error("EIP712ProxyUtils wasn't initialized"); 90 | } 91 | 92 | return { 93 | name: this.name, 94 | version: this.config.version, 95 | chainId: this.config.chainId, 96 | verifyingContract: this.config.address 97 | }; 98 | } 99 | 100 | public async signDelegatedProxyAttestation( 101 | attester: Signer, 102 | schema: string, 103 | recipient: string | Signer, 104 | expirationTime: bigint, 105 | revocable: boolean, 106 | refUID: string, 107 | data: string, 108 | value: bigint, 109 | deadline: bigint 110 | ): Promise> { 111 | const params = { 112 | attester: await attester.getAddress(), 113 | schema, 114 | recipient: typeof recipient === 'string' ? recipient : await recipient.getAddress(), 115 | expirationTime, 116 | revocable, 117 | refUID, 118 | data: Buffer.from(data.slice(2), 'hex'), 119 | value, 120 | deadline 121 | }; 122 | 123 | return EIP712Utils.signTypedDataRequest( 124 | params, 125 | { 126 | domain: this.getDomainTypedData(), 127 | primaryType: ATTEST_PROXY_PRIMARY_TYPE, 128 | message: params, 129 | types: { 130 | Attest: ATTEST_PROXY_TYPE 131 | } 132 | }, 133 | attester 134 | ); 135 | } 136 | 137 | public async verifyDelegatedProxyAttestationSignature( 138 | attester: string | Signer, 139 | request: EIP712Request 140 | ): Promise { 141 | return EIP712Utils.verifyTypedDataRequestSignature( 142 | typeof attester === 'string' ? attester : await attester.getAddress(), 143 | request 144 | ); 145 | } 146 | 147 | public async signDelegatedProxyRevocation( 148 | revoker: Signer, 149 | schema: string, 150 | uid: string, 151 | value: bigint, 152 | deadline: bigint 153 | ): Promise> { 154 | const params = { 155 | revoker: await revoker.getAddress(), 156 | schema, 157 | uid, 158 | value, 159 | deadline 160 | }; 161 | 162 | return EIP712Utils.signTypedDataRequest( 163 | params, 164 | { 165 | domain: this.getDomainTypedData(), 166 | primaryType: REVOKE_PROXY_PRIMARY_TYPE, 167 | message: params, 168 | types: { 169 | Revoke: REVOKE_PROXY_TYPE 170 | } 171 | }, 172 | revoker 173 | ); 174 | } 175 | 176 | public async verifyDelegatedProxyRevocationSignature( 177 | attester: string | Signer, 178 | request: EIP712Request 179 | ): Promise { 180 | return EIP712Utils.verifyTypedDataRequestSignature( 181 | typeof attester === 'string' ? attester : await attester.getAddress(), 182 | request 183 | ); 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /test/helpers/Time.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from 'hardhat'; 2 | 3 | export * from '../../utils/Time'; 4 | 5 | export const latest = async (): Promise => { 6 | const block = await ethers.provider.getBlock('latest'); 7 | if (!block) { 8 | throw new Error('Unable to get the latest block'); 9 | } 10 | 11 | return BigInt(block.timestamp); 12 | }; 13 | -------------------------------------------------------------------------------- /test/helpers/Transaction.ts: -------------------------------------------------------------------------------- 1 | import { TransactionResponse } from 'ethers'; 2 | 3 | export const getTransactionGas = async (res: TransactionResponse) => { 4 | const receipt = await res.wait(); 5 | if (!receipt) { 6 | throw new Error(`Unable to confirm: ${res}`); 7 | } 8 | 9 | return receipt.cumulativeGasUsed; 10 | }; 11 | 12 | export const getTransactionCost = async (res: TransactionResponse) => { 13 | const receipt = await res.wait(); 14 | if (!receipt) { 15 | throw new Error(`Unable to confirm: ${res}`); 16 | } 17 | 18 | return receipt.gasPrice * (await getTransactionGas(res)); 19 | }; 20 | -------------------------------------------------------------------------------- /test/helpers/Wallet.ts: -------------------------------------------------------------------------------- 1 | import { Wallet } from 'ethers'; 2 | import { ethers } from 'hardhat'; 3 | 4 | // eslint-disable-next-line require-await 5 | export const getBalance = async (address: string) => ethers.provider.getBalance(address); 6 | 7 | export const createWallet = async () => { 8 | const wallet = Wallet.createRandom().connect(ethers.provider); 9 | const deployer = (await ethers.getSigners())[0]; 10 | await deployer.sendTransaction({ 11 | value: 10_000_000n * 10n ** 18n, 12 | to: await wallet.getAddress() 13 | }); 14 | 15 | return wallet; 16 | }; 17 | -------------------------------------------------------------------------------- /test/resolver/AttesterResolver.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { Signer } from 'ethers'; 3 | import { ethers } from 'hardhat'; 4 | import Contracts from '../../components/Contracts'; 5 | import { SchemaRegistry, TestEAS } from '../../typechain-types'; 6 | import { NO_EXPIRATION } from '../../utils/Constants'; 7 | import { 8 | expectAttestation, 9 | expectFailedAttestation, 10 | expectFailedMultiAttestations, 11 | expectMultiAttestations, 12 | expectMultiRevocations, 13 | expectRevocation, 14 | registerSchema 15 | } from '../helpers/EAS'; 16 | import { latest } from '../helpers/Time'; 17 | import { createWallet } from '../helpers/Wallet'; 18 | 19 | describe('AttesterResolver', () => { 20 | let accounts: Signer[]; 21 | let recipient: Signer; 22 | let sender: Signer; 23 | let sender2: Signer; 24 | let targetSender: Signer; 25 | 26 | let registry: SchemaRegistry; 27 | let eas: TestEAS; 28 | 29 | const schema = 'bytes32 eventId,uint8 ticketType,uint32 ticketNum'; 30 | let schemaId: string; 31 | const data = '0x1234'; 32 | const expirationTime = NO_EXPIRATION; 33 | 34 | before(async () => { 35 | accounts = await ethers.getSigners(); 36 | 37 | [recipient] = accounts; 38 | }); 39 | 40 | beforeEach(async () => { 41 | sender = await createWallet(); 42 | 43 | registry = await Contracts.SchemaRegistry.deploy(); 44 | eas = await Contracts.TestEAS.deploy(await registry.getAddress()); 45 | 46 | await eas.setTime(await latest()); 47 | 48 | sender2 = await createWallet(); 49 | targetSender = sender2; 50 | 51 | const resolver = await Contracts.AttesterResolver.deploy(await eas.getAddress(), await targetSender.getAddress()); 52 | expect(await resolver.isPayable()).to.be.false; 53 | 54 | schemaId = await registerSchema(schema, registry, resolver, true); 55 | }); 56 | 57 | it('should revert when attesting via the wrong attester', async () => { 58 | await expectFailedAttestation( 59 | { eas }, 60 | schemaId, 61 | { recipient: await recipient.getAddress(), expirationTime, data }, 62 | { from: sender }, 63 | 'InvalidAttestation' 64 | ); 65 | 66 | await expectFailedMultiAttestations( 67 | { eas }, 68 | [ 69 | { 70 | schema: schemaId, 71 | requests: [ 72 | { recipient: await recipient.getAddress(), expirationTime, data }, 73 | { recipient: await recipient.getAddress(), expirationTime, data } 74 | ] 75 | } 76 | ], 77 | { from: sender }, 78 | 'InvalidAttestations' 79 | ); 80 | }); 81 | 82 | it('should allow attesting via the correct attester', async () => { 83 | const { uid } = await expectAttestation( 84 | { eas }, 85 | schemaId, 86 | { recipient: await recipient.getAddress(), expirationTime, data }, 87 | { from: targetSender } 88 | ); 89 | 90 | await expectRevocation({ eas }, schemaId, { uid }, { from: targetSender }); 91 | 92 | const res = await expectMultiAttestations( 93 | { eas }, 94 | [ 95 | { 96 | schema: schemaId, 97 | requests: [ 98 | { recipient: await recipient.getAddress(), expirationTime, data }, 99 | { recipient: await recipient.getAddress(), expirationTime, data } 100 | ] 101 | } 102 | ], 103 | { from: targetSender } 104 | ); 105 | 106 | await expectMultiRevocations( 107 | { eas }, 108 | [ 109 | { 110 | schema: schemaId, 111 | requests: res.uids.map((uid) => ({ uid })) 112 | } 113 | ], 114 | { from: targetSender } 115 | ); 116 | }); 117 | }); 118 | -------------------------------------------------------------------------------- /test/resolver/DataResolver.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { Signer } from 'ethers'; 3 | import { ethers } from 'hardhat'; 4 | import Contracts from '../../components/Contracts'; 5 | import { SchemaRegistry, TestEAS } from '../../typechain-types'; 6 | import { NO_EXPIRATION } from '../../utils/Constants'; 7 | import { 8 | expectAttestation, 9 | expectFailedAttestation, 10 | expectFailedMultiAttestations, 11 | expectMultiAttestations, 12 | expectMultiRevocations, 13 | expectRevocation, 14 | registerSchema 15 | } from '../helpers/EAS'; 16 | import { latest } from '../helpers/Time'; 17 | import { createWallet } from '../helpers/Wallet'; 18 | 19 | describe('DataResolver', () => { 20 | let accounts: Signer[]; 21 | let recipient: Signer; 22 | let sender: Signer; 23 | 24 | let registry: SchemaRegistry; 25 | let eas: TestEAS; 26 | 27 | const schema = 'bytes32 eventId,uint8 ticketType,uint32 ticketNum'; 28 | let schemaId: string; 29 | const expirationTime = NO_EXPIRATION; 30 | 31 | const DATA1 = '0x00'; 32 | const DATA2 = '0x01'; 33 | 34 | before(async () => { 35 | accounts = await ethers.getSigners(); 36 | 37 | [recipient] = accounts; 38 | }); 39 | 40 | beforeEach(async () => { 41 | sender = await createWallet(); 42 | 43 | registry = await Contracts.SchemaRegistry.deploy(); 44 | eas = await Contracts.TestEAS.deploy(await registry.getAddress()); 45 | 46 | await eas.setTime(await latest()); 47 | 48 | const resolver = await Contracts.DataResolver.deploy(await eas.getAddress()); 49 | expect(await resolver.isPayable()).to.be.false; 50 | 51 | schemaId = await registerSchema(schema, registry, resolver, true); 52 | }); 53 | 54 | it('should revert when attesting with wrong data', async () => { 55 | await expectFailedAttestation( 56 | { 57 | eas 58 | }, 59 | schemaId, 60 | { 61 | recipient: await recipient.getAddress(), 62 | expirationTime, 63 | data: '0x1234' 64 | }, 65 | { from: sender }, 66 | 'InvalidAttestation' 67 | ); 68 | 69 | await expectFailedAttestation( 70 | { 71 | eas 72 | }, 73 | schemaId, 74 | { 75 | recipient: await recipient.getAddress(), 76 | expirationTime, 77 | data: '0x02' 78 | }, 79 | { from: sender }, 80 | 'InvalidAttestation' 81 | ); 82 | 83 | await expectFailedMultiAttestations( 84 | { 85 | eas 86 | }, 87 | [ 88 | { 89 | schema: schemaId, 90 | requests: [ 91 | { 92 | recipient: await recipient.getAddress(), 93 | expirationTime, 94 | data: '0x02' 95 | }, 96 | { 97 | recipient: await recipient.getAddress(), 98 | expirationTime, 99 | data: DATA1 100 | } 101 | ] 102 | } 103 | ], 104 | { from: sender }, 105 | 'InvalidAttestations' 106 | ); 107 | 108 | await expectFailedMultiAttestations( 109 | { 110 | eas 111 | }, 112 | [ 113 | { 114 | schema: schemaId, 115 | requests: [ 116 | { 117 | recipient: await recipient.getAddress(), 118 | expirationTime, 119 | data: DATA2 120 | }, 121 | { 122 | recipient: await recipient.getAddress(), 123 | expirationTime, 124 | data: '0x02' 125 | } 126 | ] 127 | } 128 | ], 129 | { from: sender }, 130 | 'InvalidAttestations' 131 | ); 132 | }); 133 | 134 | it('should allow attesting with correct data', async () => { 135 | const { uid } = await expectAttestation( 136 | { 137 | eas 138 | }, 139 | schemaId, 140 | { 141 | recipient: await recipient.getAddress(), 142 | expirationTime, 143 | data: DATA1 144 | }, 145 | { 146 | from: sender 147 | } 148 | ); 149 | 150 | await expectRevocation({ eas }, schemaId, { uid }, { from: sender }); 151 | 152 | const { uid: uid2 } = await expectAttestation( 153 | { 154 | eas 155 | }, 156 | schemaId, 157 | { 158 | recipient: await recipient.getAddress(), 159 | expirationTime, 160 | data: DATA2 161 | }, 162 | { 163 | from: sender 164 | } 165 | ); 166 | 167 | await expectRevocation({ eas }, schemaId, { uid: uid2 }, { from: sender }); 168 | 169 | const res = await expectMultiAttestations( 170 | { 171 | eas 172 | }, 173 | [ 174 | { 175 | schema: schemaId, 176 | requests: [ 177 | { 178 | recipient: await recipient.getAddress(), 179 | expirationTime, 180 | data: DATA1 181 | }, 182 | { 183 | recipient: await recipient.getAddress(), 184 | expirationTime, 185 | data: DATA2 186 | } 187 | ] 188 | } 189 | ], 190 | { 191 | from: sender 192 | } 193 | ); 194 | 195 | await expectMultiRevocations( 196 | { eas }, 197 | [ 198 | { 199 | schema: schemaId, 200 | requests: res.uids.map((uid) => ({ uid })) 201 | } 202 | ], 203 | { from: sender } 204 | ); 205 | }); 206 | }); 207 | -------------------------------------------------------------------------------- /test/resolver/ExpirationTimeResolver.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { Signer } from 'ethers'; 3 | import { ethers } from 'hardhat'; 4 | import Contracts from '../../components/Contracts'; 5 | import { SchemaRegistry, TestEAS } from '../../typechain-types'; 6 | import { 7 | expectAttestation, 8 | expectFailedAttestation, 9 | expectFailedMultiAttestations, 10 | expectMultiAttestations, 11 | expectMultiRevocations, 12 | expectRevocation, 13 | registerSchema 14 | } from '../helpers/EAS'; 15 | import { duration, latest } from '../helpers/Time'; 16 | import { createWallet } from '../helpers/Wallet'; 17 | 18 | describe('ExpirationTimeResolver', () => { 19 | let accounts: Signer[]; 20 | let recipient: Signer; 21 | let sender: Signer; 22 | 23 | let registry: SchemaRegistry; 24 | let eas: TestEAS; 25 | 26 | const schema = 'bytes32 eventId,uint8 ticketType,uint32 ticketNum'; 27 | let schemaId: string; 28 | const data = '0x1234'; 29 | let validAfter: bigint; 30 | 31 | before(async () => { 32 | accounts = await ethers.getSigners(); 33 | 34 | [recipient] = accounts; 35 | }); 36 | 37 | beforeEach(async () => { 38 | sender = await createWallet(); 39 | 40 | registry = await Contracts.SchemaRegistry.deploy(); 41 | eas = await Contracts.TestEAS.deploy(await registry.getAddress()); 42 | 43 | await eas.setTime(await latest()); 44 | 45 | validAfter = (await eas.getTime()) + duration.years(1n); 46 | 47 | const resolver = await Contracts.ExpirationTimeResolver.deploy(await eas.getAddress(), validAfter); 48 | expect(await resolver.isPayable()).to.be.false; 49 | 50 | schemaId = await registerSchema(schema, registry, resolver, true); 51 | }); 52 | 53 | it('should revert when attesting with a wrong expiration time', async () => { 54 | await expectFailedAttestation( 55 | { eas }, 56 | schemaId, 57 | { recipient: await recipient.getAddress(), expirationTime: validAfter - duration.days(1n), data }, 58 | { from: sender }, 59 | 'InvalidAttestation' 60 | ); 61 | 62 | await expectFailedMultiAttestations( 63 | { eas }, 64 | [ 65 | { 66 | schema: schemaId, 67 | requests: [ 68 | { recipient: await recipient.getAddress(), expirationTime: validAfter - duration.days(1n), data }, 69 | { recipient: await recipient.getAddress(), expirationTime: validAfter + duration.seconds(1n), data } 70 | ] 71 | } 72 | ], 73 | { from: sender }, 74 | 'InvalidAttestations' 75 | ); 76 | 77 | await expectFailedMultiAttestations( 78 | { eas }, 79 | [ 80 | { 81 | schema: schemaId, 82 | requests: [ 83 | { recipient: await recipient.getAddress(), expirationTime: validAfter + duration.days(1n), data }, 84 | { recipient: await recipient.getAddress(), expirationTime: validAfter - duration.seconds(1n), data } 85 | ] 86 | } 87 | ], 88 | { from: sender }, 89 | 'InvalidAttestations' 90 | ); 91 | }); 92 | 93 | it('should allow attesting with the correct expiration time', async () => { 94 | const { uid } = await expectAttestation( 95 | { eas }, 96 | schemaId, 97 | { recipient: await recipient.getAddress(), expirationTime: validAfter + duration.seconds(1n), data }, 98 | { from: sender } 99 | ); 100 | 101 | await expectRevocation({ eas }, schemaId, { uid }, { from: sender }); 102 | 103 | const res = await expectMultiAttestations( 104 | { eas }, 105 | [ 106 | { 107 | schema: schemaId, 108 | requests: [ 109 | { recipient: await recipient.getAddress(), expirationTime: validAfter + duration.seconds(1n), data }, 110 | { recipient: await recipient.getAddress(), expirationTime: validAfter + duration.weeks(1n), data } 111 | ] 112 | } 113 | ], 114 | { from: sender } 115 | ); 116 | 117 | await expectMultiRevocations( 118 | { eas }, 119 | [ 120 | { 121 | schema: schemaId, 122 | requests: res.uids.map((uid) => ({ uid })) 123 | } 124 | ], 125 | { from: sender } 126 | ); 127 | }); 128 | }); 129 | -------------------------------------------------------------------------------- /test/resolver/RecipientResolver.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { Signer } from 'ethers'; 3 | import { ethers } from 'hardhat'; 4 | import Contracts from '../../components/Contracts'; 5 | import { SchemaRegistry, TestEAS } from '../../typechain-types'; 6 | import { NO_EXPIRATION } from '../../utils/Constants'; 7 | import { 8 | expectAttestation, 9 | expectFailedAttestation, 10 | expectFailedMultiAttestations, 11 | expectMultiAttestations, 12 | expectMultiRevocations, 13 | expectRevocation, 14 | registerSchema 15 | } from '../helpers/EAS'; 16 | import { latest } from '../helpers/Time'; 17 | import { createWallet } from '../helpers/Wallet'; 18 | 19 | describe('RecipientResolver', () => { 20 | let accounts: Signer[]; 21 | let recipient: Signer; 22 | let sender: Signer; 23 | 24 | let registry: SchemaRegistry; 25 | let eas: TestEAS; 26 | 27 | const schema = 'bytes32 eventId,uint8 ticketType,uint32 ticketNum'; 28 | let schemaId: string; 29 | const expirationTime = NO_EXPIRATION; 30 | const data = '0x1234'; 31 | 32 | let targetRecipient: Signer; 33 | 34 | before(async () => { 35 | accounts = await ethers.getSigners(); 36 | 37 | [recipient] = accounts; 38 | }); 39 | 40 | beforeEach(async () => { 41 | sender = await createWallet(); 42 | 43 | registry = await Contracts.SchemaRegistry.deploy(); 44 | eas = await Contracts.TestEAS.deploy(await registry.getAddress()); 45 | 46 | await eas.setTime(await latest()); 47 | 48 | targetRecipient = accounts[5]; 49 | 50 | const resolver = await Contracts.RecipientResolver.deploy( 51 | await eas.getAddress(), 52 | await targetRecipient.getAddress() 53 | ); 54 | expect(await resolver.isPayable()).to.be.false; 55 | 56 | schemaId = await registerSchema(schema, registry, resolver, true); 57 | }); 58 | 59 | it('should revert when attesting to a wrong recipient', async () => { 60 | await expectFailedAttestation( 61 | { eas }, 62 | schemaId, 63 | { recipient: await recipient.getAddress(), expirationTime, data }, 64 | { from: sender }, 65 | 'InvalidAttestation' 66 | ); 67 | 68 | await expectFailedMultiAttestations( 69 | { eas }, 70 | [ 71 | { 72 | schema: schemaId, 73 | requests: [ 74 | { recipient: await recipient.getAddress(), expirationTime, data }, 75 | { recipient: await targetRecipient.getAddress(), expirationTime, data } 76 | ] 77 | } 78 | ], 79 | { from: sender }, 80 | 'InvalidAttestations' 81 | ); 82 | 83 | await expectFailedMultiAttestations( 84 | { eas }, 85 | [ 86 | { 87 | schema: schemaId, 88 | requests: [ 89 | { recipient: await targetRecipient.getAddress(), expirationTime, data }, 90 | { recipient: await recipient.getAddress(), expirationTime, data } 91 | ] 92 | } 93 | ], 94 | { from: sender }, 95 | 'InvalidAttestations' 96 | ); 97 | }); 98 | 99 | it('should allow attesting to the correct recipient', async () => { 100 | const { uid } = await expectAttestation( 101 | { eas }, 102 | schemaId, 103 | { recipient: await targetRecipient.getAddress(), expirationTime, data }, 104 | { from: sender } 105 | ); 106 | 107 | await expectRevocation({ eas }, schemaId, { uid }, { from: sender }); 108 | 109 | const res = await expectMultiAttestations( 110 | { eas }, 111 | [ 112 | { 113 | schema: schemaId, 114 | requests: [ 115 | { recipient: await targetRecipient.getAddress(), expirationTime, data }, 116 | { recipient: await targetRecipient.getAddress(), expirationTime, data } 117 | ] 118 | } 119 | ], 120 | { from: sender } 121 | ); 122 | 123 | await expectMultiRevocations( 124 | { eas }, 125 | [ 126 | { 127 | schema: schemaId, 128 | requests: res.uids.map((uid) => ({ uid })) 129 | } 130 | ], 131 | { from: sender } 132 | ); 133 | }); 134 | }); 135 | -------------------------------------------------------------------------------- /test/resolver/RevocationResolver.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { Signer } from 'ethers'; 3 | import { ethers } from 'hardhat'; 4 | import Contracts from '../../components/Contracts'; 5 | import { RevocationResolver, SchemaRegistry, TestEAS } from '../../typechain-types'; 6 | import { NO_EXPIRATION, ZERO_BYTES32 } from '../../utils/Constants'; 7 | import { getUIDFromAttestTx } from '../../utils/EAS'; 8 | import { 9 | expectFailedMultiRevocations, 10 | expectFailedRevocation, 11 | expectMultiRevocations, 12 | expectRevocation, 13 | registerSchema 14 | } from '../helpers/EAS'; 15 | import { latest } from '../helpers/Time'; 16 | import { createWallet } from '../helpers/Wallet'; 17 | 18 | describe('RevocationResolver', () => { 19 | let accounts: Signer[]; 20 | let recipient: Signer; 21 | let sender: Signer; 22 | 23 | let registry: SchemaRegistry; 24 | let eas: TestEAS; 25 | let resolver: RevocationResolver; 26 | let uid: string; 27 | let uids: string[] = []; 28 | 29 | const schema = 'bytes32 eventId,uint8 ticketType,uint32 ticketNum'; 30 | let schemaId: string; 31 | const data = '0x1234'; 32 | const expirationTime = NO_EXPIRATION; 33 | 34 | before(async () => { 35 | accounts = await ethers.getSigners(); 36 | 37 | [recipient] = accounts; 38 | }); 39 | 40 | beforeEach(async () => { 41 | sender = await createWallet(); 42 | 43 | registry = await Contracts.SchemaRegistry.deploy(); 44 | eas = await Contracts.TestEAS.deploy(await registry.getAddress()); 45 | 46 | await eas.setTime(await latest()); 47 | 48 | resolver = await Contracts.RevocationResolver.deploy(await eas.getAddress()); 49 | expect(await resolver.isPayable()).to.be.false; 50 | 51 | schemaId = await registerSchema(schema, registry, resolver, true); 52 | 53 | uid = await getUIDFromAttestTx( 54 | eas.connect(sender).attest({ 55 | schema: schemaId, 56 | data: { 57 | recipient: await recipient.getAddress(), 58 | expirationTime, 59 | revocable: true, 60 | refUID: ZERO_BYTES32, 61 | data, 62 | value: 0 63 | } 64 | }) 65 | ); 66 | 67 | uids = []; 68 | 69 | for (let i = 0; i < 2; i++) { 70 | uids.push( 71 | await getUIDFromAttestTx( 72 | eas.connect(sender).attest({ 73 | schema: schemaId, 74 | data: { 75 | recipient: await recipient.getAddress(), 76 | expirationTime, 77 | revocable: true, 78 | refUID: ZERO_BYTES32, 79 | data, 80 | value: 0 81 | } 82 | }) 83 | ) 84 | ); 85 | } 86 | }); 87 | 88 | context('when revocations are allowed', () => { 89 | beforeEach(async () => { 90 | await resolver.setRevocation(true); 91 | }); 92 | 93 | it('should allow revoking an existing attestation', async () => { 94 | await expectRevocation({ eas }, schemaId, { uid }, { from: sender }); 95 | 96 | await expectMultiRevocations({ eas }, [{ schema: schemaId, requests: uids.map((uid) => ({ uid })) }], { 97 | from: sender 98 | }); 99 | }); 100 | }); 101 | 102 | context('when revocations are not allowed', () => { 103 | beforeEach(async () => { 104 | await resolver.setRevocation(false); 105 | }); 106 | 107 | it('should revert when attempting to revoke an existing attestation', async () => { 108 | await expectFailedRevocation({ eas }, schemaId, { uid }, { from: sender }, 'InvalidRevocation'); 109 | 110 | await expectFailedMultiRevocations( 111 | { eas }, 112 | [{ schema: schemaId, requests: uids.map((uid) => ({ uid })) }], 113 | { from: sender }, 114 | 'InvalidRevocations' 115 | ); 116 | }); 117 | }); 118 | }); 119 | -------------------------------------------------------------------------------- /test/resolver/TokenResolver.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { Signer } from 'ethers'; 3 | import { ethers } from 'hardhat'; 4 | import Contracts from '../../components/Contracts'; 5 | import { SchemaRegistry, SchemaResolver, TestEAS, TestERC20Token } from '../../typechain-types'; 6 | import { NO_EXPIRATION } from '../../utils/Constants'; 7 | import { 8 | expectAttestation, 9 | expectFailedAttestation, 10 | expectFailedMultiAttestations, 11 | expectMultiAttestations, 12 | expectMultiRevocations, 13 | expectRevocation, 14 | registerSchema 15 | } from '../helpers/EAS'; 16 | import { latest } from '../helpers/Time'; 17 | import { createWallet } from '../helpers/Wallet'; 18 | 19 | describe('TokenResolver', () => { 20 | let accounts: Signer[]; 21 | let recipient: Signer; 22 | let sender: Signer; 23 | 24 | let registry: SchemaRegistry; 25 | let eas: TestEAS; 26 | let resolver: SchemaResolver; 27 | 28 | const targetAmount = 22334; 29 | let token: TestERC20Token; 30 | 31 | const schema = 'bytes32 eventId,uint8 ticketType,uint32 ticketNum'; 32 | let schemaId: string; 33 | const data = '0x1234'; 34 | const expirationTime = NO_EXPIRATION; 35 | 36 | before(async () => { 37 | accounts = await ethers.getSigners(); 38 | 39 | [recipient] = accounts; 40 | }); 41 | 42 | beforeEach(async () => { 43 | sender = await createWallet(); 44 | 45 | registry = await Contracts.SchemaRegistry.deploy(); 46 | eas = await Contracts.TestEAS.deploy(await registry.getAddress()); 47 | 48 | await eas.setTime(await latest()); 49 | 50 | token = await Contracts.TestERC20Token.deploy('TKN', 'TKN', 9999999999); 51 | await token.transfer(await sender.getAddress(), targetAmount * 100); 52 | 53 | resolver = await Contracts.TokenResolver.deploy(await eas.getAddress(), await token.getAddress(), targetAmount); 54 | expect(await resolver.isPayable()).to.be.false; 55 | 56 | schemaId = await registerSchema(schema, registry, resolver, true); 57 | }); 58 | 59 | it('should revert when attesting with the wrong token amount', async () => { 60 | await expectFailedAttestation( 61 | { eas }, 62 | schemaId, 63 | { recipient: await recipient.getAddress(), expirationTime, data }, 64 | { from: sender }, 65 | 'InvalidAllowance', 66 | resolver 67 | ); 68 | 69 | await expectFailedMultiAttestations( 70 | { eas }, 71 | [ 72 | { 73 | schema: schemaId, 74 | requests: [ 75 | { recipient: await recipient.getAddress(), expirationTime, data }, 76 | { recipient: await recipient.getAddress(), expirationTime, data } 77 | ] 78 | } 79 | ], 80 | { from: sender }, 81 | 'InvalidAllowance', 82 | resolver 83 | ); 84 | 85 | await token.connect(sender).approve(await resolver.getAddress(), targetAmount - 1); 86 | await expectFailedAttestation( 87 | { eas }, 88 | schemaId, 89 | { recipient: await recipient.getAddress(), expirationTime, data }, 90 | { from: sender }, 91 | 'InvalidAllowance', 92 | resolver 93 | ); 94 | }); 95 | 96 | it('should allow attesting with the correct token amount', async () => { 97 | await token.connect(sender).approve(await resolver.getAddress(), targetAmount); 98 | 99 | const { uid } = await expectAttestation( 100 | { eas }, 101 | schemaId, 102 | { recipient: await recipient.getAddress(), expirationTime, data }, 103 | { from: sender } 104 | ); 105 | 106 | await expectRevocation({ eas }, schemaId, { uid }, { from: sender }); 107 | 108 | await token.connect(sender).approve(await resolver.getAddress(), targetAmount * 2); 109 | 110 | const res = await expectMultiAttestations( 111 | { eas }, 112 | [ 113 | { 114 | schema: schemaId, 115 | requests: [ 116 | { recipient: await recipient.getAddress(), expirationTime, data }, 117 | { recipient: await recipient.getAddress(), expirationTime, data } 118 | ] 119 | } 120 | ], 121 | { from: sender } 122 | ); 123 | 124 | await expectMultiRevocations( 125 | { eas }, 126 | [ 127 | { 128 | schema: schemaId, 129 | requests: res.uids.map((uid) => ({ uid })) 130 | } 131 | ], 132 | { from: sender } 133 | ); 134 | }); 135 | }); 136 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "lib": ["dom", "esnext"], 5 | "module": "commonjs", 6 | "moduleResolution": "node", 7 | "declaration": true, 8 | "declarationMap": true, 9 | "sourceMap": true, 10 | "strict": true, 11 | "esModuleInterop": true, 12 | "baseUrl": "./", 13 | "paths": { 14 | "@nomiclabs/hardhat-ethers/*": ["node_modules/@nomiclabs/hardhat-ethers/dist/src/*"], 15 | "*": ["node_modules/*"] 16 | }, 17 | "outDir": "./dist/typechain-types" 18 | }, 19 | "include": [ 20 | "./components", 21 | "./data", 22 | "./deployments", 23 | "./hardhat.config.ts", 24 | "./scripts", 25 | "./test", 26 | "./typechain-types", 27 | "./utils" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /tsconfig.release.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "include": ["./typechain-types"] 4 | } 5 | -------------------------------------------------------------------------------- /utils/Constants.ts: -------------------------------------------------------------------------------- 1 | import { ZeroAddress } from 'ethers'; 2 | 3 | export const ZERO_ADDRESS = ZeroAddress; 4 | export const ZERO_BYTES = '0x'; 5 | export const ZERO_BYTES32 = '0x0000000000000000000000000000000000000000000000000000000000000000'; 6 | 7 | export const NO_EXPIRATION = 0n; 8 | -------------------------------------------------------------------------------- /utils/EAS.ts: -------------------------------------------------------------------------------- 1 | import { 2 | hexlify, 3 | Interface, 4 | keccak256, 5 | solidityPackedKeccak256, 6 | toUtf8Bytes, 7 | TransactionReceipt, 8 | TransactionResponse 9 | } from 'ethers'; 10 | import { EAS__factory } from '../typechain-types'; 11 | 12 | enum Event { 13 | Attested = 'Attested', 14 | Timestamped = 'Timestamped', 15 | RevokedOffchain = 'RevokedOffchain' 16 | } 17 | 18 | const TOPICS = { 19 | [Event.Attested]: keccak256(toUtf8Bytes('Attested(address,address,bytes32,bytes32)')), 20 | [Event.Timestamped]: keccak256(toUtf8Bytes('Timestamped(bytes32,uint64)')), 21 | [Event.RevokedOffchain]: keccak256(toUtf8Bytes('RevokedOffchain(address,bytes32,uint64)')) 22 | }; 23 | 24 | export const getSchemaUID = (schema: string, resolverAddress: string, revocable: boolean) => 25 | solidityPackedKeccak256(['string', 'address', 'bool'], [schema, resolverAddress, revocable]); 26 | 27 | export const getUID = ( 28 | schema: string, 29 | recipient: string, 30 | attester: string, 31 | time: number, 32 | expirationTime: number, 33 | revocable: boolean, 34 | refUID: string, 35 | data: string, 36 | bump: number 37 | ) => 38 | solidityPackedKeccak256( 39 | ['bytes', 'address', 'address', 'uint32', 'uint32', 'bool', 'bytes32', 'bytes', 'uint32'], 40 | [hexlify(toUtf8Bytes(schema)), recipient, attester, time, expirationTime, revocable, refUID, data, bump] 41 | ); 42 | 43 | const getDataFromReceipt = (receipt: TransactionReceipt, event: Event, attribute: string): string[] => { 44 | // eslint-disable-next-line camelcase 45 | const eas = new Interface(EAS__factory.abi); 46 | const logs = []; 47 | 48 | for (const log of receipt.logs.filter((l) => l.topics[0] === TOPICS[event]) || []) { 49 | logs.push({ 50 | ...log, 51 | log: event, 52 | fragment: { 53 | name: event 54 | }, 55 | args: eas.decodeEventLog(event, log.data, log.topics) 56 | }); 57 | } 58 | 59 | if (!logs) { 60 | return []; 61 | } 62 | 63 | const filteredLogs = logs.filter((l) => l.fragment?.name === event); 64 | if (filteredLogs.length === 0) { 65 | throw new Error(`Unable to process ${event} events`); 66 | } 67 | 68 | return filteredLogs.map((log: any) => eas.decodeEventLog(event, log.data, log.topics)[attribute]); 69 | }; 70 | 71 | export const getUIDsFromAttestReceipt = (receipt: TransactionReceipt): string[] => 72 | getDataFromReceipt(receipt, Event.Attested, 'uid'); 73 | 74 | export const getTimestampFromTimestampReceipt = (receipt: TransactionReceipt): bigint[] => 75 | getDataFromReceipt(receipt, Event.Timestamped, 'timestamp').map((s) => BigInt(s)); 76 | 77 | export const getTimestampFromOffchainRevocationReceipt = (receipt: TransactionReceipt): bigint[] => 78 | getDataFromReceipt(receipt, Event.RevokedOffchain, 'timestamp').map((s) => BigInt(s)); 79 | 80 | export const getUIDsFromMultiAttestTx = async ( 81 | res: Promise | TransactionResponse 82 | ): Promise => { 83 | const tx = await res; 84 | const receipt = await tx.wait(); 85 | if (!receipt) { 86 | throw new Error(`Unable to confirm: ${tx}`); 87 | } 88 | 89 | return getUIDsFromAttestReceipt(receipt); 90 | }; 91 | 92 | export const getUIDFromAttestTx = async (res: Promise | TransactionResponse): Promise => { 93 | return (await getUIDsFromMultiAttestTx(res))[0]; 94 | }; 95 | 96 | export const getUIDFromMultiDelegatedProxyAttestTx = async ( 97 | res: Promise | TransactionResponse 98 | ): Promise => { 99 | const tx = await res; 100 | const receipt = await tx.wait(); 101 | if (!receipt) { 102 | throw new Error(`Unable to confirm: ${tx}`); 103 | } 104 | 105 | return getUIDFromMultiDelegatedProxyAttestReceipt(receipt); 106 | }; 107 | 108 | export const getUIDFromMultiDelegatedProxyAttestReceipt = async ( 109 | res: Promise | TransactionReceipt 110 | ): Promise => { 111 | const receipt = await res; 112 | if (!receipt) { 113 | throw new Error(`Unable to confirm: ${res}`); 114 | } 115 | 116 | return getUIDsFromAttestReceipt(receipt); 117 | }; 118 | 119 | export const getUIDFromDelegatedProxyAttestTx = async ( 120 | res: Promise | TransactionResponse 121 | ): Promise => { 122 | return (await getUIDFromMultiDelegatedProxyAttestTx(res))[0]; 123 | }; 124 | 125 | export const getUIDFromDelegatedProxyAttestReceipt = async ( 126 | res: Promise | TransactionReceipt 127 | ): Promise => { 128 | return (await getUIDFromMultiDelegatedProxyAttestReceipt(res))[0]; 129 | }; 130 | -------------------------------------------------------------------------------- /utils/Logger.ts: -------------------------------------------------------------------------------- 1 | export default console; 2 | -------------------------------------------------------------------------------- /utils/Time.ts: -------------------------------------------------------------------------------- 1 | const seconds = (val: bigint) => val; 2 | const minutes = (val: bigint) => val * seconds(60n); 3 | const hours = (val: bigint) => val * minutes(60n); 4 | const days = (val: bigint) => val * hours(24n); 5 | const weeks = (val: bigint) => val * days(7n); 6 | const years = (val: bigint) => val * days(365n); 7 | 8 | export const duration = { seconds, minutes, hours, days, weeks, years }; 9 | --------------------------------------------------------------------------------