From 45836c7164ac103fa93c4f810015925a1f8220cb Mon Sep 17 00:00:00 2001 From: JOY <5027251+JOY@users.noreply.github.com> Date: Wed, 12 Aug 2026 14:08:55 +0700 Subject: [PATCH 01/14] feat: add ENSv2 BENS subgraph --- .github/workflows/main.yml | 35 +- subgraph/dos-names/.gitignore | 7 + subgraph/dos-names/abis/DOSRegistrar.json | 795 ++ .../dos-names/abis/PermissionedRegistry.json | 1667 ++++ .../dos-names/abis/PermissionedResolver.json | 1762 ++++ subgraph/dos-names/package-lock.json | 7200 +++++++++++++++++ subgraph/dos-names/package.json | 20 + subgraph/dos-names/schema.graphql | 324 + .../dos-names/scripts/render-manifest.mjs | 91 + subgraph/dos-names/src/registrar.ts | 142 + subgraph/dos-names/src/registry.ts | 403 + subgraph/dos-names/src/resolver.ts | 197 + subgraph/dos-names/src/userRegistry.ts | 324 + subgraph/dos-names/src/utils.ts | 88 + subgraph/dos-names/subgraph.template.yaml | 181 + .../tests/fixtures/dos-testnet-3939.json | 9 + subgraph/dos-names/tests/registrar.test.ts | 185 + subgraph/dos-names/tests/registry.test.ts | 682 ++ .../dos-names/tests/render-manifest.test.mjs | 84 + subgraph/dos-names/tests/resolver.test.ts | 126 + subgraph/dos-names/tsconfig.json | 9 + 21 files changed, 14330 insertions(+), 1 deletion(-) create mode 100644 subgraph/dos-names/.gitignore create mode 100644 subgraph/dos-names/abis/DOSRegistrar.json create mode 100644 subgraph/dos-names/abis/PermissionedRegistry.json create mode 100644 subgraph/dos-names/abis/PermissionedResolver.json create mode 100644 subgraph/dos-names/package-lock.json create mode 100644 subgraph/dos-names/package.json create mode 100644 subgraph/dos-names/schema.graphql create mode 100644 subgraph/dos-names/scripts/render-manifest.mjs create mode 100644 subgraph/dos-names/src/registrar.ts create mode 100644 subgraph/dos-names/src/registry.ts create mode 100644 subgraph/dos-names/src/resolver.ts create mode 100644 subgraph/dos-names/src/userRegistry.ts create mode 100644 subgraph/dos-names/src/utils.ts create mode 100644 subgraph/dos-names/subgraph.template.yaml create mode 100644 subgraph/dos-names/tests/fixtures/dos-testnet-3939.json create mode 100644 subgraph/dos-names/tests/registrar.test.ts create mode 100644 subgraph/dos-names/tests/registry.test.ts create mode 100644 subgraph/dos-names/tests/render-manifest.test.mjs create mode 100644 subgraph/dos-names/tests/resolver.test.ts create mode 100644 subgraph/dos-names/tsconfig.json diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6c0c1ae0d..e8edce014 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -113,10 +113,43 @@ jobs: - name: Format run: bun --filter contracts format:check + subgraph-tests: + name: DOS Names Subgraph + runs-on: ubuntu-latest + defaults: + run: + working-directory: subgraph/dos-names + steps: + - uses: actions/checkout@v5 + + - uses: actions/setup-node@v4 + with: + node-version: 24 + cache: npm + cache-dependency-path: subgraph/dos-names/package-lock.json + + - name: Install dependencies + run: npm ci + + - name: Test manifest rendering + run: npm run test:render + + - name: Render test manifest + run: npm run render:test + + - name: Generate subgraph types + run: npm run codegen + + - name: Test mappings + run: npm test + + - name: Build subgraph + run: npm run build + publish-docker: name: Publish Docker Image if: github.ref == 'refs/heads/main' || (github.event_name == 'workflow_dispatch' && github.ref_type == 'branch') - needs: [check-types, e2e-tests, forge-tests, hardhat-tests, lint] + needs: [check-types, e2e-tests, forge-tests, hardhat-tests, lint, subgraph-tests] runs-on: ubuntu-latest permissions: contents: read diff --git a/subgraph/dos-names/.gitignore b/subgraph/dos-names/.gitignore new file mode 100644 index 000000000..3ac120f6b --- /dev/null +++ b/subgraph/dos-names/.gitignore @@ -0,0 +1,7 @@ +build/ +node_modules/ +src/types/ +subgraph.yaml +tests/.latest.json +tests/.bin/ +tests/.docker/ diff --git a/subgraph/dos-names/abis/DOSRegistrar.json b/subgraph/dos-names/abis/DOSRegistrar.json new file mode 100644 index 000000000..d55f9b6fc --- /dev/null +++ b/subgraph/dos-names/abis/DOSRegistrar.json @@ -0,0 +1,795 @@ +[ + { + "type": "constructor", + "inputs": [ + { + "name": "owner_", + "type": "address", + "internalType": "address" + }, + { + "name": "dosRegistry", + "type": "address", + "internalType": "contract IPermissionedRegistry" + }, + { + "name": "beneficiary", + "type": "address", + "internalType": "address" + }, + { + "name": "oracle", + "type": "address", + "internalType": "contract IRentPriceOracle" + }, + { + "name": "gracePeriod", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "minCommitmentAge", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "maxCommitmentAge", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "minRegisterDuration", + "type": "uint64", + "internalType": "uint64" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "BENEFICIARY", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "ETH_REGISTRY", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract IPermissionedRegistry" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "GRACE_PERIOD", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint64", + "internalType": "uint64" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MAX_COMMITMENT_AGE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint64", + "internalType": "uint64" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MIN_COMMITMENT_AGE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint64", + "internalType": "uint64" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MIN_REGISTER_DURATION", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint64", + "internalType": "uint64" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MIN_RENEW_DURATION", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint64", + "internalType": "uint64" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "commit", + "inputs": [ + { + "name": "commitment", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "commitmentAt", + "inputs": [ + { + "name": "commitment", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "commitTime", + "type": "uint64", + "internalType": "uint64" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRegisterPrice", + "inputs": [ + { + "name": "label", + "type": "string", + "internalType": "string" + }, + { + "name": "duration", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "paymentToken", + "type": "address", + "internalType": "contract IERC20" + } + ], + "outputs": [ + { + "name": "base", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "premium", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRemainingGracePeriod", + "inputs": [ + { + "name": "label", + "type": "string", + "internalType": "string" + } + ], + "outputs": [ + { + "name": "", + "type": "uint64", + "internalType": "uint64" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRenewPrice", + "inputs": [ + { + "name": "label", + "type": "string", + "internalType": "string" + }, + { + "name": "duration", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "paymentToken", + "type": "address", + "internalType": "contract IERC20" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "isAvailable", + "inputs": [ + { + "name": "label", + "type": "string", + "internalType": "string" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "isRenewable", + "inputs": [ + { + "name": "label", + "type": "string", + "internalType": "string" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "makeCommitment", + "inputs": [ + { + "name": "label", + "type": "string", + "internalType": "string" + }, + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "secret", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "subregistry", + "type": "address", + "internalType": "contract IRegistry" + }, + { + "name": "resolver", + "type": "address", + "internalType": "address" + }, + { + "name": "duration", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "referrer", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "owner", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "register", + "inputs": [ + { + "name": "label", + "type": "string", + "internalType": "string" + }, + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "secret", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "subregistry", + "type": "address", + "internalType": "contract IRegistry" + }, + { + "name": "resolver", + "type": "address", + "internalType": "address" + }, + { + "name": "duration", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "paymentToken", + "type": "address", + "internalType": "contract IERC20" + }, + { + "name": "referrer", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "renew", + "inputs": [ + { + "name": "label", + "type": "string", + "internalType": "string" + }, + { + "name": "duration", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "paymentToken", + "type": "address", + "internalType": "contract IERC20" + }, + { + "name": "referrer", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "renounceOwnership", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "rentPriceOracle", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract IRentPriceOracle" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "setRentPriceOracle", + "inputs": [ + { + "name": "oracle", + "type": "address", + "internalType": "contract IRentPriceOracle" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "supportsInterface", + "inputs": [ + { + "name": "interfaceId", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "transferOwnership", + "inputs": [ + { + "name": "newOwner", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "CommitmentMade", + "inputs": [ + { + "name": "commitment", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "NameRegistered", + "inputs": [ + { + "name": "tokenId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "label", + "type": "string", + "indexed": false, + "internalType": "string" + }, + { + "name": "owner", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "subregistry", + "type": "address", + "indexed": false, + "internalType": "contract IRegistry" + }, + { + "name": "resolver", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "duration", + "type": "uint64", + "indexed": false, + "internalType": "uint64" + }, + { + "name": "paymentToken", + "type": "address", + "indexed": false, + "internalType": "contract IERC20" + }, + { + "name": "referrer", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "base", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "premium", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "NameRenewed", + "inputs": [ + { + "name": "tokenId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "label", + "type": "string", + "indexed": false, + "internalType": "string" + }, + { + "name": "duration", + "type": "uint64", + "indexed": false, + "internalType": "uint64" + }, + { + "name": "newExpiry", + "type": "uint64", + "indexed": false, + "internalType": "uint64" + }, + { + "name": "paymentToken", + "type": "address", + "indexed": false, + "internalType": "contract IERC20" + }, + { + "name": "referrer", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OwnershipTransferred", + "inputs": [ + { + "name": "previousOwner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newOwner", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RentPriceOracleUpdated", + "inputs": [ + { + "name": "oracle", + "type": "address", + "indexed": false, + "internalType": "contract IRentPriceOracle" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "CommitmentTooNew", + "inputs": [ + { + "name": "commitment", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "validFrom", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "blockTimestamp", + "type": "uint64", + "internalType": "uint64" + } + ] + }, + { + "type": "error", + "name": "CommitmentTooOld", + "inputs": [ + { + "name": "commitment", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "validTo", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "blockTimestamp", + "type": "uint64", + "internalType": "uint64" + } + ] + }, + { + "type": "error", + "name": "DurationTooShort", + "inputs": [ + { + "name": "duration", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "minDuration", + "type": "uint64", + "internalType": "uint64" + } + ] + }, + { + "type": "error", + "name": "InvalidOwner", + "inputs": [] + }, + { + "type": "error", + "name": "MaxCommitmentAgeTooLow", + "inputs": [] + }, + { + "type": "error", + "name": "NameNotAvailable", + "inputs": [ + { + "name": "label", + "type": "string", + "internalType": "string" + } + ] + }, + { + "type": "error", + "name": "NameNotRenewable", + "inputs": [ + { + "name": "label", + "type": "string", + "internalType": "string" + } + ] + }, + { + "type": "error", + "name": "OwnableInvalidOwner", + "inputs": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "OwnableUnauthorizedAccount", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "SafeERC20FailedOperation", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "UnexpiredCommitmentExists", + "inputs": [ + { + "name": "commitment", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } +] diff --git a/subgraph/dos-names/abis/PermissionedRegistry.json b/subgraph/dos-names/abis/PermissionedRegistry.json new file mode 100644 index 000000000..2d64cba1e --- /dev/null +++ b/subgraph/dos-names/abis/PermissionedRegistry.json @@ -0,0 +1,1667 @@ +[ + { + "type": "constructor", + "inputs": [ + { + "name": "labelStore", + "type": "address", + "internalType": "contract ILabelStore" + }, + { + "name": "rootAccount", + "type": "address", + "internalType": "address" + }, + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "LABEL_STORE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract ILabelStore" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "ROOT_RESOURCE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "balanceOf", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + }, + { + "name": "id", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "balanceOfBatch", + "inputs": [ + { + "name": "accounts", + "type": "address[]", + "internalType": "address[]" + }, + { + "name": "ids", + "type": "uint256[]", + "internalType": "uint256[]" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256[]", + "internalType": "uint256[]" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "findExpiry", + "inputs": [ + { + "name": "label", + "type": "string", + "internalType": "string" + } + ], + "outputs": [ + { + "name": "", + "type": "uint64", + "internalType": "uint64" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "findOwner", + "inputs": [ + { + "name": "label", + "type": "string", + "internalType": "string" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "findTokenId", + "inputs": [ + { + "name": "label", + "type": "string", + "internalType": "string" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getAssigneeCount", + "inputs": [ + { + "name": "anyId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "counts", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "mask", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getExpiry", + "inputs": [ + { + "name": "anyId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint64", + "internalType": "uint64" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getOwner", + "inputs": [ + { + "name": "anyId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getParent", + "inputs": [], + "outputs": [ + { + "name": "parent", + "type": "address", + "internalType": "contract IRegistry" + }, + { + "name": "label", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getResolver", + "inputs": [ + { + "name": "label", + "type": "string", + "internalType": "string" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getResource", + "inputs": [ + { + "name": "anyId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getState", + "inputs": [ + { + "name": "anyId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "state", + "type": "tuple", + "internalType": "struct IPermissionedRegistry.State", + "components": [ + { + "name": "status", + "type": "uint8", + "internalType": "enum IPermissionedRegistry.Status" + }, + { + "name": "expiry", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "latestOwner", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "resource", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getStatus", + "inputs": [ + { + "name": "anyId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint8", + "internalType": "enum IPermissionedRegistry.Status" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getSubregistry", + "inputs": [ + { + "name": "label", + "type": "string", + "internalType": "string" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract IRegistry" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getTokenId", + "inputs": [ + { + "name": "anyId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "grantRoles", + "inputs": [ + { + "name": "anyId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "grantRootRoles", + "inputs": [ + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "hasAssignees", + "inputs": [ + { + "name": "anyId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "hasRoles", + "inputs": [ + { + "name": "anyId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "hasRootRoles", + "inputs": [ + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "isApprovedForAll", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + }, + { + "name": "operator", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "isContractNamer", + "inputs": [ + { + "name": "namer", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "latestOwnerOf", + "inputs": [ + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "ownerOf", + "inputs": [ + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "register", + "inputs": [ + { + "name": "label", + "type": "string", + "internalType": "string" + }, + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "registry", + "type": "address", + "internalType": "contract IRegistry" + }, + { + "name": "resolver", + "type": "address", + "internalType": "address" + }, + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "expiry", + "type": "uint64", + "internalType": "uint64" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "renew", + "inputs": [ + { + "name": "anyId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "newExpiry", + "type": "uint64", + "internalType": "uint64" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "revokeRoles", + "inputs": [ + { + "name": "anyId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "revokeRootRoles", + "inputs": [ + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "roleCount", + "inputs": [ + { + "name": "anyId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "roles", + "inputs": [ + { + "name": "anyId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "safeBatchTransferFrom", + "inputs": [ + { + "name": "from", + "type": "address", + "internalType": "address" + }, + { + "name": "to", + "type": "address", + "internalType": "address" + }, + { + "name": "ids", + "type": "uint256[]", + "internalType": "uint256[]" + }, + { + "name": "values", + "type": "uint256[]", + "internalType": "uint256[]" + }, + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "safeTransferFrom", + "inputs": [ + { + "name": "from", + "type": "address", + "internalType": "address" + }, + { + "name": "to", + "type": "address", + "internalType": "address" + }, + { + "name": "id", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setApprovalForAll", + "inputs": [ + { + "name": "operator", + "type": "address", + "internalType": "address" + }, + { + "name": "approved", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setParent", + "inputs": [ + { + "name": "parent", + "type": "address", + "internalType": "contract IRegistry" + }, + { + "name": "label", + "type": "string", + "internalType": "string" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setResolver", + "inputs": [ + { + "name": "anyId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "resolver", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setSubregistry", + "inputs": [ + { + "name": "anyId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "registry", + "type": "address", + "internalType": "contract IRegistry" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setURI", + "inputs": [ + { + "name": "uri_", + "type": "string", + "internalType": "string" + }, + { + "name": "renderer", + "type": "address", + "internalType": "contract IRegistryURIRenderer" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "supportsInterface", + "inputs": [ + { + "name": "interfaceId", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "unregister", + "inputs": [ + { + "name": "anyId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "uri", + "inputs": [ + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "view" + }, + { + "type": "event", + "name": "ApprovalForAll", + "inputs": [ + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "operator", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "approved", + "type": "bool", + "indexed": false, + "internalType": "bool" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "EACRolesChanged", + "inputs": [ + { + "name": "resource", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "oldRoleBitmap", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "newRoleBitmap", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ExpiryUpdated", + "inputs": [ + { + "name": "tokenId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "newExpiry", + "type": "uint64", + "indexed": true, + "internalType": "uint64" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "LabelRegistered", + "inputs": [ + { + "name": "tokenId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "labelHash", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "label", + "type": "string", + "indexed": false, + "internalType": "string" + }, + { + "name": "owner", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "expiry", + "type": "uint64", + "indexed": false, + "internalType": "uint64" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "LabelReserved", + "inputs": [ + { + "name": "tokenId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "labelHash", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "label", + "type": "string", + "indexed": false, + "internalType": "string" + }, + { + "name": "expiry", + "type": "uint64", + "indexed": false, + "internalType": "uint64" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "LabelUnregistered", + "inputs": [ + { + "name": "tokenId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ParentUpdated", + "inputs": [ + { + "name": "parent", + "type": "address", + "indexed": true, + "internalType": "contract IRegistry" + }, + { + "name": "label", + "type": "string", + "indexed": false, + "internalType": "string" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RegistryCreated", + "inputs": [], + "anonymous": false + }, + { + "type": "event", + "name": "ResolverUpdated", + "inputs": [ + { + "name": "tokenId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "resolver", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "SubregistryUpdated", + "inputs": [ + { + "name": "tokenId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "subregistry", + "type": "address", + "indexed": true, + "internalType": "contract IRegistry" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "TokenRegenerated", + "inputs": [ + { + "name": "oldTokenId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "newTokenId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "TokenResource", + "inputs": [ + { + "name": "tokenId", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "resource", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "TransferBatch", + "inputs": [ + { + "name": "operator", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "from", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "to", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "ids", + "type": "uint256[]", + "indexed": false, + "internalType": "uint256[]" + }, + { + "name": "values", + "type": "uint256[]", + "indexed": false, + "internalType": "uint256[]" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "TransferSingle", + "inputs": [ + { + "name": "operator", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "from", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "to", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "id", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "value", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "URI", + "inputs": [ + { + "name": "value", + "type": "string", + "indexed": false, + "internalType": "string" + }, + { + "name": "id", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "URIUpdated", + "inputs": [ + { + "name": "uri", + "type": "string", + "indexed": false, + "internalType": "string" + }, + { + "name": "renderer", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "CannotReduceExpiry", + "inputs": [ + { + "name": "oldExpiry", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "newExpiry", + "type": "uint64", + "internalType": "uint64" + } + ] + }, + { + "type": "error", + "name": "CannotSetPastExpiry", + "inputs": [ + { + "name": "expiry", + "type": "uint64", + "internalType": "uint64" + } + ] + }, + { + "type": "error", + "name": "EACCannotGrantRoles", + "inputs": [ + { + "name": "resource", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "EACCannotRevokeRoles", + "inputs": [ + { + "name": "resource", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "EACInvalidAccount", + "inputs": [] + }, + { + "type": "error", + "name": "EACInvalidRoleBitmap", + "inputs": [ + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "EACMaxAssignees", + "inputs": [ + { + "name": "resource", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "role", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "EACMinAssignees", + "inputs": [ + { + "name": "resource", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "role", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "EACRootResourceNotAllowed", + "inputs": [] + }, + { + "type": "error", + "name": "EACUnauthorizedAccountRoles", + "inputs": [ + { + "name": "resource", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC1155InsufficientBalance", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "balance", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "needed", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "ERC1155InvalidApprover", + "inputs": [ + { + "name": "approver", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC1155InvalidArrayLength", + "inputs": [ + { + "name": "idsLength", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "valuesLength", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "ERC1155InvalidOperator", + "inputs": [ + { + "name": "operator", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC1155InvalidReceiver", + "inputs": [ + { + "name": "receiver", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC1155InvalidSender", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC1155MissingApprovalForAll", + "inputs": [ + { + "name": "operator", + "type": "address", + "internalType": "address" + }, + { + "name": "owner", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "LabelAlreadyRegistered", + "inputs": [ + { + "name": "label", + "type": "string", + "internalType": "string" + } + ] + }, + { + "type": "error", + "name": "LabelAlreadyReserved", + "inputs": [ + { + "name": "label", + "type": "string", + "internalType": "string" + } + ] + }, + { + "type": "error", + "name": "LabelExpired", + "inputs": [ + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "TransferDisallowed", + "inputs": [ + { + "name": "tokenId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "from", + "type": "address", + "internalType": "address" + } + ] + } +] diff --git a/subgraph/dos-names/abis/PermissionedResolver.json b/subgraph/dos-names/abis/PermissionedResolver.json new file mode 100644 index 000000000..3098b3e5e --- /dev/null +++ b/subgraph/dos-names/abis/PermissionedResolver.json @@ -0,0 +1,1762 @@ +[ + { + "type": "constructor", + "inputs": [ + { + "name": "namer", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "ABI", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "contentTypes", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "contentType", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "value", + "type": "bytes", + "internalType": "bytes" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "ROOT_RESOURCE", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "UPGRADE_INTERFACE_VERSION", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "addr", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address payable" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "addr", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "coinType", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "addressBytes", + "type": "bytes", + "internalType": "bytes" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "authorizeAddrRoles", + "inputs": [ + { + "name": "toName", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "coinType", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + }, + { + "name": "grant", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [ + { + "name": "updated", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "authorizeDataRoles", + "inputs": [ + { + "name": "toName", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "key", + "type": "string", + "internalType": "string" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + }, + { + "name": "grant", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "authorizeNameRoles", + "inputs": [ + { + "name": "toName", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + }, + { + "name": "grant", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "authorizeTextRoles", + "inputs": [ + { + "name": "toName", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "key", + "type": "string", + "internalType": "string" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + }, + { + "name": "grant", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "canUpgradeFrom", + "inputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "allowed", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "clearRecords", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "contenthash", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes", + "internalType": "bytes" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "data", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "key", + "type": "string", + "internalType": "string" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes", + "internalType": "bytes" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getAlias", + "inputs": [ + { + "name": "fromName", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "toName", + "type": "bytes", + "internalType": "bytes" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getAssigneeCount", + "inputs": [ + { + "name": "resource", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "counts", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "mask", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "grantRoles", + "inputs": [ + { + "name": "resource", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "grantRootRoles", + "inputs": [ + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "hasAddr", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "coinType", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "hasAssignees", + "inputs": [ + { + "name": "resource", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "hasRoles", + "inputs": [ + { + "name": "resource", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "hasRootRoles", + "inputs": [ + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "initialize", + "inputs": [ + { + "name": "admin", + "type": "address", + "internalType": "address" + }, + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "setters", + "type": "bytes[]", + "internalType": "bytes[]" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "interfaceImplementer", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "interfaceId", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "outputs": [ + { + "name": "implementer", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "isContractNamer", + "inputs": [ + { + "name": "namer", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "multicall", + "inputs": [ + { + "name": "calls", + "type": "bytes[]", + "internalType": "bytes[]" + } + ], + "outputs": [ + { + "name": "results", + "type": "bytes[]", + "internalType": "bytes[]" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "multicallWithNodeCheck", + "inputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "calls", + "type": "bytes[]", + "internalType": "bytes[]" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes[]", + "internalType": "bytes[]" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "name", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "proxiableUUID", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "pubkey", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "x", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "y", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "recordVersions", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "uint64", + "internalType": "uint64" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "resolve", + "inputs": [ + { + "name": "fromName", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "fromData", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes", + "internalType": "bytes" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "revokeRoles", + "inputs": [ + { + "name": "resource", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "revokeRootRoles", + "inputs": [ + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "roleCount", + "inputs": [ + { + "name": "resource", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "roles", + "inputs": [ + { + "name": "resource", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "setABI", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "contentType", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "value", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setAddr", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "coinType", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "addressBytes", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setAddr", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "addr_", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setAlias", + "inputs": [ + { + "name": "fromName", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "toName", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setContenthash", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "hash", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setData", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "key", + "type": "string", + "internalType": "string" + }, + { + "name": "value", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setInterface", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "interfaceId", + "type": "bytes4", + "internalType": "bytes4" + }, + { + "name": "implementer", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setName", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "primary", + "type": "string", + "internalType": "string" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setPubkey", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "x", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "y", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setText", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "key", + "type": "string", + "internalType": "string" + }, + { + "name": "value", + "type": "string", + "internalType": "string" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "supportsFeature", + "inputs": [ + { + "name": "feature", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "supportsInterface", + "inputs": [ + { + "name": "interfaceId", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "text", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "key", + "type": "string", + "internalType": "string" + } + ], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "upgradeToAndCall", + "inputs": [ + { + "name": "newImplementation", + "type": "address", + "internalType": "address" + }, + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "event", + "name": "ABIChanged", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "contentType", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "AddrChanged", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "a", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "AddressChanged", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "coinType", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "newAddress", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "AliasChanged", + "inputs": [ + { + "name": "indexedFromName", + "type": "bytes", + "indexed": true, + "internalType": "bytes" + }, + { + "name": "indexedToName", + "type": "bytes", + "indexed": true, + "internalType": "bytes" + }, + { + "name": "fromName", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + }, + { + "name": "toName", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ContenthashChanged", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "hash", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "DataChanged", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "indexedKey", + "type": "string", + "indexed": true, + "internalType": "string" + }, + { + "name": "key", + "type": "string", + "indexed": false, + "internalType": "string" + }, + { + "name": "indexedData", + "type": "bytes", + "indexed": true, + "internalType": "bytes" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "EACRolesChanged", + "inputs": [ + { + "name": "resource", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "oldRoleBitmap", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "newRoleBitmap", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Initialized", + "inputs": [ + { + "name": "version", + "type": "uint64", + "indexed": false, + "internalType": "uint64" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "InterfaceChanged", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "interfaceID", + "type": "bytes4", + "indexed": true, + "internalType": "bytes4" + }, + { + "name": "implementer", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "NameChanged", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "name", + "type": "string", + "indexed": false, + "internalType": "string" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "NamedAddrResource", + "inputs": [ + { + "name": "resource", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "name", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + }, + { + "name": "coinType", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "NamedDataResource", + "inputs": [ + { + "name": "resource", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "name", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + }, + { + "name": "keyHash", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "key", + "type": "string", + "indexed": false, + "internalType": "string" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "NamedResource", + "inputs": [ + { + "name": "resource", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "name", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "NamedTextResource", + "inputs": [ + { + "name": "resource", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "name", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + }, + { + "name": "keyHash", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "key", + "type": "string", + "indexed": false, + "internalType": "string" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "PubkeyChanged", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "x", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "y", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "TextChanged", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "indexedKey", + "type": "string", + "indexed": true, + "internalType": "string" + }, + { + "name": "key", + "type": "string", + "indexed": false, + "internalType": "string" + }, + { + "name": "value", + "type": "string", + "indexed": false, + "internalType": "string" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Upgraded", + "inputs": [ + { + "name": "implementation", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "VersionChanged", + "inputs": [ + { + "name": "node", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "newVersion", + "type": "uint64", + "indexed": false, + "internalType": "uint64" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AddressEmptyCode", + "inputs": [ + { + "name": "target", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "DNSDecodingFailed", + "inputs": [ + { + "name": "dns", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "type": "error", + "name": "EACCannotGrantRoles", + "inputs": [ + { + "name": "resource", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "EACCannotRevokeRoles", + "inputs": [ + { + "name": "resource", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "EACInvalidAccount", + "inputs": [] + }, + { + "type": "error", + "name": "EACInvalidRoleBitmap", + "inputs": [ + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "EACMaxAssignees", + "inputs": [ + { + "name": "resource", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "role", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "EACMinAssignees", + "inputs": [ + { + "name": "resource", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "role", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "EACRootResourceNotAllowed", + "inputs": [] + }, + { + "type": "error", + "name": "EACUnauthorizedAccountRoles", + "inputs": [ + { + "name": "resource", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "roleBitmap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC1967InvalidImplementation", + "inputs": [ + { + "name": "implementation", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC1967NonPayable", + "inputs": [] + }, + { + "type": "error", + "name": "FailedCall", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidContentType", + "inputs": [ + { + "name": "contentType", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "InvalidEVMAddress", + "inputs": [ + { + "name": "addressBytes", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "type": "error", + "name": "InvalidInitialization", + "inputs": [] + }, + { + "type": "error", + "name": "NotInitializing", + "inputs": [] + }, + { + "type": "error", + "name": "UUPSUnauthorizedCallContext", + "inputs": [] + }, + { + "type": "error", + "name": "UUPSUnsupportedProxiableUUID", + "inputs": [ + { + "name": "slot", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "UnsupportedResolverProfile", + "inputs": [ + { + "name": "selector", + "type": "bytes4", + "internalType": "bytes4" + } + ] + } +] diff --git a/subgraph/dos-names/package-lock.json b/subgraph/dos-names/package-lock.json new file mode 100644 index 000000000..8f68f3a84 --- /dev/null +++ b/subgraph/dos-names/package-lock.json @@ -0,0 +1,7200 @@ +{ + "name": "@dos/names-bens-subgraph", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@dos/names-bens-subgraph", + "version": "0.1.0", + "devDependencies": { + "@graphprotocol/graph-cli": "0.51.2", + "@graphprotocol/graph-ts": "0.31.0", + "assemblyscript": "0.19.23", + "matchstick-as": "0.5.2" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@ethersproject/abi": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", + "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.0.4", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/hash": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/strings": "^5.0.4" + } + }, + "node_modules/@ethersproject/abstract-provider": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.8.0.tgz", + "integrity": "sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/networks": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/web": "^5.8.0" + } + }, + "node_modules/@ethersproject/abstract-signer": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.8.0.tgz", + "integrity": "sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0" + } + }, + "node_modules/@ethersproject/address": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.8.0.tgz", + "integrity": "sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/rlp": "^5.8.0" + } + }, + "node_modules/@ethersproject/base64": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.8.0.tgz", + "integrity": "sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0" + } + }, + "node_modules/@ethersproject/bignumber": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.8.0.tgz", + "integrity": "sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/@ethersproject/bytes": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz", + "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/constants": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.8.0.tgz", + "integrity": "sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0" + } + }, + "node_modules/@ethersproject/hash": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.8.0.tgz", + "integrity": "sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/@ethersproject/keccak256": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.8.0.tgz", + "integrity": "sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz", + "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/@ethersproject/networks": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.8.0.tgz", + "integrity": "sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/properties": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz", + "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/rlp": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.8.0.tgz", + "integrity": "sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/signing-key": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz", + "integrity": "sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "bn.js": "^5.2.1", + "elliptic": "6.6.1", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/strings": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.8.0.tgz", + "integrity": "sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/transactions": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", + "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/rlp": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0" + } + }, + "node_modules/@ethersproject/web": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.8.0.tgz", + "integrity": "sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/@float-capital/float-subgraph-uncrashable": { + "version": "0.0.0-internal-testing.5", + "resolved": "https://registry.npmjs.org/@float-capital/float-subgraph-uncrashable/-/float-subgraph-uncrashable-0.0.0-internal-testing.5.tgz", + "integrity": "sha512-yZ0H5e3EpAYKokX/AbtplzlvSxEJY7ZfpvQyDzyODkks0hakAAlDG6fQu1SlDJMWorY7bbq1j7fCiFeTWci6TA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rescript/std": "9.0.0", + "graphql": "^16.6.0", + "graphql-import-node": "^0.0.5", + "js-yaml": "^4.1.0" + }, + "bin": { + "uncrashable": "bin/uncrashable" + } + }, + "node_modules/@float-capital/float-subgraph-uncrashable/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/@float-capital/float-subgraph-uncrashable/node_modules/graphql": { + "version": "16.14.2", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.14.2.tgz", + "integrity": "sha512-Chq1s4CY7jmh8gO2qvLIJyfCDIN+EHLFW/9iShnp1z8FjBQMoodWP1kDC36VAMXXIvAjj4ARa7ntfAV2BrjsbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, + "node_modules/@float-capital/float-subgraph-uncrashable/node_modules/js-yaml": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", + "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@graphprotocol/graph-cli": { + "version": "0.51.2", + "resolved": "https://registry.npmjs.org/@graphprotocol/graph-cli/-/graph-cli-0.51.2.tgz", + "integrity": "sha512-C+h6HLeYhsNFpV3TmVz1j6MMYA0K81+iInysFdnqX2J1ZwH7ldiHZyJuNq4ajxZlXhBL7+UV9zx7id6OSaj6GA==", + "dev": true, + "license": "(Apache-2.0 OR MIT)", + "dependencies": { + "@float-capital/float-subgraph-uncrashable": "^0.0.0-alpha.4", + "@oclif/core": "2.8.6", + "@whatwg-node/fetch": "^0.8.4", + "assemblyscript": "0.19.23", + "binary-install-raw": "0.0.13", + "chalk": "3.0.0", + "chokidar": "3.5.3", + "debug": "4.3.4", + "docker-compose": "0.23.19", + "dockerode": "2.5.8", + "fs-extra": "9.1.0", + "glob": "9.3.5", + "gluegun": "5.1.2", + "graphql": "15.5.0", + "immutable": "4.2.1", + "ipfs-http-client": "55.0.0", + "jayson": "4.0.0", + "js-yaml": "3.14.1", + "prettier": "1.19.1", + "request": "2.88.2", + "semver": "7.4.0", + "sync-request": "6.1.0", + "tmp-promise": "3.0.3", + "web3-eth-abi": "1.7.0", + "which": "2.0.2", + "yaml": "1.10.2" + }, + "bin": { + "graph": "bin/run" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@graphprotocol/graph-ts": { + "version": "0.31.0", + "resolved": "https://registry.npmjs.org/@graphprotocol/graph-ts/-/graph-ts-0.31.0.tgz", + "integrity": "sha512-xreRVM6ho2BtolyOh2flDkNoGZximybnzUnF53zJVp0+Ed0KnAlO1/KOCUYw06euVI9tk0c9nA2Z/D5SIQV2Rg==", + "dev": true, + "dependencies": { + "assemblyscript": "0.19.10" + } + }, + "node_modules/@graphprotocol/graph-ts/node_modules/assemblyscript": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.19.10.tgz", + "integrity": "sha512-HavcUBXB3mBTRGJcpvaQjmnmaqKHBGREjSPNsIvnAk2f9dj78y4BkMaSSdvBQYWcDDzsHQjyUC8stICFkD1Odg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "binaryen": "101.0.0-nightly.20210723", + "long": "^4.0.0" + }, + "bin": { + "asc": "bin/asc", + "asinit": "bin/asinit" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/assemblyscript" + } + }, + "node_modules/@graphprotocol/graph-ts/node_modules/binaryen": { + "version": "101.0.0-nightly.20210723", + "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-101.0.0-nightly.20210723.tgz", + "integrity": "sha512-eioJNqhHlkguVSbblHOtLqlhtC882SOEPKmNFZaDuz1hzQjolxZ+eu3/kaS10n3sGPONsIZsO7R9fR00UyhEUA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "wasm-opt": "bin/wasm-opt" + } + }, + "node_modules/@graphprotocol/graph-ts/node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@ipld/dag-cbor": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@ipld/dag-cbor/-/dag-cbor-7.0.3.tgz", + "integrity": "sha512-1VVh2huHsuohdXC1bGJNE8WR72slZ9XE2T3wbBBq31dm7ZBatmKLLxrB+XAqafxfRFjv08RZmj/W/ZqaM13AuA==", + "dev": true, + "license": "(Apache-2.0 AND MIT)", + "dependencies": { + "cborg": "^1.6.0", + "multiformats": "^9.5.4" + } + }, + "node_modules/@ipld/dag-json": { + "version": "8.0.11", + "resolved": "https://registry.npmjs.org/@ipld/dag-json/-/dag-json-8.0.11.tgz", + "integrity": "sha512-Pea7JXeYHTWXRTIhBqBlhw7G53PJ7yta3G/sizGEZyzdeEwhZRr0od5IQ0r2ZxOt1Do+2czddjeEPp+YTxDwCA==", + "dev": true, + "license": "(Apache-2.0 AND MIT)", + "dependencies": { + "cborg": "^1.5.4", + "multiformats": "^9.5.4" + } + }, + "node_modules/@ipld/dag-pb": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/@ipld/dag-pb/-/dag-pb-2.1.18.tgz", + "integrity": "sha512-ZBnf2fuX9y3KccADURG5vb9FaOeMjFkCrNysB0PtftME/4iCTjxfaLoNq/IAh5fTqUOMXvryN6Jyka4ZGuMLIg==", + "dev": true, + "license": "(Apache-2.0 AND MIT)", + "dependencies": { + "multiformats": "^9.5.4" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@oclif/core": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/@oclif/core/-/core-2.8.6.tgz", + "integrity": "sha512-1QlPaHMhOORySCXkQyzjsIsy2GYTilOw3LkjeHkCgsPJQjAT4IclVytJusWktPbYNys9O+O4V23J44yomQvnBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/cli-progress": "^3.11.0", + "ansi-escapes": "^4.3.2", + "ansi-styles": "^4.3.0", + "cardinal": "^2.1.1", + "chalk": "^4.1.2", + "clean-stack": "^3.0.1", + "cli-progress": "^3.12.0", + "debug": "^4.3.4", + "ejs": "^3.1.8", + "fs-extra": "^9.1.0", + "get-package-type": "^0.1.0", + "globby": "^11.1.0", + "hyperlinker": "^1.0.0", + "indent-string": "^4.0.0", + "is-wsl": "^2.2.0", + "js-yaml": "^3.14.1", + "natural-orderby": "^2.0.3", + "object-treeify": "^1.1.33", + "password-prompt": "^1.1.2", + "semver": "^7.3.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "supports-color": "^8.1.1", + "supports-hyperlinks": "^2.2.0", + "ts-node": "^10.9.1", + "tslib": "^2.5.0", + "widest-line": "^3.1.0", + "wordwrap": "^1.0.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oclif/core/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@oclif/core/node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@peculiar/asn1-schema": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.8.0.tgz", + "integrity": "sha512-7YT0U/ze0tF2QOBbE15gKZwy5tvgGyLRiRHLzhlbOpf7BT032oBSd0haZqXn5W6l26WLlu3dyxzjM+2638/z2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/utils": "^2.0.2", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/json-schema": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@peculiar/json-schema/-/json-schema-1.1.12.tgz", + "integrity": "sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@peculiar/utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@peculiar/utils/-/utils-2.0.3.tgz", + "integrity": "sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/webcrypto": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@peculiar/webcrypto/-/webcrypto-1.7.1.tgz", + "integrity": "sha512-ODOov0sGMJMf3jPonOkgGqPknTsu+DdQ7kD++gz8aI+aFMOMHFbWAA2taqXXVTdP+OTOQR/znGvSpmkeI0WTYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.7.0", + "@peculiar/json-schema": "^1.1.12", + "@peculiar/utils": "^2.0.2", + "tslib": "^2.8.1", + "webcrypto-core": "^1.9.2" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz", + "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz", + "integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz", + "integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.2.tgz", + "integrity": "sha512-pa0vFRuws4wkvaXKK1uXZMAwAX4/t8ANaJo45iw/oQHNQ9q5xUzwgFmVJGXiga2BeN+zpX7Vf9vmsiIa2J+MUw==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.2.tgz", + "integrity": "sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@rescript/std": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@rescript/std/-/std-9.0.0.tgz", + "integrity": "sha512-zGzFsgtZ44mgL4Xef2gOy1hrRVdrs9mcxCOOKZrIPsmbZW14yTkaF591GXxpQvjXiHtgZ/iA9qLyWH6oSReIxQ==", + "dev": true, + "license": "SEE LICENSE IN LICENSE" + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", + "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cli-progress": { + "version": "3.11.6", + "resolved": "https://registry.npmjs.org/@types/cli-progress/-/cli-progress-3.11.6.tgz", + "integrity": "sha512-cE3+jb9WRlu+uOSAugewNpITJDt1VF8dHOopPO4IABFc3SXYL5WE/+PTz/FCdZRRfIujiWW3n3aMbv1eIGVRWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/concat-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", + "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.2.0.tgz", + "integrity": "sha512-5IviulTZeRNp2vAJ514cc/HUlY5nZ9fCbq9DMyC52BrhFZACo3nI0R7qBxhQmo/d27NFe96ur/b7Wwxklda+kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~8.3.0" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.15.1.tgz", + "integrity": "sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/secp256k1": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.7.tgz", + "integrity": "sha512-Rcvjl6vARGAKRO6jHeKMatGrvOMGrR/AR11N1x2LqintPCyDZ7NBhrh238Z2VZc7aM7KIwnFpFQ7fnfK4H/9Qw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ws": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript/typescript-aix-ppc64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-aix-ppc64/-/typescript-aix-ppc64-7.0.2.tgz", + "integrity": "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "aix" + ], + "peer": true, + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-darwin-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-arm64/-/typescript-darwin-arm64-7.0.2.tgz", + "integrity": "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-darwin-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-x64/-/typescript-darwin-x64-7.0.2.tgz", + "integrity": "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-freebsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-arm64/-/typescript-freebsd-arm64-7.0.2.tgz", + "integrity": "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-freebsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-x64/-/typescript-freebsd-x64-7.0.2.tgz", + "integrity": "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-arm": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm/-/typescript-linux-arm-7.0.2.tgz", + "integrity": "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm64/-/typescript-linux-arm64-7.0.2.tgz", + "integrity": "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-loong64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-loong64/-/typescript-linux-loong64-7.0.2.tgz", + "integrity": "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-mips64el": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-mips64el/-/typescript-linux-mips64el-7.0.2.tgz", + "integrity": "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-ppc64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-ppc64/-/typescript-linux-ppc64-7.0.2.tgz", + "integrity": "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-riscv64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-riscv64/-/typescript-linux-riscv64-7.0.2.tgz", + "integrity": "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-s390x": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-s390x/-/typescript-linux-s390x-7.0.2.tgz", + "integrity": "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-x64/-/typescript-linux-x64-7.0.2.tgz", + "integrity": "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-netbsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-arm64/-/typescript-netbsd-arm64-7.0.2.tgz", + "integrity": "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "netbsd" + ], + "peer": true, + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-netbsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-x64/-/typescript-netbsd-x64-7.0.2.tgz", + "integrity": "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "netbsd" + ], + "peer": true, + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-openbsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-arm64/-/typescript-openbsd-arm64-7.0.2.tgz", + "integrity": "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "openbsd" + ], + "peer": true, + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-openbsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-x64/-/typescript-openbsd-x64-7.0.2.tgz", + "integrity": "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "openbsd" + ], + "peer": true, + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-sunos-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-sunos-x64/-/typescript-sunos-x64-7.0.2.tgz", + "integrity": "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "sunos" + ], + "peer": true, + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-win32-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-arm64/-/typescript-win32-arm64-7.0.2.tgz", + "integrity": "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-win32-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-x64/-/typescript-win32-x64-7.0.2.tgz", + "integrity": "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@whatwg-node/events": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.0.3.tgz", + "integrity": "sha512-IqnKIDWfXBJkvy/k6tzskWTc2NK3LcqHlb+KHGCrjOCH4jfQckRX0NAiIcC/vIqQkzLYw2r2CTSwAxcrtcD6lA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@whatwg-node/fetch": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.8.8.tgz", + "integrity": "sha512-CdcjGC2vdKhc13KKxgsc6/616BQ7ooDIgPeTuAiE8qfCnS0mGzcfCOoZXypQSz73nxI+GWc7ZReIAVhxoE1KCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/webcrypto": "^1.4.0", + "@whatwg-node/node-fetch": "^0.3.6", + "busboy": "^1.6.0", + "urlpattern-polyfill": "^8.0.0", + "web-streams-polyfill": "^3.2.1" + } + }, + "node_modules/@whatwg-node/node-fetch": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.3.6.tgz", + "integrity": "sha512-w9wKgDO4C95qnXZRwZTfCmLWqyRnooGjcIwG0wADWjw9/HN0p7dtvtgSvItZtUyNteEvgTrd8QojNEqV6DAGTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@whatwg-node/events": "^0.0.3", + "busboy": "^1.6.0", + "fast-querystring": "^1.1.1", + "fast-url-parser": "^1.1.3", + "tslib": "^2.3.1" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/acorn": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.5", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", + "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/any-signal": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/any-signal/-/any-signal-2.1.2.tgz", + "integrity": "sha512-B+rDnWasMi/eWcajPcCWSlYc7muXOrcYrqgyzcdKisl2H/WTlQ0gip1KyQfr0ZlxJdsuWCj/LWwQm7fhyhRfIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "native-abort-controller": "^1.0.3" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/apisauce": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/apisauce/-/apisauce-2.1.6.tgz", + "integrity": "sha512-MdxR391op/FucS2YQRfB/NMRyCnHEPDd4h17LRIuVYi0BpGmMhpxc0shbOpfs5ahABuBEffNCGal5EcsydbBWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "axios": "^0.21.4" + } + }, + "node_modules/app-module-path": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz", + "integrity": "sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/asn1js": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.10.tgz", + "integrity": "sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "pvtsutils": "^1.3.6", + "pvutils": "^1.1.5", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/assemblyscript": { + "version": "0.19.23", + "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.19.23.tgz", + "integrity": "sha512-fwOQNZVTMga5KRsfY80g7cpOl4PsFQczMwHzdtgoqLXaYhkhavufKb0sB0l3T1DUxpAufA0KNhlbpuuhZUwxMA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "binaryen": "102.0.0-nightly.20211028", + "long": "^5.2.0", + "source-map-support": "^0.5.20" + }, + "bin": { + "asc": "bin/asc", + "asinit": "bin/asinit" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/assemblyscript" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true, + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", + "dev": true, + "license": "MIT" + }, + "node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base-x": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz", + "integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/binary-install-raw": { + "version": "0.0.13", + "resolved": "https://registry.npmjs.org/binary-install-raw/-/binary-install-raw-0.0.13.tgz", + "integrity": "sha512-v7ms6N/H7iciuk6QInon3/n2mu7oRX+6knJ9xFPsJ3rQePgAqcR3CRTwUheFd8SLbiq4LL7Z4G/44L9zscdt9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "axios": "^0.21.1", + "rimraf": "^3.0.2", + "tar": "^6.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/binaryen": { + "version": "102.0.0-nightly.20211028", + "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-102.0.0-nightly.20211028.tgz", + "integrity": "sha512-GCJBVB5exbxzzvyt8MGDv/MeUjs6gkXDvf4xOIItRBptYl0Tz5sm1o/uG95YK0L0VeG5ajDu3hRtkBP2kzqC5w==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "wasm-opt": "bin/wasm-opt" + } + }, + "node_modules/bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/blob-to-it": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/blob-to-it/-/blob-to-it-1.0.4.tgz", + "integrity": "sha512-iCmk0W4NdbrWgRRuxOriU8aM5ijeVLI61Zulsmg/lUHNr7pYjoj+U77opLefNagevtrrbMt3JQ5Qip7ar178kA==", + "dev": true, + "license": "ISC", + "dependencies": { + "browser-readablestream-to-it": "^1.0.3" + } + }, + "node_modules/bn.js": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.5.tgz", + "integrity": "sha512-Vq886eXykuP5E6HcKSSStP3bJgrE6In5WKxVUvJ8XGpWWYs2xZHWqUwzCtGgEtBcxyd57KBFDPFoUfNzdaHCNg==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/browser-readablestream-to-it": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/browser-readablestream-to-it/-/browser-readablestream-to-it-1.0.3.tgz", + "integrity": "sha512-+12sHB+Br8HIh6VAMVEG5r3UXCyESIgDW7kzk3BjIXa43DVqVwL7GC5TW3jeh+72dtcH99pPVpw0X8i0jt+/kw==", + "dev": true, + "license": "ISC" + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "node_modules/buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true, + "license": "MIT" + }, + "node_modules/buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dev": true, + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + }, + "bin": { + "cdl": "bin/cdl.js" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/cborg": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/cborg/-/cborg-1.10.2.tgz", + "integrity": "sha512-b3tFPA9pUr2zCUiCfRd2+wok2/LBSNUMKOuRRok+WlvvAgEt/PlbgPTsZUcwCOs53IJvLgTp0eotwtosE6njug==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "cborg": "cli.js" + } + }, + "node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/cipher-base": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.7.tgz", + "integrity": "sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cipher-base/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/clean-stack": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-3.0.1.tgz", + "integrity": "sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-progress": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.12.0.tgz", + "integrity": "sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.3" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-table3": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.0.tgz", + "integrity": "sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4.1.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "colors": "^1.1.2" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", + "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delay": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", + "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/diff": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", + "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dns-over-http-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/dns-over-http-resolver/-/dns-over-http-resolver-1.2.3.tgz", + "integrity": "sha512-miDiVSI6KSNbi4SVifzO/reD8rMnxgrlnkrlkugOLQpWQTe2qMdHsZp5DmfKjxNE+/T3VAAYLQUZMv9SMr6+AA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.1", + "native-fetch": "^3.0.0", + "receptacle": "^1.3.2" + } + }, + "node_modules/docker-compose": { + "version": "0.23.19", + "resolved": "https://registry.npmjs.org/docker-compose/-/docker-compose-0.23.19.tgz", + "integrity": "sha512-v5vNLIdUqwj4my80wxFDkNH+4S85zsRuH29SO7dCWVWPCMt/ohZBsGN6g6KXWifT0pzQ7uOxqEKCYCDPJ8Vz4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "yaml": "^1.10.2" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/docker-modem": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-1.0.9.tgz", + "integrity": "sha512-lVjqCSCIAUDZPAZIeyM125HXfNvOmYYInciphNrLrylUtKyW66meAjSPXWchKVzoIYZx69TPnAepVSSkeawoIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "debug": "^3.2.6", + "JSONStream": "1.3.2", + "readable-stream": "~1.0.26-4", + "split-ca": "^1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/docker-modem/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/docker-modem/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/docker-modem/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/docker-modem/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/dockerode": { + "version": "2.5.8", + "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-2.5.8.tgz", + "integrity": "sha512-+7iOUYBeDTScmOmQqpUYQaE7F4vvIt6+gIZNHWhqAQEI887tiPFB9OvXI/HzQYqfUNvukMK+9myLW63oTJPZpw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "concat-stream": "~1.6.2", + "docker-modem": "^1.0.8", + "tar-fs": "~1.16.3" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-fetch": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/electron-fetch/-/electron-fetch-1.9.1.tgz", + "integrity": "sha512-M9qw6oUILGVrcENMSRRefE1MbHPIz0h79EKIeJWK9v563aT9Qkh8aEHPO1H5vi970wPirNY+jO9OpFoLiMsMGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "encoding": "^0.1.13" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/elliptic": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", + "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.5", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", + "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/err-code": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-3.0.1.tgz", + "integrity": "sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==", + "dev": true, + "license": "MIT" + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es6-promise": "^4.0.3" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ethereum-bloom-filters": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.2.0.tgz", + "integrity": "sha512-28hyiE7HVsWubqhpVLVmZXFd4ITeHi+BUu05o9isf0GUpMtzBUi+8/gFrGaGYzvGAJQmJ3JKj77Mk9G98T84rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "^1.4.0" + } + }, + "node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ethereumjs-util": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", + "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ethjs-unit": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", + "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ethjs-unit/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "dev": true, + "license": "MIT" + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" + }, + "node_modules/eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==", + "dev": true, + "engines": { + "node": "> 0.1.90" + } + }, + "node_modules/fast-decode-uri-component": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", + "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-querystring": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", + "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-decode-uri-component": "^1.0.1" + } + }, + "node_modules/fast-url-parser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", + "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^1.3.2" + } + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/filelist": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.6.tgz", + "integrity": "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true, + "license": "MIT" + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs-jetpack": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/fs-jetpack/-/fs-jetpack-4.3.1.tgz", + "integrity": "sha512-dbeOK84F6BiQzk2yqqCVwCPWTxAvVGJ3fMQc6E2wuEohS28mR6yHngbrKuVCK1KHRx/ccByDylqu4H5PCP2urQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.2", + "rimraf": "^2.6.3" + } + }, + "node_modules/fs-jetpack/node_modules/brace-expansion": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/fs-jetpack/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fs-jetpack/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/fs-jetpack/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-iterator": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-iterator/-/get-iterator-1.0.2.tgz", + "integrity": "sha512-v+dm9bNVfOYsY1OrhaCrmyOcYoSeVvbt+hHZ0Au+T+p1y+0Uyj9aMaGIeUTT6xdpRbWzDeYKvfOslPhggQMcsg==", + "dev": true, + "license": "MIT" + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "9.3.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", + "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gluegun": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/gluegun/-/gluegun-5.1.2.tgz", + "integrity": "sha512-Cwx/8S8Z4YQg07a6AFsaGnnnmd8mN17414NcPS3OoDtZRwxgsvwRNJNg69niD6fDa8oNwslCG0xH7rEpRNNE/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "apisauce": "^2.1.5", + "app-module-path": "^2.2.0", + "cli-table3": "0.6.0", + "colors": "1.4.0", + "cosmiconfig": "7.0.1", + "cross-spawn": "7.0.3", + "ejs": "3.1.6", + "enquirer": "2.3.6", + "execa": "5.1.1", + "fs-jetpack": "4.3.1", + "lodash.camelcase": "^4.3.0", + "lodash.kebabcase": "^4.1.1", + "lodash.lowercase": "^4.3.0", + "lodash.lowerfirst": "^4.3.1", + "lodash.pad": "^4.5.1", + "lodash.padend": "^4.6.1", + "lodash.padstart": "^4.6.1", + "lodash.repeat": "^4.1.0", + "lodash.snakecase": "^4.1.1", + "lodash.startcase": "^4.4.0", + "lodash.trim": "^4.5.1", + "lodash.trimend": "^4.5.1", + "lodash.trimstart": "^4.5.1", + "lodash.uppercase": "^4.3.0", + "lodash.upperfirst": "^4.3.1", + "ora": "4.0.2", + "pluralize": "^8.0.0", + "semver": "7.3.5", + "which": "2.0.2", + "yargs-parser": "^21.0.0" + }, + "bin": { + "gluegun": "bin/gluegun" + } + }, + "node_modules/gluegun/node_modules/ejs": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz", + "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.6.1" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gluegun/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gluegun/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/graphql": { + "version": "15.5.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.5.0.tgz", + "integrity": "sha512-OmaM7y0kaK31NKG31q4YbD2beNYa6jBBKtMFT6gLYJljHLJr42IqJ8KX08u3Li/0ifzTU5HjmoOOrwa5BRLeDA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/graphql-import-node": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/graphql-import-node/-/graphql-import-node-0.0.5.tgz", + "integrity": "sha512-OXbou9fqh9/Lm7vwXT0XoRN9J5+WCYKnbiTalgFDvkQERITRmcfncZs6aVABedd5B85yQU5EULS4a5pnbpuI0Q==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "graphql": "*" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.2.tgz", + "integrity": "sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^2.3.8", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/hash-base/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/http-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^10.0.3" + } + }, + "node_modules/http-response-object/node_modules/@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", + "dev": true, + "license": "MIT" + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/hyperlinker": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hyperlinker/-/hyperlinker-1.0.0.tgz", + "integrity": "sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immutable": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.2.1.tgz", + "integrity": "sha512-7WYV7Q5BTs0nlQm7tl92rDYYoyELLKHoDMBKhrxEoiV4mrfVdRz8hzPiYOzH7yWjzoVEamxRuAqhxL2PLRwZYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/interface-datastore": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/interface-datastore/-/interface-datastore-6.1.1.tgz", + "integrity": "sha512-AmCS+9CT34pp2u0QQVXjKztkuq3y5T+BIciuiHDDtDZucZD8VudosnSdUyXJV6IsRkN5jc4RFDhCk1O6Q3Gxjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "interface-store": "^2.0.2", + "nanoid": "^3.0.2", + "uint8arrays": "^3.0.0" + } + }, + "node_modules/interface-store": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/interface-store/-/interface-store-2.0.2.tgz", + "integrity": "sha512-rScRlhDcz6k199EkHqT8NpM87ebN89ICOzILoBHgaG36/WX50N32BnU/kpZgCGPLhARRAWUUX5/cyaIjt7Kipg==", + "dev": true, + "license": "(Apache-2.0 OR MIT)" + }, + "node_modules/ip-regex": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", + "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ipfs-core-types": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/ipfs-core-types/-/ipfs-core-types-0.9.0.tgz", + "integrity": "sha512-VJ8vJSHvI1Zm7/SxsZo03T+zzpsg8pkgiIi5hfwSJlsrJ1E2v68QPlnLshGHUSYw89Oxq0IbETYl2pGTFHTWfg==", + "deprecated": "js-IPFS has been deprecated in favour of Helia - please see https://github.com/ipfs/js-ipfs/issues/4336 for details", + "dev": true, + "license": "(Apache-2.0 OR MIT)", + "dependencies": { + "interface-datastore": "^6.0.2", + "multiaddr": "^10.0.0", + "multiformats": "^9.4.13" + } + }, + "node_modules/ipfs-core-utils": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/ipfs-core-utils/-/ipfs-core-utils-0.13.0.tgz", + "integrity": "sha512-HP5EafxU4/dLW3U13CFsgqVO5Ika8N4sRSIb/dTg16NjLOozMH31TXV0Grtu2ZWo1T10ahTzMvrfT5f4mhioXw==", + "deprecated": "js-IPFS has been deprecated in favour of Helia - please see https://github.com/ipfs/js-ipfs/issues/4336 for details", + "dev": true, + "license": "MIT", + "dependencies": { + "any-signal": "^2.1.2", + "blob-to-it": "^1.0.1", + "browser-readablestream-to-it": "^1.0.1", + "debug": "^4.1.1", + "err-code": "^3.0.1", + "ipfs-core-types": "^0.9.0", + "ipfs-unixfs": "^6.0.3", + "ipfs-utils": "^9.0.2", + "it-all": "^1.0.4", + "it-map": "^1.0.4", + "it-peekable": "^1.0.2", + "it-to-stream": "^1.0.0", + "merge-options": "^3.0.4", + "multiaddr": "^10.0.0", + "multiaddr-to-uri": "^8.0.0", + "multiformats": "^9.4.13", + "nanoid": "^3.1.23", + "parse-duration": "^1.0.0", + "timeout-abort-controller": "^2.0.0", + "uint8arrays": "^3.0.0" + } + }, + "node_modules/ipfs-http-client": { + "version": "55.0.0", + "resolved": "https://registry.npmjs.org/ipfs-http-client/-/ipfs-http-client-55.0.0.tgz", + "integrity": "sha512-GpvEs7C7WL9M6fN/kZbjeh4Y8YN7rY8b18tVWZnKxRsVwM25cIFrRI8CwNt3Ugin9yShieI3i9sPyzYGMrLNnQ==", + "deprecated": "js-IPFS has been deprecated in favour of Helia - please see https://github.com/ipfs/js-ipfs/issues/4336 for details", + "dev": true, + "license": "(Apache-2.0 OR MIT)", + "dependencies": { + "@ipld/dag-cbor": "^7.0.0", + "@ipld/dag-json": "^8.0.1", + "@ipld/dag-pb": "^2.1.3", + "abort-controller": "^3.0.0", + "any-signal": "^2.1.2", + "debug": "^4.1.1", + "err-code": "^3.0.1", + "ipfs-core-types": "^0.9.0", + "ipfs-core-utils": "^0.13.0", + "ipfs-utils": "^9.0.2", + "it-first": "^1.0.6", + "it-last": "^1.0.4", + "merge-options": "^3.0.4", + "multiaddr": "^10.0.0", + "multiformats": "^9.4.13", + "native-abort-controller": "^1.0.3", + "parse-duration": "^1.0.0", + "stream-to-it": "^0.2.2", + "uint8arrays": "^3.0.0" + }, + "engines": { + "node": ">=14.0.0", + "npm": ">=3.0.0" + } + }, + "node_modules/ipfs-unixfs": { + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/ipfs-unixfs/-/ipfs-unixfs-6.0.9.tgz", + "integrity": "sha512-0DQ7p0/9dRB6XCb0mVCTli33GzIzSVx5udpJuVM47tGcD+W+Bl4LsnoLswd3ggNnNEakMv1FdoFITiEnchXDqQ==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "dependencies": { + "err-code": "^3.0.1", + "protobufjs": "^6.10.2" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/ipfs-utils": { + "version": "9.0.14", + "resolved": "https://registry.npmjs.org/ipfs-utils/-/ipfs-utils-9.0.14.tgz", + "integrity": "sha512-zIaiEGX18QATxgaS0/EOQNoo33W0islREABAcxXE8n7y2MGAlB+hdsxXn4J0hGZge8IqVQhW8sWIb+oJz2yEvg==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "dependencies": { + "any-signal": "^3.0.0", + "browser-readablestream-to-it": "^1.0.0", + "buffer": "^6.0.1", + "electron-fetch": "^1.7.2", + "err-code": "^3.0.1", + "is-electron": "^2.2.0", + "iso-url": "^1.1.5", + "it-all": "^1.0.4", + "it-glob": "^1.0.1", + "it-to-stream": "^1.0.0", + "merge-options": "^3.0.4", + "nanoid": "^3.1.20", + "native-fetch": "^3.0.0", + "node-fetch": "^2.6.8", + "react-native-fetch-api": "^3.0.0", + "stream-to-it": "^0.2.2" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/ipfs-utils/node_modules/any-signal": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/any-signal/-/any-signal-3.0.1.tgz", + "integrity": "sha512-xgZgJtKEa9YmDqXodIgl7Fl1C8yNXr8w6gXjqK3LW4GcEiYT+6AQfJSE/8SPsEpLLmcvbv8YU+qet94UewHxqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-electron": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-electron/-/is-electron-2.2.2.tgz", + "integrity": "sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-ip": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-3.1.0.tgz", + "integrity": "sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-regex": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/iso-url": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/iso-url/-/iso-url-1.2.1.tgz", + "integrity": "sha512-9JPDgCN4B7QPkLtYAAOrEuAWvP9rWvR5offAr0/SeF046wIkglqH3VXgYYP6NcsKslH80UIVgmPqNe3j7tG2ng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/it-all": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/it-all/-/it-all-1.0.6.tgz", + "integrity": "sha512-3cmCc6Heqe3uWi3CVM/k51fa/XbMFpQVzFoDsV0IZNHSQDyAXl3c4MjHkFX5kF3922OGj7Myv1nSEUgRtcuM1A==", + "dev": true, + "license": "ISC" + }, + "node_modules/it-first": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/it-first/-/it-first-1.0.7.tgz", + "integrity": "sha512-nvJKZoBpZD/6Rtde6FXqwDqDZGF1sCADmr2Zoc0hZsIvnE449gRFnGctxDf09Bzc/FWnHXAdaHVIetY6lrE0/g==", + "dev": true, + "license": "ISC" + }, + "node_modules/it-glob": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/it-glob/-/it-glob-1.0.2.tgz", + "integrity": "sha512-Ch2Dzhw4URfB9L/0ZHyY+uqOnKvBNeS/SMcRiPmJfpHiM0TsUZn+GkpcZxAoF3dJVdPm/PuIk3A4wlV7SUo23Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "@types/minimatch": "^3.0.4", + "minimatch": "^3.0.4" + } + }, + "node_modules/it-glob/node_modules/brace-expansion": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/it-glob/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/it-last": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/it-last/-/it-last-1.0.6.tgz", + "integrity": "sha512-aFGeibeiX/lM4bX3JY0OkVCFkAw8+n9lkukkLNivbJRvNz8lI3YXv5xcqhFUV2lDJiraEK3OXRDbGuevnnR67Q==", + "dev": true, + "license": "ISC" + }, + "node_modules/it-map": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/it-map/-/it-map-1.0.6.tgz", + "integrity": "sha512-XT4/RM6UHIFG9IobGlQPFQUrlEKkU4eBUFG3qhWhfAdh1JfF2x11ShCrKCdmZ0OiZppPfoLuzcfA4cey6q3UAQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/it-peekable": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/it-peekable/-/it-peekable-1.0.3.tgz", + "integrity": "sha512-5+8zemFS+wSfIkSZyf0Zh5kNN+iGyccN02914BY4w/Dj+uoFEoPSvj5vaWn8pNZJNSxzjW0zHRxC3LUb2KWJTQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/it-to-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/it-to-stream/-/it-to-stream-1.0.0.tgz", + "integrity": "sha512-pLULMZMAB/+vbdvbZtebC0nWBTbG581lk6w8P7DfIIIKUfa8FbY7Oi0FxZcFPbxvISs7A9E+cMpLDBc1XhpAOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^6.0.3", + "fast-fifo": "^1.0.0", + "get-iterator": "^1.0.2", + "p-defer": "^3.0.0", + "p-fifo": "^1.0.0", + "readable-stream": "^3.6.0" + } + }, + "node_modules/it-to-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jake": { + "version": "10.9.4", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", + "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.6", + "filelist": "^1.0.4", + "picocolors": "^1.1.1" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jayson": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jayson/-/jayson-4.0.0.tgz", + "integrity": "sha512-v2RNpDCMu45fnLzSk47vx7I+QUaOsox6f5X0CUlabAFwxoP+8MfAY0NQRFwOEYXIxm8Ih5y6OaEa5KYiQMkyAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/connect": "^3.4.33", + "@types/node": "^12.12.54", + "@types/ws": "^7.4.4", + "commander": "^2.20.3", + "delay": "^5.0.0", + "es6-promisify": "^5.0.0", + "eyes": "^0.1.8", + "isomorphic-ws": "^4.0.1", + "json-stringify-safe": "^5.0.1", + "JSONStream": "^1.3.5", + "uuid": "^8.3.2", + "ws": "^7.4.5" + }, + "bin": { + "jayson": "bin/jayson.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jayson/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jayson/node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true, + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "license": "ISC" + }, + "node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/JSONStream": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.2.tgz", + "integrity": "sha512-mn0KSip7N4e0UDPZHnqDsHECo5uGQrixQKnAskOM1BIB8hd7QKbd6il8IPRPudPHOeHiECoCFqhyMaRO9+nWyA==", + "dev": true, + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/keccak": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", + "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/keccak/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.lowercase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.lowercase/-/lodash.lowercase-4.3.0.tgz", + "integrity": "sha512-UcvP1IZYyDKyEL64mmrwoA1AbFu5ahojhTtkOUr1K9dbuxzS9ev8i4TxMMGCqRC9TE8uDaSoufNAXxRPNTseVA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.lowerfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.lowerfirst/-/lodash.lowerfirst-4.3.1.tgz", + "integrity": "sha512-UUKX7VhP1/JL54NXg2aq/E1Sfnjjes8fNYTNkPU8ZmsaVeBvPHKdbNaN79Re5XRL01u6wbq3j0cbYZj71Fcu5w==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.pad": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", + "integrity": "sha512-mvUHifnLqM+03YNzeTBS1/Gr6JRFjd3rRx88FHWUvamVaT9k2O/kXha3yBSOwB9/DTQrSTLJNHvLBBt2FdX7Mg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.padend": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", + "integrity": "sha512-sOQs2aqGpbl27tmCS1QNZA09Uqp01ZzWfDUoD+xzTii0E7dSQfRKcRetFwa+uXaxaqL+TKm7CgD2JdKP7aZBSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.padstart": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", + "integrity": "sha512-sW73O6S8+Tg66eY56DBk85aQzzUJDtpoXFBgELMd5P/SotAguo+1kYO6RuYgXxA4HJH3LFTFPASX6ET6bjfriw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.repeat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lodash.repeat/-/lodash.repeat-4.1.0.tgz", + "integrity": "sha512-eWsgQW89IewS95ZOcr15HHCX6FVDxq3f2PNUIng3fyzsPev9imFQxIYdFZ6crl8L56UR6ZlGDLcEb3RZsCSSqw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.trim": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/lodash.trim/-/lodash.trim-4.18.0.tgz", + "integrity": "sha512-q8B9MlXzN9NaTtS2JCd7kKl3RqwrVURgKEXoHDII8A/v7y3tWOq3rLEe+vN6LNvT+EYBVKVt6roNQxMkosS2aA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.trimend": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/lodash.trimend/-/lodash.trimend-4.18.0.tgz", + "integrity": "sha512-8w2M3nZAWLN1OX/6mTPCwRlZiD/LhVyPV9l7DEbkd9wybExvg9AcCjbD19swj6oVzX5hcMZHp3/Y1b4Sl3sHKg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.trimstart": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/lodash.trimstart/-/lodash.trimstart-4.5.1.tgz", + "integrity": "sha512-b/+D6La8tU76L/61/aN0jULWHkT0EeJCmVstPBn/K9MtD2qBW83AsBNrr63dKuWYwVMO7ucv13QNO/Ek/2RKaQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.uppercase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.uppercase/-/lodash.uppercase-4.3.0.tgz", + "integrity": "sha512-+Nbnxkj7s8K5U8z6KnEYPGUOGp3woZbB7Ecs7v3LkkjLQSm2kP9SKIILitN1ktn2mB/tmM9oSlku06I+/lH7QA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.upperfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, + "node_modules/matchstick-as": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/matchstick-as/-/matchstick-as-0.5.2.tgz", + "integrity": "sha512-fb1OVphDKEvJY06Ue02Eh1CNncuW95vp6b8tNAP7UIqplICSLoU/zgN6U7ge7R0upsoO78C7CRi4EyK/7Jxz7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "wabt": "1.0.24" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/merge-options": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz", + "integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "dev": true, + "license": "MIT" + }, + "node_modules/minimatch": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.7.tgz", + "integrity": "sha512-V+1uQNdzybxa14e/p00HZnQNNcTjnRJjDxg2V8wtkjFctq4M7hXFws4oekyTP0Jebeq7QYtpFyOeBAjc88zvYg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/multiaddr": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/multiaddr/-/multiaddr-10.0.1.tgz", + "integrity": "sha512-G5upNcGzEGuTHkzxezPrrD6CaIHR9uo+7MwqhNVcXTs33IInon4y7nMiGxl2CY5hG7chvYQUQhz5V52/Qe3cbg==", + "deprecated": "This module is deprecated, please upgrade to @multiformats/multiaddr", + "dev": true, + "license": "MIT", + "dependencies": { + "dns-over-http-resolver": "^1.2.3", + "err-code": "^3.0.1", + "is-ip": "^3.1.0", + "multiformats": "^9.4.5", + "uint8arrays": "^3.0.0", + "varint": "^6.0.0" + } + }, + "node_modules/multiaddr-to-uri": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/multiaddr-to-uri/-/multiaddr-to-uri-8.0.0.tgz", + "integrity": "sha512-dq4p/vsOOUdVEd1J1gl+R2GFrXJQH8yjLtz4hodqdVbieg39LvBOdMQRdQnfbg5LSM/q1BYNVf5CBbwZFFqBgA==", + "deprecated": "This module is deprecated, please upgrade to @multiformats/multiaddr-to-uri", + "dev": true, + "license": "MIT", + "dependencies": { + "multiaddr": "^10.0.0" + } + }, + "node_modules/multiformats": { + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz", + "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==", + "dev": true, + "license": "(Apache-2.0 AND MIT)" + }, + "node_modules/nanoid": { + "version": "3.3.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/native-abort-controller": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/native-abort-controller/-/native-abort-controller-1.0.4.tgz", + "integrity": "sha512-zp8yev7nxczDJMoP6pDxyD20IU0T22eX8VwN2ztDccKvSZhRaV33yP1BGwKSZfXuqWUzsXopVFjBdau9OOAwMQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "abort-controller": "*" + } + }, + "node_modules/native-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/native-fetch/-/native-fetch-3.0.0.tgz", + "integrity": "sha512-G3Z7vx0IFb/FQ4JxvtqGABsOTIqRWvgQz6e+erkB+JJD6LrszQtMozEHI4EkmgZQvnGHrpLVzUWk7t4sJCIkVw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "node-fetch": "*" + } + }, + "node_modules/natural-orderby": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/natural-orderby/-/natural-orderby-2.0.3.tgz", + "integrity": "sha512-p7KTHxU0CUrcOXe62Zfrb5Z13nLvPhSWR/so3kFulUQU0sgUll2Z0LwpsLN351eOOD+hRGu/F1g+6xDfPeD++Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "dev": true, + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/number-to-bn": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", + "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/number-to-bn/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "dev": true, + "license": "MIT" + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-treeify": { + "version": "1.1.33", + "resolved": "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.33.tgz", + "integrity": "sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/ora/-/ora-4.0.2.tgz", + "integrity": "sha512-YUOZbamht5mfLxPmk4M35CD/5DuOkAacxlEUbStVXpBAt4fyhBf+vZHI/HRkI++QUp3sNoeA2Gw4C+hi4eGSig==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^2.4.2", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.2.0", + "is-interactive": "^1.0.0", + "log-symbols": "^3.0.0", + "strip-ansi": "^5.2.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/ora/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ora/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ora/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ora/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-defer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-3.0.0.tgz", + "integrity": "sha512-ugZxsxmtTln604yeYd29EGrNhazN2lywetzpKhfmQjW/VJmhpDmWbiX+h0zL8V91R0UXkhb3KtPmyq9PZw3aYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-fifo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-fifo/-/p-fifo-1.0.0.tgz", + "integrity": "sha512-IjoCxXW48tqdtDFz6fqo5q1UfFVjjVZe8TC1QRflvNUJtNfCUhxOUw6MOVZhDPjqhSzc26xKdugsO17gmzd5+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-fifo": "^1.0.0", + "p-defer": "^3.0.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", + "dev": true + }, + "node_modules/parse-duration": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-1.1.2.tgz", + "integrity": "sha512-p8EIONG8L0u7f8GFgfVlL4n8rnChTt8O5FSxgxMz2tjc9FMP199wxVKVB6IbKx11uTbKHACSvaLVIKNnoeNR/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/password-prompt": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/password-prompt/-/password-prompt-1.1.3.tgz", + "integrity": "sha512-HkrjG2aJlvF0t2BMH0e2LB/EHf3Lcq3fNMzy4GYHcQblAvOl+QQji1Lx7WRBMqpVK8p+KR7bCg7oqAMXtdgqyw==", + "dev": true, + "license": "0BSD", + "dependencies": { + "ansi-escapes": "^4.3.2", + "cross-spawn": "^7.0.3" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.6.tgz", + "integrity": "sha512-BT6eelPB1EyGHo8pC0o9Bl6k6SYVhKO1jEbd3lcTrtr7XHdjP8BW1YpfCV3G9Kwkxgattk+S5q2/RvuttCsS1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "ripemd160": "^2.0.3", + "safe-buffer": "^5.2.1", + "sha.js": "^2.4.12", + "to-buffer": "^1.2.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pbkdf2/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "dev": true, + "license": "MIT", + "dependencies": { + "asap": "~2.0.6" + } + }, + "node_modules/protobufjs": { + "version": "6.11.6", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.6.tgz", + "integrity": "sha512-k8BHqgPBOtrlougZZqF2uUk5Z7bN8f0wj+3e8M3hvtSv0NBAz4VBy5f6R5Nxq/l+i7mRFTgNZb2trxqTpHNY/A==", + "dev": true, + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/protobufjs/node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/psl": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } + }, + "node_modules/psl/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pump": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", + "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pvtsutils": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.6.tgz", + "integrity": "sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + } + }, + "node_modules/pvutils": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.2.0.tgz", + "integrity": "sha512-BbubeCEyTuQjVMakvJQ/Sxbc93F2pwmbsxONT/ZRrwU7Ua38d8unYTwXpTVLAKJ4BDuH9IGztCjQcd/N/39Dvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/qs": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.5.tgz", + "integrity": "sha512-mzR4sElr1bfCaPJe7m8ilJ6ZXdDaGoObcYR0ZHSsktM/Lt21MVHj5De30GQH2eiZ1qGRTO7LCAzQsUeXTNexWQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/react-native-fetch-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-native-fetch-api/-/react-native-fetch-api-3.0.0.tgz", + "integrity": "sha512-g2rtqPjdroaboDKTsJCTlcmtw54E25OjyaunUP0anOZn4Fuo2IKs8BVfe02zVggA/UysbmfSnRJIqtNkAgggNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-defer": "^3.0.0" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/receptacle": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/receptacle/-/receptacle-1.3.2.tgz", + "integrity": "sha512-HrsFvqZZheusncQRiEE7GatOAETrARKV/lnfYicIm8lbvp/JQOdADOfhjBd2DajvoszEyxSM6RlAAIZgEoeu/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esprima": "~4.0.0" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/retimer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/retimer/-/retimer-3.0.0.tgz", + "integrity": "sha512-WKE0j11Pa0ZJI5YIk0nflGI7SQsfl2ljihVy7ogh7DeQSeYAUi0ubZ/yEueGtDfUPk6GH5LRw1hBdLq4IwUBWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ripemd160": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.3.tgz", + "integrity": "sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.1.2", + "inherits": "^2.0.4" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rlp": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^5.2.0" + }, + "bin": { + "rlp": "bin/rlp" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", + "dev": true, + "license": "MIT" + }, + "node_modules/secp256k1": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.5.tgz", + "integrity": "sha512-SQZi5+/uiJIFPYbeRrVuu77Sr3bFOTq0oCQs67CqYwdmg0lhnqi/8djSWhzNO3GKGOqxBYCdx8zJJv0zUwDDvw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "elliptic": "^6.5.7", + "node-addon-api": "^5.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/secp256k1/node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", + "dev": true, + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true, + "license": "MIT" + }, + "node_modules/sha.js": { + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", + "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", + "dev": true, + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.0" + }, + "bin": { + "sha.js": "bin.js" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/sha.js/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/split-ca": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split-ca/-/split-ca-1.0.1.tgz", + "integrity": "sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stream-to-it": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/stream-to-it/-/stream-to-it-0.2.4.tgz", + "integrity": "sha512-4vEbkSs83OahpmBybNJXlJd7d6/RxzkkSdT3I0mnGt79Xd2Kk+e1JqbvAvsQfCeKj3aKb0QIWkyK3/n0j506vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-iterator": "^1.0.2" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/sync-rpc": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.7.tgz", + "integrity": "sha512-YHciI7TUxL8EPqz/bg01sZfwuzQA0odao1wf1Ywdtw7j5vl30aQ6s+bLRTvgPPgzr94cg+WMm6Bxi/P7BJOxgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-port": "^3.1.0" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "deprecated": "Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar-fs": { + "version": "1.16.6", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.6.tgz", + "integrity": "sha512-JkOgFt3FxM/2v2CNpAVHqMW2QASjc/Hxo7IGfNd3MHaDYSW/sBFiS7YVmmhmr8x6vwN1VFQDQGdT2MWpmIuVKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chownr": "^1.0.1", + "mkdirp": "^0.5.1", + "pump": "^1.0.0", + "tar-stream": "^1.1.2" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true, + "license": "ISC" + }, + "node_modules/tar-fs/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/then-request/node_modules/@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/timeout-abort-controller": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/timeout-abort-controller/-/timeout-abort-controller-2.0.0.tgz", + "integrity": "sha512-2FAPXfzTPYEgw27bQGTHc0SzrbmnU2eso4qo172zMLZzaGqeu09PFa5B2FCUHM1tflgRqPgn5KQgp6+Vex4uNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "native-abort-controller": "^1.0.4", + "retimer": "^3.0.0" + } + }, + "node_modules/tmp": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.7.tgz", + "integrity": "sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/tmp-promise": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tmp": "^0.2.0" + } + }, + "node_modules/to-buffer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", + "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "isarray": "^2.0.5", + "safe-buffer": "^5.2.1", + "typed-array-buffer": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/to-buffer/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/to-buffer/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tough-cookie/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true, + "license": "Unlicense" + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/typescript": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-7.0.2.tgz", + "integrity": "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc" + }, + "engines": { + "node": ">=16.20.0" + }, + "optionalDependencies": { + "@typescript/typescript-aix-ppc64": "7.0.2", + "@typescript/typescript-darwin-arm64": "7.0.2", + "@typescript/typescript-darwin-x64": "7.0.2", + "@typescript/typescript-freebsd-arm64": "7.0.2", + "@typescript/typescript-freebsd-x64": "7.0.2", + "@typescript/typescript-linux-arm": "7.0.2", + "@typescript/typescript-linux-arm64": "7.0.2", + "@typescript/typescript-linux-loong64": "7.0.2", + "@typescript/typescript-linux-mips64el": "7.0.2", + "@typescript/typescript-linux-ppc64": "7.0.2", + "@typescript/typescript-linux-riscv64": "7.0.2", + "@typescript/typescript-linux-s390x": "7.0.2", + "@typescript/typescript-linux-x64": "7.0.2", + "@typescript/typescript-netbsd-arm64": "7.0.2", + "@typescript/typescript-netbsd-x64": "7.0.2", + "@typescript/typescript-openbsd-arm64": "7.0.2", + "@typescript/typescript-openbsd-x64": "7.0.2", + "@typescript/typescript-sunos-x64": "7.0.2", + "@typescript/typescript-win32-arm64": "7.0.2", + "@typescript/typescript-win32-x64": "7.0.2" + } + }, + "node_modules/uint8arrays": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.1.1.tgz", + "integrity": "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "multiformats": "^9.4.2" + } + }, + "node_modules/undici-types": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", + "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uri-js/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/urlpattern-polyfill": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-8.0.2.tgz", + "integrity": "sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" + }, + "node_modules/varint": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", + "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==", + "dev": true, + "license": "MIT" + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/wabt": { + "version": "1.0.24", + "resolved": "https://registry.npmjs.org/wabt/-/wabt-1.0.24.tgz", + "integrity": "sha512-8l7sIOd3i5GWfTWciPL0+ff/FK/deVK2Q6FN+MPz4vfUcD78i2M/49XJTwF6aml91uIiuXJEsLKWMB2cw/mtKg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "wasm-decompile": "bin/wasm-decompile", + "wasm-interp": "bin/wasm-interp", + "wasm-objdump": "bin/wasm-objdump", + "wasm-opcodecnt": "bin/wasm-opcodecnt", + "wasm-strip": "bin/wasm-strip", + "wasm-validate": "bin/wasm-validate", + "wasm2c": "bin/wasm2c", + "wasm2wat": "bin/wasm2wat", + "wat2wasm": "bin/wat2wasm" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/web3-eth-abi": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.0.tgz", + "integrity": "sha512-heqR0bWxgCJwjWIhq2sGyNj9bwun5+Xox/LdZKe+WMyTSy0cXDXEAgv3XKNkXC4JqdDt/ZlbTEx4TWak4TRMSg==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "@ethersproject/abi": "5.0.7", + "web3-utils": "1.7.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-utils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.0.tgz", + "integrity": "sha512-O8Tl4Ky40Sp6pe89Olk2FsaUkgHyb5QAXuaKo38ms3CxZZ4d3rPGfjP9DNKGm5+IUgAZBNpF1VmlSmNCqfDI1w==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-utils/node_modules/bn.js": { + "version": "4.12.5", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", + "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/webcrypto-core": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.9.2.tgz", + "integrity": "sha512-gsXecm82UQNlTBURJGuqOWy1Ww08S3kZUcr3aOJS02Pk0xLtkfeUAVC0u0xhgdonFme80edSJUIJyuvL/7250Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.7.0", + "@peculiar/json-schema": "^1.1.12", + "@peculiar/utils": "^2.0.2", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.22", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.22.tgz", + "integrity": "sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "7.5.13", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.13.tgz", + "integrity": "sha512-rsKI6xDBFVf4r/x8XyChGK04QR/XHroxs/jUcoWvtEZM8TPU/X/uIY9B1CsSzYws9ZJb/6bbBu7dPhFW00CAoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + } + } +} diff --git a/subgraph/dos-names/package.json b/subgraph/dos-names/package.json new file mode 100644 index 000000000..fe01577b8 --- /dev/null +++ b/subgraph/dos-names/package.json @@ -0,0 +1,20 @@ +{ + "name": "@dos/names-bens-subgraph", + "version": "0.1.0", + "private": true, + "description": "DOS ENSv2 to Blockscout BENS subgraph adapter", + "scripts": { + "codegen": "graph codegen --output-dir src/types/", + "build": "graph build", + "render": "node scripts/render-manifest.mjs", + "render:test": "node scripts/render-manifest.mjs tests/fixtures/dos-testnet-3939.json subgraph.template.yaml subgraph.yaml", + "test": "graph test", + "test:render": "node --test tests/render-manifest.test.mjs" + }, + "devDependencies": { + "@graphprotocol/graph-cli": "0.51.2", + "@graphprotocol/graph-ts": "0.31.0", + "assemblyscript": "0.19.23", + "matchstick-as": "0.5.2" + } +} diff --git a/subgraph/dos-names/schema.graphql b/subgraph/dos-names/schema.graphql new file mode 100644 index 000000000..5c38eab47 --- /dev/null +++ b/subgraph/dos-names/schema.graphql @@ -0,0 +1,324 @@ +# DOS Name Service subgraph schema +# Compatible with Blockscout BENS (reuses ENS schema entities) + +type Domain @entity { + "The namehash of the name" + id: ID! + "The human readable name, if known" + name: String + "The human readable label name, if known" + labelName: String + "keccak256(labelName)" + labelhash: Bytes + "The namehash (id) of the parent name" + parent: Domain + "Can count domains from length of array" + subdomains: [Domain!]! @derivedFrom(field: "parent") + "The number of subdomains" + subdomainCount: Int! + "Address logged from current resolver, if any" + resolvedAddress: Account + + "The resolver that controls the domain's settings" + resolver: Resolver + "The time-to-live (TTL) value of the domain's records" + ttl: BigInt + + "Indicates whether the domain has been migrated to a new registrar" + isMigrated: Boolean! + "The time when the domain was created" + createdAt: BigInt! + + "The account that owns the domain" + owner: Account! + "The account that owns the ERC721 NFT for the domain" + registrant: Account + "The account that owns the wrapped domain" + wrappedOwner: Account + + "The expiry date for the domain" + expiryDate: BigInt + + "The registration associated with the domain" + registration: Registration @derivedFrom(field: "domain") + "The wrapped domain associated with the domain" + wrappedDomain: WrappedDomain @derivedFrom(field: "domain") + + "The events associated with the domain" + events: [DomainEvent!]! @derivedFrom(field: "domain") + + "Is domain stored offchain" + storedOffchain: Boolean! + "Is domain resolved with wildcard" + resolvedWithWildcard: Boolean! + + "Token ID for the domain (ERC1155 in ENSv2)" + tokenId: BigInt +} + +interface DomainEvent { + id: ID! + domain: Domain! + blockNumber: Int! + transactionID: Bytes! +} + +type Transfer implements DomainEvent @entity { + id: ID! + domain: Domain! + blockNumber: Int! + transactionID: Bytes! + owner: Account! +} + +type NewOwner implements DomainEvent @entity { + id: ID! + parentDomain: Domain! + domain: Domain! + blockNumber: Int! + transactionID: Bytes! + owner: Account! +} + +type NewResolver implements DomainEvent @entity { + id: ID! + domain: Domain! + blockNumber: Int! + transactionID: Bytes! + resolver: Resolver! +} + +type NewTTL implements DomainEvent @entity { + id: ID! + domain: Domain! + blockNumber: Int! + transactionID: Bytes! + ttl: BigInt! +} + +type WrappedTransfer implements DomainEvent @entity { + id: ID! + domain: Domain! + blockNumber: Int! + transactionID: Bytes! + owner: Account! +} + +type NameWrapped implements DomainEvent @entity { + id: ID! + domain: Domain! + blockNumber: Int! + transactionID: Bytes! + name: String + fuses: Int! + owner: Account! + expiryDate: BigInt! +} + +type NameUnwrapped implements DomainEvent @entity { + id: ID! + domain: Domain! + blockNumber: Int! + transactionID: Bytes! + owner: Account! +} + +type FusesSet implements DomainEvent @entity { + id: ID! + domain: Domain! + blockNumber: Int! + transactionID: Bytes! + fuses: Int! +} + +type ExpiryExtended implements DomainEvent @entity { + id: ID! + domain: Domain! + blockNumber: Int! + transactionID: Bytes! + expiryDate: BigInt! +} + +type Registration @entity { + id: ID! + domain: Domain! + registrationDate: BigInt! + expiryDate: BigInt! + cost: BigInt + registrant: Account! + labelName: String + events: [RegistrationEvent!]! @derivedFrom(field: "registration") +} + +interface RegistrationEvent { + id: ID! + registration: Registration! + blockNumber: Int! + transactionID: Bytes! +} + +type NameRegistered implements RegistrationEvent @entity { + id: ID! + registration: Registration! + blockNumber: Int! + transactionID: Bytes! + registrant: Account! + expiryDate: BigInt! +} + +type NameRenewed implements RegistrationEvent @entity { + id: ID! + registration: Registration! + blockNumber: Int! + transactionID: Bytes! + expiryDate: BigInt! +} + +type NameTransferred implements RegistrationEvent @entity { + id: ID! + registration: Registration! + blockNumber: Int! + transactionID: Bytes! + newOwner: Account! +} + +type WrappedDomain @entity { + id: ID! + domain: Domain! + expiryDate: BigInt! + fuses: Int! + owner: Account! + name: String +} + +type Account @entity { + id: ID! + domains: [Domain!]! @derivedFrom(field: "owner") + wrappedDomains: [WrappedDomain!] @derivedFrom(field: "owner") + registrations: [Registration!] @derivedFrom(field: "registrant") +} + +type Resolver @entity { + id: ID! + domain: Domain + address: Bytes! + addr: Account + contentHash: Bytes + texts: [String!] + coinTypes: [BigInt!] + events: [ResolverEvent!]! @derivedFrom(field: "resolver") +} + +interface ResolverEvent { + id: ID! + resolver: Resolver! + blockNumber: Int! + transactionID: Bytes! +} + +type AddrChanged implements ResolverEvent @entity { + id: ID! + resolver: Resolver! + blockNumber: Int! + transactionID: Bytes! + addr: Account! +} + +type MulticoinAddrChanged implements ResolverEvent @entity { + id: ID! + resolver: Resolver! + blockNumber: Int! + transactionID: Bytes! + coinType: BigInt! + addr: Bytes! +} + +type NameChanged implements ResolverEvent @entity { + id: ID! + resolver: Resolver! + blockNumber: Int! + transactionID: Bytes! + name: String! +} + +type AbiChanged implements ResolverEvent @entity { + id: ID! + resolver: Resolver! + blockNumber: Int! + transactionID: Bytes! + contentType: BigInt! +} + +type PubkeyChanged implements ResolverEvent @entity { + id: ID! + resolver: Resolver! + blockNumber: Int! + transactionID: Bytes! + x: Bytes! + y: Bytes! +} + +type TextChanged implements ResolverEvent @entity { + id: ID! + resolver: Resolver! + blockNumber: Int! + transactionID: Bytes! + key: String! + value: String +} + +type ContenthashChanged implements ResolverEvent @entity { + id: ID! + resolver: Resolver! + blockNumber: Int! + transactionID: Bytes! + hash: Bytes! +} + +type InterfaceChanged implements ResolverEvent @entity { + id: ID! + resolver: Resolver! + blockNumber: Int! + transactionID: Bytes! + interfaceID: Bytes! + implementer: Bytes! +} + +type AuthorisationChanged implements ResolverEvent @entity { + id: ID! + resolver: Resolver! + blockNumber: Int! + transactionID: Bytes! + owner: Bytes! + target: Bytes! + isAuthorized: Boolean! +} + +type VersionChanged implements ResolverEvent @entity { + id: ID! + resolver: Resolver! + blockNumber: Int! + transactionID: Bytes! + version: BigInt! +} + +"Maps ERC1155 tokenId to domain namehash (ENSv2: tokenId != namehash)" +type TokenToDomain @entity { + "tokenId as hex string" + id: ID! + "The domain namehash" + domain: Domain! +} + +"Links a dynamically discovered ENSv2 registry to a parent domain path" +type RegistryPath @entity { + id: ID! + registry: Bytes! + parentDomain: Domain! +} + +"Tracks resolver addresses already registered as dynamic data sources" +type ResolverSource @entity { + id: ID! + address: Bytes! +} diff --git a/subgraph/dos-names/scripts/render-manifest.mjs b/subgraph/dos-names/scripts/render-manifest.mjs new file mode 100644 index 000000000..29f832b62 --- /dev/null +++ b/subgraph/dos-names/scripts/render-manifest.mjs @@ -0,0 +1,91 @@ +import fs from "node:fs"; +import path from "node:path"; +import { pathToFileURL } from "node:url"; + +const EXPECTED_CHAIN_ID = 3939; +const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"; +const ADDRESS_PATTERN = /^0x[0-9a-fA-F]{40}$/; + +const CONTRACT_PLACEHOLDERS = [ + ["dosRegistry", "__DOS_REGISTRY_ADDRESS__"], + ["dosRegistrar", "__DOS_REGISTRAR_ADDRESS__"], + [ + "permissionedResolverImplementation", + "__PERMISSIONED_RESOLVER_IMPLEMENTATION_ADDRESS__", + ], +]; + +export function validateDeployment(deployment) { + if (deployment?.chainId !== EXPECTED_CHAIN_ID) { + throw new Error(`chainId must be ${EXPECTED_CHAIN_ID}`); + } + + if ( + !Number.isInteger(deployment.deploymentBlock) || + deployment.deploymentBlock < 0 + ) { + throw new Error("deploymentBlock must be a non-negative integer"); + } + + for (const [contractName] of CONTRACT_PLACEHOLDERS) { + const address = deployment.contracts?.[contractName]; + if (!ADDRESS_PATTERN.test(address ?? "")) { + throw new Error(`contracts.${contractName} must be an EVM address`); + } + if (address.toLowerCase() === ZERO_ADDRESS) { + throw new Error(`contracts.${contractName} must not be the zero address`); + } + } + + return deployment; +} + +export function renderManifest(template, deployment) { + validateDeployment(deployment); + + let rendered = template; + for (const [contractName, placeholder] of CONTRACT_PLACEHOLDERS) { + if (!rendered.includes(placeholder)) { + throw new Error(`template is missing ${placeholder}`); + } + rendered = rendered.replaceAll( + placeholder, + deployment.contracts[contractName], + ); + } + + if (!rendered.includes("__START_BLOCK__")) { + throw new Error("template is missing __START_BLOCK__"); + } + rendered = rendered.replaceAll( + "__START_BLOCK__", + String(deployment.deploymentBlock), + ); + + const unresolved = rendered.match(/__[A-Z0-9_]+__/g); + if (unresolved) { + throw new Error(`unresolved placeholders: ${unresolved.join(", ")}`); + } + + return rendered; +} + +function main(argv) { + if (argv.length !== 3) { + throw new Error( + "usage: render-manifest.mjs ", + ); + } + + const [deploymentPath, templatePath, outputPath] = argv; + const deployment = JSON.parse(fs.readFileSync(deploymentPath, "utf8")); + const template = fs.readFileSync(templatePath, "utf8"); + const rendered = renderManifest(template, deployment); + + fs.mkdirSync(path.dirname(outputPath), { recursive: true }); + fs.writeFileSync(outputPath, rendered, "utf8"); +} + +if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) { + main(process.argv.slice(2)); +} diff --git a/subgraph/dos-names/src/registrar.ts b/subgraph/dos-names/src/registrar.ts new file mode 100644 index 000000000..8195183ae --- /dev/null +++ b/subgraph/dos-names/src/registrar.ts @@ -0,0 +1,142 @@ +/** + * DOSRegistrar event handlers. + * + * Actual event signatures: + * NameRegistered(indexed uint256 tokenId, string label, address owner, address subregistry, + * address resolver, uint64 duration, address paymentToken, indexed bytes32 referrer, + * uint256 base, uint256 premium) + * NameRenewed(indexed uint256 tokenId, string label, uint64 duration, uint64 newExpiry, + * address paymentToken, indexed bytes32 referrer, uint256 amount) + */ +import { BigInt } from "@graphprotocol/graph-ts"; + +import { + NameRegistered as RegistrarNameRegisteredEvent, + NameRenewed as RegistrarNameRenewedEvent, +} from "./types/DOSRegistrar/DOSRegistrar"; + +import { + Domain, + NameRegistered, + NameRenewed, + Registration, + TokenToDomain, +} from "./types/schema"; + +import { + checkValidLabel, + createEventID, + createOrLoadAccount, + tokenIdToHex, +} from "./utils"; + +function resolveDomainNode(tokenId: BigInt): string | null { + let mapping = TokenToDomain.load(tokenIdToHex(tokenId)); + return mapping === null ? null : mapping.domain; +} + +/** + * NameRegistered - emitted by DOSRegistrar after commit-reveal registration. + * Provides cost info and name preimage. + * The registry's LabelRegistered already created the Domain + Registration entities. + */ +export function handleNameRegisteredByRegistrar( + event: RegistrarNameRegisteredEvent +): void { + let label = event.params.label; + let tokenId = event.params.tokenId; + let owner = event.params.owner; + let base = event.params.base; + let premium = event.params.premium; + + if (!checkValidLabel(label)) { + return; + } + + let node = resolveDomainNode(tokenId); + if (node === null) { + return; + } + + let cost = base.plus(premium); + + // Update domain name preimage + let domain = Domain.load(node); + if (domain !== null) { + if (domain.labelName !== label) { + domain.labelName = label; + domain.name = label + ".dos"; + domain.save(); + } + + // Update registration with cost + if (domain.labelhash !== null) { + let registration = Registration.load(domain.labelhash!.toHexString()); + if (registration !== null) { + registration.labelName = label; + registration.cost = cost; + registration.save(); + } + } + + // Create NameRegistered registration event + let account = createOrLoadAccount(owner.toHexString()); + let registrationEvent = new NameRegistered(createEventID(event)); + registrationEvent.registration = + domain.labelhash !== null ? domain.labelhash!.toHexString() : node; + registrationEvent.blockNumber = event.block.number.toI32(); + registrationEvent.transactionID = event.transaction.hash; + registrationEvent.registrant = account.id; + registrationEvent.expiryDate = + domain.expiryDate !== null ? domain.expiryDate! : BigInt.fromI32(0); + registrationEvent.save(); + } +} + +/** + * NameRenewed - emitted by DOSRegistrar when a name is renewed. + */ +export function handleNameRenewedByRegistrar( + event: RegistrarNameRenewedEvent +): void { + let label = event.params.label; + let tokenId = event.params.tokenId; + let newExpiry = event.params.newExpiry; + let amount = event.params.amount; + + if (!checkValidLabel(label)) { + return; + } + + let node = resolveDomainNode(tokenId); + if (node === null) { + return; + } + + // Update domain expiry + let domain = Domain.load(node); + if (domain !== null) { + domain.expiryDate = newExpiry; + domain.save(); + + // Update registration + if (domain.labelhash !== null) { + let registration = Registration.load(domain.labelhash!.toHexString()); + if (registration !== null) { + registration.expiryDate = newExpiry; + registration.cost = amount; + registration.labelName = label; + registration.save(); + } + } + + // Create NameRenewed event + let renewedEvent = new NameRenewed(createEventID(event)); + renewedEvent.registration = + domain.labelhash !== null ? domain.labelhash!.toHexString() : node; + renewedEvent.blockNumber = event.block.number.toI32(); + renewedEvent.transactionID = event.transaction.hash; + renewedEvent.expiryDate = newExpiry; + renewedEvent.save(); + } +} diff --git a/subgraph/dos-names/src/registry.ts b/subgraph/dos-names/src/registry.ts new file mode 100644 index 000000000..6d6bc3ee4 --- /dev/null +++ b/subgraph/dos-names/src/registry.ts @@ -0,0 +1,403 @@ +/** + * ENSv2 PermissionedRegistry event handlers for DOS Name Service. + * + * IMPORTANT: In ENSv2, the ERC1155 tokenId != namehash. + * tokenId = labelhash with lower 32 bits replaced by version (LibLabel.withVersion). + * namehash = keccak256(parentNode || labelHash). + * We use a TokenToDomain mapping entity to resolve tokenId → domain. + */ +import { + BigInt, + ByteArray, + Bytes, + crypto, + DataSourceContext, + store, +} from "@graphprotocol/graph-ts"; + +import { + LabelRegistered as LabelRegisteredEvent, + ResolverUpdated as ResolverUpdatedEvent, + ExpiryUpdated as ExpiryUpdatedEvent, + LabelUnregistered as LabelUnregisteredEvent, + SubregistryUpdated as SubregistryUpdatedEvent, + TokenRegenerated as TokenRegeneratedEvent, + TransferSingle as TransferSingleEvent, +} from "./types/DOSTLDRegistry/PermissionedRegistry"; + +import { + Account, + Domain, + NewOwner, + NewResolver, + Registration, + RegistryPath, + Resolver, + ResolverSource, + TokenToDomain, + Transfer, + WrappedDomain, + WrappedTransfer, +} from "./types/schema"; +import { ResolverTemplate, UserRegistryTemplate } from "./types/templates"; + +import { + concat, + createEventID, + createOrLoadAccount, + createOrLoadDomain, + byteArrayFromHex, + checkValidLabel, + DOS_NODE, + EMPTY_ADDRESS, + tokenIdToHex, +} from "./utils"; + +var dosNode: ByteArray = byteArrayFromHex( + DOS_NODE.slice(2) // strip 0x prefix +); + +/** Resolve a tokenId to a domain node (namehash) using TokenToDomain mapping */ +function resolveDomainNode(tokenId: BigInt): string | null { + let tokenHex = tokenIdToHex(tokenId); + let mapping = TokenToDomain.load(tokenHex); + if (mapping !== null) { + return mapping.domain; + } + return null; +} + +/** + * LabelRegistered(uint256 tokenId, bytes32 labelHash, string label, address owner, uint64 expiry, address sender) + */ +export function handleLabelRegistered(event: LabelRegisteredEvent): void { + let label = event.params.label; + let labelHash = event.params.labelHash; + let owner = event.params.owner; + let expiry = event.params.expiry; + let tokenId = event.params.tokenId; + + if (!checkValidLabel(label)) { + return; + } + + // Compute the domain node (namehash) = keccak256(dosNode || labelHash) + let node = crypto.keccak256(concat(dosNode, labelHash)).toHexString(); + + // Save tokenId → domain mapping + let tokenHex = tokenIdToHex(tokenId); + let tokenMapping = new TokenToDomain(tokenHex); + tokenMapping.domain = node; + tokenMapping.save(); + + // Create account + let account = createOrLoadAccount(owner.toHexString()); + + // Create or load the .dos TLD domain (parent) + let parentDomain = createOrLoadDomain(DOS_NODE); + if (parentDomain.name == null) { + parentDomain.name = "dos"; + parentDomain.labelName = "dos"; + parentDomain.isMigrated = true; + parentDomain.createdAt = event.block.timestamp; + parentDomain.save(); + } + + // Create the domain + let domain = Domain.load(node); + let isNew = domain === null; + if (domain === null) { + domain = new Domain(node); + domain.createdAt = event.block.timestamp; + domain.subdomainCount = 0; + domain.storedOffchain = false; + domain.resolvedWithWildcard = false; + domain.isMigrated = true; + } + + domain.owner = account.id; + domain.registrant = account.id; + domain.parent = DOS_NODE; + domain.labelName = label; + domain.labelhash = labelHash; + domain.name = label + ".dos"; + domain.expiryDate = expiry; + domain.tokenId = tokenId; + domain.save(); + + // Update parent subdomain count + if (isNew) { + parentDomain.subdomainCount = parentDomain.subdomainCount + 1; + parentDomain.save(); + } + + // Create Registration entity (id = labelHash hex) + let registration = new Registration(labelHash.toHexString()); + registration.domain = node; + registration.registrationDate = event.block.timestamp; + registration.expiryDate = expiry; + registration.registrant = account.id; + registration.labelName = label; + registration.save(); + + // Create WrappedDomain entity (ENSv2 names are always "wrapped" - ERC1155) + let wrappedDomain = new WrappedDomain(node); + wrappedDomain.domain = node; + wrappedDomain.expiryDate = expiry; + wrappedDomain.fuses = 0; + wrappedDomain.owner = account.id; + wrappedDomain.name = label + ".dos"; + wrappedDomain.save(); + + domain.wrappedOwner = account.id; + domain.save(); + + // Create NewOwner domain event + let domainEvent = new NewOwner(createEventID(event)); + domainEvent.blockNumber = event.block.number.toI32(); + domainEvent.transactionID = event.transaction.hash; + domainEvent.parentDomain = DOS_NODE; + domainEvent.domain = node; + domainEvent.owner = account.id; + domainEvent.save(); +} + +/** + * ResolverUpdated(uint256 tokenId, address resolver, address sender) + */ +export function handleResolverUpdated(event: ResolverUpdatedEvent): void { + let tokenId = event.params.tokenId; + let node = resolveDomainNode(tokenId); + if (node === null) { + return; + } + + let domain = Domain.load(node); + if (domain === null) { + return; + } + + let resolverAddress = event.params.resolver; + if (resolverAddress.toHexString() == EMPTY_ADDRESS) { + domain.resolver = null; + domain.resolvedAddress = null; + domain.save(); + return; + } + + let sourceId = resolverAddress.toHexString(); + let source = ResolverSource.load(sourceId); + if (source === null) { + source = new ResolverSource(sourceId); + source.address = resolverAddress; + source.save(); + ResolverTemplate.create(resolverAddress); + } + + let resolverId = resolverAddress + .toHexString() + .concat("-") + .concat(node); + + let resolver = Resolver.load(resolverId); + if (resolver === null) { + resolver = new Resolver(resolverId); + resolver.domain = node; + resolver.address = resolverAddress; + resolver.save(); + domain.resolvedAddress = null; + } else { + domain.resolvedAddress = resolver.addr; + } + + domain.resolver = resolverId; + domain.save(); + + let domainEvent = new NewResolver(createEventID(event)); + domainEvent.blockNumber = event.block.number.toI32(); + domainEvent.transactionID = event.transaction.hash; + domainEvent.domain = node; + domainEvent.resolver = resolverId; + domainEvent.save(); +} + +/** + * ExpiryUpdated(uint256 tokenId, uint64 newExpiry, address sender) + */ +export function handleExpiryUpdated(event: ExpiryUpdatedEvent): void { + let tokenId = event.params.tokenId; + let node = resolveDomainNode(tokenId); + if (node === null) { + return; + } + + let newExpiry = event.params.newExpiry; + let domain = Domain.load(node); + if (domain === null) { + return; + } + + domain.expiryDate = newExpiry; + domain.save(); + + let wrappedDomain = WrappedDomain.load(node); + if (wrappedDomain !== null) { + wrappedDomain.expiryDate = newExpiry; + wrappedDomain.save(); + } + + if (domain.labelhash !== null) { + let registration = Registration.load(domain.labelhash!.toHexString()); + if (registration !== null) { + registration.expiryDate = newExpiry; + registration.save(); + } + } +} + +/** + * TransferSingle(address operator, address from, address to, uint256 id, uint256 value) + * + * ERC1155 transfer. The `id` is the tokenId (NOT the namehash). + * We use TokenToDomain mapping to find the correct domain. + */ +export function handleTransferSingle(event: TransferSingleEvent): void { + let tokenId = event.params.id; + let to = event.params.to; + + let node = resolveDomainNode(tokenId); + if (node === null) { + // No mapping found - this TransferSingle fired BEFORE LabelRegistered + // (e.g., _mint emits TransferSingle before LabelRegistered in same tx). + // Skip silently - LabelRegistered will set the owner. + return; + } + + let account = createOrLoadAccount(to.toHexString()); + + let domain = Domain.load(node); + if (domain === null) { + return; + } + + domain.owner = account.id; + domain.registrant = account.id; + domain.wrappedOwner = account.id; + domain.save(); + + // Update WrappedDomain owner + let wrappedDomain = WrappedDomain.load(node); + if (wrappedDomain !== null) { + wrappedDomain.owner = account.id; + wrappedDomain.save(); + } + + // Create Transfer event + let transferEvent = new Transfer(createEventID(event)); + transferEvent.blockNumber = event.block.number.toI32(); + transferEvent.transactionID = event.transaction.hash; + transferEvent.domain = node; + transferEvent.owner = account.id; + transferEvent.save(); + + // Create WrappedTransfer event + let wrappedTransfer = new WrappedTransfer( + createEventID(event).concat("-wrapped") + ); + wrappedTransfer.blockNumber = event.block.number.toI32(); + wrappedTransfer.transactionID = event.transaction.hash; + wrappedTransfer.domain = node; + wrappedTransfer.owner = account.id; + wrappedTransfer.save(); + + // Update registration registrant + if (domain.labelhash !== null) { + let registration = Registration.load(domain.labelhash!.toHexString()); + if (registration !== null) { + registration.registrant = account.id; + registration.save(); + } + } +} + +export function handleTokenRegenerated(event: TokenRegeneratedEvent): void { + let oldTokenHex = tokenIdToHex(event.params.oldTokenId); + let oldMapping = TokenToDomain.load(oldTokenHex); + if (oldMapping === null) { + return; + } + + let newTokenHex = tokenIdToHex(event.params.newTokenId); + let newMapping = new TokenToDomain(newTokenHex); + newMapping.domain = oldMapping.domain; + newMapping.save(); + store.remove("TokenToDomain", oldTokenHex); + + let domain = Domain.load(oldMapping.domain); + if (domain !== null) { + domain.tokenId = event.params.newTokenId; + domain.save(); + } +} + +export function handleLabelUnregistered(event: LabelUnregisteredEvent): void { + let tokenHex = tokenIdToHex(event.params.tokenId); + let mapping = TokenToDomain.load(tokenHex); + if (mapping === null) { + return; + } + + let domain = Domain.load(mapping.domain); + if (domain === null) { + store.remove("TokenToDomain", tokenHex); + return; + } + + let zeroAccount = createOrLoadAccount(EMPTY_ADDRESS); + domain.owner = zeroAccount.id; + domain.registrant = zeroAccount.id; + domain.wrappedOwner = zeroAccount.id; + domain.expiryDate = event.block.timestamp; + domain.tokenId = null; + domain.save(); + + let wrappedDomain = WrappedDomain.load(mapping.domain); + if (wrappedDomain !== null) { + wrappedDomain.owner = zeroAccount.id; + wrappedDomain.expiryDate = event.block.timestamp; + wrappedDomain.save(); + } + + if (domain.labelhash !== null) { + let registration = Registration.load(domain.labelhash!.toHexString()); + if (registration !== null) { + registration.registrant = zeroAccount.id; + registration.expiryDate = event.block.timestamp; + registration.save(); + } + } + + store.remove("TokenToDomain", tokenHex); +} + +export function handleSubregistryUpdated(event: SubregistryUpdatedEvent): void { + if (event.params.subregistry.toHexString() == EMPTY_ADDRESS) { + return; + } + + let node = resolveDomainNode(event.params.tokenId); + if (node === null || Domain.load(node) === null) { + return; + } + + let registryAddress = event.params.subregistry.toHexString(); + let pathId = registryAddress.concat("-").concat(node); + let path = new RegistryPath(pathId); + path.registry = event.params.subregistry; + path.parentDomain = node; + path.save(); + + let context = new DataSourceContext(); + context.setBytes("parentNode", Bytes.fromHexString(node)); + UserRegistryTemplate.createWithContext(event.params.subregistry, context); +} diff --git a/subgraph/dos-names/src/resolver.ts b/subgraph/dos-names/src/resolver.ts new file mode 100644 index 000000000..45979b4b0 --- /dev/null +++ b/subgraph/dos-names/src/resolver.ts @@ -0,0 +1,197 @@ +/** + * PermissionedResolver event handlers for DOS Name Service. + * + * These are identical to the ENSv1 resolver handlers - the resolver events + * have the same signatures (AddrChanged, AddressChanged, TextChanged, etc.) + */ +import { Address, Bytes, ethereum } from "@graphprotocol/graph-ts"; + +import { + ABIChanged as ABIChangedEvent, + AddrChanged as AddrChangedEvent, + AddressChanged as AddressChangedEvent, + ContenthashChanged as ContenthashChangedEvent, + NameChanged as NameChangedEvent, + PubkeyChanged as PubkeyChangedEvent, + TextChanged as TextChangedEvent, + VersionChanged as VersionChangedEvent, +} from "./types/Resolver/PermissionedResolver"; + +import { + AbiChanged, + Account, + AddrChanged, + ContenthashChanged, + Domain, + MulticoinAddrChanged, + NameChanged, + PubkeyChanged, + Resolver, + TextChanged, + VersionChanged, +} from "./types/schema"; + +function createResolverID(node: Bytes, resolver: Address): string { + return resolver + .toHexString() + .concat("-") + .concat(node.toHexString()); +} + +function createEventID(event: ethereum.Event): string { + return event.block.number + .toString() + .concat("-") + .concat(event.logIndex.toString()); +} + +function getOrCreateResolver(node: Bytes, address: Address): Resolver { + let id = createResolverID(node, address); + let resolver = Resolver.load(id); + if (resolver === null) { + resolver = new Resolver(id); + resolver.domain = node.toHexString(); + resolver.address = address; + } + return resolver as Resolver; +} + +export function handleAddrChanged(event: AddrChangedEvent): void { + let account = new Account(event.params.a.toHexString()); + account.save(); + + let resolver = getOrCreateResolver(event.params.node, event.address); + resolver.addr = event.params.a.toHexString(); + resolver.save(); + + let domain = Domain.load(event.params.node.toHexString()); + if (domain && domain.resolver == resolver.id) { + domain.resolvedAddress = event.params.a.toHexString(); + domain.save(); + } + + let resolverEvent = new AddrChanged(createEventID(event)); + resolverEvent.resolver = resolver.id; + resolverEvent.blockNumber = event.block.number.toI32(); + resolverEvent.transactionID = event.transaction.hash; + resolverEvent.addr = event.params.a.toHexString(); + resolverEvent.save(); +} + +export function handleMulticoinAddrChanged(event: AddressChangedEvent): void { + let resolver = getOrCreateResolver(event.params.node, event.address); + let coinType = event.params.coinType; + + if (resolver.coinTypes == null) { + resolver.coinTypes = [coinType]; + resolver.save(); + } else { + let coinTypes = resolver.coinTypes!; + if (!coinTypes.includes(coinType)) { + coinTypes.push(coinType); + resolver.coinTypes = coinTypes; + resolver.save(); + } + } + + let resolverEvent = new MulticoinAddrChanged(createEventID(event)); + resolverEvent.resolver = resolver.id; + resolverEvent.blockNumber = event.block.number.toI32(); + resolverEvent.transactionID = event.transaction.hash; + resolverEvent.coinType = coinType; + resolverEvent.addr = event.params.newAddress; + resolverEvent.save(); +} + +export function handleTextChanged(event: TextChangedEvent): void { + let resolver = getOrCreateResolver(event.params.node, event.address); + let key = event.params.key; + + if (resolver.texts == null) { + resolver.texts = [key]; + resolver.save(); + } else { + let texts = resolver.texts!; + if (!texts.includes(key)) { + texts.push(key); + resolver.texts = texts; + resolver.save(); + } + } + + let resolverEvent = new TextChanged(createEventID(event)); + resolverEvent.resolver = createResolverID(event.params.node, event.address); + resolverEvent.blockNumber = event.block.number.toI32(); + resolverEvent.transactionID = event.transaction.hash; + resolverEvent.key = event.params.key; + resolverEvent.value = event.params.value; + resolverEvent.save(); +} + +export function handleContentHashChanged(event: ContenthashChangedEvent): void { + let resolver = getOrCreateResolver(event.params.node, event.address); + resolver.contentHash = event.params.hash; + resolver.save(); + + let resolverEvent = new ContenthashChanged(createEventID(event)); + resolverEvent.resolver = createResolverID(event.params.node, event.address); + resolverEvent.blockNumber = event.block.number.toI32(); + resolverEvent.transactionID = event.transaction.hash; + resolverEvent.hash = event.params.hash; + resolverEvent.save(); +} + +export function handleNameChanged(event: NameChangedEvent): void { + if (event.params.name.indexOf("\u0000") != -1) return; + + let resolver = getOrCreateResolver(event.params.node, event.address); + resolver.save(); + + let resolverEvent = new NameChanged(createEventID(event)); + resolverEvent.resolver = resolver.id; + resolverEvent.blockNumber = event.block.number.toI32(); + resolverEvent.transactionID = event.transaction.hash; + resolverEvent.name = event.params.name; + resolverEvent.save(); +} + +export function handleABIChanged(event: ABIChangedEvent): void { + let resolverEvent = new AbiChanged(createEventID(event)); + resolverEvent.resolver = createResolverID(event.params.node, event.address); + resolverEvent.blockNumber = event.block.number.toI32(); + resolverEvent.transactionID = event.transaction.hash; + resolverEvent.contentType = event.params.contentType; + resolverEvent.save(); +} + +export function handlePubkeyChanged(event: PubkeyChangedEvent): void { + let resolverEvent = new PubkeyChanged(createEventID(event)); + resolverEvent.resolver = createResolverID(event.params.node, event.address); + resolverEvent.blockNumber = event.block.number.toI32(); + resolverEvent.transactionID = event.transaction.hash; + resolverEvent.x = event.params.x; + resolverEvent.y = event.params.y; + resolverEvent.save(); +} + +export function handleVersionChanged(event: VersionChangedEvent): void { + let resolverEvent = new VersionChanged(createEventID(event)); + resolverEvent.blockNumber = event.block.number.toI32(); + resolverEvent.transactionID = event.transaction.hash; + resolverEvent.resolver = createResolverID(event.params.node, event.address); + resolverEvent.version = event.params.newVersion; + resolverEvent.save(); + + let domain = Domain.load(event.params.node.toHexString()); + if (domain && domain.resolver === resolverEvent.resolver) { + domain.resolvedAddress = null; + domain.save(); + } + + let resolver = getOrCreateResolver(event.params.node, event.address); + resolver.addr = null; + resolver.contentHash = null; + resolver.texts = null; + resolver.coinTypes = null; + resolver.save(); +} diff --git a/subgraph/dos-names/src/userRegistry.ts b/subgraph/dos-names/src/userRegistry.ts new file mode 100644 index 000000000..5acfe4fb8 --- /dev/null +++ b/subgraph/dos-names/src/userRegistry.ts @@ -0,0 +1,324 @@ +import { + ByteArray, + Bytes, + crypto, + DataSourceContext, + dataSource, + ethereum, + store, +} from "@graphprotocol/graph-ts"; + +import { + ExpiryUpdated as ExpiryUpdatedEvent, + LabelUnregistered as LabelUnregisteredEvent, + LabelRegistered as LabelRegisteredEvent, + ResolverUpdated as ResolverUpdatedEvent, + SubregistryUpdated as SubregistryUpdatedEvent, + TokenRegenerated as TokenRegeneratedEvent, + TransferSingle as TransferSingleEvent, +} from "./types/templates/UserRegistryTemplate/PermissionedRegistry"; +import { + Domain, + NewResolver, + NewOwner, + Registration, + RegistryPath, + Resolver, + ResolverSource, + TokenToDomain, + Transfer, + WrappedDomain, + WrappedTransfer, +} from "./types/schema"; +import { ResolverTemplate, UserRegistryTemplate } from "./types/templates"; +import { + checkValidLabel, + concat, + createEventID, + createOrLoadAccount, + EMPTY_ADDRESS, + tokenIdToHex, +} from "./utils"; + +function registryTokenId(event: ethereum.Event, tokenId: string): string { + return event.address.toHexString().concat("-").concat(tokenId); +} + +function resolveDomainNode(event: ethereum.Event, tokenId: string): string | null { + let mapping = TokenToDomain.load(registryTokenId(event, tokenId)); + return mapping === null ? null : mapping.domain; +} + +export function handleUserRegistryLabelRegistered(event: LabelRegisteredEvent): void { + let label = event.params.label; + if (!checkValidLabel(label)) { + return; + } + + let context = dataSource.context(); + let parentNode = context.getBytes("parentNode"); + let parentId = parentNode.toHexString(); + let parent = Domain.load(parentId); + if (parent === null || parent.name === null) { + return; + } + + let node = crypto + .keccak256(concat(changetype(parentNode), event.params.labelHash)) + .toHexString(); + let account = createOrLoadAccount(event.params.owner.toHexString()); + let domain = Domain.load(node); + let isNew = domain === null; + if (domain === null) { + domain = new Domain(node); + domain.createdAt = event.block.timestamp; + domain.subdomainCount = 0; + domain.storedOffchain = false; + domain.resolvedWithWildcard = false; + domain.isMigrated = true; + } + + domain.owner = account.id; + domain.registrant = account.id; + domain.wrappedOwner = account.id; + domain.parent = parentId; + domain.labelName = label; + domain.labelhash = event.params.labelHash; + domain.name = label.concat(".").concat(parent.name!); + domain.expiryDate = event.params.expiry; + domain.tokenId = event.params.tokenId; + domain.save(); + + if (isNew) { + parent.subdomainCount = parent.subdomainCount + 1; + parent.save(); + } + + let tokenMapping = new TokenToDomain( + registryTokenId(event, tokenIdToHex(event.params.tokenId)) + ); + tokenMapping.domain = node; + tokenMapping.save(); + + let registration = new Registration(node); + registration.domain = node; + registration.registrationDate = event.block.timestamp; + registration.expiryDate = event.params.expiry; + registration.registrant = account.id; + registration.labelName = label; + registration.save(); + + let wrappedDomain = new WrappedDomain(node); + wrappedDomain.domain = node; + wrappedDomain.expiryDate = event.params.expiry; + wrappedDomain.fuses = 0; + wrappedDomain.owner = account.id; + wrappedDomain.name = domain.name; + wrappedDomain.save(); + + let domainEvent = new NewOwner(createEventID(event)); + domainEvent.blockNumber = event.block.number.toI32(); + domainEvent.transactionID = event.transaction.hash; + domainEvent.parentDomain = parentId; + domainEvent.domain = node; + domainEvent.owner = account.id; + domainEvent.save(); +} + +export function handleUserRegistryResolverUpdated(event: ResolverUpdatedEvent): void { + let node = resolveDomainNode(event, tokenIdToHex(event.params.tokenId)); + if (node === null) { + return; + } + + let domain = Domain.load(node); + if (domain === null) { + return; + } + + let resolverAddress = event.params.resolver; + if (resolverAddress.toHexString() == EMPTY_ADDRESS) { + domain.resolver = null; + domain.resolvedAddress = null; + domain.save(); + return; + } + + let sourceId = resolverAddress.toHexString(); + let source = ResolverSource.load(sourceId); + if (source === null) { + source = new ResolverSource(sourceId); + source.address = resolverAddress; + source.save(); + ResolverTemplate.create(resolverAddress); + } + + let resolverId = sourceId.concat("-").concat(node); + let resolver = Resolver.load(resolverId); + if (resolver === null) { + resolver = new Resolver(resolverId); + resolver.domain = node; + resolver.address = resolverAddress; + resolver.save(); + } + + domain.resolver = resolverId; + domain.resolvedAddress = resolver.addr; + domain.save(); + + let domainEvent = new NewResolver(createEventID(event)); + domainEvent.domain = node; + domainEvent.blockNumber = event.block.number.toI32(); + domainEvent.transactionID = event.transaction.hash; + domainEvent.resolver = resolverId; + domainEvent.save(); +} + +export function handleUserRegistryExpiryUpdated(event: ExpiryUpdatedEvent): void { + let node = resolveDomainNode(event, tokenIdToHex(event.params.tokenId)); + if (node === null) { + return; + } + + let domain = Domain.load(node); + if (domain !== null) { + domain.expiryDate = event.params.newExpiry; + domain.save(); + } + + let wrappedDomain = WrappedDomain.load(node); + if (wrappedDomain !== null) { + wrappedDomain.expiryDate = event.params.newExpiry; + wrappedDomain.save(); + } + + let registration = Registration.load(node); + if (registration !== null) { + registration.expiryDate = event.params.newExpiry; + registration.save(); + } +} + +export function handleUserRegistryTransferSingle(event: TransferSingleEvent): void { + let node = resolveDomainNode(event, tokenIdToHex(event.params.id)); + if (node === null) { + return; + } + + let domain = Domain.load(node); + if (domain === null) { + return; + } + + let account = createOrLoadAccount(event.params.to.toHexString()); + domain.owner = account.id; + domain.registrant = account.id; + domain.wrappedOwner = account.id; + domain.save(); + + let wrappedDomain = WrappedDomain.load(node); + if (wrappedDomain !== null) { + wrappedDomain.owner = account.id; + wrappedDomain.save(); + } + + let registration = Registration.load(node); + if (registration !== null) { + registration.registrant = account.id; + registration.save(); + } + + let transferEvent = new Transfer(createEventID(event)); + transferEvent.domain = node; + transferEvent.blockNumber = event.block.number.toI32(); + transferEvent.transactionID = event.transaction.hash; + transferEvent.owner = account.id; + transferEvent.save(); + + let wrappedTransfer = new WrappedTransfer(createEventID(event).concat("-wrapped")); + wrappedTransfer.domain = node; + wrappedTransfer.blockNumber = event.block.number.toI32(); + wrappedTransfer.transactionID = event.transaction.hash; + wrappedTransfer.owner = account.id; + wrappedTransfer.save(); +} + +export function handleUserRegistryTokenRegenerated(event: TokenRegeneratedEvent): void { + let oldId = registryTokenId(event, tokenIdToHex(event.params.oldTokenId)); + let oldMapping = TokenToDomain.load(oldId); + if (oldMapping === null) { + return; + } + + let newId = registryTokenId(event, tokenIdToHex(event.params.newTokenId)); + let newMapping = new TokenToDomain(newId); + newMapping.domain = oldMapping.domain; + newMapping.save(); + store.remove("TokenToDomain", oldId); + + let domain = Domain.load(oldMapping.domain); + if (domain !== null) { + domain.tokenId = event.params.newTokenId; + domain.save(); + } +} + +export function handleUserRegistrySubregistryUpdated(event: SubregistryUpdatedEvent): void { + if (event.params.subregistry.toHexString() == EMPTY_ADDRESS) { + return; + } + + let node = resolveDomainNode(event, tokenIdToHex(event.params.tokenId)); + if (node === null || Domain.load(node) === null) { + return; + } + + let registryAddress = event.params.subregistry.toHexString(); + let pathId = registryAddress.concat("-").concat(node); + let path = new RegistryPath(pathId); + path.registry = event.params.subregistry; + path.parentDomain = node; + path.save(); + + let context = new DataSourceContext(); + context.setBytes("parentNode", Bytes.fromHexString(node)); + UserRegistryTemplate.createWithContext(event.params.subregistry, context); +} + +export function handleUserRegistryLabelUnregistered(event: LabelUnregisteredEvent): void { + let tokenKey = registryTokenId(event, tokenIdToHex(event.params.tokenId)); + let mapping = TokenToDomain.load(tokenKey); + if (mapping === null) { + return; + } + + let domain = Domain.load(mapping.domain); + if (domain === null) { + store.remove("TokenToDomain", tokenKey); + return; + } + + let zeroAccount = createOrLoadAccount(EMPTY_ADDRESS); + domain.owner = zeroAccount.id; + domain.registrant = zeroAccount.id; + domain.wrappedOwner = zeroAccount.id; + domain.expiryDate = event.block.timestamp; + domain.tokenId = null; + domain.save(); + + let wrappedDomain = WrappedDomain.load(mapping.domain); + if (wrappedDomain !== null) { + wrappedDomain.owner = zeroAccount.id; + wrappedDomain.expiryDate = event.block.timestamp; + wrappedDomain.save(); + } + + let registration = Registration.load(mapping.domain); + if (registration !== null) { + registration.registrant = zeroAccount.id; + registration.expiryDate = event.block.timestamp; + registration.save(); + } + + store.remove("TokenToDomain", tokenKey); +} diff --git a/subgraph/dos-names/src/utils.ts b/subgraph/dos-names/src/utils.ts new file mode 100644 index 000000000..033206e11 --- /dev/null +++ b/subgraph/dos-names/src/utils.ts @@ -0,0 +1,88 @@ +import { BigInt, ByteArray, ethereum } from "@graphprotocol/graph-ts"; +import { Account, Domain } from "./types/schema"; + +export function createEventID(event: ethereum.Event): string { + return event.block.number + .toString() + .concat("-") + .concat(event.logIndex.toString()); +} + +// namehash("dos") - the TLD node for .dos names +export const DOS_NODE = + "0x8e1f7a0df062729dae36d32364311b5d5489b24e89ccd756d515451da642bb92"; + +export const ROOT_NODE = + "0x0000000000000000000000000000000000000000000000000000000000000000"; +export const EMPTY_ADDRESS = "0x0000000000000000000000000000000000000000"; +export const EMPTY_ADDRESS_BYTEARRAY = new ByteArray(20); + +export function concat(a: ByteArray, b: ByteArray): ByteArray { + let out = new Uint8Array(a.length + b.length); + for (let i = 0; i < a.length; i++) { + out[i] = a[i]; + } + for (let j = 0; j < b.length; j++) { + out[a.length + j] = b[j]; + } + return changetype(out); +} + +export function byteArrayFromHex(s: string): ByteArray { + if (s.length % 2 !== 0) { + throw new TypeError("Hex string must have an even number of characters"); + } + let out = new Uint8Array(s.length / 2); + for (var i = 0; i < s.length; i += 2) { + out[i / 2] = parseInt(s.substring(i, i + 2), 16) as u32; + } + return changetype(out); +} + +export function uint256ToByteArray(i: BigInt): ByteArray { + let hex = i + .toHex() + .slice(2) + .padStart(64, "0"); + return byteArrayFromHex(hex); +} + +export function tokenIdToHex(tokenId: BigInt): string { + return "0x" + tokenId.toHex().slice(2).padStart(64, "0"); +} + +export function createOrLoadAccount(address: string): Account { + let account = Account.load(address); + if (account == null) { + account = new Account(address); + account.save(); + } + return account; +} + +export function createOrLoadDomain(node: string): Domain { + let domain = Domain.load(node); + if (domain == null) { + domain = new Domain(node); + domain.owner = EMPTY_ADDRESS; + domain.isMigrated = true; + domain.createdAt = BigInt.fromI32(0); + domain.subdomainCount = 0; + domain.storedOffchain = false; + domain.resolvedWithWildcard = false; + domain.save(); + } + return domain; +} + +export function checkValidLabel(name: string): boolean { + for (let i = 0; i < name.length; i++) { + let c = name.charCodeAt(i); + if (c === 0) { + return false; + } else if (c === 46) { + return false; + } + } + return true; +} diff --git a/subgraph/dos-names/subgraph.template.yaml b/subgraph/dos-names/subgraph.template.yaml new file mode 100644 index 000000000..7272ee989 --- /dev/null +++ b/subgraph/dos-names/subgraph.template.yaml @@ -0,0 +1,181 @@ +specVersion: 0.0.5 +description: DOS Name Service (.dos) - ENSv2 fork on DOS Chain +schema: + file: ./schema.graphql +dataSources: + # DOSTLDRegistry (PermissionedRegistry) - .dos TLD registry + # Emits: NameRegistered, ResolverUpdated, ExpiryUpdated, SubregistryUpdated, TransferSingle + - kind: ethereum/contract + name: DOSTLDRegistry + network: dos-testnet + source: + abi: PermissionedRegistry + address: "__DOS_REGISTRY_ADDRESS__" + startBlock: __START_BLOCK__ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + file: ./src/registry.ts + entities: + - Domain + - Account + - Registration + abis: + - name: PermissionedRegistry + file: ./abis/PermissionedRegistry.json + eventHandlers: + - event: LabelRegistered(indexed uint256,indexed bytes32,string,address,uint64,indexed address) + handler: handleLabelRegistered + - event: ResolverUpdated(indexed uint256,indexed address,indexed address) + handler: handleResolverUpdated + - event: ExpiryUpdated(indexed uint256,indexed uint64,indexed address) + handler: handleExpiryUpdated + - event: TransferSingle(indexed address,indexed address,indexed address,uint256,uint256) + handler: handleTransferSingle + - event: TokenRegenerated(indexed uint256,indexed uint256) + handler: handleTokenRegenerated + - event: SubregistryUpdated(indexed uint256,indexed address,indexed address) + handler: handleSubregistryUpdated + - event: LabelUnregistered(indexed uint256,indexed address) + handler: handleLabelUnregistered + + # DOSRegistrar - commit-reveal registrar for .dos names + # Emits: NameRegistered (with cost info), NameRenewed + - kind: ethereum/contract + name: DOSRegistrar + network: dos-testnet + source: + abi: DOSRegistrar + address: "__DOS_REGISTRAR_ADDRESS__" + startBlock: __START_BLOCK__ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + file: ./src/registrar.ts + entities: + - Registration + - NameRegistered + - NameRenewed + abis: + - name: DOSRegistrar + file: ./abis/DOSRegistrar.json + eventHandlers: + - event: NameRegistered(indexed uint256,string,address,address,address,uint64,address,indexed bytes32,uint256,uint256) + handler: handleNameRegisteredByRegistrar + - event: NameRenewed(indexed uint256,string,uint64,uint64,address,indexed bytes32,uint256) + handler: handleNameRenewedByRegistrar + + # PermissionedResolver proxy - resolver events + # Emits: AddrChanged, AddressChanged, TextChanged, ContenthashChanged, etc. + - kind: ethereum/contract + name: Resolver + network: dos-testnet + source: + abi: PermissionedResolver + address: "__PERMISSIONED_RESOLVER_IMPLEMENTATION_ADDRESS__" + startBlock: __START_BLOCK__ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + file: ./src/resolver.ts + entities: + - Resolver + - AddrChanged + - MulticoinAddrChanged + - TextChanged + - ContenthashChanged + abis: + - name: PermissionedResolver + file: ./abis/PermissionedResolver.json + eventHandlers: + - event: AddrChanged(indexed bytes32,address) + handler: handleAddrChanged + - event: AddressChanged(indexed bytes32,uint256,bytes) + handler: handleMulticoinAddrChanged + - event: TextChanged(indexed bytes32,indexed string,string,string) + handler: handleTextChanged + - event: ContenthashChanged(indexed bytes32,bytes) + handler: handleContentHashChanged + - event: NameChanged(indexed bytes32,string) + handler: handleNameChanged + - event: ABIChanged(indexed bytes32,indexed uint256) + handler: handleABIChanged + - event: PubkeyChanged(indexed bytes32,bytes32,bytes32) + handler: handlePubkeyChanged + - event: VersionChanged(indexed bytes32,uint64) + handler: handleVersionChanged + +templates: + - kind: ethereum/contract + name: UserRegistryTemplate + network: dos-testnet + source: + abi: PermissionedRegistry + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + file: ./src/userRegistry.ts + entities: + - Domain + - Account + - Registration + - RegistryPath + abis: + - name: PermissionedRegistry + file: ./abis/PermissionedRegistry.json + eventHandlers: + - event: LabelRegistered(indexed uint256,indexed bytes32,string,address,uint64,indexed address) + handler: handleUserRegistryLabelRegistered + - event: ResolverUpdated(indexed uint256,indexed address,indexed address) + handler: handleUserRegistryResolverUpdated + - event: ExpiryUpdated(indexed uint256,indexed uint64,indexed address) + handler: handleUserRegistryExpiryUpdated + - event: TransferSingle(indexed address,indexed address,indexed address,uint256,uint256) + handler: handleUserRegistryTransferSingle + - event: TokenRegenerated(indexed uint256,indexed uint256) + handler: handleUserRegistryTokenRegenerated + - event: SubregistryUpdated(indexed uint256,indexed address,indexed address) + handler: handleUserRegistrySubregistryUpdated + - event: LabelUnregistered(indexed uint256,indexed address) + handler: handleUserRegistryLabelUnregistered + + - kind: ethereum/contract + name: ResolverTemplate + network: dos-testnet + source: + abi: PermissionedResolver + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + file: ./src/resolver.ts + entities: + - Resolver + - AddrChanged + - MulticoinAddrChanged + - TextChanged + - ContenthashChanged + abis: + - name: PermissionedResolver + file: ./abis/PermissionedResolver.json + eventHandlers: + - event: AddrChanged(indexed bytes32,address) + handler: handleAddrChanged + - event: AddressChanged(indexed bytes32,uint256,bytes) + handler: handleMulticoinAddrChanged + - event: TextChanged(indexed bytes32,indexed string,string,string) + handler: handleTextChanged + - event: ContenthashChanged(indexed bytes32,bytes) + handler: handleContentHashChanged + - event: NameChanged(indexed bytes32,string) + handler: handleNameChanged + - event: ABIChanged(indexed bytes32,indexed uint256) + handler: handleABIChanged + - event: PubkeyChanged(indexed bytes32,bytes32,bytes32) + handler: handlePubkeyChanged + - event: VersionChanged(indexed bytes32,uint64) + handler: handleVersionChanged diff --git a/subgraph/dos-names/tests/fixtures/dos-testnet-3939.json b/subgraph/dos-names/tests/fixtures/dos-testnet-3939.json new file mode 100644 index 000000000..8000eb435 --- /dev/null +++ b/subgraph/dos-names/tests/fixtures/dos-testnet-3939.json @@ -0,0 +1,9 @@ +{ + "chainId": 3939, + "deploymentBlock": 0, + "contracts": { + "dosRegistry": "0x1111111111111111111111111111111111111111", + "dosRegistrar": "0x2222222222222222222222222222222222222222", + "permissionedResolverImplementation": "0x3333333333333333333333333333333333333333" + } +} diff --git a/subgraph/dos-names/tests/registrar.test.ts b/subgraph/dos-names/tests/registrar.test.ts new file mode 100644 index 000000000..db52b8008 --- /dev/null +++ b/subgraph/dos-names/tests/registrar.test.ts @@ -0,0 +1,185 @@ +import { Address, BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts"; +import { + afterEach, + assert, + clearStore, + newMockEvent, + test, +} from "matchstick-as/assembly/index"; + +import { + handleNameRegisteredByRegistrar, + handleNameRenewedByRegistrar, +} from "../src/registrar"; +import { handleLabelRegistered } from "../src/registry"; +import { NameRegistered as RegistrarNameRegistered } from "../src/types/DOSRegistrar/DOSRegistrar"; +import { NameRenewed as RegistrarNameRenewed } from "../src/types/DOSRegistrar/DOSRegistrar"; +import { LabelRegistered as RegistryLabelRegistered } from "../src/types/DOSTLDRegistry/PermissionedRegistry"; + +const OWNER = "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7"; +const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"; +const ZERO_BYTES32 = + "0x0000000000000000000000000000000000000000000000000000000000000000"; +const LABEL_HASH = + "0x9c0257114eb9399a2985f8e75dad7600c5d89fe3824ffa99ec1c3eb8bf3b0501"; +const ALICE_DOS = + "0x424d8e54ceea7400cbef56f721accb0a42bf370777b1439bfaee1d4eb678040f"; + +function registryRegistration(tokenId: i32): RegistryLabelRegistered { + let mock = newMockEvent(); + let event = new RegistryLabelRegistered( + mock.address, + mock.logIndex, + mock.transactionLogIndex, + mock.logType, + mock.block, + mock.transaction, + mock.parameters, + mock.receipt + ); + event.parameters = [ + new ethereum.EventParam( + "tokenId", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(tokenId)) + ), + new ethereum.EventParam( + "labelHash", + ethereum.Value.fromFixedBytes(Bytes.fromHexString(LABEL_HASH)) + ), + new ethereum.EventParam("label", ethereum.Value.fromString("alice")), + new ethereum.EventParam( + "owner", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + new ethereum.EventParam( + "expiry", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(2_000_000_000)) + ), + new ethereum.EventParam( + "sender", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + ]; + return event; +} + +function registrarRegistration(tokenId: i32): RegistrarNameRegistered { + let mock = newMockEvent(); + mock.logIndex = BigInt.fromI32(1); + let event = new RegistrarNameRegistered( + mock.address, + mock.logIndex, + mock.transactionLogIndex, + mock.logType, + mock.block, + mock.transaction, + mock.parameters, + mock.receipt + ); + event.parameters = [ + new ethereum.EventParam( + "tokenId", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(tokenId)) + ), + new ethereum.EventParam("label", ethereum.Value.fromString("alice")), + new ethereum.EventParam( + "owner", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + new ethereum.EventParam( + "subregistry", + ethereum.Value.fromAddress(Address.fromString(ZERO_ADDRESS)) + ), + new ethereum.EventParam( + "resolver", + ethereum.Value.fromAddress(Address.fromString(ZERO_ADDRESS)) + ), + new ethereum.EventParam( + "duration", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(31_536_000)) + ), + new ethereum.EventParam( + "paymentToken", + ethereum.Value.fromAddress(Address.fromString(ZERO_ADDRESS)) + ), + new ethereum.EventParam( + "referrer", + ethereum.Value.fromFixedBytes(Bytes.fromHexString(ZERO_BYTES32)) + ), + new ethereum.EventParam( + "base", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(10)) + ), + new ethereum.EventParam( + "premium", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(2)) + ), + ]; + return event; +} + +function registrarRenewal(tokenId: i32): RegistrarNameRenewed { + let mock = newMockEvent(); + mock.logIndex = BigInt.fromI32(2); + let event = new RegistrarNameRenewed( + mock.address, + mock.logIndex, + mock.transactionLogIndex, + mock.logType, + mock.block, + mock.transaction, + mock.parameters, + mock.receipt + ); + event.parameters = [ + new ethereum.EventParam( + "tokenId", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(tokenId)) + ), + new ethereum.EventParam("label", ethereum.Value.fromString("alice")), + new ethereum.EventParam( + "duration", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(31_536_000)) + ), + new ethereum.EventParam( + "newExpiry", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(2_100_000_000)) + ), + new ethereum.EventParam( + "paymentToken", + ethereum.Value.fromAddress(Address.fromString(ZERO_ADDRESS)) + ), + new ethereum.EventParam( + "referrer", + ethereum.Value.fromFixedBytes(Bytes.fromHexString(ZERO_BYTES32)) + ), + new ethereum.EventParam( + "amount", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(7)) + ), + ]; + return event; +} + +afterEach(() => { + clearStore(); +}); + +test("registrar enriches the domain mapped from an ENSv2 token ID", () => { + handleLabelRegistered(registryRegistration(123)); + handleNameRegisteredByRegistrar(registrarRegistration(123)); + + assert.fieldEquals("Domain", ALICE_DOS, "name", "alice.dos"); + assert.fieldEquals("Registration", LABEL_HASH, "cost", "12"); + assert.entityCount("NameRegistered", 1); +}); + +test("registrar renewal stores the ENSv2 amount and new expiry", () => { + handleLabelRegistered(registryRegistration(123)); + handleNameRenewedByRegistrar(registrarRenewal(123)); + + assert.fieldEquals("Domain", ALICE_DOS, "expiryDate", "2100000000"); + assert.fieldEquals("Registration", LABEL_HASH, "cost", "7"); + assert.fieldEquals("Registration", LABEL_HASH, "expiryDate", "2100000000"); + assert.entityCount("NameRenewed", 1); +}); diff --git a/subgraph/dos-names/tests/registry.test.ts b/subgraph/dos-names/tests/registry.test.ts new file mode 100644 index 000000000..475bef7e3 --- /dev/null +++ b/subgraph/dos-names/tests/registry.test.ts @@ -0,0 +1,682 @@ +import { + Address, + BigInt, + Bytes, + DataSourceContext, + ethereum, +} from "@graphprotocol/graph-ts"; +import { + afterEach, + assert, + clearStore, + dataSourceMock, + newMockEvent, + test, +} from "matchstick-as/assembly/index"; + +import { + handleLabelRegistered, + handleLabelUnregistered, + handleResolverUpdated, + handleSubregistryUpdated, + handleTokenRegenerated, + handleTransferSingle, +} from "../src/registry"; +import { + handleUserRegistryLabelRegistered, + handleUserRegistryLabelUnregistered, + handleUserRegistryExpiryUpdated, + handleUserRegistryResolverUpdated, + handleUserRegistryTokenRegenerated, + handleUserRegistrySubregistryUpdated, + handleUserRegistryTransferSingle, +} from "../src/userRegistry"; +import { + LabelRegistered, + LabelUnregistered, + ResolverUpdated, + SubregistryUpdated, + TokenRegenerated, + TransferSingle, +} from "../src/types/DOSTLDRegistry/PermissionedRegistry"; +import { LabelRegistered as UserRegistryLabelRegistered } from "../src/types/templates/UserRegistryTemplate/PermissionedRegistry"; +import { LabelUnregistered as UserRegistryLabelUnregistered } from "../src/types/templates/UserRegistryTemplate/PermissionedRegistry"; +import { TransferSingle as UserRegistryTransferSingle } from "../src/types/templates/UserRegistryTemplate/PermissionedRegistry"; +import { ResolverUpdated as UserRegistryResolverUpdated } from "../src/types/templates/UserRegistryTemplate/PermissionedRegistry"; +import { ExpiryUpdated as UserRegistryExpiryUpdated } from "../src/types/templates/UserRegistryTemplate/PermissionedRegistry"; +import { TokenRegenerated as UserRegistryTokenRegenerated } from "../src/types/templates/UserRegistryTemplate/PermissionedRegistry"; +import { SubregistryUpdated as UserRegistrySubregistryUpdated } from "../src/types/templates/UserRegistryTemplate/PermissionedRegistry"; +import { Domain } from "../src/types/schema"; + +const OWNER = "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7"; +const NEW_OWNER = "0x4976fb03c32e5b8cfe2b6ccb31c09ba78ebaba41"; +const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"; +const USER_REGISTRY = "0x1111111111111111111111111111111111111111"; +const RESOLVER = "0x2222222222222222222222222222222222222222"; +const NESTED_REGISTRY = "0x3333333333333333333333333333333333333333"; +const LABEL_HASH = + "0x9c0257114eb9399a2985f8e75dad7600c5d89fe3824ffa99ec1c3eb8bf3b0501"; +const ALICE_DOS = + "0x424d8e54ceea7400cbef56f721accb0a42bf370777b1439bfaee1d4eb678040f"; +const SUB_LABEL_HASH = + "0xfa1ea47215815692a5f1391cff19abbaf694c82fb2151a4c351b6c0eeaaf317b"; +const SUB_ALICE_DOS = + "0x1c1ff2cdbb0b7cc0b67c4b92a0ba7633d2cf2d2e756ea950fbe437050296f930"; + +function registration(tokenId: i32): LabelRegistered { + let mock = newMockEvent(); + let event = new LabelRegistered( + mock.address, + mock.logIndex, + mock.transactionLogIndex, + mock.logType, + mock.block, + mock.transaction, + mock.parameters, + mock.receipt + ); + event.parameters = [ + new ethereum.EventParam( + "tokenId", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(tokenId)) + ), + new ethereum.EventParam( + "labelHash", + ethereum.Value.fromFixedBytes(Bytes.fromHexString(LABEL_HASH)) + ), + new ethereum.EventParam("label", ethereum.Value.fromString("alice")), + new ethereum.EventParam( + "owner", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + new ethereum.EventParam( + "expiry", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(2_000_000_000)) + ), + new ethereum.EventParam( + "sender", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + ]; + return event; +} + +function regeneration(oldTokenId: i32, newTokenId: i32): TokenRegenerated { + let mock = newMockEvent(); + mock.logIndex = BigInt.fromI32(1); + let event = new TokenRegenerated( + mock.address, + mock.logIndex, + mock.transactionLogIndex, + mock.logType, + mock.block, + mock.transaction, + mock.parameters, + mock.receipt + ); + event.parameters = [ + new ethereum.EventParam( + "oldTokenId", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(oldTokenId)) + ), + new ethereum.EventParam( + "newTokenId", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(newTokenId)) + ), + ]; + return event; +} + +function subregistryUpdated(tokenId: i32): SubregistryUpdated { + let mock = newMockEvent(); + mock.logIndex = BigInt.fromI32(1); + let event = new SubregistryUpdated( + mock.address, + mock.logIndex, + mock.transactionLogIndex, + mock.logType, + mock.block, + mock.transaction, + mock.parameters, + mock.receipt + ); + event.parameters = [ + new ethereum.EventParam( + "tokenId", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(tokenId)) + ), + new ethereum.EventParam( + "subregistry", + ethereum.Value.fromAddress(Address.fromString(USER_REGISTRY)) + ), + new ethereum.EventParam( + "sender", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + ]; + return event; +} + +function resolverUpdated(tokenId: i32, resolver: string, logIndex: i32): ResolverUpdated { + let mock = newMockEvent(); + mock.logIndex = BigInt.fromI32(logIndex); + let event = new ResolverUpdated( + mock.address, + mock.logIndex, + mock.transactionLogIndex, + mock.logType, + mock.block, + mock.transaction, + mock.parameters, + mock.receipt + ); + event.parameters = [ + new ethereum.EventParam( + "tokenId", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(tokenId)) + ), + new ethereum.EventParam( + "resolver", + ethereum.Value.fromAddress(Address.fromString(resolver)) + ), + new ethereum.EventParam( + "sender", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + ]; + return event; +} + +function labelUnregistered(tokenId: i32): LabelUnregistered { + let mock = newMockEvent(); + mock.logIndex = BigInt.fromI32(1); + mock.block.timestamp = BigInt.fromI32(2_000_000_100); + let event = new LabelUnregistered( + mock.address, + mock.logIndex, + mock.transactionLogIndex, + mock.logType, + mock.block, + mock.transaction, + mock.parameters, + mock.receipt + ); + event.parameters = [ + new ethereum.EventParam( + "tokenId", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(tokenId)) + ), + new ethereum.EventParam( + "sender", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + ]; + return event; +} + +function transfer(tokenId: i32): TransferSingle { + let mock = newMockEvent(); + mock.logIndex = BigInt.fromI32(2); + let event = new TransferSingle( + mock.address, + mock.logIndex, + mock.transactionLogIndex, + mock.logType, + mock.block, + mock.transaction, + mock.parameters, + mock.receipt + ); + event.parameters = [ + new ethereum.EventParam( + "operator", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + new ethereum.EventParam( + "from", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + new ethereum.EventParam( + "to", + ethereum.Value.fromAddress(Address.fromString(NEW_OWNER)) + ), + new ethereum.EventParam( + "id", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(tokenId)) + ), + new ethereum.EventParam( + "value", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(1)) + ), + ]; + return event; +} + +function userRegistryRegistration(tokenId: i32): UserRegistryLabelRegistered { + let mock = newMockEvent(); + mock.address = Address.fromString(USER_REGISTRY); + let event = new UserRegistryLabelRegistered( + mock.address, + mock.logIndex, + mock.transactionLogIndex, + mock.logType, + mock.block, + mock.transaction, + mock.parameters, + mock.receipt + ); + event.parameters = [ + new ethereum.EventParam( + "tokenId", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(tokenId)) + ), + new ethereum.EventParam( + "labelHash", + ethereum.Value.fromFixedBytes(Bytes.fromHexString(SUB_LABEL_HASH)) + ), + new ethereum.EventParam("label", ethereum.Value.fromString("sub")), + new ethereum.EventParam( + "owner", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + new ethereum.EventParam( + "expiry", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(2_000_000_000)) + ), + new ethereum.EventParam( + "sender", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + ]; + return event; +} + +function userRegistryLabelUnregistered(tokenId: i32): UserRegistryLabelUnregistered { + let mock = newMockEvent(); + mock.address = Address.fromString(USER_REGISTRY); + mock.logIndex = BigInt.fromI32(2); + mock.block.timestamp = BigInt.fromI32(2_000_000_200); + let event = new UserRegistryLabelUnregistered( + mock.address, + mock.logIndex, + mock.transactionLogIndex, + mock.logType, + mock.block, + mock.transaction, + mock.parameters, + mock.receipt + ); + event.parameters = [ + new ethereum.EventParam( + "tokenId", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(tokenId)) + ), + new ethereum.EventParam( + "sender", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + ]; + return event; +} + +function userRegistryTransfer(tokenId: i32): UserRegistryTransferSingle { + let mock = newMockEvent(); + mock.address = Address.fromString(USER_REGISTRY); + mock.logIndex = BigInt.fromI32(1); + let event = new UserRegistryTransferSingle( + mock.address, + mock.logIndex, + mock.transactionLogIndex, + mock.logType, + mock.block, + mock.transaction, + mock.parameters, + mock.receipt + ); + event.parameters = [ + new ethereum.EventParam( + "operator", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + new ethereum.EventParam( + "from", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + new ethereum.EventParam( + "to", + ethereum.Value.fromAddress(Address.fromString(NEW_OWNER)) + ), + new ethereum.EventParam( + "id", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(tokenId)) + ), + new ethereum.EventParam( + "value", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(1)) + ), + ]; + return event; +} + +function userRegistryResolverUpdated(tokenId: i32): UserRegistryResolverUpdated { + let mock = newMockEvent(); + mock.address = Address.fromString(USER_REGISTRY); + mock.logIndex = BigInt.fromI32(1); + let event = new UserRegistryResolverUpdated( + mock.address, + mock.logIndex, + mock.transactionLogIndex, + mock.logType, + mock.block, + mock.transaction, + mock.parameters, + mock.receipt + ); + event.parameters = [ + new ethereum.EventParam( + "tokenId", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(tokenId)) + ), + new ethereum.EventParam( + "resolver", + ethereum.Value.fromAddress(Address.fromString(RESOLVER)) + ), + new ethereum.EventParam( + "sender", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + ]; + return event; +} + +function userRegistryExpiryUpdated(tokenId: i32): UserRegistryExpiryUpdated { + let mock = newMockEvent(); + mock.address = Address.fromString(USER_REGISTRY); + mock.logIndex = BigInt.fromI32(1); + let event = new UserRegistryExpiryUpdated( + mock.address, + mock.logIndex, + mock.transactionLogIndex, + mock.logType, + mock.block, + mock.transaction, + mock.parameters, + mock.receipt + ); + event.parameters = [ + new ethereum.EventParam( + "tokenId", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(tokenId)) + ), + new ethereum.EventParam( + "newExpiry", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(2_100_000_000)) + ), + new ethereum.EventParam( + "sender", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + ]; + return event; +} + +function userRegistryTokenRegenerated( + oldTokenId: i32, + newTokenId: i32 +): UserRegistryTokenRegenerated { + let mock = newMockEvent(); + mock.address = Address.fromString(USER_REGISTRY); + mock.logIndex = BigInt.fromI32(1); + let event = new UserRegistryTokenRegenerated( + mock.address, + mock.logIndex, + mock.transactionLogIndex, + mock.logType, + mock.block, + mock.transaction, + mock.parameters, + mock.receipt + ); + event.parameters = [ + new ethereum.EventParam( + "oldTokenId", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(oldTokenId)) + ), + new ethereum.EventParam( + "newTokenId", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(newTokenId)) + ), + ]; + return event; +} + +function userRegistrySubregistryUpdated(tokenId: i32): UserRegistrySubregistryUpdated { + let mock = newMockEvent(); + mock.address = Address.fromString(USER_REGISTRY); + mock.logIndex = BigInt.fromI32(1); + let event = new UserRegistrySubregistryUpdated( + mock.address, + mock.logIndex, + mock.transactionLogIndex, + mock.logType, + mock.block, + mock.transaction, + mock.parameters, + mock.receipt + ); + event.parameters = [ + new ethereum.EventParam( + "tokenId", + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(tokenId)) + ), + new ethereum.EventParam( + "subregistry", + ethereum.Value.fromAddress(Address.fromString(NESTED_REGISTRY)) + ), + new ethereum.EventParam( + "sender", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + ]; + return event; +} + +afterEach(() => { + clearStore(); +}); + +test("token regeneration preserves the canonical domain mapping", () => { + handleLabelRegistered(registration(123)); + handleTokenRegenerated(regeneration(123, 456)); + handleTransferSingle(transfer(456)); + + assert.fieldEquals("Domain", ALICE_DOS, "owner", NEW_OWNER); + assert.fieldEquals("Domain", ALICE_DOS, "tokenId", "456"); + assert.fieldEquals( + "TokenToDomain", + "0x00000000000000000000000000000000000000000000000000000000000001c8", + "domain", + ALICE_DOS + ); + assert.notInStore( + "TokenToDomain", + "0x000000000000000000000000000000000000000000000000000000000000007b" + ); +}); + +test("a discovered user registry indexes a subname under its parent path", () => { + handleLabelRegistered(registration(123)); + + let context = new DataSourceContext(); + context.setBytes("parentNode", Bytes.fromHexString(ALICE_DOS)); + dataSourceMock.setContext(context); + + handleUserRegistryLabelRegistered(userRegistryRegistration(456)); + + assert.fieldEquals("Domain", SUB_ALICE_DOS, "name", "sub.alice.dos"); + assert.fieldEquals("Domain", SUB_ALICE_DOS, "parent", ALICE_DOS); + assert.fieldEquals("Domain", ALICE_DOS, "subdomainCount", "1"); +}); + +test("a user-registry token transfer updates the subname owner", () => { + handleLabelRegistered(registration(123)); + let context = new DataSourceContext(); + context.setBytes("parentNode", Bytes.fromHexString(ALICE_DOS)); + dataSourceMock.setContext(context); + handleUserRegistryLabelRegistered(userRegistryRegistration(456)); + + handleUserRegistryTransferSingle(userRegistryTransfer(456)); + + assert.fieldEquals("Domain", SUB_ALICE_DOS, "owner", NEW_OWNER); + assert.fieldEquals("WrappedDomain", SUB_ALICE_DOS, "owner", NEW_OWNER); + assert.fieldEquals("Registration", SUB_ALICE_DOS, "registrant", NEW_OWNER); +}); + +test("a user-registry unregistration retires the scoped token mapping", () => { + handleLabelRegistered(registration(123)); + let context = new DataSourceContext(); + context.setBytes("parentNode", Bytes.fromHexString(ALICE_DOS)); + dataSourceMock.setContext(context); + handleUserRegistryLabelRegistered(userRegistryRegistration(456)); + + handleUserRegistryLabelUnregistered(userRegistryLabelUnregistered(456)); + + assert.fieldEquals("Domain", SUB_ALICE_DOS, "owner", ZERO_ADDRESS); + assert.fieldEquals("Domain", SUB_ALICE_DOS, "expiryDate", "2000000200"); + assert.fieldEquals("WrappedDomain", SUB_ALICE_DOS, "owner", ZERO_ADDRESS); + assert.fieldEquals("Registration", SUB_ALICE_DOS, "registrant", ZERO_ADDRESS); + assert.notInStore( + "TokenToDomain", + USER_REGISTRY.concat("-0x00000000000000000000000000000000000000000000000000000000000001c8") + ); +}); + +test("a user-registry resolver is attached to the subname and dynamically indexed", () => { + handleLabelRegistered(registration(123)); + let context = new DataSourceContext(); + context.setBytes("parentNode", Bytes.fromHexString(ALICE_DOS)); + dataSourceMock.setContext(context); + handleUserRegistryLabelRegistered(userRegistryRegistration(456)); + + handleUserRegistryResolverUpdated(userRegistryResolverUpdated(456)); + + assert.fieldEquals("ResolverSource", RESOLVER, "address", RESOLVER); + assert.fieldEquals( + "Domain", + SUB_ALICE_DOS, + "resolver", + RESOLVER.concat("-").concat(SUB_ALICE_DOS) + ); +}); + +test("a user-registry renewal updates every BENS expiry view", () => { + handleLabelRegistered(registration(123)); + let context = new DataSourceContext(); + context.setBytes("parentNode", Bytes.fromHexString(ALICE_DOS)); + dataSourceMock.setContext(context); + handleUserRegistryLabelRegistered(userRegistryRegistration(456)); + + handleUserRegistryExpiryUpdated(userRegistryExpiryUpdated(456)); + + assert.fieldEquals("Domain", SUB_ALICE_DOS, "expiryDate", "2100000000"); + assert.fieldEquals( + "WrappedDomain", + SUB_ALICE_DOS, + "expiryDate", + "2100000000" + ); + assert.fieldEquals( + "Registration", + SUB_ALICE_DOS, + "expiryDate", + "2100000000" + ); +}); + +test("user-registry token regeneration keeps later transfers attached to the subname", () => { + handleLabelRegistered(registration(123)); + let context = new DataSourceContext(); + context.setBytes("parentNode", Bytes.fromHexString(ALICE_DOS)); + dataSourceMock.setContext(context); + handleUserRegistryLabelRegistered(userRegistryRegistration(456)); + + handleUserRegistryTokenRegenerated(userRegistryTokenRegenerated(456, 789)); + handleUserRegistryTransferSingle(userRegistryTransfer(789)); + + assert.fieldEquals("Domain", SUB_ALICE_DOS, "tokenId", "789"); + assert.fieldEquals("Domain", SUB_ALICE_DOS, "owner", NEW_OWNER); + assert.fieldEquals( + "TokenToDomain", + USER_REGISTRY.concat("-0x0000000000000000000000000000000000000000000000000000000000000315"), + "domain", + SUB_ALICE_DOS + ); + assert.notInStore( + "TokenToDomain", + USER_REGISTRY.concat("-0x00000000000000000000000000000000000000000000000000000000000001c8") + ); +}); + +test("a nested user registry preserves the complete parent path", () => { + handleLabelRegistered(registration(123)); + let context = new DataSourceContext(); + context.setBytes("parentNode", Bytes.fromHexString(ALICE_DOS)); + dataSourceMock.setContext(context); + handleUserRegistryLabelRegistered(userRegistryRegistration(456)); + + handleUserRegistrySubregistryUpdated(userRegistrySubregistryUpdated(456)); + + assert.fieldEquals( + "RegistryPath", + NESTED_REGISTRY.concat("-").concat(SUB_ALICE_DOS), + "parentDomain", + SUB_ALICE_DOS + ); +}); + +test("subregistry discovery stores the parent path for dynamic indexing", () => { + handleLabelRegistered(registration(123)); + handleSubregistryUpdated(subregistryUpdated(123)); + + assert.fieldEquals( + "RegistryPath", + USER_REGISTRY.concat("-").concat(ALICE_DOS), + "registry", + USER_REGISTRY + ); + assert.fieldEquals( + "RegistryPath", + USER_REGISTRY.concat("-").concat(ALICE_DOS), + "parentDomain", + ALICE_DOS + ); +}); + +test("resolver discovery creates a dynamic source and zero address clears it", () => { + handleLabelRegistered(registration(123)); + handleResolverUpdated(resolverUpdated(123, RESOLVER, 1)); + + assert.fieldEquals("ResolverSource", RESOLVER, "address", RESOLVER); + assert.fieldEquals( + "Domain", + ALICE_DOS, + "resolver", + RESOLVER.concat("-").concat(ALICE_DOS) + ); + + handleResolverUpdated(resolverUpdated(123, ZERO_ADDRESS, 2)); + let domain = Domain.load(ALICE_DOS)!; + assert.assertNull(domain.resolver); +}); + +test("unregistration retires the token mapping without losing domain history", () => { + handleLabelRegistered(registration(123)); + handleLabelUnregistered(labelUnregistered(123)); + + assert.fieldEquals("Domain", ALICE_DOS, "owner", ZERO_ADDRESS); + assert.fieldEquals("Domain", ALICE_DOS, "expiryDate", "2000000100"); + assert.notInStore( + "TokenToDomain", + "0x000000000000000000000000000000000000000000000000000000000000007b" + ); +}); diff --git a/subgraph/dos-names/tests/render-manifest.test.mjs b/subgraph/dos-names/tests/render-manifest.test.mjs new file mode 100644 index 000000000..022d15b86 --- /dev/null +++ b/subgraph/dos-names/tests/render-manifest.test.mjs @@ -0,0 +1,84 @@ +import assert from "node:assert/strict"; +import test from "node:test"; + +import { renderManifest, validateDeployment } from "../scripts/render-manifest.mjs"; + +const VALID_DEPLOYMENT = { + chainId: 3939, + deploymentBlock: 68, + contracts: { + dosRegistry: "0x1111111111111111111111111111111111111111", + dosRegistrar: "0x2222222222222222222222222222222222222222", + permissionedResolverImplementation: + "0x3333333333333333333333333333333333333333", + }, +}; + +const TEMPLATE = ` +registry: __DOS_REGISTRY_ADDRESS__ +registrar: __DOS_REGISTRAR_ADDRESS__ +resolver: __PERMISSIONED_RESOLVER_IMPLEMENTATION_ADDRESS__ +startBlock: __START_BLOCK__ +`; + +test("renders every contract address and deployment block", () => { + const rendered = renderManifest(TEMPLATE, VALID_DEPLOYMENT); + + assert.match(rendered, /0x1111111111111111111111111111111111111111/); + assert.match(rendered, /0x2222222222222222222222222222222222222222/); + assert.match(rendered, /0x3333333333333333333333333333333333333333/); + assert.match(rendered, /startBlock: 68/); + assert.doesNotMatch(rendered, /__[A-Z0-9_]+__/); +}); + +test("rejects a deployment for another chain", () => { + assert.throws( + () => validateDeployment({ ...VALID_DEPLOYMENT, chainId: 7979 }), + /chainId must be 3939/, + ); +}); + +test("rejects a missing deployment block", () => { + const deployment = { ...VALID_DEPLOYMENT }; + delete deployment.deploymentBlock; + + assert.throws( + () => validateDeployment(deployment), + /deploymentBlock must be a non-negative integer/, + ); +}); + +test("rejects a missing required contract", () => { + const deployment = { + ...VALID_DEPLOYMENT, + contracts: { ...VALID_DEPLOYMENT.contracts }, + }; + delete deployment.contracts.dosRegistrar; + + assert.throws( + () => validateDeployment(deployment), + /contracts\.dosRegistrar must be an EVM address/, + ); +}); + +test("rejects a zero contract address", () => { + const deployment = { + ...VALID_DEPLOYMENT, + contracts: { + ...VALID_DEPLOYMENT.contracts, + dosRegistry: "0x0000000000000000000000000000000000000000", + }, + }; + + assert.throws( + () => validateDeployment(deployment), + /contracts\.dosRegistry must not be the zero address/, + ); +}); + +test("rejects a template missing a required placeholder", () => { + assert.throws( + () => renderManifest("startBlock: __START_BLOCK__", VALID_DEPLOYMENT), + /template is missing __DOS_REGISTRY_ADDRESS__/, + ); +}); diff --git a/subgraph/dos-names/tests/resolver.test.ts b/subgraph/dos-names/tests/resolver.test.ts new file mode 100644 index 000000000..1532d57a9 --- /dev/null +++ b/subgraph/dos-names/tests/resolver.test.ts @@ -0,0 +1,126 @@ +import { Address, BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts"; +import { + afterEach, + assert, + clearStore, + newMockEvent, + test, +} from "matchstick-as/assembly/index"; + +import { + handleAddrChanged, + handleNameChanged, + handleTextChanged, +} from "../src/resolver"; +import { + AddrChanged, + NameChanged, + TextChanged, +} from "../src/types/Resolver/PermissionedResolver"; + +const RESOLVER = "0x2222222222222222222222222222222222222222"; +const OWNER = "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7"; +const NODE = + "0x424d8e54ceea7400cbef56f721accb0a42bf370777b1439bfaee1d4eb678040f"; + +function addrChanged(): AddrChanged { + let mock = newMockEvent(); + mock.address = Address.fromString(RESOLVER); + let event = new AddrChanged( + mock.address, + mock.logIndex, + mock.transactionLogIndex, + mock.logType, + mock.block, + mock.transaction, + mock.parameters, + mock.receipt + ); + event.parameters = [ + new ethereum.EventParam( + "node", + ethereum.Value.fromFixedBytes(Bytes.fromHexString(NODE)) + ), + new ethereum.EventParam( + "a", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + ]; + return event; +} + +function textChanged(): TextChanged { + let mock = newMockEvent(); + mock.address = Address.fromString(RESOLVER); + mock.logIndex = BigInt.fromI32(1); + let event = new TextChanged( + mock.address, + mock.logIndex, + mock.transactionLogIndex, + mock.logType, + mock.block, + mock.transaction, + mock.parameters, + mock.receipt + ); + event.parameters = [ + new ethereum.EventParam( + "node", + ethereum.Value.fromFixedBytes(Bytes.fromHexString(NODE)) + ), + new ethereum.EventParam("indexedKey", ethereum.Value.fromString("url")), + new ethereum.EventParam("key", ethereum.Value.fromString("url")), + new ethereum.EventParam( + "value", + ethereum.Value.fromString("https://doschain.com") + ), + ]; + return event; +} + +function nameChanged(): NameChanged { + let mock = newMockEvent(); + mock.address = Address.fromString(RESOLVER); + mock.logIndex = BigInt.fromI32(2); + let event = new NameChanged( + mock.address, + mock.logIndex, + mock.transactionLogIndex, + mock.logType, + mock.block, + mock.transaction, + mock.parameters, + mock.receipt + ); + event.parameters = [ + new ethereum.EventParam( + "node", + ethereum.Value.fromFixedBytes(Bytes.fromHexString(NODE)) + ), + new ethereum.EventParam("name", ethereum.Value.fromString("alice.dos")), + ]; + return event; +} + +afterEach(() => { + clearStore(); +}); + +test("address and text records retain resolver state", () => { + handleAddrChanged(addrChanged()); + handleTextChanged(textChanged()); + + let resolverId = RESOLVER.concat("-").concat(NODE); + assert.fieldEquals("Resolver", resolverId, "addr", OWNER); + assert.fieldEquals("Resolver", resolverId, "texts", "[url]"); + assert.fieldEquals("TextChanged", "1-1", "value", "https://doschain.com"); +}); + +test("name records create their resolver relation when indexed standalone", () => { + handleNameChanged(nameChanged()); + + let resolverId = RESOLVER.concat("-").concat(NODE); + assert.fieldEquals("Resolver", resolverId, "address", RESOLVER); + assert.fieldEquals("NameChanged", "1-2", "resolver", resolverId); + assert.fieldEquals("NameChanged", "1-2", "name", "alice.dos"); +}); diff --git a/subgraph/dos-names/tsconfig.json b/subgraph/dos-names/tsconfig.json new file mode 100644 index 000000000..1cc6ebfc0 --- /dev/null +++ b/subgraph/dos-names/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "assemblyscript/std/assembly", + "include": [ + "node_modules/@graphprotocol/graph-ts/index.ts", + "node_modules/@graphprotocol/graph-ts/helper-functions.ts", + "node_modules/@graphprotocol/graph-ts/global/global.ts", + "src/**/*.ts" + ] +} From fa450f7e67becd76d22f66ac004a065374e74455 Mon Sep 17 00:00:00 2001 From: JOY <5027251+JOY@users.noreply.github.com> Date: Wed, 12 Aug 2026 17:47:43 +0700 Subject: [PATCH 02/14] ci: run subgraph tests on Ubuntu 22 --- .github/workflows/main.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e8edce014..be765078e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -115,7 +115,8 @@ jobs: subgraph-tests: name: DOS Names Subgraph - runs-on: ubuntu-latest + # Matchstick 0.6.0 publishes a Linux 22 binary but no Linux 24 binary. + runs-on: ubuntu-22.04 defaults: run: working-directory: subgraph/dos-names From 06d765afd5a8b7ebce75b9bc81b1d22d37af2ac8 Mon Sep 17 00:00:00 2001 From: JOY <5027251+JOY@users.noreply.github.com> Date: Wed, 12 Aug 2026 18:03:30 +0700 Subject: [PATCH 03/14] fix: preserve ENSv2 registry ownership --- subgraph/dos-names/schema.graphql | 1 + subgraph/dos-names/src/registry.ts | 59 +++-- subgraph/dos-names/src/subregistry.ts | 52 +++++ subgraph/dos-names/src/userRegistry.ts | 93 ++++++-- subgraph/dos-names/subgraph.template.yaml | 4 + subgraph/dos-names/tests/registry.test.ts | 249 +++++++++++++++++++--- 6 files changed, 382 insertions(+), 76 deletions(-) create mode 100644 subgraph/dos-names/src/subregistry.ts diff --git a/subgraph/dos-names/schema.graphql b/subgraph/dos-names/schema.graphql index 5c38eab47..e4fc45c78 100644 --- a/subgraph/dos-names/schema.graphql +++ b/subgraph/dos-names/schema.graphql @@ -315,6 +315,7 @@ type RegistryPath @entity { id: ID! registry: Bytes! parentDomain: Domain! + active: Boolean! } "Tracks resolver addresses already registered as dynamic data sources" diff --git a/subgraph/dos-names/src/registry.ts b/subgraph/dos-names/src/registry.ts index 6d6bc3ee4..abf4d4d98 100644 --- a/subgraph/dos-names/src/registry.ts +++ b/subgraph/dos-names/src/registry.ts @@ -7,11 +7,11 @@ * We use a TokenToDomain mapping entity to resolve tokenId → domain. */ import { + Address, BigInt, ByteArray, - Bytes, crypto, - DataSourceContext, + ethereum, store, } from "@graphprotocol/graph-ts"; @@ -22,6 +22,7 @@ import { LabelUnregistered as LabelUnregisteredEvent, SubregistryUpdated as SubregistryUpdatedEvent, TokenRegenerated as TokenRegeneratedEvent, + TransferBatch as TransferBatchEvent, TransferSingle as TransferSingleEvent, } from "./types/DOSTLDRegistry/PermissionedRegistry"; @@ -31,7 +32,6 @@ import { NewOwner, NewResolver, Registration, - RegistryPath, Resolver, ResolverSource, TokenToDomain, @@ -39,7 +39,8 @@ import { WrappedDomain, WrappedTransfer, } from "./types/schema"; -import { ResolverTemplate, UserRegistryTemplate } from "./types/templates"; +import { ResolverTemplate } from "./types/templates"; +import { updateSubregistry } from "./subregistry"; import { concat, @@ -262,10 +263,11 @@ export function handleExpiryUpdated(event: ExpiryUpdatedEvent): void { * We use TokenToDomain mapping to find the correct domain. */ export function handleTransferSingle(event: TransferSingleEvent): void { - let tokenId = event.params.id; - let to = event.params.to; + if (event.params.value.equals(BigInt.fromI32(0))) { + return; + } - let node = resolveDomainNode(tokenId); + let node = resolveDomainNode(event.params.id); if (node === null) { // No mapping found - this TransferSingle fired BEFORE LabelRegistered // (e.g., _mint emits TransferSingle before LabelRegistered in same tx). @@ -273,6 +275,30 @@ export function handleTransferSingle(event: TransferSingleEvent): void { return; } + applyOwnershipTransfer(node, event.params.to, event, ""); +} + +export function handleTransferBatch(event: TransferBatchEvent): void { + let ids = event.params.ids; + let values = event.params.values; + let count = ids.length < values.length ? ids.length : values.length; + for (let i = 0; i < count; i++) { + if (values[i].equals(BigInt.fromI32(0))) { + continue; + } + let node = resolveDomainNode(ids[i]); + if (node !== null) { + applyOwnershipTransfer(node, event.params.to, event, "-".concat(i.toString())); + } + } +} + +function applyOwnershipTransfer( + node: string, + to: Address, + event: ethereum.Event, + eventSuffix: string +): void { let account = createOrLoadAccount(to.toHexString()); let domain = Domain.load(node); @@ -293,7 +319,7 @@ export function handleTransferSingle(event: TransferSingleEvent): void { } // Create Transfer event - let transferEvent = new Transfer(createEventID(event)); + let transferEvent = new Transfer(createEventID(event).concat(eventSuffix)); transferEvent.blockNumber = event.block.number.toI32(); transferEvent.transactionID = event.transaction.hash; transferEvent.domain = node; @@ -303,6 +329,7 @@ export function handleTransferSingle(event: TransferSingleEvent): void { // Create WrappedTransfer event let wrappedTransfer = new WrappedTransfer( createEventID(event).concat("-wrapped") + .concat(eventSuffix) ); wrappedTransfer.blockNumber = event.block.number.toI32(); wrappedTransfer.transactionID = event.transaction.hash; @@ -381,23 +408,9 @@ export function handleLabelUnregistered(event: LabelUnregisteredEvent): void { } export function handleSubregistryUpdated(event: SubregistryUpdatedEvent): void { - if (event.params.subregistry.toHexString() == EMPTY_ADDRESS) { - return; - } - let node = resolveDomainNode(event.params.tokenId); if (node === null || Domain.load(node) === null) { return; } - - let registryAddress = event.params.subregistry.toHexString(); - let pathId = registryAddress.concat("-").concat(node); - let path = new RegistryPath(pathId); - path.registry = event.params.subregistry; - path.parentDomain = node; - path.save(); - - let context = new DataSourceContext(); - context.setBytes("parentNode", Bytes.fromHexString(node)); - UserRegistryTemplate.createWithContext(event.params.subregistry, context); + updateSubregistry(node, event.params.subregistry); } diff --git a/subgraph/dos-names/src/subregistry.ts b/subgraph/dos-names/src/subregistry.ts new file mode 100644 index 000000000..e4481829b --- /dev/null +++ b/subgraph/dos-names/src/subregistry.ts @@ -0,0 +1,52 @@ +import { + Address, + Bytes, + DataSourceContext, + dataSource, +} from "@graphprotocol/graph-ts"; + +import { RegistryPath } from "./types/schema"; +import { UserRegistryTemplate } from "./types/templates"; +import { EMPTY_ADDRESS } from "./utils"; + +export function isActiveUserRegistry(registry: Address): boolean { + let parentNode = dataSource.context().getBytes("parentNode").toHexString(); + let path = RegistryPath.load(parentNode); + return ( + path !== null && + path.active && + path.registry.toHexString() == registry.toHexString() + ); +} + +export function updateSubregistry( + parentNode: string, + registry: Address +): void { + let path = RegistryPath.load(parentNode); + let registryAddress = registry.toHexString(); + + if (registryAddress == EMPTY_ADDRESS) { + if (path !== null) { + path.active = false; + path.save(); + } + return; + } + + let requiresSource = + path === null || path.registry.toHexString() != registryAddress; + if (path === null) { + path = new RegistryPath(parentNode); + path.parentDomain = parentNode; + } + path.registry = registry; + path.active = true; + path.save(); + + if (requiresSource) { + let context = new DataSourceContext(); + context.setBytes("parentNode", Bytes.fromHexString(parentNode)); + UserRegistryTemplate.createWithContext(registry, context); + } +} diff --git a/subgraph/dos-names/src/userRegistry.ts b/subgraph/dos-names/src/userRegistry.ts index 5acfe4fb8..ea594e2ae 100644 --- a/subgraph/dos-names/src/userRegistry.ts +++ b/subgraph/dos-names/src/userRegistry.ts @@ -1,8 +1,9 @@ import { + Address, + BigInt, ByteArray, Bytes, crypto, - DataSourceContext, dataSource, ethereum, store, @@ -15,6 +16,7 @@ import { ResolverUpdated as ResolverUpdatedEvent, SubregistryUpdated as SubregistryUpdatedEvent, TokenRegenerated as TokenRegeneratedEvent, + TransferBatch as TransferBatchEvent, TransferSingle as TransferSingleEvent, } from "./types/templates/UserRegistryTemplate/PermissionedRegistry"; import { @@ -22,7 +24,6 @@ import { NewResolver, NewOwner, Registration, - RegistryPath, Resolver, ResolverSource, TokenToDomain, @@ -30,7 +31,8 @@ import { WrappedDomain, WrappedTransfer, } from "./types/schema"; -import { ResolverTemplate, UserRegistryTemplate } from "./types/templates"; +import { ResolverTemplate } from "./types/templates"; +import { isActiveUserRegistry, updateSubregistry } from "./subregistry"; import { checkValidLabel, concat, @@ -41,7 +43,12 @@ import { } from "./utils"; function registryTokenId(event: ethereum.Event, tokenId: string): string { - return event.address.toHexString().concat("-").concat(tokenId); + return event.address + .toHexString() + .concat("-") + .concat(dataSource.context().getBytes("parentNode").toHexString()) + .concat("-") + .concat(tokenId); } function resolveDomainNode(event: ethereum.Event, tokenId: string): string | null { @@ -50,6 +57,9 @@ function resolveDomainNode(event: ethereum.Event, tokenId: string): string | nul } export function handleUserRegistryLabelRegistered(event: LabelRegisteredEvent): void { + if (!isActiveUserRegistry(event.address)) { + return; + } let label = event.params.label; if (!checkValidLabel(label)) { return; @@ -126,6 +136,9 @@ export function handleUserRegistryLabelRegistered(event: LabelRegisteredEvent): } export function handleUserRegistryResolverUpdated(event: ResolverUpdatedEvent): void { + if (!isActiveUserRegistry(event.address)) { + return; + } let node = resolveDomainNode(event, tokenIdToHex(event.params.tokenId)); if (node === null) { return; @@ -175,6 +188,9 @@ export function handleUserRegistryResolverUpdated(event: ResolverUpdatedEvent): } export function handleUserRegistryExpiryUpdated(event: ExpiryUpdatedEvent): void { + if (!isActiveUserRegistry(event.address)) { + return; + } let node = resolveDomainNode(event, tokenIdToHex(event.params.tokenId)); if (node === null) { return; @@ -200,6 +216,12 @@ export function handleUserRegistryExpiryUpdated(event: ExpiryUpdatedEvent): void } export function handleUserRegistryTransferSingle(event: TransferSingleEvent): void { + if ( + !isActiveUserRegistry(event.address) || + event.params.value.equals(BigInt.fromI32(0)) + ) { + return; + } let node = resolveDomainNode(event, tokenIdToHex(event.params.id)); if (node === null) { return; @@ -210,7 +232,43 @@ export function handleUserRegistryTransferSingle(event: TransferSingleEvent): vo return; } - let account = createOrLoadAccount(event.params.to.toHexString()); + applyOwnershipTransfer(node, event.params.to, event, ""); +} + +export function handleUserRegistryTransferBatch(event: TransferBatchEvent): void { + if (!isActiveUserRegistry(event.address)) { + return; + } + let ids = event.params.ids; + let values = event.params.values; + let count = ids.length < values.length ? ids.length : values.length; + for (let i = 0; i < count; i++) { + if (values[i].equals(BigInt.fromI32(0))) { + continue; + } + let node = resolveDomainNode(event, tokenIdToHex(ids[i])); + if (node !== null) { + applyOwnershipTransfer( + node, + event.params.to, + event, + "-".concat(i.toString()) + ); + } + } +} + +function applyOwnershipTransfer( + node: string, + to: Address, + event: ethereum.Event, + eventSuffix: string +): void { + let account = createOrLoadAccount(to.toHexString()); + let domain = Domain.load(node); + if (domain === null) { + return; + } domain.owner = account.id; domain.registrant = account.id; domain.wrappedOwner = account.id; @@ -228,14 +286,16 @@ export function handleUserRegistryTransferSingle(event: TransferSingleEvent): vo registration.save(); } - let transferEvent = new Transfer(createEventID(event)); + let transferEvent = new Transfer(createEventID(event).concat(eventSuffix)); transferEvent.domain = node; transferEvent.blockNumber = event.block.number.toI32(); transferEvent.transactionID = event.transaction.hash; transferEvent.owner = account.id; transferEvent.save(); - let wrappedTransfer = new WrappedTransfer(createEventID(event).concat("-wrapped")); + let wrappedTransfer = new WrappedTransfer( + createEventID(event).concat("-wrapped").concat(eventSuffix) + ); wrappedTransfer.domain = node; wrappedTransfer.blockNumber = event.block.number.toI32(); wrappedTransfer.transactionID = event.transaction.hash; @@ -244,6 +304,9 @@ export function handleUserRegistryTransferSingle(event: TransferSingleEvent): vo } export function handleUserRegistryTokenRegenerated(event: TokenRegeneratedEvent): void { + if (!isActiveUserRegistry(event.address)) { + return; + } let oldId = registryTokenId(event, tokenIdToHex(event.params.oldTokenId)); let oldMapping = TokenToDomain.load(oldId); if (oldMapping === null) { @@ -264,7 +327,7 @@ export function handleUserRegistryTokenRegenerated(event: TokenRegeneratedEvent) } export function handleUserRegistrySubregistryUpdated(event: SubregistryUpdatedEvent): void { - if (event.params.subregistry.toHexString() == EMPTY_ADDRESS) { + if (!isActiveUserRegistry(event.address)) { return; } @@ -273,19 +336,13 @@ export function handleUserRegistrySubregistryUpdated(event: SubregistryUpdatedEv return; } - let registryAddress = event.params.subregistry.toHexString(); - let pathId = registryAddress.concat("-").concat(node); - let path = new RegistryPath(pathId); - path.registry = event.params.subregistry; - path.parentDomain = node; - path.save(); - - let context = new DataSourceContext(); - context.setBytes("parentNode", Bytes.fromHexString(node)); - UserRegistryTemplate.createWithContext(event.params.subregistry, context); + updateSubregistry(node, event.params.subregistry); } export function handleUserRegistryLabelUnregistered(event: LabelUnregisteredEvent): void { + if (!isActiveUserRegistry(event.address)) { + return; + } let tokenKey = registryTokenId(event, tokenIdToHex(event.params.tokenId)); let mapping = TokenToDomain.load(tokenKey); if (mapping === null) { diff --git a/subgraph/dos-names/subgraph.template.yaml b/subgraph/dos-names/subgraph.template.yaml index 7272ee989..1bcbd504d 100644 --- a/subgraph/dos-names/subgraph.template.yaml +++ b/subgraph/dos-names/subgraph.template.yaml @@ -33,6 +33,8 @@ dataSources: handler: handleExpiryUpdated - event: TransferSingle(indexed address,indexed address,indexed address,uint256,uint256) handler: handleTransferSingle + - event: TransferBatch(indexed address,indexed address,indexed address,uint256[],uint256[]) + handler: handleTransferBatch - event: TokenRegenerated(indexed uint256,indexed uint256) handler: handleTokenRegenerated - event: SubregistryUpdated(indexed uint256,indexed address,indexed address) @@ -136,6 +138,8 @@ templates: handler: handleUserRegistryExpiryUpdated - event: TransferSingle(indexed address,indexed address,indexed address,uint256,uint256) handler: handleUserRegistryTransferSingle + - event: TransferBatch(indexed address,indexed address,indexed address,uint256[],uint256[]) + handler: handleUserRegistryTransferBatch - event: TokenRegenerated(indexed uint256,indexed uint256) handler: handleUserRegistryTokenRegenerated - event: SubregistryUpdated(indexed uint256,indexed address,indexed address) diff --git a/subgraph/dos-names/tests/registry.test.ts b/subgraph/dos-names/tests/registry.test.ts index 475bef7e3..5d80a2f89 100644 --- a/subgraph/dos-names/tests/registry.test.ts +++ b/subgraph/dos-names/tests/registry.test.ts @@ -20,6 +20,7 @@ import { handleResolverUpdated, handleSubregistryUpdated, handleTokenRegenerated, + handleTransferBatch, handleTransferSingle, } from "../src/registry"; import { @@ -29,6 +30,7 @@ import { handleUserRegistryResolverUpdated, handleUserRegistryTokenRegenerated, handleUserRegistrySubregistryUpdated, + handleUserRegistryTransferBatch, handleUserRegistryTransferSingle, } from "../src/userRegistry"; import { @@ -37,16 +39,18 @@ import { ResolverUpdated, SubregistryUpdated, TokenRegenerated, + TransferBatch, TransferSingle, } from "../src/types/DOSTLDRegistry/PermissionedRegistry"; import { LabelRegistered as UserRegistryLabelRegistered } from "../src/types/templates/UserRegistryTemplate/PermissionedRegistry"; import { LabelUnregistered as UserRegistryLabelUnregistered } from "../src/types/templates/UserRegistryTemplate/PermissionedRegistry"; import { TransferSingle as UserRegistryTransferSingle } from "../src/types/templates/UserRegistryTemplate/PermissionedRegistry"; +import { TransferBatch as UserRegistryTransferBatch } from "../src/types/templates/UserRegistryTemplate/PermissionedRegistry"; import { ResolverUpdated as UserRegistryResolverUpdated } from "../src/types/templates/UserRegistryTemplate/PermissionedRegistry"; import { ExpiryUpdated as UserRegistryExpiryUpdated } from "../src/types/templates/UserRegistryTemplate/PermissionedRegistry"; import { TokenRegenerated as UserRegistryTokenRegenerated } from "../src/types/templates/UserRegistryTemplate/PermissionedRegistry"; import { SubregistryUpdated as UserRegistrySubregistryUpdated } from "../src/types/templates/UserRegistryTemplate/PermissionedRegistry"; -import { Domain } from "../src/types/schema"; +import { Domain, RegistryPath } from "../src/types/schema"; const OWNER = "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7"; const NEW_OWNER = "0x4976fb03c32e5b8cfe2b6ccb31c09ba78ebaba41"; @@ -62,6 +66,8 @@ const SUB_LABEL_HASH = "0xfa1ea47215815692a5f1391cff19abbaf694c82fb2151a4c351b6c0eeaaf317b"; const SUB_ALICE_DOS = "0x1c1ff2cdbb0b7cc0b67c4b92a0ba7633d2cf2d2e756ea950fbe437050296f930"; +const BOB_DOS = + "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; function registration(tokenId: i32): LabelRegistered { let mock = newMockEvent(); @@ -127,7 +133,10 @@ function regeneration(oldTokenId: i32, newTokenId: i32): TokenRegenerated { return event; } -function subregistryUpdated(tokenId: i32): SubregistryUpdated { +function subregistryUpdated( + tokenId: i32, + registry: string = USER_REGISTRY +): SubregistryUpdated { let mock = newMockEvent(); mock.logIndex = BigInt.fromI32(1); let event = new SubregistryUpdated( @@ -147,7 +156,7 @@ function subregistryUpdated(tokenId: i32): SubregistryUpdated { ), new ethereum.EventParam( "subregistry", - ethereum.Value.fromAddress(Address.fromString(USER_REGISTRY)) + ethereum.Value.fromAddress(Address.fromString(registry)) ), new ethereum.EventParam( "sender", @@ -214,7 +223,7 @@ function labelUnregistered(tokenId: i32): LabelUnregistered { return event; } -function transfer(tokenId: i32): TransferSingle { +function transfer(tokenId: i32, value: i32 = 1): TransferSingle { let mock = newMockEvent(); mock.logIndex = BigInt.fromI32(2); let event = new TransferSingle( @@ -246,7 +255,48 @@ function transfer(tokenId: i32): TransferSingle { ), new ethereum.EventParam( "value", - ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(1)) + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(value)) + ), + ]; + return event; +} + +function batchTransfer(tokenIds: i32[], values: i32[]): TransferBatch { + let mock = newMockEvent(); + mock.logIndex = BigInt.fromI32(3); + let event = new TransferBatch( + mock.address, + mock.logIndex, + mock.transactionLogIndex, + mock.logType, + mock.block, + mock.transaction, + mock.parameters, + mock.receipt + ); + let ids = new Array(); + let amounts = new Array(); + for (let i = 0; i < tokenIds.length; i++) { + ids.push(BigInt.fromI32(tokenIds[i])); + amounts.push(BigInt.fromI32(values[i])); + } + event.parameters = [ + new ethereum.EventParam( + "operator", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + new ethereum.EventParam( + "from", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + new ethereum.EventParam( + "to", + ethereum.Value.fromAddress(Address.fromString(NEW_OWNER)) + ), + new ethereum.EventParam("ids", ethereum.Value.fromUnsignedBigIntArray(ids)), + new ethereum.EventParam( + "values", + ethereum.Value.fromUnsignedBigIntArray(amounts) ), ]; return event; @@ -319,7 +369,10 @@ function userRegistryLabelUnregistered(tokenId: i32): UserRegistryLabelUnregiste return event; } -function userRegistryTransfer(tokenId: i32): UserRegistryTransferSingle { +function userRegistryTransfer( + tokenId: i32, + value: i32 = 1 +): UserRegistryTransferSingle { let mock = newMockEvent(); mock.address = Address.fromString(USER_REGISTRY); mock.logIndex = BigInt.fromI32(1); @@ -352,12 +405,64 @@ function userRegistryTransfer(tokenId: i32): UserRegistryTransferSingle { ), new ethereum.EventParam( "value", - ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(1)) + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(value)) + ), + ]; + return event; +} + +function userRegistryBatchTransfer( + tokenIds: i32[], + values: i32[] +): UserRegistryTransferBatch { + let mock = newMockEvent(); + mock.address = Address.fromString(USER_REGISTRY); + mock.logIndex = BigInt.fromI32(3); + let event = new UserRegistryTransferBatch( + mock.address, + mock.logIndex, + mock.transactionLogIndex, + mock.logType, + mock.block, + mock.transaction, + mock.parameters, + mock.receipt + ); + let ids = new Array(); + let amounts = new Array(); + for (let i = 0; i < tokenIds.length; i++) { + ids.push(BigInt.fromI32(tokenIds[i])); + amounts.push(BigInt.fromI32(values[i])); + } + event.parameters = [ + new ethereum.EventParam( + "operator", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + new ethereum.EventParam( + "from", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + new ethereum.EventParam( + "to", + ethereum.Value.fromAddress(Address.fromString(NEW_OWNER)) + ), + new ethereum.EventParam("ids", ethereum.Value.fromUnsignedBigIntArray(ids)), + new ethereum.EventParam( + "values", + ethereum.Value.fromUnsignedBigIntArray(amounts) ), ]; return event; } +function activateUserRegistry(): void { + handleSubregistryUpdated(subregistryUpdated(123)); + let context = new DataSourceContext(); + context.setBytes("parentNode", Bytes.fromHexString(ALICE_DOS)); + dataSourceMock.setContext(context); +} + function userRegistryResolverUpdated(tokenId: i32): UserRegistryResolverUpdated { let mock = newMockEvent(); mock.address = Address.fromString(USER_REGISTRY); @@ -504,12 +609,27 @@ test("token regeneration preserves the canonical domain mapping", () => { ); }); -test("a discovered user registry indexes a subname under its parent path", () => { +test("zero-value transfers do not change top-level ownership", () => { handleLabelRegistered(registration(123)); - let context = new DataSourceContext(); - context.setBytes("parentNode", Bytes.fromHexString(ALICE_DOS)); - dataSourceMock.setContext(context); + handleTransferSingle(transfer(123, 0)); + + assert.fieldEquals("Domain", ALICE_DOS, "owner", OWNER); + assert.entityCount("Transfer", 0); +}); + +test("batch transfers update mapped top-level names and ignore zero values", () => { + handleLabelRegistered(registration(123)); + + handleTransferBatch(batchTransfer([123, 999], [1, 0])); + + assert.fieldEquals("Domain", ALICE_DOS, "owner", NEW_OWNER); + assert.entityCount("Transfer", 1); +}); + +test("a discovered user registry indexes a subname under its parent path", () => { + handleLabelRegistered(registration(123)); + activateUserRegistry(); handleUserRegistryLabelRegistered(userRegistryRegistration(456)); @@ -520,9 +640,7 @@ test("a discovered user registry indexes a subname under its parent path", () => test("a user-registry token transfer updates the subname owner", () => { handleLabelRegistered(registration(123)); - let context = new DataSourceContext(); - context.setBytes("parentNode", Bytes.fromHexString(ALICE_DOS)); - dataSourceMock.setContext(context); + activateUserRegistry(); handleUserRegistryLabelRegistered(userRegistryRegistration(456)); handleUserRegistryTransferSingle(userRegistryTransfer(456)); @@ -532,11 +650,71 @@ test("a user-registry token transfer updates the subname owner", () => { assert.fieldEquals("Registration", SUB_ALICE_DOS, "registrant", NEW_OWNER); }); +test("zero-value user-registry transfers do not change ownership", () => { + handleLabelRegistered(registration(123)); + activateUserRegistry(); + handleUserRegistryLabelRegistered(userRegistryRegistration(456)); + + handleUserRegistryTransferSingle(userRegistryTransfer(456, 0)); + + assert.fieldEquals("Domain", SUB_ALICE_DOS, "owner", OWNER); +}); + +test("batch transfers update mapped user-registry names", () => { + handleLabelRegistered(registration(123)); + activateUserRegistry(); + handleUserRegistryLabelRegistered(userRegistryRegistration(456)); + + handleUserRegistryTransferBatch(userRegistryBatchTransfer([456, 999], [1, 0])); + + assert.fieldEquals("Domain", SUB_ALICE_DOS, "owner", NEW_OWNER); + assert.fieldEquals("WrappedDomain", SUB_ALICE_DOS, "owner", NEW_OWNER); +}); + +test("detached user registries stop mutating their former parent path", () => { + handleLabelRegistered(registration(123)); + activateUserRegistry(); + handleUserRegistryLabelRegistered(userRegistryRegistration(456)); + + handleSubregistryUpdated(subregistryUpdated(123, ZERO_ADDRESS)); + handleUserRegistryTransferSingle(userRegistryTransfer(456)); + + assert.fieldEquals("RegistryPath", ALICE_DOS, "active", "false"); + assert.fieldEquals("Domain", SUB_ALICE_DOS, "owner", OWNER); +}); + +test("a shared user registry keeps token mappings scoped to each parent", () => { + handleLabelRegistered(registration(123)); + activateUserRegistry(); + handleUserRegistryLabelRegistered(userRegistryRegistration(456)); + + let bob = new Domain(BOB_DOS); + bob.name = "bob.dos"; + bob.labelName = "bob"; + bob.owner = OWNER; + bob.isMigrated = true; + bob.createdAt = BigInt.fromI32(1); + bob.subdomainCount = 0; + bob.storedOffchain = false; + bob.resolvedWithWildcard = false; + bob.save(); + let path = new RegistryPath(BOB_DOS); + path.registry = Address.fromString(USER_REGISTRY); + path.parentDomain = BOB_DOS; + path.active = true; + path.save(); + + let bobContext = new DataSourceContext(); + bobContext.setBytes("parentNode", Bytes.fromHexString(BOB_DOS)); + dataSourceMock.setContext(bobContext); + handleUserRegistryLabelRegistered(userRegistryRegistration(456)); + + assert.entityCount("TokenToDomain", 3); +}); + test("a user-registry unregistration retires the scoped token mapping", () => { handleLabelRegistered(registration(123)); - let context = new DataSourceContext(); - context.setBytes("parentNode", Bytes.fromHexString(ALICE_DOS)); - dataSourceMock.setContext(context); + activateUserRegistry(); handleUserRegistryLabelRegistered(userRegistryRegistration(456)); handleUserRegistryLabelUnregistered(userRegistryLabelUnregistered(456)); @@ -547,15 +725,16 @@ test("a user-registry unregistration retires the scoped token mapping", () => { assert.fieldEquals("Registration", SUB_ALICE_DOS, "registrant", ZERO_ADDRESS); assert.notInStore( "TokenToDomain", - USER_REGISTRY.concat("-0x00000000000000000000000000000000000000000000000000000000000001c8") + USER_REGISTRY + .concat("-") + .concat(ALICE_DOS) + .concat("-0x00000000000000000000000000000000000000000000000000000000000001c8") ); }); test("a user-registry resolver is attached to the subname and dynamically indexed", () => { handleLabelRegistered(registration(123)); - let context = new DataSourceContext(); - context.setBytes("parentNode", Bytes.fromHexString(ALICE_DOS)); - dataSourceMock.setContext(context); + activateUserRegistry(); handleUserRegistryLabelRegistered(userRegistryRegistration(456)); handleUserRegistryResolverUpdated(userRegistryResolverUpdated(456)); @@ -571,9 +750,7 @@ test("a user-registry resolver is attached to the subname and dynamically indexe test("a user-registry renewal updates every BENS expiry view", () => { handleLabelRegistered(registration(123)); - let context = new DataSourceContext(); - context.setBytes("parentNode", Bytes.fromHexString(ALICE_DOS)); - dataSourceMock.setContext(context); + activateUserRegistry(); handleUserRegistryLabelRegistered(userRegistryRegistration(456)); handleUserRegistryExpiryUpdated(userRegistryExpiryUpdated(456)); @@ -595,9 +772,7 @@ test("a user-registry renewal updates every BENS expiry view", () => { test("user-registry token regeneration keeps later transfers attached to the subname", () => { handleLabelRegistered(registration(123)); - let context = new DataSourceContext(); - context.setBytes("parentNode", Bytes.fromHexString(ALICE_DOS)); - dataSourceMock.setContext(context); + activateUserRegistry(); handleUserRegistryLabelRegistered(userRegistryRegistration(456)); handleUserRegistryTokenRegenerated(userRegistryTokenRegenerated(456, 789)); @@ -607,28 +782,32 @@ test("user-registry token regeneration keeps later transfers attached to the sub assert.fieldEquals("Domain", SUB_ALICE_DOS, "owner", NEW_OWNER); assert.fieldEquals( "TokenToDomain", - USER_REGISTRY.concat("-0x0000000000000000000000000000000000000000000000000000000000000315"), + USER_REGISTRY + .concat("-") + .concat(ALICE_DOS) + .concat("-0x0000000000000000000000000000000000000000000000000000000000000315"), "domain", SUB_ALICE_DOS ); assert.notInStore( "TokenToDomain", - USER_REGISTRY.concat("-0x00000000000000000000000000000000000000000000000000000000000001c8") + USER_REGISTRY + .concat("-") + .concat(ALICE_DOS) + .concat("-0x00000000000000000000000000000000000000000000000000000000000001c8") ); }); test("a nested user registry preserves the complete parent path", () => { handleLabelRegistered(registration(123)); - let context = new DataSourceContext(); - context.setBytes("parentNode", Bytes.fromHexString(ALICE_DOS)); - dataSourceMock.setContext(context); + activateUserRegistry(); handleUserRegistryLabelRegistered(userRegistryRegistration(456)); handleUserRegistrySubregistryUpdated(userRegistrySubregistryUpdated(456)); assert.fieldEquals( "RegistryPath", - NESTED_REGISTRY.concat("-").concat(SUB_ALICE_DOS), + SUB_ALICE_DOS, "parentDomain", SUB_ALICE_DOS ); @@ -640,13 +819,13 @@ test("subregistry discovery stores the parent path for dynamic indexing", () => assert.fieldEquals( "RegistryPath", - USER_REGISTRY.concat("-").concat(ALICE_DOS), + ALICE_DOS, "registry", USER_REGISTRY ); assert.fieldEquals( "RegistryPath", - USER_REGISTRY.concat("-").concat(ALICE_DOS), + ALICE_DOS, "parentDomain", ALICE_DOS ); From ff7e28149c807002399d04333267303eb948611a Mon Sep 17 00:00:00 2001 From: JOY <5027251+JOY@users.noreply.github.com> Date: Wed, 12 Aug 2026 18:06:21 +0700 Subject: [PATCH 04/14] feat: add Testnet BENS smoke name --- .../script/foundry/DeployDOSTestnet.s.sol | 23 +++++++++++++++++++ contracts/test/unit/testnet/WrappedDOS.t.sol | 4 ++++ 2 files changed, 27 insertions(+) diff --git a/contracts/script/foundry/DeployDOSTestnet.s.sol b/contracts/script/foundry/DeployDOSTestnet.s.sol index 99948631a..1f1f186db 100644 --- a/contracts/script/foundry/DeployDOSTestnet.s.sol +++ b/contracts/script/foundry/DeployDOSTestnet.s.sol @@ -10,6 +10,7 @@ import { StandardRentPriceOracle } from "~src/registrar/StandardRentPriceOracle.sol"; import {PermissionedRegistry} from "~src/registry/PermissionedRegistry.sol"; +import {IRegistry} from "~src/registry/interfaces/IRegistry.sol"; import {RegistryRolesLib} from "~src/registry/libraries/RegistryRolesLib.sol"; import {PermissionedResolver} from "~src/resolver/PermissionedResolver.sol"; import {PermissionedResolverLib} from "~src/resolver/libraries/PermissionedResolverLib.sol"; @@ -19,6 +20,7 @@ import {LibLabel} from "~src/utils/LibLabel.sol"; /// @title Deploy DOS Name Service on testnet /// @notice Deploys a standard wrapped-native WDOS token and the complete `.dos` ENSv2 stack. contract DeployDOSTestnet is DeployDOS { + string internal constant BENS_SMOKE_LABEL = "bens-smoke"; /// @notice Contracts produced by the DOS testnet deployment profile. struct TestnetDeployment { WrappedDOS wdos; @@ -55,9 +57,30 @@ contract DeployDOSTestnet is DeployDOS { IERC20(address(deployment.wdos)), chainId ); + _registerBensSmokeName(deployment.names.dosRegistry, initialOwner, owner); _handoff(deployment.names, initialOwner, owner); } + /// @dev Creates one stable Testnet record used by Graph Node and BENS acceptance gates. + function _registerBensSmokeName( + PermissionedRegistry registry, + address initialOwner, + address owner + ) + internal + { + registry.grantRootRoles(RegistryRolesLib.ROLE_REGISTRAR, initialOwner); + registry.register( + BENS_SMOKE_LABEL, + owner, + IRegistry(address(0)), + address(0), + 0, + type(uint64).max + ); + registry.revokeRootRoles(RegistryRolesLib.ROLE_REGISTRAR, initialOwner); + } + function _handoff(Deployment memory deployment, address initialOwner, address owner) internal { if (owner == initialOwner) { return; diff --git a/contracts/test/unit/testnet/WrappedDOS.t.sol b/contracts/test/unit/testnet/WrappedDOS.t.sol index a531db408..9157dee45 100644 --- a/contracts/test/unit/testnet/WrappedDOS.t.sol +++ b/contracts/test/unit/testnet/WrappedDOS.t.sol @@ -95,12 +95,16 @@ contract WrappedDOSTest is Test { uint256 dosTokenId = deployment.names.rootRegistry.getTokenId(LibLabel.id("dos")); uint256 reverseTokenId = deployment.names.rootRegistry.getTokenId(LibLabel.id("reverse")); + uint256 smokeTokenId = deployment.names.dosRegistry.getTokenId( + LibLabel.id("bens-smoke") + ); assertEq(deployment.names.rootRegistry.ownerOf(dosTokenId), protocolOwner); assertEq(deployment.names.rootRegistry.ownerOf(reverseTokenId), protocolOwner); assertEq(deployment.names.rootRegistry.roles(dosTokenId, address(deployer)), 0); assertEq(deployment.names.rootRegistry.roles(reverseTokenId, address(deployer)), 0); assertTrue(deployment.names.rootRegistry.roles(dosTokenId, protocolOwner) != 0); assertTrue(deployment.names.rootRegistry.roles(reverseTokenId, protocolOwner) != 0); + assertEq(deployment.names.dosRegistry.ownerOf(smokeTokenId), protocolOwner); vm.expectRevert(); vm.prank(address(deployer)); From ca0d40712e30723359d0fa61558c0218f7d1e4d2 Mon Sep 17 00:00:00 2001 From: JOY <5027251+JOY@users.noreply.github.com> Date: Wed, 12 Aug 2026 18:21:39 +0700 Subject: [PATCH 05/14] fix: backfill shared ENSv2 registries --- .../script/foundry/DeployDOSTestnet.s.sol | 3 +- contracts/test/unit/testnet/WrappedDOS.t.sol | 5 + docs/indexing-ensv2-events.md | 7 + subgraph/dos-names/schema.graphql | 29 ++ subgraph/dos-names/src/registry.ts | 2 +- subgraph/dos-names/src/subregistry.ts | 263 +++++++++++++++++- subgraph/dos-names/src/userRegistry.ts | 192 ++++++------- subgraph/dos-names/subgraph.template.yaml | 8 +- subgraph/dos-names/tests/registry.test.ts | 75 ++++- 9 files changed, 459 insertions(+), 125 deletions(-) diff --git a/contracts/script/foundry/DeployDOSTestnet.s.sol b/contracts/script/foundry/DeployDOSTestnet.s.sol index 1f1f186db..cf1c2c841 100644 --- a/contracts/script/foundry/DeployDOSTestnet.s.sol +++ b/contracts/script/foundry/DeployDOSTestnet.s.sol @@ -21,6 +21,7 @@ import {LibLabel} from "~src/utils/LibLabel.sol"; /// @notice Deploys a standard wrapped-native WDOS token and the complete `.dos` ENSv2 stack. contract DeployDOSTestnet is DeployDOS { string internal constant BENS_SMOKE_LABEL = "bens-smoke"; + uint64 internal constant BENS_SMOKE_LIFETIME = 10 * 365 days; /// @notice Contracts produced by the DOS testnet deployment profile. struct TestnetDeployment { WrappedDOS wdos; @@ -76,7 +77,7 @@ contract DeployDOSTestnet is DeployDOS { IRegistry(address(0)), address(0), 0, - type(uint64).max + uint64(block.timestamp + BENS_SMOKE_LIFETIME) ); registry.revokeRootRoles(RegistryRolesLib.ROLE_REGISTRAR, initialOwner); } diff --git a/contracts/test/unit/testnet/WrappedDOS.t.sol b/contracts/test/unit/testnet/WrappedDOS.t.sol index 9157dee45..2b803f41e 100644 --- a/contracts/test/unit/testnet/WrappedDOS.t.sol +++ b/contracts/test/unit/testnet/WrappedDOS.t.sol @@ -105,6 +105,11 @@ contract WrappedDOSTest is Test { assertTrue(deployment.names.rootRegistry.roles(dosTokenId, protocolOwner) != 0); assertTrue(deployment.names.rootRegistry.roles(reverseTokenId, protocolOwner) != 0); assertEq(deployment.names.dosRegistry.ownerOf(smokeTokenId), protocolOwner); + assertLe( + deployment.names.dosRegistry.getExpiry(smokeTokenId), + 253402300799, + "smoke expiry must remain BENS/PostgreSQL timestamp-safe" + ); vm.expectRevert(); vm.prank(address(deployer)); diff --git a/docs/indexing-ensv2-events.md b/docs/indexing-ensv2-events.md index 90d6291d6..0eef24110 100644 --- a/docs/indexing-ensv2-events.md +++ b/docs/indexing-ensv2-events.md @@ -458,6 +458,13 @@ Multiple parent names can point to the same subregistry via `setSubregistry()`. Children registered in `0xABC` appear under both parents. The token `wallet` in registry `0xABC` is simultaneously `wallet.sub1.sub2.parent.eth` and `wallet.linked.parent.eth` — they share the same tokenId. +Because a Graph dynamic data source cannot replay blocks before its creation, an +indexer must also retain the current child state for every discovered registry. +When an already-known registry is attached to another parent, the indexer +materializes those retained children under the new parent immediately. Event +entity IDs must include the parent context so the two alias paths do not +overwrite each other's history rows. + ### Alias Resolution Aliases are a resolver-level concept, not a registry-level one: diff --git a/subgraph/dos-names/schema.graphql b/subgraph/dos-names/schema.graphql index e4fc45c78..65351d40c 100644 --- a/subgraph/dos-names/schema.graphql +++ b/subgraph/dos-names/schema.graphql @@ -318,6 +318,35 @@ type RegistryPath @entity { active: Boolean! } +"Tracks the linked list of known children for one dynamic ENSv2 registry" +type RegistrySource @entity { + id: ID! + registry: Bytes! + firstChild: RegistryChild +} + +"Stores current child state so a registry attached to another parent can be backfilled" +type RegistryChild @entity { + id: ID! + source: RegistrySource! + tokenId: BigInt! + labelName: String! + labelhash: Bytes! + owner: Bytes! + expiryDate: BigInt! + resolver: Bytes! + subregistry: Bytes! + active: Boolean! + createdAt: BigInt! + nextChild: RegistryChild +} + +"Maps a dynamic registry's current ERC1155 token ID to its stable child snapshot" +type RegistryChildToken @entity { + id: ID! + child: RegistryChild! +} + "Tracks resolver addresses already registered as dynamic data sources" type ResolverSource @entity { id: ID! diff --git a/subgraph/dos-names/src/registry.ts b/subgraph/dos-names/src/registry.ts index abf4d4d98..5c55c0535 100644 --- a/subgraph/dos-names/src/registry.ts +++ b/subgraph/dos-names/src/registry.ts @@ -412,5 +412,5 @@ export function handleSubregistryUpdated(event: SubregistryUpdatedEvent): void { if (node === null || Domain.load(node) === null) { return; } - updateSubregistry(node, event.params.subregistry); + updateSubregistry(node, event.params.subregistry, event); } diff --git a/subgraph/dos-names/src/subregistry.ts b/subgraph/dos-names/src/subregistry.ts index e4481829b..a65596a6d 100644 --- a/subgraph/dos-names/src/subregistry.ts +++ b/subgraph/dos-names/src/subregistry.ts @@ -1,13 +1,53 @@ import { Address, + BigInt, + ByteArray, Bytes, DataSourceContext, dataSource, + ethereum, + crypto, + store, } from "@graphprotocol/graph-ts"; -import { RegistryPath } from "./types/schema"; -import { UserRegistryTemplate } from "./types/templates"; -import { EMPTY_ADDRESS } from "./utils"; +import { + Domain, + NewOwner, + Registration, + RegistryChild, + RegistryChildToken, + RegistryPath, + RegistrySource, + Resolver, + ResolverSource, + TokenToDomain, + WrappedDomain, +} from "./types/schema"; +import { ResolverTemplate, UserRegistryTemplate } from "./types/templates"; +import { + concat, + createEventID, + createOrLoadAccount, + EMPTY_ADDRESS, + tokenIdToHex, +} from "./utils"; + +function childTokenId(registry: Address, tokenId: BigInt): string { + return registry.toHexString().concat("-").concat(tokenIdToHex(tokenId)); +} + +function scopedTokenId( + registry: Address, + parentNode: string, + tokenId: BigInt +): string { + return registry + .toHexString() + .concat("-") + .concat(parentNode) + .concat("-") + .concat(tokenIdToHex(tokenId)); +} export function isActiveUserRegistry(registry: Address): boolean { let parentNode = dataSource.context().getBytes("parentNode").toHexString(); @@ -19,9 +59,203 @@ export function isActiveUserRegistry(registry: Address): boolean { ); } +export function loadRegistryChild( + registry: Address, + tokenId: BigInt +): RegistryChild | null { + let token = RegistryChildToken.load(childTokenId(registry, tokenId)); + return token === null ? null : RegistryChild.load(token.child); +} + +export function rememberRegistryChild( + registry: Address, + tokenId: BigInt, + labelName: string, + labelhash: Bytes, + owner: Address, + expiryDate: BigInt, + createdAt: BigInt +): RegistryChild { + let sourceId = registry.toHexString(); + let source = RegistrySource.load(sourceId); + if (source === null) { + source = new RegistrySource(sourceId); + source.registry = registry; + source.save(); + } + + let tokenKey = childTokenId(registry, tokenId); + let token = RegistryChildToken.load(tokenKey); + let child: RegistryChild | null = null; + if (token !== null) { + child = RegistryChild.load(token.child); + } + if (child === null) { + child = new RegistryChild(tokenKey); + child.source = sourceId; + child.createdAt = createdAt; + child.resolver = Address.fromString(EMPTY_ADDRESS); + child.subregistry = Address.fromString(EMPTY_ADDRESS); + child.nextChild = source.firstChild; + source.firstChild = child.id; + source.save(); + } + + let currentChild = child as RegistryChild; + currentChild.tokenId = tokenId; + currentChild.labelName = labelName; + currentChild.labelhash = labelhash; + currentChild.owner = owner; + currentChild.expiryDate = expiryDate; + currentChild.resolver = Address.fromString(EMPTY_ADDRESS); + currentChild.subregistry = Address.fromString(EMPTY_ADDRESS); + currentChild.active = true; + currentChild.save(); + + if (token === null) { + token = new RegistryChildToken(tokenKey); + } + token.child = currentChild.id; + token.save(); + return currentChild; +} + +export function moveRegistryChildToken( + registry: Address, + oldTokenId: BigInt, + newTokenId: BigInt +): RegistryChild | null { + let oldKey = childTokenId(registry, oldTokenId); + let oldToken = RegistryChildToken.load(oldKey); + if (oldToken === null) { + return null; + } + let child = RegistryChild.load(oldToken.child); + if (child === null) { + return null; + } + + child.tokenId = newTokenId; + child.save(); + let newToken = new RegistryChildToken(childTokenId(registry, newTokenId)); + newToken.child = child.id; + newToken.save(); + store.remove("RegistryChildToken", oldKey); + return child; +} + +export function materializeRegistryChild( + parentId: string, + registry: Address, + child: RegistryChild, + event: ethereum.Event +): string | null { + if (!child.active) { + return null; + } + let parent = Domain.load(parentId); + if (parent === null || parent.name === null) { + return null; + } + + let parentNode = Bytes.fromHexString(parentId); + let node = crypto + .keccak256(concat(changetype(parentNode), child.labelhash)) + .toHexString(); + let account = createOrLoadAccount(child.owner.toHexString()); + let domain = Domain.load(node); + let isNew = domain === null; + if (domain === null) { + domain = new Domain(node); + domain.createdAt = child.createdAt; + domain.subdomainCount = 0; + domain.storedOffchain = false; + domain.resolvedWithWildcard = false; + domain.isMigrated = true; + } + + domain.owner = account.id; + domain.registrant = account.id; + domain.wrappedOwner = account.id; + domain.parent = parentId; + domain.labelName = child.labelName; + domain.labelhash = child.labelhash; + domain.name = child.labelName.concat(".").concat(parent.name!); + domain.expiryDate = child.expiryDate; + domain.tokenId = child.tokenId; + domain.save(); + + if (isNew) { + parent.subdomainCount = parent.subdomainCount + 1; + parent.save(); + } + + let tokenMapping = new TokenToDomain( + scopedTokenId(registry, parentId, child.tokenId) + ); + tokenMapping.domain = node; + tokenMapping.save(); + + let registration = new Registration(node); + registration.domain = node; + registration.registrationDate = child.createdAt; + registration.expiryDate = child.expiryDate; + registration.registrant = account.id; + registration.labelName = child.labelName; + registration.save(); + + let wrappedDomain = new WrappedDomain(node); + wrappedDomain.domain = node; + wrappedDomain.expiryDate = child.expiryDate; + wrappedDomain.fuses = 0; + wrappedDomain.owner = account.id; + wrappedDomain.name = domain.name; + wrappedDomain.save(); + + let resolverAddress = Address.fromBytes(child.resolver); + if (resolverAddress.toHexString() != EMPTY_ADDRESS) { + attachResolver(domain, resolverAddress); + } + + let domainEvent = new NewOwner( + createEventID(event).concat("-").concat(parentId) + ); + domainEvent.blockNumber = event.block.number.toI32(); + domainEvent.transactionID = event.transaction.hash; + domainEvent.parentDomain = parentId; + domainEvent.domain = node; + domainEvent.owner = account.id; + domainEvent.save(); + return node; +} + +export function attachResolver(domain: Domain, resolverAddress: Address): void { + let sourceId = resolverAddress.toHexString(); + let source = ResolverSource.load(sourceId); + if (source === null) { + source = new ResolverSource(sourceId); + source.address = resolverAddress; + source.save(); + ResolverTemplate.create(resolverAddress); + } + + let resolverId = sourceId.concat("-").concat(domain.id); + let resolver = Resolver.load(resolverId); + if (resolver === null) { + resolver = new Resolver(resolverId); + resolver.domain = domain.id; + resolver.address = resolverAddress; + resolver.save(); + } + domain.resolver = resolverId; + domain.resolvedAddress = resolver.addr; + domain.save(); +} + export function updateSubregistry( parentNode: string, - registry: Address + registry: Address, + event: ethereum.Event ): void { let path = RegistryPath.load(parentNode); let registryAddress = registry.toHexString(); @@ -49,4 +283,25 @@ export function updateSubregistry( context.setBytes("parentNode", Bytes.fromHexString(parentNode)); UserRegistryTemplate.createWithContext(registry, context); } + + let source = RegistrySource.load(registryAddress); + let childId: string | null = null; + if (source !== null) { + childId = source.firstChild; + } + while (childId !== null) { + let currentId = childId as string; + let child = RegistryChild.load(currentId); + if (child === null) { + break; + } + let node = materializeRegistryChild(parentNode, registry, child, event); + if ( + node !== null && + child.subregistry.toHexString() != EMPTY_ADDRESS + ) { + updateSubregistry(node as string, Address.fromBytes(child.subregistry), event); + } + childId = child.nextChild; + } } diff --git a/subgraph/dos-names/src/userRegistry.ts b/subgraph/dos-names/src/userRegistry.ts index ea594e2ae..22826ff22 100644 --- a/subgraph/dos-names/src/userRegistry.ts +++ b/subgraph/dos-names/src/userRegistry.ts @@ -1,9 +1,6 @@ import { Address, BigInt, - ByteArray, - Bytes, - crypto, dataSource, ethereum, store, @@ -22,20 +19,23 @@ import { import { Domain, NewResolver, - NewOwner, Registration, - Resolver, - ResolverSource, TokenToDomain, Transfer, WrappedDomain, WrappedTransfer, } from "./types/schema"; -import { ResolverTemplate } from "./types/templates"; -import { isActiveUserRegistry, updateSubregistry } from "./subregistry"; +import { + attachResolver, + isActiveUserRegistry, + loadRegistryChild, + materializeRegistryChild, + moveRegistryChildToken, + rememberRegistryChild, + updateSubregistry, +} from "./subregistry"; import { checkValidLabel, - concat, createEventID, createOrLoadAccount, EMPTY_ADDRESS, @@ -56,86 +56,44 @@ function resolveDomainNode(event: ethereum.Event, tokenId: string): string | nul return mapping === null ? null : mapping.domain; } +function contextEventID(event: ethereum.Event): string { + return createEventID(event) + .concat("-") + .concat(dataSource.context().getBytes("parentNode").toHexString()); +} + export function handleUserRegistryLabelRegistered(event: LabelRegisteredEvent): void { - if (!isActiveUserRegistry(event.address)) { - return; - } let label = event.params.label; if (!checkValidLabel(label)) { return; } - - let context = dataSource.context(); - let parentNode = context.getBytes("parentNode"); - let parentId = parentNode.toHexString(); - let parent = Domain.load(parentId); - if (parent === null || parent.name === null) { + let child = rememberRegistryChild( + event.address, + event.params.tokenId, + label, + event.params.labelHash, + event.params.owner, + event.params.expiry, + event.block.timestamp + ); + if (!isActiveUserRegistry(event.address)) { return; } - - let node = crypto - .keccak256(concat(changetype(parentNode), event.params.labelHash)) - .toHexString(); - let account = createOrLoadAccount(event.params.owner.toHexString()); - let domain = Domain.load(node); - let isNew = domain === null; - if (domain === null) { - domain = new Domain(node); - domain.createdAt = event.block.timestamp; - domain.subdomainCount = 0; - domain.storedOffchain = false; - domain.resolvedWithWildcard = false; - domain.isMigrated = true; - } - - domain.owner = account.id; - domain.registrant = account.id; - domain.wrappedOwner = account.id; - domain.parent = parentId; - domain.labelName = label; - domain.labelhash = event.params.labelHash; - domain.name = label.concat(".").concat(parent.name!); - domain.expiryDate = event.params.expiry; - domain.tokenId = event.params.tokenId; - domain.save(); - - if (isNew) { - parent.subdomainCount = parent.subdomainCount + 1; - parent.save(); - } - - let tokenMapping = new TokenToDomain( - registryTokenId(event, tokenIdToHex(event.params.tokenId)) + materializeRegistryChild( + dataSource.context().getBytes("parentNode").toHexString(), + event.address, + child, + event ); - tokenMapping.domain = node; - tokenMapping.save(); - - let registration = new Registration(node); - registration.domain = node; - registration.registrationDate = event.block.timestamp; - registration.expiryDate = event.params.expiry; - registration.registrant = account.id; - registration.labelName = label; - registration.save(); - - let wrappedDomain = new WrappedDomain(node); - wrappedDomain.domain = node; - wrappedDomain.expiryDate = event.params.expiry; - wrappedDomain.fuses = 0; - wrappedDomain.owner = account.id; - wrappedDomain.name = domain.name; - wrappedDomain.save(); - - let domainEvent = new NewOwner(createEventID(event)); - domainEvent.blockNumber = event.block.number.toI32(); - domainEvent.transactionID = event.transaction.hash; - domainEvent.parentDomain = parentId; - domainEvent.domain = node; - domainEvent.owner = account.id; - domainEvent.save(); } export function handleUserRegistryResolverUpdated(event: ResolverUpdatedEvent): void { + let child = loadRegistryChild(event.address, event.params.tokenId); + if (child === null) { + return; + } + child.resolver = event.params.resolver; + child.save(); if (!isActiveUserRegistry(event.address)) { return; } @@ -157,29 +115,10 @@ export function handleUserRegistryResolverUpdated(event: ResolverUpdatedEvent): return; } - let sourceId = resolverAddress.toHexString(); - let source = ResolverSource.load(sourceId); - if (source === null) { - source = new ResolverSource(sourceId); - source.address = resolverAddress; - source.save(); - ResolverTemplate.create(resolverAddress); - } - - let resolverId = sourceId.concat("-").concat(node); - let resolver = Resolver.load(resolverId); - if (resolver === null) { - resolver = new Resolver(resolverId); - resolver.domain = node; - resolver.address = resolverAddress; - resolver.save(); - } - - domain.resolver = resolverId; - domain.resolvedAddress = resolver.addr; - domain.save(); + attachResolver(domain, resolverAddress); + let resolverId = resolverAddress.toHexString().concat("-").concat(node); - let domainEvent = new NewResolver(createEventID(event)); + let domainEvent = new NewResolver(contextEventID(event)); domainEvent.domain = node; domainEvent.blockNumber = event.block.number.toI32(); domainEvent.transactionID = event.transaction.hash; @@ -188,6 +127,11 @@ export function handleUserRegistryResolverUpdated(event: ResolverUpdatedEvent): } export function handleUserRegistryExpiryUpdated(event: ExpiryUpdatedEvent): void { + let child = loadRegistryChild(event.address, event.params.tokenId); + if (child !== null) { + child.expiryDate = event.params.newExpiry; + child.save(); + } if (!isActiveUserRegistry(event.address)) { return; } @@ -216,10 +160,15 @@ export function handleUserRegistryExpiryUpdated(event: ExpiryUpdatedEvent): void } export function handleUserRegistryTransferSingle(event: TransferSingleEvent): void { - if ( - !isActiveUserRegistry(event.address) || - event.params.value.equals(BigInt.fromI32(0)) - ) { + if (event.params.value.equals(BigInt.fromI32(0))) { + return; + } + let child = loadRegistryChild(event.address, event.params.id); + if (child !== null) { + child.owner = event.params.to; + child.save(); + } + if (!isActiveUserRegistry(event.address)) { return; } let node = resolveDomainNode(event, tokenIdToHex(event.params.id)); @@ -236,9 +185,7 @@ export function handleUserRegistryTransferSingle(event: TransferSingleEvent): vo } export function handleUserRegistryTransferBatch(event: TransferBatchEvent): void { - if (!isActiveUserRegistry(event.address)) { - return; - } + let active = isActiveUserRegistry(event.address); let ids = event.params.ids; let values = event.params.values; let count = ids.length < values.length ? ids.length : values.length; @@ -246,6 +193,14 @@ export function handleUserRegistryTransferBatch(event: TransferBatchEvent): void if (values[i].equals(BigInt.fromI32(0))) { continue; } + let child = loadRegistryChild(event.address, ids[i]); + if (child !== null) { + child.owner = event.params.to; + child.save(); + } + if (!active) { + continue; + } let node = resolveDomainNode(event, tokenIdToHex(ids[i])); if (node !== null) { applyOwnershipTransfer( @@ -286,7 +241,7 @@ function applyOwnershipTransfer( registration.save(); } - let transferEvent = new Transfer(createEventID(event).concat(eventSuffix)); + let transferEvent = new Transfer(contextEventID(event).concat(eventSuffix)); transferEvent.domain = node; transferEvent.blockNumber = event.block.number.toI32(); transferEvent.transactionID = event.transaction.hash; @@ -294,7 +249,7 @@ function applyOwnershipTransfer( transferEvent.save(); let wrappedTransfer = new WrappedTransfer( - createEventID(event).concat("-wrapped").concat(eventSuffix) + contextEventID(event).concat("-wrapped").concat(eventSuffix) ); wrappedTransfer.domain = node; wrappedTransfer.blockNumber = event.block.number.toI32(); @@ -304,6 +259,11 @@ function applyOwnershipTransfer( } export function handleUserRegistryTokenRegenerated(event: TokenRegeneratedEvent): void { + moveRegistryChildToken( + event.address, + event.params.oldTokenId, + event.params.newTokenId + ); if (!isActiveUserRegistry(event.address)) { return; } @@ -327,6 +287,11 @@ export function handleUserRegistryTokenRegenerated(event: TokenRegeneratedEvent) } export function handleUserRegistrySubregistryUpdated(event: SubregistryUpdatedEvent): void { + let child = loadRegistryChild(event.address, event.params.tokenId); + if (child !== null) { + child.subregistry = event.params.subregistry; + child.save(); + } if (!isActiveUserRegistry(event.address)) { return; } @@ -336,10 +301,17 @@ export function handleUserRegistrySubregistryUpdated(event: SubregistryUpdatedEv return; } - updateSubregistry(node, event.params.subregistry); + updateSubregistry(node, event.params.subregistry, event); } export function handleUserRegistryLabelUnregistered(event: LabelUnregisteredEvent): void { + let child = loadRegistryChild(event.address, event.params.tokenId); + if (child !== null) { + child.active = false; + child.expiryDate = event.block.timestamp; + child.owner = Address.fromString(EMPTY_ADDRESS); + child.save(); + } if (!isActiveUserRegistry(event.address)) { return; } diff --git a/subgraph/dos-names/subgraph.template.yaml b/subgraph/dos-names/subgraph.template.yaml index 1bcbd504d..5aadae947 100644 --- a/subgraph/dos-names/subgraph.template.yaml +++ b/subgraph/dos-names/subgraph.template.yaml @@ -4,7 +4,7 @@ schema: file: ./schema.graphql dataSources: # DOSTLDRegistry (PermissionedRegistry) - .dos TLD registry - # Emits: NameRegistered, ResolverUpdated, ExpiryUpdated, SubregistryUpdated, TransferSingle + # Emits: NameRegistered, ResolverUpdated, ExpiryUpdated, SubregistryUpdated, ERC1155 transfers - kind: ethereum/contract name: DOSTLDRegistry network: dos-testnet @@ -21,6 +21,9 @@ dataSources: - Domain - Account - Registration + - RegistryChild + - RegistryChildToken + - RegistrySource abis: - name: PermissionedRegistry file: ./abis/PermissionedRegistry.json @@ -125,7 +128,10 @@ templates: - Domain - Account - Registration + - RegistryChild + - RegistryChildToken - RegistryPath + - RegistrySource abis: - name: PermissionedRegistry file: ./abis/PermissionedRegistry.json diff --git a/subgraph/dos-names/tests/registry.test.ts b/subgraph/dos-names/tests/registry.test.ts index 5d80a2f89..56f970a1a 100644 --- a/subgraph/dos-names/tests/registry.test.ts +++ b/subgraph/dos-names/tests/registry.test.ts @@ -33,6 +33,7 @@ import { handleUserRegistryTransferBatch, handleUserRegistryTransferSingle, } from "../src/userRegistry"; +import { updateSubregistry } from "../src/subregistry"; import { LabelRegistered, LabelUnregistered, @@ -68,6 +69,8 @@ const SUB_ALICE_DOS = "0x1c1ff2cdbb0b7cc0b67c4b92a0ba7633d2cf2d2e756ea950fbe437050296f930"; const BOB_DOS = "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; +const SUB_BOB_DOS = + "0x7ee7b82ae369bf398c232f0c2b4def081af73b8ed707d68cce8a3f685b0c07f7"; function registration(tokenId: i32): LabelRegistered { let mock = newMockEvent(); @@ -683,7 +686,60 @@ test("detached user registries stop mutating their former parent path", () => { assert.fieldEquals("Domain", SUB_ALICE_DOS, "owner", OWNER); }); -test("a shared user registry keeps token mappings scoped to each parent", () => { +test("detached registry sources retain current state for a later attachment", () => { + handleLabelRegistered(registration(123)); + activateUserRegistry(); + handleUserRegistryLabelRegistered(userRegistryRegistration(456)); + handleSubregistryUpdated(subregistryUpdated(123, ZERO_ADDRESS)); + handleUserRegistryTransferSingle(userRegistryTransfer(456)); + + let bob = new Domain(BOB_DOS); + bob.name = "bob.dos"; + bob.labelName = "bob"; + bob.owner = OWNER; + bob.isMigrated = true; + bob.createdAt = BigInt.fromI32(1); + bob.subdomainCount = 0; + bob.storedOffchain = false; + bob.resolvedWithWildcard = false; + bob.save(); + updateSubregistry( + BOB_DOS, + Address.fromString(USER_REGISTRY), + subregistryUpdated(123) + ); + + assert.fieldEquals("Domain", SUB_ALICE_DOS, "owner", OWNER); + assert.fieldEquals("Domain", SUB_BOB_DOS, "owner", NEW_OWNER); +}); + +test("attaching a shared registry backfills existing children for the new parent", () => { + handleLabelRegistered(registration(123)); + activateUserRegistry(); + handleUserRegistryLabelRegistered(userRegistryRegistration(456)); + + let bob = new Domain(BOB_DOS); + bob.name = "bob.dos"; + bob.labelName = "bob"; + bob.owner = OWNER; + bob.isMigrated = true; + bob.createdAt = BigInt.fromI32(1); + bob.subdomainCount = 0; + bob.storedOffchain = false; + bob.resolvedWithWildcard = false; + bob.save(); + updateSubregistry( + BOB_DOS, + Address.fromString(USER_REGISTRY), + subregistryUpdated(123) + ); + + assert.entityCount("TokenToDomain", 3); + assert.fieldEquals("Domain", SUB_BOB_DOS, "name", "sub.bob.dos"); + assert.fieldEquals("Domain", SUB_BOB_DOS, "owner", OWNER); +}); + +test("shared registry events retain one history row per parent context", () => { handleLabelRegistered(registration(123)); activateUserRegistry(); handleUserRegistryLabelRegistered(userRegistryRegistration(456)); @@ -698,18 +754,21 @@ test("a shared user registry keeps token mappings scoped to each parent", () => bob.storedOffchain = false; bob.resolvedWithWildcard = false; bob.save(); - let path = new RegistryPath(BOB_DOS); - path.registry = Address.fromString(USER_REGISTRY); - path.parentDomain = BOB_DOS; - path.active = true; - path.save(); + updateSubregistry( + BOB_DOS, + Address.fromString(USER_REGISTRY), + subregistryUpdated(123) + ); + handleUserRegistryTransferSingle(userRegistryTransfer(456)); let bobContext = new DataSourceContext(); bobContext.setBytes("parentNode", Bytes.fromHexString(BOB_DOS)); dataSourceMock.setContext(bobContext); - handleUserRegistryLabelRegistered(userRegistryRegistration(456)); + handleUserRegistryTransferSingle(userRegistryTransfer(456)); - assert.entityCount("TokenToDomain", 3); + assert.entityCount("Transfer", 2); + assert.fieldEquals("Domain", SUB_ALICE_DOS, "owner", NEW_OWNER); + assert.fieldEquals("Domain", SUB_BOB_DOS, "owner", NEW_OWNER); }); test("a user-registry unregistration retires the scoped token mapping", () => { From 52740f31f7dd72a12ad9817e8faa954a85f3207a Mon Sep 17 00:00:00 2001 From: JOY <5027251+JOY@users.noreply.github.com> Date: Wed, 12 Aug 2026 18:31:09 +0700 Subject: [PATCH 06/14] fix: retire detached ENSv2 paths --- subgraph/dos-names/src/registry.ts | 3 +- subgraph/dos-names/src/subregistry.ts | 138 +++++++++++++++++++++- subgraph/dos-names/src/userRegistry.ts | 13 +- subgraph/dos-names/tests/registry.test.ts | 100 ++++++++++++++-- 4 files changed, 239 insertions(+), 15 deletions(-) diff --git a/subgraph/dos-names/src/registry.ts b/subgraph/dos-names/src/registry.ts index 5c55c0535..df8d1ecd3 100644 --- a/subgraph/dos-names/src/registry.ts +++ b/subgraph/dos-names/src/registry.ts @@ -380,6 +380,7 @@ export function handleLabelUnregistered(event: LabelUnregisteredEvent): void { return; } + updateSubregistry(mapping.domain, Address.fromString(EMPTY_ADDRESS), event, []); let zeroAccount = createOrLoadAccount(EMPTY_ADDRESS); domain.owner = zeroAccount.id; domain.registrant = zeroAccount.id; @@ -412,5 +413,5 @@ export function handleSubregistryUpdated(event: SubregistryUpdatedEvent): void { if (node === null || Domain.load(node) === null) { return; } - updateSubregistry(node, event.params.subregistry, event); + updateSubregistry(node, event.params.subregistry, event, []); } diff --git a/subgraph/dos-names/src/subregistry.ts b/subgraph/dos-names/src/subregistry.ts index a65596a6d..fe0180bca 100644 --- a/subgraph/dos-names/src/subregistry.ts +++ b/subgraph/dos-names/src/subregistry.ts @@ -32,6 +32,9 @@ import { tokenIdToHex, } from "./utils"; +const MAX_REGISTRY_DEPTH = 32; +const MAX_REGISTRY_CHILDREN = 10000; + function childTokenId(registry: Address, tokenId: BigInt): string { return registry.toHexString().concat("-").concat(tokenIdToHex(tokenId)); } @@ -218,7 +221,11 @@ export function materializeRegistryChild( } let domainEvent = new NewOwner( - createEventID(event).concat("-").concat(parentId) + createEventID(event) + .concat("-") + .concat(parentId) + .concat("-") + .concat(child.id) ); domainEvent.blockNumber = event.block.number.toI32(); domainEvent.transactionID = event.transaction.hash; @@ -229,6 +236,92 @@ export function materializeRegistryChild( return node; } +function childNode(parentId: string, child: RegistryChild): string { + return crypto + .keccak256( + concat( + changetype(Bytes.fromHexString(parentId)), + child.labelhash + ) + ) + .toHexString(); +} + +function retireDomain(node: string, timestamp: BigInt): void { + let domain = Domain.load(node); + if (domain === null) { + return; + } + let zeroAccount = createOrLoadAccount(EMPTY_ADDRESS); + domain.owner = zeroAccount.id; + domain.registrant = zeroAccount.id; + domain.wrappedOwner = zeroAccount.id; + domain.expiryDate = timestamp; + domain.tokenId = null; + domain.resolver = null; + domain.resolvedAddress = null; + domain.save(); + + let wrapped = WrappedDomain.load(node); + if (wrapped !== null) { + wrapped.owner = zeroAccount.id; + wrapped.expiryDate = timestamp; + wrapped.save(); + } + let registration = Registration.load(node); + if (registration !== null) { + registration.registrant = zeroAccount.id; + registration.expiryDate = timestamp; + registration.save(); + } +} + +function retireRegistryPath( + parentNode: string, + registry: Address, + event: ethereum.Event, + ancestors: string[], + depth: i32 +): void { + if (depth >= MAX_REGISTRY_DEPTH) { + return; + } + let registryAddress = registry.toHexString(); + if (ancestors.includes(registryAddress)) { + return; + } + let nextAncestors = ancestors.concat([registryAddress]); + let source = RegistrySource.load(registryAddress); + let childId: string | null = source === null ? null : source.firstChild; + let visitedChildren = 0; + while (childId !== null && visitedChildren < MAX_REGISTRY_CHILDREN) { + let child = RegistryChild.load(childId as string); + if (child === null) { + break; + } + let node = childNode(parentNode, child); + let nestedPath = RegistryPath.load(node); + if (nestedPath !== null && nestedPath.active) { + retireRegistryPath( + node, + Address.fromBytes(nestedPath.registry), + event, + nextAncestors, + depth + 1 + ); + nestedPath.active = false; + nestedPath.save(); + } + retireDomain(node, event.block.timestamp); + store.remove( + "TokenToDomain", + scopedTokenId(registry, parentNode, child.tokenId) + ); + childId = child.nextChild; + visitedChildren += 1; + } +} + export function attachResolver(domain: Domain, resolverAddress: Address): void { let sourceId = resolverAddress.toHexString(); let source = ResolverSource.load(sourceId); @@ -255,19 +348,48 @@ export function attachResolver(domain: Domain, resolverAddress: Address): void { export function updateSubregistry( parentNode: string, registry: Address, - event: ethereum.Event + event: ethereum.Event, + ancestors: string[] ): void { let path = RegistryPath.load(parentNode); let registryAddress = registry.toHexString(); if (registryAddress == EMPTY_ADDRESS) { if (path !== null) { + if (path.active) { + retireRegistryPath( + parentNode, + Address.fromBytes(path.registry), + event, + ancestors, + 0 + ); + } path.active = false; path.save(); } return; } + if (ancestors.includes(registryAddress)) { + return; + } + if ( + path !== null && + path.active && + path.registry.toHexString() != registryAddress + ) { + retireRegistryPath( + parentNode, + Address.fromBytes(path.registry), + event, + ancestors, + 0 + ); + path.active = false; + path.save(); + } + let requiresSource = path === null || path.registry.toHexString() != registryAddress; if (path === null) { @@ -289,7 +411,9 @@ export function updateSubregistry( if (source !== null) { childId = source.firstChild; } - while (childId !== null) { + let visitedChildren = 0; + let nextAncestors = ancestors.concat([registryAddress]); + while (childId !== null && visitedChildren < MAX_REGISTRY_CHILDREN) { let currentId = childId as string; let child = RegistryChild.load(currentId); if (child === null) { @@ -300,8 +424,14 @@ export function updateSubregistry( node !== null && child.subregistry.toHexString() != EMPTY_ADDRESS ) { - updateSubregistry(node as string, Address.fromBytes(child.subregistry), event); + updateSubregistry( + node as string, + Address.fromBytes(child.subregistry), + event, + nextAncestors + ); } childId = child.nextChild; + visitedChildren += 1; } } diff --git a/subgraph/dos-names/src/userRegistry.ts b/subgraph/dos-names/src/userRegistry.ts index 22826ff22..d78aa6183 100644 --- a/subgraph/dos-names/src/userRegistry.ts +++ b/subgraph/dos-names/src/userRegistry.ts @@ -301,7 +301,12 @@ export function handleUserRegistrySubregistryUpdated(event: SubregistryUpdatedEv return; } - updateSubregistry(node, event.params.subregistry, event); + updateSubregistry( + node, + event.params.subregistry, + event, + [event.address.toHexString()] + ); } export function handleUserRegistryLabelUnregistered(event: LabelUnregisteredEvent): void { @@ -327,6 +332,12 @@ export function handleUserRegistryLabelUnregistered(event: LabelUnregisteredEven return; } + updateSubregistry( + mapping.domain, + Address.fromString(EMPTY_ADDRESS), + event, + [event.address.toHexString()] + ); let zeroAccount = createOrLoadAccount(EMPTY_ADDRESS); domain.owner = zeroAccount.id; domain.registrant = zeroAccount.id; diff --git a/subgraph/dos-names/tests/registry.test.ts b/subgraph/dos-names/tests/registry.test.ts index 56f970a1a..a673161ff 100644 --- a/subgraph/dos-names/tests/registry.test.ts +++ b/subgraph/dos-names/tests/registry.test.ts @@ -71,6 +71,10 @@ const BOB_DOS = "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; const SUB_BOB_DOS = "0x7ee7b82ae369bf398c232f0c2b4def081af73b8ed707d68cce8a3f685b0c07f7"; +const SECOND_LABEL_HASH = + "0x45318970bfff215a328f56895f3a97d4f276a44c24c135c12c37867a1f667b8a"; +const SECOND_BOB_DOS = + "0xc2c4870365c617dfcbdc325faf5901634da2c66d1469f96233dd050284c15481"; function registration(tokenId: i32): LabelRegistered { let mock = newMockEvent(); @@ -306,6 +310,14 @@ function batchTransfer(tokenIds: i32[], values: i32[]): TransferBatch { } function userRegistryRegistration(tokenId: i32): UserRegistryLabelRegistered { + return userRegistryRegistrationFor(tokenId, "sub", SUB_LABEL_HASH); +} + +function userRegistryRegistrationFor( + tokenId: i32, + label: string, + labelHash: string +): UserRegistryLabelRegistered { let mock = newMockEvent(); mock.address = Address.fromString(USER_REGISTRY); let event = new UserRegistryLabelRegistered( @@ -325,9 +337,9 @@ function userRegistryRegistration(tokenId: i32): UserRegistryLabelRegistered { ), new ethereum.EventParam( "labelHash", - ethereum.Value.fromFixedBytes(Bytes.fromHexString(SUB_LABEL_HASH)) + ethereum.Value.fromFixedBytes(Bytes.fromHexString(labelHash)) ), - new ethereum.EventParam("label", ethereum.Value.fromString("sub")), + new ethereum.EventParam("label", ethereum.Value.fromString(label)), new ethereum.EventParam( "owner", ethereum.Value.fromAddress(Address.fromString(OWNER)) @@ -558,7 +570,10 @@ function userRegistryTokenRegenerated( return event; } -function userRegistrySubregistryUpdated(tokenId: i32): UserRegistrySubregistryUpdated { +function userRegistrySubregistryUpdated( + tokenId: i32, + registry: string = NESTED_REGISTRY +): UserRegistrySubregistryUpdated { let mock = newMockEvent(); mock.address = Address.fromString(USER_REGISTRY); mock.logIndex = BigInt.fromI32(1); @@ -579,7 +594,7 @@ function userRegistrySubregistryUpdated(tokenId: i32): UserRegistrySubregistryUp ), new ethereum.EventParam( "subregistry", - ethereum.Value.fromAddress(Address.fromString(NESTED_REGISTRY)) + ethereum.Value.fromAddress(Address.fromString(registry)) ), new ethereum.EventParam( "sender", @@ -683,7 +698,7 @@ test("detached user registries stop mutating their former parent path", () => { handleUserRegistryTransferSingle(userRegistryTransfer(456)); assert.fieldEquals("RegistryPath", ALICE_DOS, "active", "false"); - assert.fieldEquals("Domain", SUB_ALICE_DOS, "owner", OWNER); + assert.fieldEquals("Domain", SUB_ALICE_DOS, "owner", ZERO_ADDRESS); }); test("detached registry sources retain current state for a later attachment", () => { @@ -706,10 +721,11 @@ test("detached registry sources retain current state for a later attachment", () updateSubregistry( BOB_DOS, Address.fromString(USER_REGISTRY), - subregistryUpdated(123) + subregistryUpdated(123), + [] ); - assert.fieldEquals("Domain", SUB_ALICE_DOS, "owner", OWNER); + assert.fieldEquals("Domain", SUB_ALICE_DOS, "owner", ZERO_ADDRESS); assert.fieldEquals("Domain", SUB_BOB_DOS, "owner", NEW_OWNER); }); @@ -731,7 +747,8 @@ test("attaching a shared registry backfills existing children for the new parent updateSubregistry( BOB_DOS, Address.fromString(USER_REGISTRY), - subregistryUpdated(123) + subregistryUpdated(123), + [] ); assert.entityCount("TokenToDomain", 3); @@ -739,6 +756,59 @@ test("attaching a shared registry backfills existing children for the new parent assert.fieldEquals("Domain", SUB_BOB_DOS, "owner", OWNER); }); +test("backfilling multiple children preserves each ownership event", () => { + handleLabelRegistered(registration(123)); + activateUserRegistry(); + handleUserRegistryLabelRegistered(userRegistryRegistration(456)); + handleUserRegistryLabelRegistered( + userRegistryRegistrationFor(457, "second", SECOND_LABEL_HASH) + ); + + let bob = new Domain(BOB_DOS); + bob.name = "bob.dos"; + bob.labelName = "bob"; + bob.owner = OWNER; + bob.isMigrated = true; + bob.createdAt = BigInt.fromI32(1); + bob.subdomainCount = 0; + bob.storedOffchain = false; + bob.resolvedWithWildcard = false; + bob.save(); + updateSubregistry( + BOB_DOS, + Address.fromString(USER_REGISTRY), + subregistryUpdated(123), + [] + ); + + assert.fieldEquals("Domain", SUB_BOB_DOS, "owner", OWNER); + assert.fieldEquals("Domain", SECOND_BOB_DOS, "owner", OWNER); + assert.entityCount("NewOwner", 5); +}); + +test("self-linked subregistries fail closed without creating a cyclic path", () => { + handleLabelRegistered(registration(123)); + activateUserRegistry(); + handleUserRegistryLabelRegistered(userRegistryRegistration(456)); + + handleUserRegistrySubregistryUpdated( + userRegistrySubregistryUpdated(456, USER_REGISTRY) + ); + + assert.notInStore("RegistryPath", SUB_ALICE_DOS); +}); + +test("replacing a subregistry retires names from the old registry", () => { + handleLabelRegistered(registration(123)); + activateUserRegistry(); + handleUserRegistryLabelRegistered(userRegistryRegistration(456)); + + handleSubregistryUpdated(subregistryUpdated(123, NESTED_REGISTRY)); + + assert.fieldEquals("Domain", SUB_ALICE_DOS, "owner", ZERO_ADDRESS); + assert.fieldEquals("RegistryPath", ALICE_DOS, "registry", NESTED_REGISTRY); +}); + test("shared registry events retain one history row per parent context", () => { handleLabelRegistered(registration(123)); activateUserRegistry(); @@ -757,7 +827,8 @@ test("shared registry events retain one history row per parent context", () => { updateSubregistry( BOB_DOS, Address.fromString(USER_REGISTRY), - subregistryUpdated(123) + subregistryUpdated(123), + [] ); handleUserRegistryTransferSingle(userRegistryTransfer(456)); @@ -791,6 +862,17 @@ test("a user-registry unregistration retires the scoped token mapping", () => { ); }); +test("unregistering a parent retires its nested registry path", () => { + handleLabelRegistered(registration(123)); + activateUserRegistry(); + handleUserRegistryLabelRegistered(userRegistryRegistration(456)); + handleUserRegistrySubregistryUpdated(userRegistrySubregistryUpdated(456)); + + handleUserRegistryLabelUnregistered(userRegistryLabelUnregistered(456)); + + assert.fieldEquals("RegistryPath", SUB_ALICE_DOS, "active", "false"); +}); + test("a user-registry resolver is attached to the subname and dynamically indexed", () => { handleLabelRegistered(registration(123)); activateUserRegistry(); From 9d6682840824d505d042ae614393bf773028b414 Mon Sep 17 00:00:00 2001 From: JOY <5027251+JOY@users.noreply.github.com> Date: Wed, 12 Aug 2026 18:37:06 +0700 Subject: [PATCH 07/14] fix: fail closed on registry traversal --- contracts/test/unit/testnet/WrappedDOS.t.sol | 4 +- subgraph/dos-names/src/registry.ts | 4 +- subgraph/dos-names/src/subregistry.ts | 45 +++++++++++++------- subgraph/dos-names/src/userRegistry.ts | 6 ++- subgraph/dos-names/tests/registry.test.ts | 12 ++++-- 5 files changed, 45 insertions(+), 26 deletions(-) diff --git a/contracts/test/unit/testnet/WrappedDOS.t.sol b/contracts/test/unit/testnet/WrappedDOS.t.sol index 2b803f41e..420bd30c8 100644 --- a/contracts/test/unit/testnet/WrappedDOS.t.sol +++ b/contracts/test/unit/testnet/WrappedDOS.t.sol @@ -95,9 +95,7 @@ contract WrappedDOSTest is Test { uint256 dosTokenId = deployment.names.rootRegistry.getTokenId(LibLabel.id("dos")); uint256 reverseTokenId = deployment.names.rootRegistry.getTokenId(LibLabel.id("reverse")); - uint256 smokeTokenId = deployment.names.dosRegistry.getTokenId( - LibLabel.id("bens-smoke") - ); + uint256 smokeTokenId = deployment.names.dosRegistry.getTokenId(LibLabel.id("bens-smoke")); assertEq(deployment.names.rootRegistry.ownerOf(dosTokenId), protocolOwner); assertEq(deployment.names.rootRegistry.ownerOf(reverseTokenId), protocolOwner); assertEq(deployment.names.rootRegistry.roles(dosTokenId, address(deployer)), 0); diff --git a/subgraph/dos-names/src/registry.ts b/subgraph/dos-names/src/registry.ts index df8d1ecd3..d19d22a50 100644 --- a/subgraph/dos-names/src/registry.ts +++ b/subgraph/dos-names/src/registry.ts @@ -380,7 +380,7 @@ export function handleLabelUnregistered(event: LabelUnregisteredEvent): void { return; } - updateSubregistry(mapping.domain, Address.fromString(EMPTY_ADDRESS), event, []); + updateSubregistry(mapping.domain, Address.fromString(EMPTY_ADDRESS), event, [], 0); let zeroAccount = createOrLoadAccount(EMPTY_ADDRESS); domain.owner = zeroAccount.id; domain.registrant = zeroAccount.id; @@ -413,5 +413,5 @@ export function handleSubregistryUpdated(event: SubregistryUpdatedEvent): void { if (node === null || Domain.load(node) === null) { return; } - updateSubregistry(node, event.params.subregistry, event, []); + updateSubregistry(node, event.params.subregistry, event, [], 0); } diff --git a/subgraph/dos-names/src/subregistry.ts b/subgraph/dos-names/src/subregistry.ts index fe0180bca..7b621fc9a 100644 --- a/subgraph/dos-names/src/subregistry.ts +++ b/subgraph/dos-names/src/subregistry.ts @@ -33,7 +33,6 @@ import { } from "./utils"; const MAX_REGISTRY_DEPTH = 32; -const MAX_REGISTRY_CHILDREN = 10000; function childTokenId(registry: Address, tokenId: BigInt): string { return registry.toHexString().concat("-").concat(tokenIdToHex(tokenId)); @@ -283,9 +282,10 @@ function retireRegistryPath( ancestors: string[], depth: i32 ): void { - if (depth >= MAX_REGISTRY_DEPTH) { - return; - } + assert( + depth < MAX_REGISTRY_DEPTH, + "ENSv2 registry nesting exceeds the supported depth" + ); let registryAddress = registry.toHexString(); if (ancestors.includes(registryAddress)) { return; @@ -293,9 +293,15 @@ function retireRegistryPath( let nextAncestors = ancestors.concat([registryAddress]); let source = RegistrySource.load(registryAddress); let childId: string | null = source === null ? null : source.firstChild; - let visitedChildren = 0; - while (childId !== null && visitedChildren < MAX_REGISTRY_CHILDREN) { - let child = RegistryChild.load(childId as string); + let visitedChildren: string[] = []; + while (childId !== null) { + let currentId = childId as string; + assert( + !visitedChildren.includes(currentId), + "ENSv2 registry child list contains a cycle" + ); + visitedChildren.push(currentId); + let child = RegistryChild.load(currentId); if (child === null) { break; } @@ -318,7 +324,6 @@ function retireRegistryPath( scopedTokenId(registry, parentNode, child.tokenId) ); childId = child.nextChild; - visitedChildren += 1; } } @@ -349,8 +354,13 @@ export function updateSubregistry( parentNode: string, registry: Address, event: ethereum.Event, - ancestors: string[] + ancestors: string[], + depth: i32 ): void { + assert( + depth < MAX_REGISTRY_DEPTH, + "ENSv2 registry nesting exceeds the supported depth" + ); let path = RegistryPath.load(parentNode); let registryAddress = registry.toHexString(); @@ -362,7 +372,7 @@ export function updateSubregistry( Address.fromBytes(path.registry), event, ancestors, - 0 + depth ); } path.active = false; @@ -384,7 +394,7 @@ export function updateSubregistry( Address.fromBytes(path.registry), event, ancestors, - 0 + depth ); path.active = false; path.save(); @@ -411,10 +421,15 @@ export function updateSubregistry( if (source !== null) { childId = source.firstChild; } - let visitedChildren = 0; + let visitedChildren: string[] = []; let nextAncestors = ancestors.concat([registryAddress]); - while (childId !== null && visitedChildren < MAX_REGISTRY_CHILDREN) { + while (childId !== null) { let currentId = childId as string; + assert( + !visitedChildren.includes(currentId), + "ENSv2 registry child list contains a cycle" + ); + visitedChildren.push(currentId); let child = RegistryChild.load(currentId); if (child === null) { break; @@ -428,10 +443,10 @@ export function updateSubregistry( node as string, Address.fromBytes(child.subregistry), event, - nextAncestors + nextAncestors, + depth + 1 ); } childId = child.nextChild; - visitedChildren += 1; } } diff --git a/subgraph/dos-names/src/userRegistry.ts b/subgraph/dos-names/src/userRegistry.ts index d78aa6183..5b823f81d 100644 --- a/subgraph/dos-names/src/userRegistry.ts +++ b/subgraph/dos-names/src/userRegistry.ts @@ -305,7 +305,8 @@ export function handleUserRegistrySubregistryUpdated(event: SubregistryUpdatedEv node, event.params.subregistry, event, - [event.address.toHexString()] + [event.address.toHexString()], + 0 ); } @@ -336,7 +337,8 @@ export function handleUserRegistryLabelUnregistered(event: LabelUnregisteredEven mapping.domain, Address.fromString(EMPTY_ADDRESS), event, - [event.address.toHexString()] + [event.address.toHexString()], + 0 ); let zeroAccount = createOrLoadAccount(EMPTY_ADDRESS); domain.owner = zeroAccount.id; diff --git a/subgraph/dos-names/tests/registry.test.ts b/subgraph/dos-names/tests/registry.test.ts index a673161ff..2726fb2ca 100644 --- a/subgraph/dos-names/tests/registry.test.ts +++ b/subgraph/dos-names/tests/registry.test.ts @@ -722,7 +722,8 @@ test("detached registry sources retain current state for a later attachment", () BOB_DOS, Address.fromString(USER_REGISTRY), subregistryUpdated(123), - [] + [], + 0 ); assert.fieldEquals("Domain", SUB_ALICE_DOS, "owner", ZERO_ADDRESS); @@ -748,7 +749,8 @@ test("attaching a shared registry backfills existing children for the new parent BOB_DOS, Address.fromString(USER_REGISTRY), subregistryUpdated(123), - [] + [], + 0 ); assert.entityCount("TokenToDomain", 3); @@ -778,7 +780,8 @@ test("backfilling multiple children preserves each ownership event", () => { BOB_DOS, Address.fromString(USER_REGISTRY), subregistryUpdated(123), - [] + [], + 0 ); assert.fieldEquals("Domain", SUB_BOB_DOS, "owner", OWNER); @@ -828,7 +831,8 @@ test("shared registry events retain one history row per parent context", () => { BOB_DOS, Address.fromString(USER_REGISTRY), subregistryUpdated(123), - [] + [], + 0 ); handleUserRegistryTransferSingle(userRegistryTransfer(456)); From 68dffffc7d6596ea07c7feafcf95e1f460f07f6d Mon Sep 17 00:00:00 2001 From: JOY <5027251+JOY@users.noreply.github.com> Date: Wed, 12 Aug 2026 18:46:28 +0700 Subject: [PATCH 08/14] fix: make registry traversal unbounded and linear --- subgraph/dos-names/src/registry.ts | 4 +- subgraph/dos-names/src/subregistry.ts | 258 ++++++++++++---------- subgraph/dos-names/src/userRegistry.ts | 15 +- subgraph/dos-names/tests/registry.test.ts | 12 +- 4 files changed, 153 insertions(+), 136 deletions(-) diff --git a/subgraph/dos-names/src/registry.ts b/subgraph/dos-names/src/registry.ts index d19d22a50..df8d1ecd3 100644 --- a/subgraph/dos-names/src/registry.ts +++ b/subgraph/dos-names/src/registry.ts @@ -380,7 +380,7 @@ export function handleLabelUnregistered(event: LabelUnregisteredEvent): void { return; } - updateSubregistry(mapping.domain, Address.fromString(EMPTY_ADDRESS), event, [], 0); + updateSubregistry(mapping.domain, Address.fromString(EMPTY_ADDRESS), event, []); let zeroAccount = createOrLoadAccount(EMPTY_ADDRESS); domain.owner = zeroAccount.id; domain.registrant = zeroAccount.id; @@ -413,5 +413,5 @@ export function handleSubregistryUpdated(event: SubregistryUpdatedEvent): void { if (node === null || Domain.load(node) === null) { return; } - updateSubregistry(node, event.params.subregistry, event, [], 0); + updateSubregistry(node, event.params.subregistry, event, []); } diff --git a/subgraph/dos-names/src/subregistry.ts b/subgraph/dos-names/src/subregistry.ts index 7b621fc9a..2a41a8008 100644 --- a/subgraph/dos-names/src/subregistry.ts +++ b/subgraph/dos-names/src/subregistry.ts @@ -32,8 +32,6 @@ import { tokenIdToHex, } from "./utils"; -const MAX_REGISTRY_DEPTH = 32; - function childTokenId(registry: Address, tokenId: BigInt): string { return registry.toHexString().concat("-").concat(tokenIdToHex(tokenId)); } @@ -275,55 +273,65 @@ function retireDomain(node: string, timestamp: BigInt): void { } } -function retireRegistryPath( - parentNode: string, - registry: Address, - event: ethereum.Event, - ancestors: string[], - depth: i32 -): void { - assert( - depth < MAX_REGISTRY_DEPTH, - "ENSv2 registry nesting exceeds the supported depth" - ); - let registryAddress = registry.toHexString(); - if (ancestors.includes(registryAddress)) { - return; +function nextChildId(childId: string): string | null { + let child = RegistryChild.load(childId); + assert(child !== null, "ENSv2 registry child list is corrupt"); + return (child as RegistryChild).nextChild; +} + +function assertAcyclicChildList(firstChild: string | null): void { + let slow = firstChild; + let fast = firstChild; + while (fast !== null) { + fast = nextChildId(fast as string); + if (fast === null) { + return; + } + fast = nextChildId(fast as string); + slow = nextChildId(slow as string); + assert(slow != fast, "ENSv2 registry child list contains a cycle"); } - let nextAncestors = ancestors.concat([registryAddress]); - let source = RegistrySource.load(registryAddress); - let childId: string | null = source === null ? null : source.firstChild; - let visitedChildren: string[] = []; - while (childId !== null) { - let currentId = childId as string; - assert( - !visitedChildren.includes(currentId), - "ENSv2 registry child list contains a cycle" - ); - visitedChildren.push(currentId); - let child = RegistryChild.load(currentId); - if (child === null) { +} + +function retireRegistryTree( + rootParent: string, + rootRegistry: Address, + event: ethereum.Event +): void { + let parents = [rootParent]; + let registries = [rootRegistry.toHexString()]; + while (parents.length > 0) { + let parentNode = parents.pop(); + let registryAddress = registries.pop(); + if (parentNode === null || registryAddress === null) { break; } - let node = childNode(parentNode, child); - let nestedPath = RegistryPath.load(node); - if (nestedPath !== null && nestedPath.active) { - retireRegistryPath( - node, - Address.fromBytes(nestedPath.registry), - event, - nextAncestors, - depth + 1 + let source = RegistrySource.load(registryAddress as string); + let childId: string | null = source === null ? null : source.firstChild; + assertAcyclicChildList(childId); + while (childId !== null) { + let child = RegistryChild.load(childId as string); + assert(child !== null, "ENSv2 registry child list is corrupt"); + let currentChild = child as RegistryChild; + let node = childNode(parentNode as string, currentChild); + let nestedPath = RegistryPath.load(node); + if (nestedPath !== null && nestedPath.active) { + parents.push(node); + registries.push(nestedPath.registry.toHexString()); + nestedPath.active = false; + nestedPath.save(); + } + retireDomain(node, event.block.timestamp); + store.remove( + "TokenToDomain", + scopedTokenId( + Address.fromString(registryAddress as string), + parentNode as string, + currentChild.tokenId + ) ); - nestedPath.active = false; - nestedPath.save(); + childId = currentChild.nextChild; } - retireDomain(node, event.block.timestamp); - store.remove( - "TokenToDomain", - scopedTokenId(registry, parentNode, child.tokenId) - ); - childId = child.nextChild; } } @@ -354,26 +362,14 @@ export function updateSubregistry( parentNode: string, registry: Address, event: ethereum.Event, - ancestors: string[], - depth: i32 + ancestors: string[] ): void { - assert( - depth < MAX_REGISTRY_DEPTH, - "ENSv2 registry nesting exceeds the supported depth" - ); - let path = RegistryPath.load(parentNode); let registryAddress = registry.toHexString(); - if (registryAddress == EMPTY_ADDRESS) { + let path = RegistryPath.load(parentNode); if (path !== null) { if (path.active) { - retireRegistryPath( - parentNode, - Address.fromBytes(path.registry), - event, - ancestors, - depth - ); + retireRegistryTree(parentNode, Address.fromBytes(path.registry), event); } path.active = false; path.save(); @@ -381,72 +377,90 @@ export function updateSubregistry( return; } - if (ancestors.includes(registryAddress)) { - return; - } - if ( - path !== null && - path.active && - path.registry.toHexString() != registryAddress - ) { - retireRegistryPath( - parentNode, - Address.fromBytes(path.registry), - event, - ancestors, - depth - ); - path.active = false; - path.save(); - } - - let requiresSource = - path === null || path.registry.toHexString() != registryAddress; - if (path === null) { - path = new RegistryPath(parentNode); - path.parentDomain = parentNode; - } - path.registry = registry; - path.active = true; - path.save(); - - if (requiresSource) { - let context = new DataSourceContext(); - context.setBytes("parentNode", Bytes.fromHexString(parentNode)); - UserRegistryTemplate.createWithContext(registry, context); - } - - let source = RegistrySource.load(registryAddress); - let childId: string | null = null; - if (source !== null) { - childId = source.firstChild; - } - let visitedChildren: string[] = []; - let nextAncestors = ancestors.concat([registryAddress]); - while (childId !== null) { - let currentId = childId as string; - assert( - !visitedChildren.includes(currentId), - "ENSv2 registry child list contains a cycle" - ); - visitedChildren.push(currentId); - let child = RegistryChild.load(currentId); - if (child === null) { + let parents = [parentNode]; + let registries = [registryAddress]; + let ancestryPaths = [ancestors.join(",")]; + while (parents.length > 0) { + let currentParent = parents.pop(); + let currentRegistry = registries.pop(); + let ancestryPath = ancestryPaths.pop(); + if ( + currentParent === null || + currentRegistry === null || + ancestryPath === null + ) { break; } - let node = materializeRegistryChild(parentNode, registry, child, event); + let currentAncestors = + (ancestryPath as string).length == 0 + ? new Array() + : (ancestryPath as string).split(","); + if (currentAncestors.includes(currentRegistry as string)) { + continue; + } + + let path = RegistryPath.load(currentParent as string); if ( - node !== null && - child.subregistry.toHexString() != EMPTY_ADDRESS + path !== null && + path.active && + path.registry.toHexString() != (currentRegistry as string) ) { - updateSubregistry( - node as string, - Address.fromBytes(child.subregistry), - event, - nextAncestors, - depth + 1 + retireRegistryTree( + currentParent as string, + Address.fromBytes(path.registry), + event ); + path.active = false; + path.save(); + } + + let requiresSource = + path === null || + path.registry.toHexString() != (currentRegistry as string); + if (path === null) { + path = new RegistryPath(currentParent as string); + path.parentDomain = currentParent as string; + } + path.registry = Address.fromString(currentRegistry as string); + path.active = true; + path.save(); + + let nextAncestors = currentAncestors.concat([currentRegistry as string]); + if (requiresSource) { + let context = new DataSourceContext(); + context.setBytes( + "parentNode", + Bytes.fromHexString(currentParent as string) + ); + context.setString("registryAncestors", nextAncestors.join(",")); + UserRegistryTemplate.createWithContext( + Address.fromString(currentRegistry as string), + context + ); + } + + let source = RegistrySource.load(currentRegistry as string); + let childId: string | null = source === null ? null : source.firstChild; + assertAcyclicChildList(childId); + while (childId !== null) { + let child = RegistryChild.load(childId as string); + assert(child !== null, "ENSv2 registry child list is corrupt"); + let currentChild = child as RegistryChild; + let node = materializeRegistryChild( + currentParent as string, + Address.fromString(currentRegistry as string), + currentChild, + event + ); + if ( + node !== null && + currentChild.subregistry.toHexString() != EMPTY_ADDRESS + ) { + parents.push(node as string); + registries.push(currentChild.subregistry.toHexString()); + ancestryPaths.push(nextAncestors.join(",")); + } + childId = currentChild.nextChild; } - childId = child.nextChild; } } diff --git a/subgraph/dos-names/src/userRegistry.ts b/subgraph/dos-names/src/userRegistry.ts index 5b823f81d..2f8646204 100644 --- a/subgraph/dos-names/src/userRegistry.ts +++ b/subgraph/dos-names/src/userRegistry.ts @@ -62,6 +62,15 @@ function contextEventID(event: ethereum.Event): string { .concat(dataSource.context().getBytes("parentNode").toHexString()); } +function contextRegistryAncestors(registry: Address): string[] { + let context = dataSource.context(); + if (!context.isSet("registryAncestors")) { + return [registry.toHexString()]; + } + let encoded = context.getString("registryAncestors"); + return encoded.length == 0 ? new Array() : encoded.split(","); +} + export function handleUserRegistryLabelRegistered(event: LabelRegisteredEvent): void { let label = event.params.label; if (!checkValidLabel(label)) { @@ -305,8 +314,7 @@ export function handleUserRegistrySubregistryUpdated(event: SubregistryUpdatedEv node, event.params.subregistry, event, - [event.address.toHexString()], - 0 + contextRegistryAncestors(event.address) ); } @@ -337,8 +345,7 @@ export function handleUserRegistryLabelUnregistered(event: LabelUnregisteredEven mapping.domain, Address.fromString(EMPTY_ADDRESS), event, - [event.address.toHexString()], - 0 + contextRegistryAncestors(event.address) ); let zeroAccount = createOrLoadAccount(EMPTY_ADDRESS); domain.owner = zeroAccount.id; diff --git a/subgraph/dos-names/tests/registry.test.ts b/subgraph/dos-names/tests/registry.test.ts index 2726fb2ca..a673161ff 100644 --- a/subgraph/dos-names/tests/registry.test.ts +++ b/subgraph/dos-names/tests/registry.test.ts @@ -722,8 +722,7 @@ test("detached registry sources retain current state for a later attachment", () BOB_DOS, Address.fromString(USER_REGISTRY), subregistryUpdated(123), - [], - 0 + [] ); assert.fieldEquals("Domain", SUB_ALICE_DOS, "owner", ZERO_ADDRESS); @@ -749,8 +748,7 @@ test("attaching a shared registry backfills existing children for the new parent BOB_DOS, Address.fromString(USER_REGISTRY), subregistryUpdated(123), - [], - 0 + [] ); assert.entityCount("TokenToDomain", 3); @@ -780,8 +778,7 @@ test("backfilling multiple children preserves each ownership event", () => { BOB_DOS, Address.fromString(USER_REGISTRY), subregistryUpdated(123), - [], - 0 + [] ); assert.fieldEquals("Domain", SUB_BOB_DOS, "owner", OWNER); @@ -831,8 +828,7 @@ test("shared registry events retain one history row per parent context", () => { BOB_DOS, Address.fromString(USER_REGISTRY), subregistryUpdated(123), - [], - 0 + [] ); handleUserRegistryTransferSingle(userRegistryTransfer(456)); From 1aef987e6fd8bee89b5abb77a33cd6a1702a5d6a Mon Sep 17 00:00:00 2001 From: JOY <5027251+JOY@users.noreply.github.com> Date: Wed, 12 Aug 2026 18:52:08 +0700 Subject: [PATCH 09/14] fix: refresh active registry ancestry --- subgraph/dos-names/schema.graphql | 2 ++ subgraph/dos-names/src/subregistry.ts | 18 +++++++++- subgraph/dos-names/src/userRegistry.ts | 23 +++++------- subgraph/dos-names/tests/registry.test.ts | 44 ++++++++++++++++++++++- 4 files changed, 71 insertions(+), 16 deletions(-) diff --git a/subgraph/dos-names/schema.graphql b/subgraph/dos-names/schema.graphql index 65351d40c..6905cfb02 100644 --- a/subgraph/dos-names/schema.graphql +++ b/subgraph/dos-names/schema.graphql @@ -315,6 +315,8 @@ type RegistryPath @entity { id: ID! registry: Bytes! parentDomain: Domain! + "Current registry ancestry for cycle detection after detach and reattachment" + registryAncestors: String! active: Boolean! } diff --git a/subgraph/dos-names/src/subregistry.ts b/subgraph/dos-names/src/subregistry.ts index 2a41a8008..8b76f9aa8 100644 --- a/subgraph/dos-names/src/subregistry.ts +++ b/subgraph/dos-names/src/subregistry.ts @@ -59,6 +59,21 @@ export function isActiveUserRegistry(registry: Address): boolean { ); } +export function activeRegistryAncestors(registry: Address): string[] | null { + let parentNode = dataSource.context().getBytes("parentNode").toHexString(); + let path = RegistryPath.load(parentNode); + if ( + path === null || + !path.active || + path.registry.toHexString() != registry.toHexString() + ) { + return null; + } + return path.registryAncestors.length == 0 + ? new Array() + : path.registryAncestors.split(","); +} + export function loadRegistryChild( registry: Address, tokenId: BigInt @@ -421,11 +436,12 @@ export function updateSubregistry( path = new RegistryPath(currentParent as string); path.parentDomain = currentParent as string; } + let nextAncestors = currentAncestors.concat([currentRegistry as string]); path.registry = Address.fromString(currentRegistry as string); + path.registryAncestors = nextAncestors.join(","); path.active = true; path.save(); - let nextAncestors = currentAncestors.concat([currentRegistry as string]); if (requiresSource) { let context = new DataSourceContext(); context.setBytes( diff --git a/subgraph/dos-names/src/userRegistry.ts b/subgraph/dos-names/src/userRegistry.ts index 2f8646204..ca20c5c9b 100644 --- a/subgraph/dos-names/src/userRegistry.ts +++ b/subgraph/dos-names/src/userRegistry.ts @@ -26,6 +26,7 @@ import { WrappedTransfer, } from "./types/schema"; import { + activeRegistryAncestors, attachResolver, isActiveUserRegistry, loadRegistryChild, @@ -62,15 +63,6 @@ function contextEventID(event: ethereum.Event): string { .concat(dataSource.context().getBytes("parentNode").toHexString()); } -function contextRegistryAncestors(registry: Address): string[] { - let context = dataSource.context(); - if (!context.isSet("registryAncestors")) { - return [registry.toHexString()]; - } - let encoded = context.getString("registryAncestors"); - return encoded.length == 0 ? new Array() : encoded.split(","); -} - export function handleUserRegistryLabelRegistered(event: LabelRegisteredEvent): void { let label = event.params.label; if (!checkValidLabel(label)) { @@ -85,7 +77,8 @@ export function handleUserRegistryLabelRegistered(event: LabelRegisteredEvent): event.params.expiry, event.block.timestamp ); - if (!isActiveUserRegistry(event.address)) { + let registryAncestors = activeRegistryAncestors(event.address); + if (registryAncestors === null) { return; } materializeRegistryChild( @@ -301,7 +294,8 @@ export function handleUserRegistrySubregistryUpdated(event: SubregistryUpdatedEv child.subregistry = event.params.subregistry; child.save(); } - if (!isActiveUserRegistry(event.address)) { + let registryAncestors = activeRegistryAncestors(event.address); + if (registryAncestors === null) { return; } @@ -314,7 +308,7 @@ export function handleUserRegistrySubregistryUpdated(event: SubregistryUpdatedEv node, event.params.subregistry, event, - contextRegistryAncestors(event.address) + registryAncestors as string[] ); } @@ -326,7 +320,8 @@ export function handleUserRegistryLabelUnregistered(event: LabelUnregisteredEven child.owner = Address.fromString(EMPTY_ADDRESS); child.save(); } - if (!isActiveUserRegistry(event.address)) { + let registryAncestors = activeRegistryAncestors(event.address); + if (registryAncestors === null) { return; } let tokenKey = registryTokenId(event, tokenIdToHex(event.params.tokenId)); @@ -345,7 +340,7 @@ export function handleUserRegistryLabelUnregistered(event: LabelUnregisteredEven mapping.domain, Address.fromString(EMPTY_ADDRESS), event, - contextRegistryAncestors(event.address) + registryAncestors as string[] ); let zeroAccount = createOrLoadAccount(EMPTY_ADDRESS); domain.owner = zeroAccount.id; diff --git a/subgraph/dos-names/tests/registry.test.ts b/subgraph/dos-names/tests/registry.test.ts index a673161ff..d283a3493 100644 --- a/subgraph/dos-names/tests/registry.test.ts +++ b/subgraph/dos-names/tests/registry.test.ts @@ -33,7 +33,10 @@ import { handleUserRegistryTransferBatch, handleUserRegistryTransferSingle, } from "../src/userRegistry"; -import { updateSubregistry } from "../src/subregistry"; +import { + activeRegistryAncestors, + updateSubregistry, +} from "../src/subregistry"; import { LabelRegistered, LabelUnregistered, @@ -59,6 +62,7 @@ const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"; const USER_REGISTRY = "0x1111111111111111111111111111111111111111"; const RESOLVER = "0x2222222222222222222222222222222222222222"; const NESTED_REGISTRY = "0x3333333333333333333333333333333333333333"; +const REPLACEMENT_REGISTRY = "0x4444444444444444444444444444444444444444"; const LABEL_HASH = "0x9c0257114eb9399a2985f8e75dad7600c5d89fe3824ffa99ec1c3eb8bf3b0501"; const ALICE_DOS = @@ -809,6 +813,44 @@ test("replacing a subregistry retires names from the old registry", () => { assert.fieldEquals("RegistryPath", ALICE_DOS, "registry", NESTED_REGISTRY); }); +test("reattaching a nested registry refreshes its active ancestry", () => { + handleLabelRegistered(registration(123)); + activateUserRegistry(); + handleUserRegistryLabelRegistered(userRegistryRegistration(456)); + handleUserRegistrySubregistryUpdated(userRegistrySubregistryUpdated(456)); + + handleSubregistryUpdated(subregistryUpdated(123, REPLACEMENT_REGISTRY)); + updateSubregistry( + SUB_ALICE_DOS, + Address.fromString(NESTED_REGISTRY), + subregistryUpdated(123), + [REPLACEMENT_REGISTRY] + ); + + let staleContext = new DataSourceContext(); + staleContext.setBytes("parentNode", Bytes.fromHexString(SUB_ALICE_DOS)); + staleContext.setString( + "registryAncestors", + USER_REGISTRY.concat(",").concat(NESTED_REGISTRY) + ); + dataSourceMock.setContext(staleContext); + let currentAncestors = activeRegistryAncestors( + Address.fromString(NESTED_REGISTRY) + ); + + assert.assertNotNull(currentAncestors); + assert.stringEquals( + (currentAncestors as string[]).join(","), + REPLACEMENT_REGISTRY.concat(",").concat(NESTED_REGISTRY) + ); + assert.fieldEquals( + "RegistryPath", + SUB_ALICE_DOS, + "registryAncestors", + REPLACEMENT_REGISTRY.concat(",").concat(NESTED_REGISTRY) + ); +}); + test("shared registry events retain one history row per parent context", () => { handleLabelRegistered(registration(123)); activateUserRegistry(); From a48f2798d0e8cbb620251febc2fa4e41c6ee750e Mon Sep 17 00:00:00 2001 From: JOY <5027251+JOY@users.noreply.github.com> Date: Wed, 12 Aug 2026 22:06:15 +0700 Subject: [PATCH 10/14] chore: record DOS Testnet ENSv2 deployment --- contracts/deployments/dos-testnet-3939.json | 32 +++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 contracts/deployments/dos-testnet-3939.json diff --git a/contracts/deployments/dos-testnet-3939.json b/contracts/deployments/dos-testnet-3939.json new file mode 100644 index 000000000..ddfd85509 --- /dev/null +++ b/contracts/deployments/dos-testnet-3939.json @@ -0,0 +1,32 @@ +{ + "environment": "dos-testnet", + "chainId": 3939, + "deploymentBlock": 78, + "finalDeploymentBlock": 118, + "deployedAt": "2026-08-12T14:57:00Z", + "deployer": "0x99999e454138f6be73E2bE82c890bc5765749999", + "owner": "0x310Bc061214ee89aF5CfB28a6ebF96c5436fa3CD", + "beneficiary": "0x310Bc061214ee89aF5CfB28a6ebF96c5436fa3CD", + "transactions": { + "first": "0x0e5179cef7c84e733ec4f71cbd9cf8a4dcca336e1e501997b3eecc7e116eed68", + "last": "0xe65eb54b3dc69b7e664c65c907c4cf9b6f049d64b27686e0d851aed03f9c648e", + "count": 41 + }, + "contracts": { + "wrappedDOS": "0xc647CCF449DEc38Bb8B7272e60fc14B3548c9547", + "contractNamerImplementation": "0x069056B2Ae8fD8c071efb827c5AF73A0996840E1", + "contractNamer": "0x030eec847cf5D9d1c4A0b4e0459d130D0B35577C", + "verifiableFactory": "0xB86bb608E6Afd7a8Eb209510c01BB859A7c315f1", + "labelStore": "0x38FC582690c3F28099087A88520056afAb08ce5F", + "rootRegistry": "0xb17Fec6fe18aC0b7F3dd934495E84eC06Cf88564", + "dosRegistry": "0x8A2730c903d93b2116Fab3d9110C7D585F7B5a91", + "reverseRegistry": "0x641Ee4711013EE40B34fAE860894227c4771F273", + "priceOracle": "0x1F31e05948769174dA256D0484b8f26cfD3d8c97", + "dosRegistrar": "0x27A3B7ff0EF7fB96D49eB50B069570F407387362", + "permissionedResolverImplementation": "0xfa579733d7C5A21B5D3C4399D3d6Ef89fc3A3720", + "userRegistryImplementation": "0x8291F1C6aEf2acBC58F3fe11C9e4EC0d3D4aE904", + "gatewayProvider": "0xCB20A0C349f079b8bD403ea8F668FE3DA49E981f", + "universalResolver": "0x5A34c9fB9806239Ed61f1570c51edb198333fbeA", + "reverseRegistrar": "0x3Cd8BdDeB177492c5e521c3B82179887f472f018" + } +} From ffcea6f2bb8a95e43dc0caec54e7c63e879ddec7 Mon Sep 17 00:00:00 2001 From: JOY <5027251+JOY@users.noreply.github.com> Date: Wed, 12 Aug 2026 22:33:05 +0700 Subject: [PATCH 11/14] fix: harden Testnet ENSv2 deployment --- .github/workflows/main.yml | 5 +- .../script/foundry/DeployDOSTestnet.s.sol | 64 ++++++++-- .../foundry/Invoke-DeployDOSTestnet.ps1 | 119 ++++++++++++++++++ contracts/test/unit/testnet/WrappedDOS.t.sol | 75 +++++++++-- subgraph/dos-names/package.json | 1 + subgraph/dos-names/src/subregistry.ts | 10 ++ subgraph/dos-names/tests/registry.test.ts | 13 ++ 7 files changed, 269 insertions(+), 18 deletions(-) create mode 100644 contracts/script/foundry/Invoke-DeployDOSTestnet.ps1 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index be765078e..99786e93f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -144,7 +144,10 @@ jobs: - name: Test mappings run: npm test - - name: Build subgraph + - name: Render canonical deployment manifest + run: npm run render:deployment + + - name: Build canonical deployment subgraph run: npm run build publish-docker: diff --git a/contracts/script/foundry/DeployDOSTestnet.s.sol b/contracts/script/foundry/DeployDOSTestnet.s.sol index cf1c2c841..6ff9d7e4f 100644 --- a/contracts/script/foundry/DeployDOSTestnet.s.sol +++ b/contracts/script/foundry/DeployDOSTestnet.s.sol @@ -2,9 +2,11 @@ pragma solidity >=0.8.20; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {NameCoder} from "@ens/contracts/utils/NameCoder.sol"; import {DeployDOS} from "./DeployDOS.s.sol"; +import {EACBaseRolesLib} from "~src/access-control/libraries/EACBaseRolesLib.sol"; import { DEFAULT_ROLE_BITMAP, StandardRentPriceOracle @@ -20,8 +22,20 @@ import {LibLabel} from "~src/utils/LibLabel.sol"; /// @title Deploy DOS Name Service on testnet /// @notice Deploys a standard wrapped-native WDOS token and the complete `.dos` ENSv2 stack. contract DeployDOSTestnet is DeployDOS { + uint256 internal constant EXPECTED_CHAIN_ID = 3939; + address internal constant EXPECTED_DEPLOYER = 0x99999e454138f6be73E2bE82c890bc5765749999; + address internal constant EXPECTED_OWNER = 0x310Bc061214ee89aF5CfB28a6ebF96c5436fa3CD; + uint256 internal constant MIN_DEPLOYMENT_BALANCE = 1 ether; string internal constant BENS_SMOKE_LABEL = "bens-smoke"; + string internal constant BENS_SMOKE_NAME = "bens-smoke.dos"; uint64 internal constant BENS_SMOKE_LIFETIME = 10 * 365 days; + + error UnexpectedChain(uint256 actual, uint256 expected); + error UnexpectedDeployer(address actual, address expected); + error UnexpectedOwner(address actual, address expected); + error UnexpectedBeneficiary(address actual, address expected); + error InsufficientDeploymentBalance(uint256 actual, uint256 required); + /// @notice Contracts produced by the DOS testnet deployment profile. struct TestnetDeployment { WrappedDOS wdos; @@ -36,6 +50,7 @@ contract DeployDOSTestnet is DeployDOS { address beneficiary = vm.envOr("BENEFICIARY", owner); address broadcaster = vm.addr(privateKey); + preflight(broadcaster, owner, beneficiary); vm.startBroadcast(privateKey); TestnetDeployment memory testnetDeployment = deployTestnet(broadcaster, owner, beneficiary, block.chainid); @@ -44,6 +59,25 @@ contract DeployDOSTestnet is DeployDOS { deployment = testnetDeployment.names; } + /// @notice Fails before broadcasting if the Testnet deployment configuration is not canonical. + function preflight(address broadcaster, address owner, address beneficiary) public view { + if (block.chainid != EXPECTED_CHAIN_ID) { + revert UnexpectedChain(block.chainid, EXPECTED_CHAIN_ID); + } + if (broadcaster != EXPECTED_DEPLOYER) { + revert UnexpectedDeployer(broadcaster, EXPECTED_DEPLOYER); + } + if (owner != EXPECTED_OWNER) { + revert UnexpectedOwner(owner, EXPECTED_OWNER); + } + if (beneficiary != EXPECTED_OWNER) { + revert UnexpectedBeneficiary(beneficiary, EXPECTED_OWNER); + } + if (broadcaster.balance < MIN_DEPLOYMENT_BALANCE) { + revert InsufficientDeploymentBalance(broadcaster.balance, MIN_DEPLOYMENT_BALANCE); + } + } + /// @notice Deploys WDOS and wires it into a DOS Name Service deployment. /// @param initialOwner Account broadcasting deployment and temporary wiring calls. /// @param owner Final protocol administrator. @@ -58,28 +92,42 @@ contract DeployDOSTestnet is DeployDOS { IERC20(address(deployment.wdos)), chainId ); - _registerBensSmokeName(deployment.names.dosRegistry, initialOwner, owner); + _registerBensSmokeName(deployment.names, initialOwner, owner, chainId); _handoff(deployment.names, initialOwner, owner); } - /// @dev Creates one stable Testnet record used by Graph Node and BENS acceptance gates. - function _registerBensSmokeName( - PermissionedRegistry registry, - address initialOwner, - address owner - ) + /// @dev Creates one stable forward and reverse record used by Graph Node and BENS acceptance gates. + function _registerBensSmokeName(Deployment memory deployment, address initialOwner, address owner, uint256 chainId) internal { + bytes[] memory setters = new bytes[](0); + PermissionedResolver resolver = PermissionedResolver( + deployment.verifiableFactory + .deployProxy( + address(deployment.permissionedResolverImplementation), + 1, + abi.encodeCall(PermissionedResolver.initialize, (initialOwner, EACBaseRolesLib.ALL_ROLES, setters)) + ) + ); + bytes32 node = NameCoder.namehash(NameCoder.encode(BENS_SMOKE_NAME), 0); + resolver.setAddr(node, initialOwner); + resolver.setAddr(node, (1 << 31) | chainId, abi.encodePacked(initialOwner)); + + PermissionedRegistry registry = deployment.dosRegistry; registry.grantRootRoles(RegistryRolesLib.ROLE_REGISTRAR, initialOwner); registry.register( BENS_SMOKE_LABEL, owner, IRegistry(address(0)), - address(0), + address(resolver), 0, uint64(block.timestamp + BENS_SMOKE_LIFETIME) ); registry.revokeRootRoles(RegistryRolesLib.ROLE_REGISTRAR, initialOwner); + + deployment.reverseRegistrar.setName(BENS_SMOKE_NAME); + resolver.grantRootRoles(EACBaseRolesLib.ALL_ROLES, owner); + resolver.revokeRootRoles(EACBaseRolesLib.ALL_ROLES, initialOwner); } function _handoff(Deployment memory deployment, address initialOwner, address owner) internal { diff --git a/contracts/script/foundry/Invoke-DeployDOSTestnet.ps1 b/contracts/script/foundry/Invoke-DeployDOSTestnet.ps1 new file mode 100644 index 000000000..0b4637fe0 --- /dev/null +++ b/contracts/script/foundry/Invoke-DeployDOSTestnet.ps1 @@ -0,0 +1,119 @@ +[CmdletBinding()] +param( + [string]$RpcUrl = "https://test.doschain.com", + [switch]$Broadcast +) + +Set-StrictMode -Version Latest +$ErrorActionPreference = "Stop" + +$expectedRpcUrl = "https://test.doschain.com" +$expectedChainId = 3939 +$expectedGenesisHash = "0x36f98b2e8b3084d57efc46622a065c2a96ed51aca86ac229bce998be6b8abd2c" +$expectedDeployer = "0x99999e454138f6be73e2be82c890bc5765749999" +$expectedOwner = "0x310bc061214ee89af5cfb28a6ebf96c5436fa3cd" +$minimumBalanceWei = [System.Numerics.BigInteger]::Parse("1000000000000000000") + +function Resolve-FoundryCommand { + param([Parameter(Mandatory)][string]$Name) + + $command = Get-Command $Name -ErrorAction SilentlyContinue + if ($null -ne $command) { + return $command.Source + } + + $bundled = Join-Path $env:USERPROFILE ".foundry\bin\$Name.exe" + if (Test-Path -LiteralPath $bundled) { + return $bundled + } + + throw "$Name was not found in PATH or the Foundry installation directory" +} + +if ($RpcUrl.TrimEnd("/") -ne $expectedRpcUrl) { + throw "RPC URL must be $expectedRpcUrl" +} +if ([string]::IsNullOrWhiteSpace($env:PRIVATE_KEY)) { + throw "PRIVATE_KEY is required" +} +if ([string]::IsNullOrWhiteSpace($env:OWNER)) { + throw "OWNER is required" +} + +$privateKey = $env:PRIVATE_KEY.Trim() +if ($privateKey -match "^[0-9a-fA-F]{64}$") { + $privateKey = "0x$privateKey" +} +if ($privateKey -notmatch "^0x[0-9a-fA-F]{64}$") { + throw "PRIVATE_KEY must be a 32-byte hexadecimal value" +} +$env:PRIVATE_KEY = $privateKey + +$owner = $env:OWNER.Trim().ToLowerInvariant() +$beneficiary = if ([string]::IsNullOrWhiteSpace($env:BENEFICIARY)) { + $env:OWNER +} else { + $env:BENEFICIARY +} +$beneficiary = $beneficiary.Trim().ToLowerInvariant() +if ($owner -ne $expectedOwner) { + throw "OWNER does not match the canonical DOS Names owner" +} +if ($beneficiary -ne $expectedOwner) { + throw "BENEFICIARY does not match the canonical DOS Names beneficiary" +} +$env:BENEFICIARY = $beneficiary + +$cast = Resolve-FoundryCommand -Name "cast" +$forge = Resolve-FoundryCommand -Name "forge" +$deployer = (& $cast wallet address --private-key $privateKey).Trim().ToLowerInvariant() +if ($LASTEXITCODE -ne 0 -or $deployer -ne $expectedDeployer) { + throw "PRIVATE_KEY does not control the canonical DOS Testnet deployer" +} + +$chainId = [int]((& $cast chain-id --rpc-url $RpcUrl).Trim()) +if ($LASTEXITCODE -ne 0 -or $chainId -ne $expectedChainId) { + throw "RPC chain ID does not match DOS Testnet" +} + +$genesis = (& $cast block 0 --rpc-url $RpcUrl --json | ConvertFrom-Json).hash.ToLowerInvariant() +if ($LASTEXITCODE -ne 0 -or $genesis -ne $expectedGenesisHash) { + throw "RPC genesis hash does not match DOS Testnet" +} + +$balanceOutput = & $cast balance $deployer --rpc-url $RpcUrl +if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($balanceOutput)) { + throw "Unable to read the canonical deployer balance" +} +$balance = [System.Numerics.BigInteger]::Parse($balanceOutput.Trim()) +if ($balance -lt $minimumBalanceWei) { + throw "Canonical deployer balance is below the 1 DOS deployment floor" +} + +$contractsRoot = Resolve-Path (Join-Path $PSScriptRoot "..\..") +Push-Location $contractsRoot +try { + & $forge script "script/foundry/DeployDOSTestnet.s.sol:DeployDOSTestnet" ` + --rpc-url $RpcUrl ` + --slow + if ($LASTEXITCODE -ne 0) { + throw "Foundry simulation failed" + } + + if (-not $Broadcast) { + Write-Output "DOS_TESTNET_ENSV2_SIMULATION_OK" + return + } + + & $forge script "script/foundry/DeployDOSTestnet.s.sol:DeployDOSTestnet" ` + --rpc-url $RpcUrl ` + --broadcast ` + --slow + if ($LASTEXITCODE -ne 0) { + throw "Foundry broadcast failed" + } + Write-Output "DOS_TESTNET_ENSV2_BROADCAST_OK" +} +finally { + Pop-Location +} diff --git a/contracts/test/unit/testnet/WrappedDOS.t.sol b/contracts/test/unit/testnet/WrappedDOS.t.sol index 420bd30c8..835465734 100644 --- a/contracts/test/unit/testnet/WrappedDOS.t.sol +++ b/contracts/test/unit/testnet/WrappedDOS.t.sol @@ -4,16 +4,19 @@ pragma solidity ^0.8.20; import {Test} from "forge-std/Test.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {NameCoder} from "@ens/contracts/utils/NameCoder.sol"; -import {DeployDOS} from "../../../script/foundry/DeployDOS.s.sol"; import {DeployDOSTestnet} from "../../../script/foundry/DeployDOSTestnet.s.sol"; import {DOSRegistrar} from "~src/registrar/DOSRegistrar.sol"; import {IRegistry} from "~src/registry/interfaces/IRegistry.sol"; +import {PermissionedResolver} from "~src/resolver/PermissionedResolver.sol"; import {LibLabel} from "~src/utils/LibLabel.sol"; import {WrappedDOS} from "~src/testnet/WrappedDOS.sol"; contract WrappedDOSTest is Test { + address internal constant TESTNET_DEPLOYER = 0x99999e454138f6be73E2bE82c890bc5765749999; + address internal constant PROTOCOL_OWNER = 0x310Bc061214ee89aF5CfB28a6ebF96c5436fa3CD; WrappedDOS internal wdos; address internal holder = makeAddr("holder"); address internal recipient = makeAddr("recipient"); @@ -103,6 +106,11 @@ contract WrappedDOSTest is Test { assertTrue(deployment.names.rootRegistry.roles(dosTokenId, protocolOwner) != 0); assertTrue(deployment.names.rootRegistry.roles(reverseTokenId, protocolOwner) != 0); assertEq(deployment.names.dosRegistry.ownerOf(smokeTokenId), protocolOwner); + address smokeResolverAddress = deployment.names.dosRegistry.getResolver("bens-smoke"); + assertNotEq(smokeResolverAddress, address(0)); + bytes32 smokeNode = NameCoder.namehash(NameCoder.encode("bens-smoke.dos"), 0); + assertEq(PermissionedResolver(smokeResolverAddress).addr(smokeNode), address(deployer)); + assertEq(deployment.names.reverseRegistrar.nameForAddr(address(deployer)), "bens-smoke.dos"); assertLe( deployment.names.dosRegistry.getExpiry(smokeTokenId), 253402300799, @@ -126,20 +134,69 @@ contract WrappedDOSTest is Test { assertEq(denom, 1); } - function test_runUsesCanonicalTestnetFlow() external { + function test_runRejectsWrongSignerBeforeBroadcast() external { DeployDOSTestnet deployer = new DeployDOSTestnet(); uint256 privateKey = 0xA11CE; - address protocolOwner = makeAddr("runProtocolOwner"); - address beneficiary = makeAddr("runBeneficiary"); vm.setEnv("PRIVATE_KEY", vm.toString(privateKey)); - vm.setEnv("OWNER", vm.toString(protocolOwner)); - vm.setEnv("BENEFICIARY", vm.toString(beneficiary)); + vm.setEnv("OWNER", vm.toString(PROTOCOL_OWNER)); + vm.setEnv("BENEFICIARY", vm.toString(PROTOCOL_OWNER)); + vm.chainId(3939); - DeployDOS.Deployment memory deployment = deployer.run(); + vm.expectRevert( + abi.encodeWithSelector(DeployDOSTestnet.UnexpectedDeployer.selector, vm.addr(privateKey), TESTNET_DEPLOYER) + ); + deployer.run(); + } + + function test_preflightAcceptsCanonicalTestnetConfiguration() external { + DeployDOSTestnet deployer = new DeployDOSTestnet(); + vm.chainId(3939); + vm.deal(TESTNET_DEPLOYER, 1 ether); + + deployer.preflight(TESTNET_DEPLOYER, PROTOCOL_OWNER, PROTOCOL_OWNER); + } + + function test_preflightRejectsWrongChain() external { + DeployDOSTestnet deployer = new DeployDOSTestnet(); + vm.chainId(7979); + vm.deal(TESTNET_DEPLOYER, 1 ether); + + vm.expectRevert(abi.encodeWithSelector(DeployDOSTestnet.UnexpectedChain.selector, 7979, 3939)); + deployer.preflight(TESTNET_DEPLOYER, PROTOCOL_OWNER, PROTOCOL_OWNER); + } + + function test_preflightRejectsWrongOwner() external { + DeployDOSTestnet deployer = new DeployDOSTestnet(); + vm.chainId(3939); + vm.deal(TESTNET_DEPLOYER, 1 ether); + + address wrongOwner = makeAddr("wrongOwner"); + vm.expectRevert(abi.encodeWithSelector(DeployDOSTestnet.UnexpectedOwner.selector, wrongOwner, PROTOCOL_OWNER)); + deployer.preflight(TESTNET_DEPLOYER, wrongOwner, PROTOCOL_OWNER); + } - assertEq(deployment.dosRegistrar.owner(), protocolOwner); - assertEq(deployment.dosRegistrar.BENEFICIARY(), beneficiary); + function test_preflightRejectsWrongBeneficiary() external { + DeployDOSTestnet deployer = new DeployDOSTestnet(); + vm.chainId(3939); + vm.deal(TESTNET_DEPLOYER, 1 ether); + + address wrongBeneficiary = makeAddr("wrongBeneficiary"); + vm.expectRevert( + abi.encodeWithSelector(DeployDOSTestnet.UnexpectedBeneficiary.selector, wrongBeneficiary, PROTOCOL_OWNER) + ); + deployer.preflight(TESTNET_DEPLOYER, PROTOCOL_OWNER, wrongBeneficiary); + } + + function test_preflightRejectsInsufficientBalance() external { + DeployDOSTestnet deployer = new DeployDOSTestnet(); + vm.chainId(3939); + vm.deal(TESTNET_DEPLOYER, 1 ether - 1); + + vm.expectRevert( + abi.encodeWithSelector(DeployDOSTestnet.InsufficientDeploymentBalance.selector, 1 ether - 1, 1 ether) + ); + deployer.preflight(TESTNET_DEPLOYER, PROTOCOL_OWNER, PROTOCOL_OWNER); } function test_testnetRegistrationUsesWrappedDOSAndPaysBeneficiary() external { diff --git a/subgraph/dos-names/package.json b/subgraph/dos-names/package.json index fe01577b8..e91ea04dd 100644 --- a/subgraph/dos-names/package.json +++ b/subgraph/dos-names/package.json @@ -8,6 +8,7 @@ "build": "graph build", "render": "node scripts/render-manifest.mjs", "render:test": "node scripts/render-manifest.mjs tests/fixtures/dos-testnet-3939.json subgraph.template.yaml subgraph.yaml", + "render:deployment": "node scripts/render-manifest.mjs ../../contracts/deployments/dos-testnet-3939.json subgraph.template.yaml subgraph.yaml", "test": "graph test", "test:render": "node --test tests/render-manifest.test.mjs" }, diff --git a/subgraph/dos-names/src/subregistry.ts b/subgraph/dos-names/src/subregistry.ts index 8b76f9aa8..7b1c45cb3 100644 --- a/subgraph/dos-names/src/subregistry.ts +++ b/subgraph/dos-names/src/subregistry.ts @@ -411,6 +411,16 @@ export function updateSubregistry( ? new Array() : (ancestryPath as string).split(","); if (currentAncestors.includes(currentRegistry as string)) { + let cyclicPath = RegistryPath.load(currentParent as string); + if (cyclicPath !== null && cyclicPath.active) { + retireRegistryTree( + currentParent as string, + Address.fromBytes(cyclicPath.registry), + event + ); + cyclicPath.active = false; + cyclicPath.save(); + } continue; } diff --git a/subgraph/dos-names/tests/registry.test.ts b/subgraph/dos-names/tests/registry.test.ts index d283a3493..4ad637504 100644 --- a/subgraph/dos-names/tests/registry.test.ts +++ b/subgraph/dos-names/tests/registry.test.ts @@ -802,6 +802,19 @@ test("self-linked subregistries fail closed without creating a cyclic path", () assert.notInStore("RegistryPath", SUB_ALICE_DOS); }); +test("replacing an active nested registry with an ancestor retires the old path", () => { + handleLabelRegistered(registration(123)); + activateUserRegistry(); + handleUserRegistryLabelRegistered(userRegistryRegistration(456)); + handleUserRegistrySubregistryUpdated(userRegistrySubregistryUpdated(456)); + + handleUserRegistrySubregistryUpdated( + userRegistrySubregistryUpdated(456, USER_REGISTRY) + ); + + assert.fieldEquals("RegistryPath", SUB_ALICE_DOS, "active", "false"); +}); + test("replacing a subregistry retires names from the old registry", () => { handleLabelRegistered(registration(123)); activateUserRegistry(); From 079a9a9a605a9bade17f7d60a01e525b4aed214b Mon Sep 17 00:00:00 2001 From: JOY <5027251+JOY@users.noreply.github.com> Date: Wed, 12 Aug 2026 22:40:20 +0700 Subject: [PATCH 12/14] fix: index Testnet smoke resolver records --- .../script/foundry/DeployDOSTestnet.s.sol | 7 +++- .../foundry/Invoke-DeployDOSTestnet.ps1 | 6 +-- contracts/test/unit/testnet/WrappedDOS.t.sol | 41 +++++++++++++++++++ subgraph/dos-names/tests/registry.test.ts | 37 +++++++++++++++++ 4 files changed, 84 insertions(+), 7 deletions(-) diff --git a/contracts/script/foundry/DeployDOSTestnet.s.sol b/contracts/script/foundry/DeployDOSTestnet.s.sol index 6ff9d7e4f..e18d6924c 100644 --- a/contracts/script/foundry/DeployDOSTestnet.s.sol +++ b/contracts/script/foundry/DeployDOSTestnet.s.sol @@ -110,8 +110,6 @@ contract DeployDOSTestnet is DeployDOS { ) ); bytes32 node = NameCoder.namehash(NameCoder.encode(BENS_SMOKE_NAME), 0); - resolver.setAddr(node, initialOwner); - resolver.setAddr(node, (1 << 31) | chainId, abi.encodePacked(initialOwner)); PermissionedRegistry registry = deployment.dosRegistry; registry.grantRootRoles(RegistryRolesLib.ROLE_REGISTRAR, initialOwner); @@ -125,6 +123,11 @@ contract DeployDOSTestnet is DeployDOS { ); registry.revokeRootRoles(RegistryRolesLib.ROLE_REGISTRAR, initialOwner); + // Resolver records must be emitted after ResolverUpdated creates the + // dynamic Graph Node source. Dynamic sources cannot replay prior logs. + resolver.setAddr(node, initialOwner); + resolver.setAddr(node, (1 << 31) | chainId, abi.encodePacked(initialOwner)); + deployment.reverseRegistrar.setName(BENS_SMOKE_NAME); resolver.grantRootRoles(EACBaseRolesLib.ALL_ROLES, owner); resolver.revokeRootRoles(EACBaseRolesLib.ALL_ROLES, initialOwner); diff --git a/contracts/script/foundry/Invoke-DeployDOSTestnet.ps1 b/contracts/script/foundry/Invoke-DeployDOSTestnet.ps1 index 0b4637fe0..4237e4815 100644 --- a/contracts/script/foundry/Invoke-DeployDOSTestnet.ps1 +++ b/contracts/script/foundry/Invoke-DeployDOSTestnet.ps1 @@ -66,10 +66,6 @@ $env:BENEFICIARY = $beneficiary $cast = Resolve-FoundryCommand -Name "cast" $forge = Resolve-FoundryCommand -Name "forge" -$deployer = (& $cast wallet address --private-key $privateKey).Trim().ToLowerInvariant() -if ($LASTEXITCODE -ne 0 -or $deployer -ne $expectedDeployer) { - throw "PRIVATE_KEY does not control the canonical DOS Testnet deployer" -} $chainId = [int]((& $cast chain-id --rpc-url $RpcUrl).Trim()) if ($LASTEXITCODE -ne 0 -or $chainId -ne $expectedChainId) { @@ -81,7 +77,7 @@ if ($LASTEXITCODE -ne 0 -or $genesis -ne $expectedGenesisHash) { throw "RPC genesis hash does not match DOS Testnet" } -$balanceOutput = & $cast balance $deployer --rpc-url $RpcUrl +$balanceOutput = & $cast balance $expectedDeployer --rpc-url $RpcUrl if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($balanceOutput)) { throw "Unable to read the canonical deployer balance" } diff --git a/contracts/test/unit/testnet/WrappedDOS.t.sol b/contracts/test/unit/testnet/WrappedDOS.t.sol index 835465734..a0b2c0181 100644 --- a/contracts/test/unit/testnet/WrappedDOS.t.sol +++ b/contracts/test/unit/testnet/WrappedDOS.t.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.20; import {Test} from "forge-std/Test.sol"; +import {Vm} from "forge-std/Vm.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {NameCoder} from "@ens/contracts/utils/NameCoder.sol"; @@ -15,6 +16,11 @@ import {LibLabel} from "~src/utils/LibLabel.sol"; import {WrappedDOS} from "~src/testnet/WrappedDOS.sol"; contract WrappedDOSTest is Test { + bytes32 internal constant LABEL_REGISTERED_TOPIC = + keccak256("LabelRegistered(uint256,bytes32,string,address,uint64,address)"); + bytes32 internal constant RESOLVER_UPDATED_TOPIC = keccak256("ResolverUpdated(uint256,address,address)"); + bytes32 internal constant ADDR_CHANGED_TOPIC = keccak256("AddrChanged(bytes32,address)"); + bytes32 internal constant ADDRESS_CHANGED_TOPIC = keccak256("AddressChanged(bytes32,uint256,bytes)"); address internal constant TESTNET_DEPLOYER = 0x99999e454138f6be73E2bE82c890bc5765749999; address internal constant PROTOCOL_OWNER = 0x310Bc061214ee89aF5CfB28a6ebF96c5436fa3CD; WrappedDOS internal wdos; @@ -134,6 +140,41 @@ contract WrappedDOSTest is Test { assertEq(denom, 1); } + function test_testnetSmokeResolverEventsFollowDynamicSourceCreation() external { + DeployDOSTestnet deployer = new DeployDOSTestnet(); + address protocolOwner = makeAddr("protocolOwner"); + address beneficiary = makeAddr("beneficiary"); + + vm.recordLogs(); + DeployDOSTestnet.TestnetDeployment memory deployment = + deployer.deployTestnet(address(deployer), protocolOwner, beneficiary, 3939); + Vm.Log[] memory logs = vm.getRecordedLogs(); + + address registry = address(deployment.names.dosRegistry); + address resolver = deployment.names.dosRegistry.getResolver("bens-smoke"); + uint256 labelRegisteredIndex = type(uint256).max; + uint256 resolverUpdatedIndex = type(uint256).max; + uint256 addrChangedIndex = type(uint256).max; + uint256 addressChangedIndex = type(uint256).max; + + for (uint256 index; index < logs.length; ++index) { + Vm.Log memory entry = logs[index]; + if (entry.emitter == registry && entry.topics[0] == LABEL_REGISTERED_TOPIC) { + labelRegisteredIndex = index; + } else if (entry.emitter == registry && entry.topics[0] == RESOLVER_UPDATED_TOPIC) { + resolverUpdatedIndex = index; + } else if (entry.emitter == resolver && entry.topics[0] == ADDR_CHANGED_TOPIC) { + addrChangedIndex = index; + } else if (entry.emitter == resolver && entry.topics[0] == ADDRESS_CHANGED_TOPIC) { + addressChangedIndex = index; + } + } + + assertLt(labelRegisteredIndex, resolverUpdatedIndex); + assertLt(resolverUpdatedIndex, addrChangedIndex); + assertLt(addrChangedIndex, addressChangedIndex); + } + function test_runRejectsWrongSignerBeforeBroadcast() external { DeployDOSTestnet deployer = new DeployDOSTestnet(); uint256 privateKey = 0xA11CE; diff --git a/subgraph/dos-names/tests/registry.test.ts b/subgraph/dos-names/tests/registry.test.ts index 4ad637504..0cd4af46a 100644 --- a/subgraph/dos-names/tests/registry.test.ts +++ b/subgraph/dos-names/tests/registry.test.ts @@ -23,6 +23,7 @@ import { handleTransferBatch, handleTransferSingle, } from "../src/registry"; +import { handleAddrChanged } from "../src/resolver"; import { handleUserRegistryLabelRegistered, handleUserRegistryLabelUnregistered, @@ -54,6 +55,7 @@ import { ResolverUpdated as UserRegistryResolverUpdated } from "../src/types/tem import { ExpiryUpdated as UserRegistryExpiryUpdated } from "../src/types/templates/UserRegistryTemplate/PermissionedRegistry"; import { TokenRegenerated as UserRegistryTokenRegenerated } from "../src/types/templates/UserRegistryTemplate/PermissionedRegistry"; import { SubregistryUpdated as UserRegistrySubregistryUpdated } from "../src/types/templates/UserRegistryTemplate/PermissionedRegistry"; +import { AddrChanged } from "../src/types/Resolver/PermissionedResolver"; import { Domain, RegistryPath } from "../src/types/schema"; const OWNER = "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7"; @@ -207,6 +209,33 @@ function resolverUpdated(tokenId: i32, resolver: string, logIndex: i32): Resolve return event; } +function addrChanged(node: string, logIndex: i32): AddrChanged { + let mock = newMockEvent(); + mock.address = Address.fromString(RESOLVER); + mock.logIndex = BigInt.fromI32(logIndex); + let event = new AddrChanged( + mock.address, + mock.logIndex, + mock.transactionLogIndex, + mock.logType, + mock.block, + mock.transaction, + mock.parameters, + mock.receipt + ); + event.parameters = [ + new ethereum.EventParam( + "node", + ethereum.Value.fromFixedBytes(Bytes.fromHexString(node)) + ), + new ethereum.EventParam( + "a", + ethereum.Value.fromAddress(Address.fromString(OWNER)) + ), + ]; + return event; +} + function labelUnregistered(tokenId: i32): LabelUnregistered { let mock = newMockEvent(); mock.logIndex = BigInt.fromI32(1); @@ -1044,6 +1073,14 @@ test("resolver discovery creates a dynamic source and zero address clears it", ( assert.assertNull(domain.resolver); }); +test("resolver address emitted after registration materializes forward resolution", () => { + handleLabelRegistered(registration(123)); + handleResolverUpdated(resolverUpdated(123, RESOLVER, 1)); + handleAddrChanged(addrChanged(ALICE_DOS, 2)); + + assert.fieldEquals("Domain", ALICE_DOS, "resolvedAddress", OWNER); +}); + test("unregistration retires the token mapping without losing domain history", () => { handleLabelRegistered(registration(123)); handleLabelUnregistered(labelUnregistered(123)); From 27df38a8d7d169a5211bcbf9a99e982d610e3f2e Mon Sep 17 00:00:00 2001 From: JOY <5027251+JOY@users.noreply.github.com> Date: Wed, 12 Aug 2026 22:45:08 +0700 Subject: [PATCH 13/14] style: format Testnet deployment sources --- .../script/foundry/DeployDOSTestnet.s.sol | 20 +++++++---- contracts/test/unit/testnet/WrappedDOS.t.sol | 36 +++++++++++++++---- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/contracts/script/foundry/DeployDOSTestnet.s.sol b/contracts/script/foundry/DeployDOSTestnet.s.sol index e18d6924c..080ec625b 100644 --- a/contracts/script/foundry/DeployDOSTestnet.s.sol +++ b/contracts/script/foundry/DeployDOSTestnet.s.sol @@ -97,18 +97,26 @@ contract DeployDOSTestnet is DeployDOS { } /// @dev Creates one stable forward and reverse record used by Graph Node and BENS acceptance gates. - function _registerBensSmokeName(Deployment memory deployment, address initialOwner, address owner, uint256 chainId) + function _registerBensSmokeName( + Deployment memory deployment, + address initialOwner, + address owner, + uint256 chainId + ) internal { bytes[] memory setters = new bytes[](0); - PermissionedResolver resolver = PermissionedResolver( - deployment.verifiableFactory - .deployProxy( + PermissionedResolver resolver = + PermissionedResolver( + deployment.verifiableFactory.deployProxy( address(deployment.permissionedResolverImplementation), 1, - abi.encodeCall(PermissionedResolver.initialize, (initialOwner, EACBaseRolesLib.ALL_ROLES, setters)) + abi.encodeCall( + PermissionedResolver.initialize, + (initialOwner, EACBaseRolesLib.ALL_ROLES, setters) + ) ) - ); + ); bytes32 node = NameCoder.namehash(NameCoder.encode(BENS_SMOKE_NAME), 0); PermissionedRegistry registry = deployment.dosRegistry; diff --git a/contracts/test/unit/testnet/WrappedDOS.t.sol b/contracts/test/unit/testnet/WrappedDOS.t.sol index a0b2c0181..69ae6b78e 100644 --- a/contracts/test/unit/testnet/WrappedDOS.t.sol +++ b/contracts/test/unit/testnet/WrappedDOS.t.sol @@ -18,9 +18,11 @@ import {WrappedDOS} from "~src/testnet/WrappedDOS.sol"; contract WrappedDOSTest is Test { bytes32 internal constant LABEL_REGISTERED_TOPIC = keccak256("LabelRegistered(uint256,bytes32,string,address,uint64,address)"); - bytes32 internal constant RESOLVER_UPDATED_TOPIC = keccak256("ResolverUpdated(uint256,address,address)"); + bytes32 internal constant RESOLVER_UPDATED_TOPIC = + keccak256("ResolverUpdated(uint256,address,address)"); bytes32 internal constant ADDR_CHANGED_TOPIC = keccak256("AddrChanged(bytes32,address)"); - bytes32 internal constant ADDRESS_CHANGED_TOPIC = keccak256("AddressChanged(bytes32,uint256,bytes)"); + bytes32 internal constant ADDRESS_CHANGED_TOPIC = + keccak256("AddressChanged(bytes32,uint256,bytes)"); address internal constant TESTNET_DEPLOYER = 0x99999e454138f6be73E2bE82c890bc5765749999; address internal constant PROTOCOL_OWNER = 0x310Bc061214ee89aF5CfB28a6ebF96c5436fa3CD; WrappedDOS internal wdos; @@ -185,7 +187,11 @@ contract WrappedDOSTest is Test { vm.chainId(3939); vm.expectRevert( - abi.encodeWithSelector(DeployDOSTestnet.UnexpectedDeployer.selector, vm.addr(privateKey), TESTNET_DEPLOYER) + abi.encodeWithSelector( + DeployDOSTestnet.UnexpectedDeployer.selector, + vm.addr(privateKey), + TESTNET_DEPLOYER + ) ); deployer.run(); } @@ -203,7 +209,9 @@ contract WrappedDOSTest is Test { vm.chainId(7979); vm.deal(TESTNET_DEPLOYER, 1 ether); - vm.expectRevert(abi.encodeWithSelector(DeployDOSTestnet.UnexpectedChain.selector, 7979, 3939)); + vm.expectRevert( + abi.encodeWithSelector(DeployDOSTestnet.UnexpectedChain.selector, 7979, 3939) + ); deployer.preflight(TESTNET_DEPLOYER, PROTOCOL_OWNER, PROTOCOL_OWNER); } @@ -213,7 +221,13 @@ contract WrappedDOSTest is Test { vm.deal(TESTNET_DEPLOYER, 1 ether); address wrongOwner = makeAddr("wrongOwner"); - vm.expectRevert(abi.encodeWithSelector(DeployDOSTestnet.UnexpectedOwner.selector, wrongOwner, PROTOCOL_OWNER)); + vm.expectRevert( + abi.encodeWithSelector( + DeployDOSTestnet.UnexpectedOwner.selector, + wrongOwner, + PROTOCOL_OWNER + ) + ); deployer.preflight(TESTNET_DEPLOYER, wrongOwner, PROTOCOL_OWNER); } @@ -224,7 +238,11 @@ contract WrappedDOSTest is Test { address wrongBeneficiary = makeAddr("wrongBeneficiary"); vm.expectRevert( - abi.encodeWithSelector(DeployDOSTestnet.UnexpectedBeneficiary.selector, wrongBeneficiary, PROTOCOL_OWNER) + abi.encodeWithSelector( + DeployDOSTestnet.UnexpectedBeneficiary.selector, + wrongBeneficiary, + PROTOCOL_OWNER + ) ); deployer.preflight(TESTNET_DEPLOYER, PROTOCOL_OWNER, wrongBeneficiary); } @@ -235,7 +253,11 @@ contract WrappedDOSTest is Test { vm.deal(TESTNET_DEPLOYER, 1 ether - 1); vm.expectRevert( - abi.encodeWithSelector(DeployDOSTestnet.InsufficientDeploymentBalance.selector, 1 ether - 1, 1 ether) + abi.encodeWithSelector( + DeployDOSTestnet.InsufficientDeploymentBalance.selector, + 1 ether - 1, + 1 ether + ) ); deployer.preflight(TESTNET_DEPLOYER, PROTOCOL_OWNER, PROTOCOL_OWNER); } From a89847e5fa41b6a89320153a5e14bdd1f68b3a22 Mon Sep 17 00:00:00 2001 From: JOY <5027251+JOY@users.noreply.github.com> Date: Wed, 12 Aug 2026 22:53:45 +0700 Subject: [PATCH 14/14] chore: record canonical Testnet ENSv2 deployment --- contracts/deployments/dos-testnet-3939.json | 45 ++++++++++--------- .../dos-names/scripts/render-manifest.mjs | 17 +++++++ .../tests/fixtures/dos-testnet-3939.json | 3 ++ .../dos-names/tests/render-manifest.test.mjs | 24 ++++++++++ 4 files changed, 68 insertions(+), 21 deletions(-) diff --git a/contracts/deployments/dos-testnet-3939.json b/contracts/deployments/dos-testnet-3939.json index ddfd85509..580bfcfe8 100644 --- a/contracts/deployments/dos-testnet-3939.json +++ b/contracts/deployments/dos-testnet-3939.json @@ -1,32 +1,35 @@ { "environment": "dos-testnet", "chainId": 3939, - "deploymentBlock": 78, - "finalDeploymentBlock": 118, - "deployedAt": "2026-08-12T14:57:00Z", + "deploymentBlock": 120, + "finalDeploymentBlock": 166, + "deployedAt": "2026-08-12T15:49:48Z", "deployer": "0x99999e454138f6be73E2bE82c890bc5765749999", "owner": "0x310Bc061214ee89aF5CfB28a6ebF96c5436fa3CD", "beneficiary": "0x310Bc061214ee89aF5CfB28a6ebF96c5436fa3CD", + "smokeName": "bens-smoke.dos", + "smokeResolvedAddress": "0x99999e454138f6be73E2bE82c890bc5765749999", "transactions": { - "first": "0x0e5179cef7c84e733ec4f71cbd9cf8a4dcca336e1e501997b3eecc7e116eed68", - "last": "0xe65eb54b3dc69b7e664c65c907c4cf9b6f049d64b27686e0d851aed03f9c648e", - "count": 41 + "first": "0xc0f8e5390dab49911ce5f0f4c0a035e3251033c7d502f3db2632e389ef3ab599", + "last": "0xa3f4e38ec91c8db369df6afa40eea3e28f73a858e3a4c1bbceca3a60b38e6d0a", + "count": 47 }, "contracts": { - "wrappedDOS": "0xc647CCF449DEc38Bb8B7272e60fc14B3548c9547", - "contractNamerImplementation": "0x069056B2Ae8fD8c071efb827c5AF73A0996840E1", - "contractNamer": "0x030eec847cf5D9d1c4A0b4e0459d130D0B35577C", - "verifiableFactory": "0xB86bb608E6Afd7a8Eb209510c01BB859A7c315f1", - "labelStore": "0x38FC582690c3F28099087A88520056afAb08ce5F", - "rootRegistry": "0xb17Fec6fe18aC0b7F3dd934495E84eC06Cf88564", - "dosRegistry": "0x8A2730c903d93b2116Fab3d9110C7D585F7B5a91", - "reverseRegistry": "0x641Ee4711013EE40B34fAE860894227c4771F273", - "priceOracle": "0x1F31e05948769174dA256D0484b8f26cfD3d8c97", - "dosRegistrar": "0x27A3B7ff0EF7fB96D49eB50B069570F407387362", - "permissionedResolverImplementation": "0xfa579733d7C5A21B5D3C4399D3d6Ef89fc3A3720", - "userRegistryImplementation": "0x8291F1C6aEf2acBC58F3fe11C9e4EC0d3D4aE904", - "gatewayProvider": "0xCB20A0C349f079b8bD403ea8F668FE3DA49E981f", - "universalResolver": "0x5A34c9fB9806239Ed61f1570c51edb198333fbeA", - "reverseRegistrar": "0x3Cd8BdDeB177492c5e521c3B82179887f472f018" + "wrappedDOS": "0x4bb2dcea9e18604741287a12d87abd9de793e3f4", + "contractNamerImplementation": "0xdd20fc2290cf664eccd3414799a9f024bdea531c", + "contractNamer": "0x64A04D812cdc62971f7E446E15a53c3C57f11418", + "verifiableFactory": "0xC9A8C00499Ef4f20Fffad7114C0eFfE8E766FE11", + "labelStore": "0x57C06ec4a92eC4eEB7c4eaFaBfBc64661483f3Bb", + "rootRegistry": "0x0dC5af261429d661BbF4903AbB79049a0713e04B", + "dosRegistry": "0x95366f1E44532F50c022aEefF708F424b7854173", + "reverseRegistry": "0x4d5429C2c0EE50b903407F44F8A21d20CAAcB475", + "priceOracle": "0x2eE958BcF29d140cdf64ad767f32E2554B0CCfa6", + "dosRegistrar": "0x4E5B48aC8B221aAF8cFF070671CB6Eeea2122b5c", + "permissionedResolverImplementation": "0x7C320eF16DE9CDD1BB9591AACF38c4c26f391e25", + "userRegistryImplementation": "0x440F74b09DfD3a848a9168d7d73784bCC03eF590", + "gatewayProvider": "0xEc7dFA7Dd3C7882d8716782689cE85e1Ccf9C68c", + "universalResolver": "0xbd0f96e3E8510a1bb806cAA9836fc76dfb1a5c47", + "reverseRegistrar": "0xD445f533aeC6E8BAE185f9903943e7B2E655472e", + "smokeResolver": "0xf2de697266073C4ba4D546d4305c228BBF5B1813" } } diff --git a/subgraph/dos-names/scripts/render-manifest.mjs b/subgraph/dos-names/scripts/render-manifest.mjs index 29f832b62..72c7b6c67 100644 --- a/subgraph/dos-names/scripts/render-manifest.mjs +++ b/subgraph/dos-names/scripts/render-manifest.mjs @@ -26,6 +26,23 @@ export function validateDeployment(deployment) { ) { throw new Error("deploymentBlock must be a non-negative integer"); } + if ( + !Number.isInteger(deployment.finalDeploymentBlock) || + deployment.finalDeploymentBlock < deployment.deploymentBlock + ) { + throw new Error( + "finalDeploymentBlock must be an integer at or after deploymentBlock", + ); + } + if (deployment.smokeName !== "bens-smoke.dos") { + throw new Error("smokeName must be bens-smoke.dos"); + } + if (!ADDRESS_PATTERN.test(deployment.smokeResolvedAddress ?? "")) { + throw new Error("smokeResolvedAddress must be an EVM address"); + } + if (deployment.smokeResolvedAddress.toLowerCase() === ZERO_ADDRESS) { + throw new Error("smokeResolvedAddress must not be the zero address"); + } for (const [contractName] of CONTRACT_PLACEHOLDERS) { const address = deployment.contracts?.[contractName]; diff --git a/subgraph/dos-names/tests/fixtures/dos-testnet-3939.json b/subgraph/dos-names/tests/fixtures/dos-testnet-3939.json index 8000eb435..892802e9d 100644 --- a/subgraph/dos-names/tests/fixtures/dos-testnet-3939.json +++ b/subgraph/dos-names/tests/fixtures/dos-testnet-3939.json @@ -1,6 +1,9 @@ { "chainId": 3939, "deploymentBlock": 0, + "finalDeploymentBlock": 1, + "smokeName": "bens-smoke.dos", + "smokeResolvedAddress": "0x4444444444444444444444444444444444444444", "contracts": { "dosRegistry": "0x1111111111111111111111111111111111111111", "dosRegistrar": "0x2222222222222222222222222222222222222222", diff --git a/subgraph/dos-names/tests/render-manifest.test.mjs b/subgraph/dos-names/tests/render-manifest.test.mjs index 022d15b86..af4d03327 100644 --- a/subgraph/dos-names/tests/render-manifest.test.mjs +++ b/subgraph/dos-names/tests/render-manifest.test.mjs @@ -6,6 +6,9 @@ import { renderManifest, validateDeployment } from "../scripts/render-manifest.m const VALID_DEPLOYMENT = { chainId: 3939, deploymentBlock: 68, + finalDeploymentBlock: 72, + smokeName: "bens-smoke.dos", + smokeResolvedAddress: "0x4444444444444444444444444444444444444444", contracts: { dosRegistry: "0x1111111111111111111111111111111111111111", dosRegistrar: "0x2222222222222222222222222222222222222222", @@ -48,6 +51,27 @@ test("rejects a missing deployment block", () => { ); }); +test("rejects a final deployment block before the first deployment block", () => { + assert.throws( + () => + validateDeployment({ + ...VALID_DEPLOYMENT, + finalDeploymentBlock: VALID_DEPLOYMENT.deploymentBlock - 1, + }), + /finalDeploymentBlock must be an integer at or after deploymentBlock/, + ); +}); + +test("rejects a missing smoke resolution address", () => { + const deployment = { ...VALID_DEPLOYMENT }; + delete deployment.smokeResolvedAddress; + + assert.throws( + () => validateDeployment(deployment), + /smokeResolvedAddress must be an EVM address/, + ); +}); + test("rejects a missing required contract", () => { const deployment = { ...VALID_DEPLOYMENT,