From 58862ef1fc0895658eae30545a95c80a34381036 Mon Sep 17 00:00:00 2001 From: Pedro Binotto Date: Tue, 7 Apr 2026 12:53:39 -0300 Subject: [PATCH] feat(hyperindex-integration): implementation first try --- apps/indexer/abis/ens-governor.json | 787 ++++++++++++++++ apps/indexer/abis/ens-token.json | 840 ++++++++++++++++++ apps/indexer/config.yaml | 37 + apps/indexer/package.json | 2 + apps/indexer/schema.graphql | 202 +++++ apps/indexer/src/eventHandlers/ENSGovernor.ts | 65 ++ apps/indexer/src/eventHandlers/ENSToken.ts | 259 ++++++ apps/indexer/src/eventHandlers/delegation.ts | 238 +++-- apps/indexer/src/eventHandlers/index.ts | 6 +- .../src/eventHandlers/metrics/circulating.ts | 37 +- .../src/eventHandlers/metrics/delegated.ts | 30 +- .../src/eventHandlers/metrics/index.ts | 8 +- .../src/eventHandlers/metrics/supply.ts | 38 +- .../src/eventHandlers/metrics/total.ts | 37 +- apps/indexer/src/eventHandlers/shared.ts | 147 +-- apps/indexer/src/eventHandlers/transfer.ts | 188 ++-- apps/indexer/src/eventHandlers/voting.ts | 220 ++--- apps/indexer/src/lib/constants.ts | 55 +- apps/indexer/src/lib/date-helpers.ts | 2 +- apps/indexer/src/lib/enums.ts | 36 +- apps/indexer/src/lib/query-helpers.ts | 2 +- apps/indexer/src/lib/time-series.ts | 4 +- apps/indexer/tsconfig.json | 13 +- eslint.config.mjs | 18 + generated@0.1.0 | 0 pnpm-lock.yaml | 669 +++++++++++++- ts-node | 0 27 files changed, 3318 insertions(+), 622 deletions(-) create mode 100644 apps/indexer/abis/ens-governor.json create mode 100644 apps/indexer/abis/ens-token.json create mode 100644 apps/indexer/config.yaml create mode 100644 apps/indexer/schema.graphql create mode 100644 apps/indexer/src/eventHandlers/ENSGovernor.ts create mode 100644 apps/indexer/src/eventHandlers/ENSToken.ts create mode 100644 generated@0.1.0 create mode 100644 ts-node diff --git a/apps/indexer/abis/ens-governor.json b/apps/indexer/abis/ens-governor.json new file mode 100644 index 000000000..ad8f4d77a --- /dev/null +++ b/apps/indexer/abis/ens-governor.json @@ -0,0 +1,787 @@ +[ + { + "inputs": [ + { + "internalType": "contract ERC20Votes", + "name": "_token", + "type": "address" + }, + { + "internalType": "contract TimelockController", + "name": "_timelock", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + } + ], + "name": "ProposalCanceled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "proposer", + "type": "address" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "targets", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "string[]", + "name": "signatures", + "type": "string[]" + }, + { + "indexed": false, + "internalType": "bytes[]", + "name": "calldatas", + "type": "bytes[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "startBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "endBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "description", + "type": "string" + } + ], + "name": "ProposalCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + } + ], + "name": "ProposalExecuted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "eta", + "type": "uint256" + } + ], + "name": "ProposalQueued", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldQuorumNumerator", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newQuorumNumerator", + "type": "uint256" + } + ], + "name": "QuorumNumeratorUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldTimelock", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newTimelock", + "type": "address" + } + ], + "name": "TimelockChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "voter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "support", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "reason", + "type": "string" + } + ], + "name": "VoteCast", + "type": "event" + }, + { + "inputs": [], + "name": "BALLOT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "COUNTING_MODE", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "support", + "type": "uint8" + } + ], + "name": "castVote", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "support", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "castVoteBySig", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "support", + "type": "uint8" + }, + { + "internalType": "string", + "name": "reason", + "type": "string" + } + ], + "name": "castVoteWithReason", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "targets", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "calldatas", + "type": "bytes[]" + }, + { + "internalType": "bytes32", + "name": "descriptionHash", + "type": "bytes32" + } + ], + "name": "execute", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + } + ], + "name": "getVotes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasVoted", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "targets", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "calldatas", + "type": "bytes[]" + }, + { + "internalType": "bytes32", + "name": "descriptionHash", + "type": "bytes32" + } + ], + "name": "hashProposal", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + } + ], + "name": "proposalDeadline", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + } + ], + "name": "proposalEta", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + } + ], + "name": "proposalSnapshot", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proposalThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + } + ], + "name": "proposalVotes", + "outputs": [ + { + "internalType": "uint256", + "name": "againstVotes", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "forVotes", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "abstainVotes", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "targets", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "calldatas", + "type": "bytes[]" + }, + { + "internalType": "string", + "name": "description", + "type": "string" + } + ], + "name": "propose", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "targets", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "calldatas", + "type": "bytes[]" + }, + { + "internalType": "bytes32", + "name": "descriptionHash", + "type": "bytes32" + } + ], + "name": "queue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + } + ], + "name": "quorum", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "quorumDenominator", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "quorumNumerator", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + } + ], + "name": "state", + "outputs": [ + { + "internalType": "enum IGovernor.ProposalState", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "timelock", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token", + "outputs": [ + { + "internalType": "contract ERC20Votes", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newQuorumNumerator", + "type": "uint256" + } + ], + "name": "updateQuorumNumerator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TimelockController", + "name": "newTimelock", + "type": "address" + } + ], + "name": "updateTimelock", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "votingDelay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "votingPeriod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + } +] \ No newline at end of file diff --git a/apps/indexer/abis/ens-token.json b/apps/indexer/abis/ens-token.json new file mode 100644 index 000000000..9d2ea9ae6 --- /dev/null +++ b/apps/indexer/abis/ens-token.json @@ -0,0 +1,840 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "freeSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "airdropSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_claimPeriodEnds", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "claimant", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "delegator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "fromDelegate", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "toDelegate", + "type": "address" + } + ], + "name": "DelegateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "delegate", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "previousBalance", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newBalance", + "type": "uint256" + } + ], + "name": "DelegateVotesChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "merkleRoot", + "type": "bytes32" + } + ], + "name": "MerkleRootChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint32", + "name": "pos", + "type": "uint32" + } + ], + "name": "checkpoints", + "outputs": [ + { + "components": [ + { + "internalType": "uint32", + "name": "fromBlock", + "type": "uint32" + }, + { + "internalType": "uint224", + "name": "votes", + "type": "uint224" + } + ], + "internalType": "struct ERC20Votes.Checkpoint", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimPeriodEnds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "delegate", + "type": "address" + }, + { + "internalType": "bytes32[]", + "name": "merkleProof", + "type": "bytes32[]" + } + ], + "name": "claimTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "delegatee", + "type": "address" + } + ], + "name": "delegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "delegatee", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "delegateBySig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "delegates", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + } + ], + "name": "getPastTotalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + } + ], + "name": "getPastVotes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getVotes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "isClaimed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "merkleRoot", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minimumMintInterval", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "dest", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "mintCap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nextMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "numCheckpoints", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_merkleRoot", + "type": "bytes32" + } + ], + "name": "setMerkleRoot", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "dest", + "type": "address" + } + ], + "name": "sweep", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/apps/indexer/config.yaml b/apps/indexer/config.yaml new file mode 100644 index 000000000..a007ff9d4 --- /dev/null +++ b/apps/indexer/config.yaml @@ -0,0 +1,37 @@ +name: anticapture-indexer +description: Anticapture DAO governance indexer +field_selection: + transaction_fields: + - hash + - to + - from + +contracts: + - name: ENSToken + abi_file_path: abis/ens-token.json + handler: src/eventHandlers/ENSToken.ts + events: + - event: "Transfer(address indexed from, address indexed to, uint256 value)" + - event: "DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate)" + - event: "DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance)" + - name: ENSGovernor + abi_file_path: abis/ens-governor.json + handler: src/eventHandlers/ENSGovernor.ts + events: + - event: "ProposalCreated(uint256 proposalId, address proposer, address[] targets, uint256[] values, string[] signatures, bytes[] calldatas, uint256 startBlock, uint256 endBlock, string description)" + - event: "VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason)" + - event: "ProposalCanceled(uint256 proposalId)" + - event: "ProposalExecuted(uint256 proposalId)" + - event: "ProposalQueued(uint256 proposalId, uint256 eta)" + +networks: + - id: 1 + hypersync_config: + url: https://eth.hypersync.xyz + start_block: 9380410 + contracts: + - name: ENSToken + address: "0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72" + - name: ENSGovernor + address: "0x323a76393544d5ecca80cd6ef2a560c6a395b7e3" + start_block: 13533772 diff --git a/apps/indexer/package.json b/apps/indexer/package.json index b8542865e..bf3dd7892 100644 --- a/apps/indexer/package.json +++ b/apps/indexer/package.json @@ -4,6 +4,7 @@ "private": true, "scripts": { "dev": "ponder dev", + "envio": "envio dev", "start": "ponder start --views-schema=anticapture --schema=$RAILWAY_DEPLOYMENT_ID", "db:list": "ponder db list", "db:prune": "ponder db prune", @@ -24,6 +25,7 @@ "@types/node": "^20.16.5", "@types/pg": "^8.15.6", "dotenv": "^16.5.0", + "envio": "^2.32.12", "eslint": "^9", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.2.1", diff --git a/apps/indexer/schema.graphql b/apps/indexer/schema.graphql new file mode 100644 index 000000000..d7c02d714 --- /dev/null +++ b/apps/indexer/schema.graphql @@ -0,0 +1,202 @@ +enum MetricType { + total + delegated + cex + dex + lending + circulating + treasury + non_circulating +} + +enum EventType { + VOTE + PROPOSAL + PROPOSAL_EXTENDED + DELEGATION + DELEGATION_VOTES_CHANGED + TRANSFER +} + +type Token { + id: ID! + name: String + decimals: Int! + totalSupply: BigInt! + delegatedSupply: BigInt! + cexSupply: BigInt! + dexSupply: BigInt! + lendingSupply: BigInt! + circulatingSupply: BigInt! + treasury: BigInt! + nonCirculatingSupply: BigInt! +} + +type Account { + id: ID! +} + +# Composite PK: "{accountId}-{tokenId}" +type AccountBalance { + id: ID! + accountId: String! @index + tokenId: String! @index + balance: BigInt! + delegate: String! +} + +# Composite PK: "{accountId}" +type AccountPower { + id: ID! + accountId: String! @index + daoId: String! + votingPower: BigInt! + votesCount: Int! + proposalsCount: Int! + delegationsCount: Int! + lastVoteTimestamp: BigInt! +} + +# Composite PK: "{txHash}-{accountId}-{logIndex}" +type VotingPowerHistory { + id: ID! + transactionHash: String! @index + daoId: String! + accountId: String! @index + votingPower: BigInt! + delta: BigInt! + deltaMod: BigInt! + timestamp: BigInt! + logIndex: Int! +} + +# Composite PK: "{txHash}-{accountId}-{logIndex}" +type BalanceHistory { + id: ID! + transactionHash: String! @index + daoId: String! + accountId: String! @index + balance: BigInt! + delta: BigInt! + deltaMod: BigInt! + timestamp: BigInt! + logIndex: Int! +} + +# Composite PK: "{txHash}-{delegatorId}-{delegateId}" +type Delegation { + id: ID! + transactionHash: String! @index + daoId: String! + delegateAccountId: String! @index + delegatorAccountId: String! @index + delegatedValue: BigInt! + previousDelegate: String + timestamp: BigInt! @index + logIndex: Int! + isCex: Boolean! + isDex: Boolean! + isLending: Boolean! + isTotal: Boolean! + delegationType: Int +} + +# Composite PK: "{txHash}-{fromId}-{toId}" +type Transfer { + id: ID! + transactionHash: String! @index + daoId: String! + tokenId: String! @index + amount: BigInt! @index + fromAccountId: String! @index + toAccountId: String! @index + timestamp: BigInt! @index + logIndex: Int! + isCex: Boolean! + isDex: Boolean! + isLending: Boolean! + isTotal: Boolean! +} + +# Composite PK: "{voterId}-{proposalId}" +type VoteOnchain { + id: ID! + txHash: String! + daoId: String! + voterAccountId: String! @index + proposalId: String! @index + support: String! + votingPower: BigInt! + reason: String + timestamp: BigInt! +} + +type ProposalOnchain { + id: ID! + txHash: String! + daoId: String! + proposerAccountId: String! @index + targets: Json! + values: Json! + signatures: Json! + calldatas: Json! + startBlock: Int! + endBlock: Int! + title: String! + description: String! + timestamp: BigInt! + logIndex: Int! + endTimestamp: BigInt! + status: String! + forVotes: BigInt! + againstVotes: BigInt! + abstainVotes: BigInt! + proposalType: Int +} + +# Composite PK: "{date}-{tokenId}-{metricType}" +type DaoMetricsDayBucket { + id: ID! + date: BigInt! + daoId: String! + tokenId: String! @index + metricType: MetricType! + openValue: BigInt! + closeValue: BigInt! + low: BigInt! + high: BigInt! + average: BigInt! + volume: BigInt! + count: Int! + lastUpdate: BigInt! +} + +type Transaction { + id: ID! + transactionHash: String! + fromAddress: String + toAddress: String + isCex: Boolean! + isDex: Boolean! + isLending: Boolean! + isTotal: Boolean! + timestamp: BigInt! +} + + +type TokenPrice { + id: ID! + price: BigInt! + timestamp: BigInt! +} + +# Composite PK: "{txHash}-{logIndex}" +type FeedEvent { + id: ID! + txHash: String! @index + logIndex: Int! + eventType: EventType! + value: BigInt! @index + timestamp: BigInt! @index + metadata: Json +} diff --git a/apps/indexer/src/eventHandlers/ENSGovernor.ts b/apps/indexer/src/eventHandlers/ENSGovernor.ts new file mode 100644 index 000000000..3ecdec77f --- /dev/null +++ b/apps/indexer/src/eventHandlers/ENSGovernor.ts @@ -0,0 +1,65 @@ +import { ENSGovernor } from "../../generated/index.js"; +import type { Hex, Address } from "viem"; + +import { ProposalStatus, CONTRACT_ADDRESSES } from "../lib/constants.ts"; +import { DaoIdEnum } from "../lib/enums.ts"; + +import { proposalCreated, updateProposalStatus, voteCast } from "./voting.ts"; + +const DAO_ID = DaoIdEnum.ENS; +const BLOCK_TIME = CONTRACT_ADDRESSES[DAO_ID].blockTime; + +ENSGovernor.VoteCast.handler(async ({ event, context }) => { + await voteCast(context, DAO_ID, { + proposalId: event.params.proposalId.toString(), + voter: event.params.voter as Address, + reason: event.params.reason, + support: Number(event.params.support), + timestamp: BigInt(event.block.timestamp), + txHash: event.transaction.hash as Hex, + votingPower: event.params.weight, + logIndex: event.logIndex, + }); +}); + +ENSGovernor.ProposalCreated.handler(async ({ event, context }) => { + await proposalCreated(context, DAO_ID, BLOCK_TIME, { + proposalId: event.params.proposalId.toString(), + txHash: event.transaction.hash as Hex, + proposer: event.params.proposer as Address, + targets: [...event.params.targets] as Address[], + values: [...event.params.values], + signatures: [...event.params.signatures], + calldatas: [...event.params.calldatas] as Hex[], + startBlock: event.params.startBlock.toString(), + endBlock: event.params.endBlock.toString(), + description: event.params.description, + timestamp: BigInt(event.block.timestamp), + blockNumber: BigInt(event.block.number as number), + logIndex: event.logIndex, + }); +}); + +ENSGovernor.ProposalCanceled.handler(async ({ event, context }) => { + await updateProposalStatus( + context, + event.params.proposalId.toString(), + ProposalStatus.CANCELED, + ); +}); + +ENSGovernor.ProposalExecuted.handler(async ({ event, context }) => { + await updateProposalStatus( + context, + event.params.proposalId.toString(), + ProposalStatus.EXECUTED, + ); +}); + +ENSGovernor.ProposalQueued.handler(async ({ event, context }) => { + await updateProposalStatus( + context, + event.params.proposalId.toString(), + ProposalStatus.QUEUED, + ); +}); diff --git a/apps/indexer/src/eventHandlers/ENSToken.ts b/apps/indexer/src/eventHandlers/ENSToken.ts new file mode 100644 index 000000000..674fbebc8 --- /dev/null +++ b/apps/indexer/src/eventHandlers/ENSToken.ts @@ -0,0 +1,259 @@ +import { ENSToken } from "../../generated/index.js"; +import type { handlerContext } from "../../generated/index.js"; +import type { Address, Hex } from "viem"; +import { getAddress } from "viem"; + +import { + CONTRACT_ADDRESSES, + MetricTypesEnum, + BurningAddresses, + CEXAddresses, + DEXAddresses, + LendingAddresses, + TreasuryAddresses, + NonCirculatingAddresses, +} from "../lib/constants.ts"; +import { DaoIdEnum } from "../lib/enums.ts"; + +import { delegateChanged, delegatedVotesChanged } from "./delegation.ts"; +import { tokenTransfer } from "./transfer.ts"; +import { createAddressSet, handleTransaction } from "./shared.ts"; +import { + updateDelegatedSupply, + updateCirculatingSupply, + updateSupplyMetric, + updateTotalSupply, +} from "./metrics/index.ts"; + +const DAO_ID = DaoIdEnum.ENS; +const ENS_CONTRACTS = CONTRACT_ADDRESSES[DAO_ID]; +const TOKEN_ADDRESS = getAddress(ENS_CONTRACTS.token.address); +const TOKEN_DECIMALS = ENS_CONTRACTS.token.decimals; + +const cexAddressSet = createAddressSet(Object.values(CEXAddresses[DAO_ID])); +const dexAddressSet = createAddressSet(Object.values(DEXAddresses[DAO_ID])); +const lendingAddressSet = createAddressSet( + Object.values(LendingAddresses[DAO_ID]), +); +const burningAddressSet = createAddressSet( + Object.values(BurningAddresses[DAO_ID]), +); +const treasuryAddressSet = createAddressSet( + Object.values(TreasuryAddresses[DAO_ID]), +); +const nonCirculatingAddressSet = createAddressSet( + Object.values(NonCirculatingAddresses[DAO_ID]), +); +const delegationAddressSets = { + cex: cexAddressSet, + dex: dexAddressSet, + lending: lendingAddressSet, + burning: burningAddressSet, +}; + +// Lazy token initialization — replaces Ponder's setup event +const ensureTokenExists = async (context: handlerContext) => { + await context.Token.getOrCreate({ + id: TOKEN_ADDRESS, + name: DAO_ID, + decimals: TOKEN_DECIMALS, + totalSupply: 0n, + delegatedSupply: 0n, + cexSupply: 0n, + dexSupply: 0n, + lendingSupply: 0n, + circulatingSupply: 0n, + treasury: 0n, + nonCirculatingSupply: 0n, + }); +}; + +ENSToken.Transfer.handler(async ({ event, context }) => { + const from = event.params.from as Address; + const to = event.params.to as Address; + const { value } = event.params; + const timestamp = BigInt(event.block.timestamp); + + await ensureTokenExists(context); + + await tokenTransfer( + context, + DAO_ID, + { + from, + to, + value, + token: TOKEN_ADDRESS, + transactionHash: event.transaction.hash as Hex, + timestamp, + logIndex: event.logIndex, + }, + { + cex: cexAddressSet, + dex: dexAddressSet, + lending: lendingAddressSet, + burning: burningAddressSet, + }, + ); + + await updateSupplyMetric( + context, + "lendingSupply", + lendingAddressSet, + MetricTypesEnum.LENDING_SUPPLY, + from, + to, + value, + DAO_ID, + TOKEN_ADDRESS, + timestamp, + ); + await updateSupplyMetric( + context, + "cexSupply", + cexAddressSet, + MetricTypesEnum.CEX_SUPPLY, + from, + to, + value, + DAO_ID, + TOKEN_ADDRESS, + timestamp, + ); + await updateSupplyMetric( + context, + "dexSupply", + dexAddressSet, + MetricTypesEnum.DEX_SUPPLY, + from, + to, + value, + DAO_ID, + TOKEN_ADDRESS, + timestamp, + ); + await updateSupplyMetric( + context, + "treasury", + treasuryAddressSet, + MetricTypesEnum.TREASURY, + from, + to, + value, + DAO_ID, + TOKEN_ADDRESS, + timestamp, + ); + await updateSupplyMetric( + context, + "nonCirculatingSupply", + nonCirculatingAddressSet, + MetricTypesEnum.NON_CIRCULATING_SUPPLY, + from, + to, + value, + DAO_ID, + TOKEN_ADDRESS, + timestamp, + ); + await updateTotalSupply( + context, + burningAddressSet, + MetricTypesEnum.TOTAL_SUPPLY, + from, + to, + value, + DAO_ID, + TOKEN_ADDRESS, + timestamp, + ); + await updateCirculatingSupply(context, DAO_ID, TOKEN_ADDRESS, timestamp); + + if (!event.transaction.to) return; + + await handleTransaction( + context, + event.transaction.hash as Hex, + from, + event.transaction.to as Address, + timestamp, + [from, to], + { + cex: cexAddressSet, + dex: dexAddressSet, + lending: lendingAddressSet, + burning: burningAddressSet, + }, + ); +}); + +ENSToken.DelegateChanged.handler(async ({ event, context }) => { + const delegator = event.params.delegator as Address; + const fromDelegate = event.params.fromDelegate as Address; + const toDelegate = event.params.toDelegate as Address; + const timestamp = BigInt(event.block.timestamp); + + await ensureTokenExists(context); + + await delegateChanged( + context, + DAO_ID, + { + delegator, + delegate: toDelegate, + tokenId: TOKEN_ADDRESS, + previousDelegate: fromDelegate, + txHash: event.transaction.hash as Hex, + timestamp, + logIndex: event.logIndex, + }, + delegationAddressSets, + ); + + if (!event.transaction.to) return; + + await handleTransaction( + context, + event.transaction.hash as Hex, + delegator, + event.transaction.to as Address, + timestamp, + [delegator, toDelegate], + ); +}); + +ENSToken.DelegateVotesChanged.handler(async ({ event, context }) => { + const delegate = event.params.delegate as Address; + const { previousBalance, newBalance } = event.params; + const timestamp = BigInt(event.block.timestamp); + + await ensureTokenExists(context); + + await delegatedVotesChanged(context, DAO_ID, { + delegate, + txHash: event.transaction.hash as Hex, + newBalance, + oldBalance: previousBalance, + timestamp, + logIndex: event.logIndex, + }); + + await updateDelegatedSupply( + context, + DAO_ID, + TOKEN_ADDRESS, + newBalance - previousBalance, + timestamp, + ); + + if (!event.transaction.to) return; + + await handleTransaction( + context, + event.transaction.hash as Hex, + delegate, + event.transaction.to as Address, + timestamp, + [delegate], + ); +}); diff --git a/apps/indexer/src/eventHandlers/delegation.ts b/apps/indexer/src/eventHandlers/delegation.ts index 586d7d963..142c1b215 100644 --- a/apps/indexer/src/eventHandlers/delegation.ts +++ b/apps/indexer/src/eventHandlers/delegation.ts @@ -1,26 +1,21 @@ -import { Context } from "ponder:registry"; -import { - accountBalance, - accountPower, - delegation, - feedEvent, - votingPowerHistory, -} from "ponder:schema"; -import { Address, getAddress, Hex, zeroAddress } from "viem"; +import type { handlerContext } from "../../generated/index.js"; +import type { EventType_t } from "../../generated/src/db/Enums.gen.ts"; +import type { Address, Hex } from "viem"; +import { getAddress, zeroAddress } from "viem"; import { BurningAddresses, CEXAddresses, DEXAddresses, LendingAddresses, -} from "@/lib/constants"; -import { DaoIdEnum } from "@/lib/enums"; +} from "../lib/constants.ts"; +import { DaoIdEnum } from "../lib/enums.ts"; import { createAddressSet, ensureAccountExists, ensureAccountsExist, -} from "./shared"; +} from "./shared.ts"; type DelegationAddressSets = { cex: ReadonlySet
; @@ -29,22 +24,8 @@ type DelegationAddressSets = { burning: ReadonlySet
; }; -/** - * ### Creates: - * - New `Account` records (for delegator and delegate if they don't exist) - * - New `Delegation` record with calculated delegated value and flags - * - New `AccountBalance` record (if delegator doesn't have one for this token) - * - New `AccountPower` record (if delegate doesn't have one for this DAO) - * - New `Transaction` record (if this transaction hasn't been processed) - * - * ### Updates: - * - `Delegation`: Adds to existing delegated value if record already exists - * - `AccountBalance`: Changes the delegate assignment for the delegator - * - `AccountPower`: Increments the delegate's delegation count - * - `Transaction`: Updates transaction flags if record already exists - */ export const delegateChanged = async ( - context: Context, + context: handlerContext, daoId: DaoIdEnum, args: { delegator: Address; @@ -72,17 +53,14 @@ export const delegateChanged = async ( const normalizedDelegator = getAddress(delegator); const normalizedDelegate = getAddress(delegate); - // Ensure all required accounts exist in parallel await ensureAccountsExist(context, [delegator, delegate]); - const delegatorBalance = _delegatorBalance + const delegatorBalanceId = `${normalizedDelegator}-${getAddress(tokenId)}`; + const storedBalance = _delegatorBalance ? { balance: _delegatorBalance } - : await context.db.find(accountBalance, { - accountId: normalizedDelegator, - tokenId: getAddress(tokenId), - }); + : await context.AccountBalance.get(delegatorBalanceId); + const delegatedValue = storedBalance?.balance ?? 0n; - // Pre-compute address lists for flag determination (normalized to checksum) const { cex, dex, lending, burning } = addressSets ?? { cex: createAddressSet(Object.values(CEXAddresses[daoId] || {})), dex: createAddressSet(Object.values(DEXAddresses[daoId] || {})), @@ -90,100 +68,90 @@ export const delegateChanged = async ( burning: createAddressSet(Object.values(BurningAddresses[daoId] || {})), }; - // Determine flags for the delegation const isCex = cex.has(normalizedDelegator) || cex.has(normalizedDelegate); const isDex = dex.has(normalizedDelegator) || dex.has(normalizedDelegate); const isLending = lending.has(normalizedDelegator) || lending.has(normalizedDelegate); - const isBurning = + const isTotal = burning.has(normalizedDelegator) || burning.has(normalizedDelegate); - const isTotal = isBurning; - await context.db - .insert(delegation) - .values({ - transactionHash: txHash, - daoId, - delegateAccountId: normalizedDelegate, - delegatorAccountId: normalizedDelegator, - delegatedValue: delegatorBalance?.balance ?? 0n, - previousDelegate: getAddress(previousDelegate), - timestamp, - logIndex, - isCex, - isDex, - isLending, - isTotal, - }) - .onConflictDoUpdate((current) => ({ - delegatedValue: - current.delegatedValue + (delegatorBalance?.balance ?? 0n), - })); - - await context.db - .insert(accountBalance) - .values({ - accountId: normalizedDelegator, - tokenId: getAddress(tokenId), - delegate: normalizedDelegate, - balance: BigInt(0), - }) - .onConflictDoUpdate({ - delegate: normalizedDelegate, - }); + const delegationId = `${txHash}-${normalizedDelegator}-${normalizedDelegate}`; + const existingDelegation = await context.Delegation.get(delegationId); + context.Delegation.set({ + id: delegationId, + transactionHash: txHash, + daoId, + delegateAccountId: normalizedDelegate, + delegatorAccountId: normalizedDelegator, + delegatedValue: (existingDelegation?.delegatedValue ?? 0n) + delegatedValue, + previousDelegate: getAddress(previousDelegate), + timestamp, + logIndex, + isCex, + isDex, + isLending, + isTotal, + delegationType: undefined, + }); + + // Update delegator's balance record to point to new delegate + const existingBalance = await context.AccountBalance.get(delegatorBalanceId); + context.AccountBalance.set({ + id: delegatorBalanceId, + accountId: normalizedDelegator, + tokenId: getAddress(tokenId), + balance: existingBalance?.balance ?? 0n, + delegate: normalizedDelegate, + }); + // Decrement previous delegate's count if (previousDelegate !== zeroAddress) { - await context.db - .insert(accountPower) - .values({ - accountId: getAddress(previousDelegate), - daoId, - }) - .onConflictDoUpdate((current) => ({ - delegationsCount: Math.max(0, current.delegationsCount - 1), - })); + const prevPowerId = getAddress(previousDelegate); + const prevPower = await context.AccountPower.get(prevPowerId); + context.AccountPower.set({ + id: prevPowerId, + accountId: prevPowerId, + daoId, + votingPower: prevPower?.votingPower ?? 0n, + votesCount: prevPower?.votesCount ?? 0, + proposalsCount: prevPower?.proposalsCount ?? 0, + delegationsCount: Math.max(0, (prevPower?.delegationsCount ?? 0) - 1), + lastVoteTimestamp: prevPower?.lastVoteTimestamp ?? 0n, + }); } - await context.db - .insert(accountPower) - .values({ - accountId: normalizedDelegate, - daoId, - delegationsCount: 1, - }) - .onConflictDoUpdate((current) => ({ - delegationsCount: current.delegationsCount + 1, - })); + // Increment new delegate's count + const delegatePowerId = normalizedDelegate; + const delegatePower = await context.AccountPower.get(delegatePowerId); + context.AccountPower.set({ + id: delegatePowerId, + accountId: normalizedDelegate, + daoId, + votingPower: delegatePower?.votingPower ?? 0n, + votesCount: delegatePower?.votesCount ?? 0, + proposalsCount: delegatePower?.proposalsCount ?? 0, + delegationsCount: (delegatePower?.delegationsCount ?? 0) + 1, + lastVoteTimestamp: delegatePower?.lastVoteTimestamp ?? 0n, + }); - await context.db.insert(feedEvent).values({ + context.FeedEvent.set({ + id: `${txHash}-${logIndex}`, txHash, logIndex, - type: "DELEGATION", - value: delegatorBalance?.balance ?? 0n, + eventType: "DELEGATION" as EventType_t, + value: delegatedValue, timestamp, metadata: { delegator: normalizedDelegator, delegate: normalizedDelegate, previousDelegate: getAddress(previousDelegate), - amount: delegatorBalance?.balance ?? 0n, + amount: delegatedValue.toString(), }, }); }; -/** - * ### Creates: - * - New `Account` record (for delegate if it doesn't exist) - * - New `VotingPowerHistory` record with voting power change details - * - New `AccountPower` record (if delegate doesn't have one for this DAO) - * - New daily metric records (via `storeDailyBucket`) - * - * ### Updates: - * - `AccountPower`: Sets the delegate's current voting power to new balance - * - `Token`: Adjusts delegated supply by the balance delta - * - Daily bucket metrics for delegated supply tracking - */ export const delegatedVotesChanged = async ( - context: Context, + context: handlerContext, daoId: DaoIdEnum, args: { delegate: Address; @@ -201,43 +169,43 @@ export const delegatedVotesChanged = async ( await ensureAccountExists(context, delegate); - const delta = newBalance - oldBalance; - const deltaMod = delta > 0n ? delta : -delta; + const diff = newBalance - oldBalance; + const deltaMod = diff > 0n ? diff : -diff; + + context.VotingPowerHistory.set({ + id: `${txHash}-${normalizedDelegate}-${logIndex}`, + daoId, + transactionHash: txHash, + accountId: normalizedDelegate, + votingPower: newBalance, + delta: diff, + deltaMod, + timestamp, + logIndex, + }); - await context.db - .insert(votingPowerHistory) - .values({ - daoId, - transactionHash: txHash, - accountId: normalizedDelegate, - votingPower: newBalance, - delta, - deltaMod, - timestamp, - logIndex, - }) - .onConflictDoNothing(); - - await context.db - .insert(accountPower) - .values({ - accountId: normalizedDelegate, - daoId, - votingPower: newBalance, - }) - .onConflictDoUpdate(() => ({ - votingPower: newBalance, - })); + const existingPower = await context.AccountPower.get(normalizedDelegate); + context.AccountPower.set({ + id: normalizedDelegate, + accountId: normalizedDelegate, + daoId, + votingPower: newBalance, + votesCount: existingPower?.votesCount ?? 0, + proposalsCount: existingPower?.proposalsCount ?? 0, + delegationsCount: existingPower?.delegationsCount ?? 0, + lastVoteTimestamp: existingPower?.lastVoteTimestamp ?? 0n, + }); - await context.db.insert(feedEvent).values({ + context.FeedEvent.set({ + id: `${txHash}-${logIndex}`, txHash, logIndex, - type: "DELEGATION_VOTES_CHANGED", + eventType: "DELEGATION_VOTES_CHANGED" as EventType_t, value: deltaMod, timestamp, metadata: { - delta, - deltaMod, + delta: diff.toString(), + deltaMod: deltaMod.toString(), delegate: normalizedDelegate, }, }); diff --git a/apps/indexer/src/eventHandlers/index.ts b/apps/indexer/src/eventHandlers/index.ts index 93374519b..a5e8d7c14 100644 --- a/apps/indexer/src/eventHandlers/index.ts +++ b/apps/indexer/src/eventHandlers/index.ts @@ -1,3 +1,3 @@ -export * from "./transfer"; -export * from "./delegation"; -export * from "./voting"; +export * from "./transfer.ts"; +export * from "./delegation.ts"; +export * from "./voting.ts"; diff --git a/apps/indexer/src/eventHandlers/metrics/circulating.ts b/apps/indexer/src/eventHandlers/metrics/circulating.ts index cce3b94d8..24c7b2479 100644 --- a/apps/indexer/src/eventHandlers/metrics/circulating.ts +++ b/apps/indexer/src/eventHandlers/metrics/circulating.ts @@ -1,32 +1,27 @@ -import { Address, getAddress } from "viem"; -import { token } from "ponder:schema"; -import { Context } from "ponder:registry"; +import type { Address } from "viem"; +import { getAddress } from "viem"; +import type { handlerContext } from "../../../generated/index.js"; -import { storeDailyBucket } from "../shared"; -import { MetricTypesEnum } from "@/lib/constants"; +import { storeDailyBucket } from "../shared.ts"; +import { MetricTypesEnum } from "../../lib/constants.ts"; export const updateCirculatingSupply = async ( - context: Context, + context: handlerContext, daoId: string, tokenAddress: Address, timestamp: bigint, ) => { - let currentCirculatingSupply = 0n; - let newCirculatingSupply = 0n; - await context.db - .update(token, { id: getAddress(tokenAddress) }) - .set((current) => { - currentCirculatingSupply = current.circulatingSupply; - newCirculatingSupply = - current.totalSupply - current.treasury - current.nonCirculatingSupply; - return { - circulatingSupply: newCirculatingSupply, - }; - }); + const tokenId = getAddress(tokenAddress); + const token = await context.Token.get(tokenId); + if (!token) return false; - if (currentCirculatingSupply === newCirculatingSupply) { - return false; - } + const currentCirculatingSupply = token.circulatingSupply; + const newCirculatingSupply = + token.totalSupply - token.treasury - token.nonCirculatingSupply; + + if (currentCirculatingSupply === newCirculatingSupply) return false; + + context.Token.set({ ...token, circulatingSupply: newCirculatingSupply }); await storeDailyBucket( context, diff --git a/apps/indexer/src/eventHandlers/metrics/delegated.ts b/apps/indexer/src/eventHandlers/metrics/delegated.ts index d41c64f67..675d39025 100644 --- a/apps/indexer/src/eventHandlers/metrics/delegated.ts +++ b/apps/indexer/src/eventHandlers/metrics/delegated.ts @@ -1,28 +1,26 @@ -import { Address, getAddress } from "viem"; -import { token } from "ponder:schema"; -import { Context } from "ponder:registry"; +import type { Address } from "viem"; +import { getAddress } from "viem"; +import type { handlerContext } from "../../../generated/index.js"; -import { DaoIdEnum } from "@/lib/enums"; -import { MetricTypesEnum } from "@/lib/constants"; -import { storeDailyBucket } from "@/eventHandlers/shared"; +import { DaoIdEnum } from "../../lib/enums.ts"; +import { MetricTypesEnum } from "../../lib/constants.ts"; +import { storeDailyBucket } from "../shared.ts"; export const updateDelegatedSupply = async ( - context: Context, + context: handlerContext, daoId: DaoIdEnum, tokenId: Address, amount: bigint, timestamp: bigint, ) => { - let currentDelegatedSupply = 0n; + const normalizedId = getAddress(tokenId); + const token = await context.Token.get(normalizedId); + if (!token) return; - const { delegatedSupply: newDelegatedSupply } = await context.db - .update(token, { id: getAddress(tokenId) }) - .set((current) => { - currentDelegatedSupply = current.delegatedSupply; - return { - delegatedSupply: current.delegatedSupply + amount, - }; - }); + const currentDelegatedSupply = token.delegatedSupply; + const newDelegatedSupply = currentDelegatedSupply + amount; + + context.Token.set({ ...token, delegatedSupply: newDelegatedSupply }); await storeDailyBucket( context, diff --git a/apps/indexer/src/eventHandlers/metrics/index.ts b/apps/indexer/src/eventHandlers/metrics/index.ts index b6dcd69be..a4126ee00 100644 --- a/apps/indexer/src/eventHandlers/metrics/index.ts +++ b/apps/indexer/src/eventHandlers/metrics/index.ts @@ -1,4 +1,4 @@ -export * from "./delegated"; -export * from "./total"; -export * from "./supply"; -export * from "./circulating"; +export * from "./delegated.ts"; +export * from "./total.ts"; +export * from "./supply.ts"; +export * from "./circulating.ts"; diff --git a/apps/indexer/src/eventHandlers/metrics/supply.ts b/apps/indexer/src/eventHandlers/metrics/supply.ts index 2067b7058..ecac65839 100644 --- a/apps/indexer/src/eventHandlers/metrics/supply.ts +++ b/apps/indexer/src/eventHandlers/metrics/supply.ts @@ -1,12 +1,16 @@ -import { Address, getAddress } from "viem"; -import { token } from "ponder:schema"; -import { Context } from "ponder:registry"; +import type { Address } from "viem"; +import { getAddress } from "viem"; +import type { handlerContext } from "../../../generated/index.js"; -import { AddressCollection, storeDailyBucket, toAddressSet } from "../shared"; -import { MetricTypesEnum } from "@/lib/constants"; +import { + AddressCollection, + storeDailyBucket, + toAddressSet, +} from "../shared.ts"; +import { MetricTypesEnum } from "../../lib/constants.ts"; export const updateSupplyMetric = async ( - context: Context, + context: handlerContext, supplyField: | "lendingSupply" | "cexSupply" @@ -27,18 +31,16 @@ export const updateSupplyMetric = async ( const isFromRelevant = normalizedAddressList.has(getAddress(from)); if ((isToRelevant || isFromRelevant) && !(isToRelevant && isFromRelevant)) { - let currentSupply: bigint = 0n; - - const { [supplyField]: newSupply } = await context.db - .update(token, { id: getAddress(tokenAddress) }) - .set((current) => { - currentSupply = current[supplyField]; - return { - [supplyField]: isToRelevant - ? current[supplyField] + value - : current[supplyField] - value, - }; - }); + const tokenId = getAddress(tokenAddress); + const token = await context.Token.get(tokenId); + if (!token) return false; + + const currentSupply = token[supplyField]; + const newSupply = isToRelevant + ? currentSupply + value + : currentSupply - value; + + context.Token.set({ ...token, [supplyField]: newSupply }); await storeDailyBucket( context, diff --git a/apps/indexer/src/eventHandlers/metrics/total.ts b/apps/indexer/src/eventHandlers/metrics/total.ts index 7019c9e0e..d80f01a61 100644 --- a/apps/indexer/src/eventHandlers/metrics/total.ts +++ b/apps/indexer/src/eventHandlers/metrics/total.ts @@ -1,17 +1,17 @@ -import { Address, getAddress } from "viem"; -import { token } from "ponder:schema"; -import { Context } from "ponder:registry"; +import type { Address } from "viem"; +import { getAddress } from "viem"; +import type { handlerContext } from "../../../generated/index.js"; -import { DaoIdEnum } from "@/lib/enums"; -import { MetricTypesEnum } from "@/lib/constants"; +import { DaoIdEnum } from "../../lib/enums.ts"; +import { MetricTypesEnum } from "../../lib/constants.ts"; import { AddressCollection, storeDailyBucket, toAddressSet, -} from "@/eventHandlers/shared"; +} from "../shared.ts"; export const updateTotalSupply = async ( - context: Context, + context: handlerContext, addressList: AddressCollection, metricType: MetricTypesEnum, from: Address, @@ -30,19 +30,16 @@ export const updateTotalSupply = async ( if (isTotalSupplyTransaction) { const isBurningTokens = normalizedAddressList.has(getAddress(to)); - let currentTotalSupply = 0n; - const newTotalSupply = ( - await context.db - .update(token, { id: getAddress(tokenAddress) }) - .set((row) => { - currentTotalSupply = row.totalSupply; - return { - totalSupply: isBurningTokens - ? row.totalSupply - value - : row.totalSupply + value, - }; - }) - ).totalSupply; + const tokenId = getAddress(tokenAddress); + const token = await context.Token.get(tokenId); + if (!token) return false; + + const currentTotalSupply = token.totalSupply; + const newTotalSupply = isBurningTokens + ? currentTotalSupply - value + : currentTotalSupply + value; + + context.Token.set({ ...token, totalSupply: newTotalSupply }); await storeDailyBucket( context, diff --git a/apps/indexer/src/eventHandlers/shared.ts b/apps/indexer/src/eventHandlers/shared.ts index 8efc79295..5771e329b 100644 --- a/apps/indexer/src/eventHandlers/shared.ts +++ b/apps/indexer/src/eventHandlers/shared.ts @@ -1,10 +1,22 @@ -import { Address, getAddress } from "viem"; -import { Context } from "ponder:registry"; -import { account, daoMetricsDayBucket, transaction } from "ponder:schema"; +import type { Address } from "viem"; +import { getAddress } from "viem"; +import type { handlerContext } from "../../generated/index.js"; +import type { MetricType_t } from "../../generated/src/db/Enums.gen.ts"; -import { MetricTypesEnum } from "@/lib/constants"; -import { delta, max, min } from "@/lib/utils"; -import { truncateTimestampToMidnight } from "@/lib/date-helpers"; +import { MetricTypesEnum } from "../lib/constants.ts"; +import { delta, max, min } from "../lib/utils.ts"; +import { truncateTimestampToMidnight } from "../lib/date-helpers.ts"; + +const METRIC_TYPE_MAP: Record = { + [MetricTypesEnum.TOTAL_SUPPLY]: "total", + [MetricTypesEnum.DELEGATED_SUPPLY]: "delegated", + [MetricTypesEnum.CEX_SUPPLY]: "cex", + [MetricTypesEnum.DEX_SUPPLY]: "dex", + [MetricTypesEnum.LENDING_SUPPLY]: "lending", + [MetricTypesEnum.CIRCULATING_SUPPLY]: "circulating", + [MetricTypesEnum.TREASURY]: "treasury", + [MetricTypesEnum.NON_CIRCULATING_SUPPLY]: "non_circulating", +}; export type AddressCollection = readonly Address[] | ReadonlySet
; @@ -15,7 +27,7 @@ const normalizeAddressCollection = ( return [...new Set(addresses.map((address) => getAddress(address)))]; } - return [...addresses]; + return [...(addresses as ReadonlySet
)]; }; export const createAddressSet = ( @@ -34,37 +46,28 @@ export const toAddressSet = ( }; export const ensureAccountExists = async ( - context: Context, + context: handlerContext, address: Address, ): Promise => { - await context.db - .insert(account) - .values({ - id: getAddress(address), - }) - .onConflictDoNothing(); + await context.Account.getOrCreate({ id: getAddress(address) }); }; /** - * Helper function to ensure multiple accounts exist in parallel + * Helper function to ensure multiple accounts exist */ export const ensureAccountsExist = async ( - context: Context, + context: handlerContext, addresses: Address[], ): Promise => { - const normalizedAddresses = normalizeAddressCollection(addresses); - if (normalizedAddresses.length === 0) { - return; - } - - await context.db - .insert(account) - .values(normalizedAddresses.map((id) => ({ id }))) - .onConflictDoNothing(); + const normalized = normalizeAddressCollection(addresses); + if (normalized.length === 0) return; + await Promise.all( + normalized.map((id) => context.Account.getOrCreate({ id })), + ); }; export const storeDailyBucket = async ( - context: Context, + context: handlerContext, metricType: MetricTypesEnum, currentValue: bigint, newValue: bigint, @@ -72,42 +75,51 @@ export const storeDailyBucket = async ( timestamp: bigint, tokenAddress: Address, ) => { - const volume = delta(newValue, currentValue); - await context.db - .insert(daoMetricsDayBucket) - .values({ - date: BigInt(truncateTimestampToMidnight(Number(timestamp))), - tokenId: getAddress(tokenAddress), - metricType, + const vol = delta(newValue, currentValue); + const date = BigInt(truncateTimestampToMidnight(Number(timestamp))); + const tokenId = getAddress(tokenAddress); + const id = `${date}-${tokenId}-${metricType}`; + + const existing = await context.DaoMetricsDayBucket.get(id); + if (existing) { + context.DaoMetricsDayBucket.set({ + ...existing, + average: + (existing.average * BigInt(existing.count) + newValue) / + BigInt(existing.count + 1), + high: max(newValue, existing.high), + low: min(newValue, existing.low), + closeValue: newValue, + volume: existing.volume + vol, + count: existing.count + 1, + lastUpdate: timestamp, + }); + } else { + context.DaoMetricsDayBucket.set({ + id, + date, + tokenId, + metricType: METRIC_TYPE_MAP[metricType], daoId, average: newValue, - open: newValue, + openValue: newValue, high: newValue, low: newValue, - close: newValue, - volume, + closeValue: newValue, + volume: vol, count: 1, lastUpdate: timestamp, - }) - .onConflictDoUpdate((row) => ({ - average: - (row.average * BigInt(row.count) + newValue) / BigInt(row.count + 1), - high: max(newValue, row.high), - low: min(newValue, row.low), - close: newValue, - volume: row.volume + volume, - count: row.count + 1, - lastUpdate: timestamp, - })); + }); + } }; export const handleTransaction = async ( - context: Context, + context: handlerContext, transactionHash: string, from: Address, to: Address, timestamp: bigint, - addresses: AddressCollection, // The addresses involved in this event + addresses: AddressCollection, { cex = [], dex = [], @@ -118,12 +130,7 @@ export const handleTransaction = async ( dex?: AddressCollection; lending?: AddressCollection; burning?: AddressCollection; - } = { - cex: [], - dex: [], - lending: [], - burning: [], - }, + } = {}, ) => { const normalizedAddresses = normalizeAddressCollection(addresses); const normalizedCex = toAddressSet(cex); @@ -144,22 +151,16 @@ export const handleTransaction = async ( return; } - await context.db - .insert(transaction) - .values({ - transactionHash, - fromAddress: getAddress(from), - toAddress: getAddress(to), - timestamp, - isCex, - isDex, - isLending, - isTotal, - }) - .onConflictDoUpdate((existing) => ({ - isCex: existing.isCex || isCex, - isDex: existing.isDex || isDex, - isLending: existing.isLending || isLending, - isTotal: existing.isTotal || isTotal, - })); + const existing = await context.Transaction.get(transactionHash); + context.Transaction.set({ + id: transactionHash, + transactionHash, + fromAddress: getAddress(from), + toAddress: getAddress(to), + timestamp, + isCex: (existing?.isCex ?? false) || isCex, + isDex: (existing?.isDex ?? false) || isDex, + isLending: (existing?.isLending ?? false) || isLending, + isTotal: (existing?.isTotal ?? false) || isTotal, + }); }; diff --git a/apps/indexer/src/eventHandlers/transfer.ts b/apps/indexer/src/eventHandlers/transfer.ts index d72ed1664..f25566823 100644 --- a/apps/indexer/src/eventHandlers/transfer.ts +++ b/apps/indexer/src/eventHandlers/transfer.ts @@ -1,37 +1,18 @@ -import { Context } from "ponder:registry"; -import { - accountBalance, - balanceHistory, - feedEvent, - transfer, -} from "ponder:schema"; -import { Address, getAddress, Hex, zeroAddress } from "viem"; +import type { handlerContext } from "../../generated/index.js"; +import type { EventType_t } from "../../generated/src/db/Enums.gen.ts"; +import type { Address, Hex } from "viem"; +import { getAddress, zeroAddress } from "viem"; -import { DaoIdEnum } from "@/lib/enums"; +import { DaoIdEnum } from "../lib/enums.ts"; -import { AddressCollection, ensureAccountsExist, toAddressSet } from "./shared"; +import { + AddressCollection, + ensureAccountsExist, + toAddressSet, +} from "./shared.ts"; -/** - * ### Creates: - * - New `Account` records (for sender and receiver if they don't exist) - * - New `accountBalance` record (for receiver if it doesn't exist) - * - New `accountBalance` record (for sender if it doesn't exist and not minting) - * - New `transfer` record with transaction details and classification flags - * - New daily metric records for supply tracking (via `updateSupplyMetric` calls) - * - * ### Updates: - * - `accountBalance`: Increments receiver's token balance by transfer value - * - `accountBalance`: Decrements sender's token balance by transfer value (if not minting from zero address) - * - `Token`: Adjusts lending supply based on transfers involving lending addresses - * - `Token`: Adjusts CEX supply based on transfers involving centralized exchange addresses - * - `Token`: Adjusts DEX supply based on transfers involving decentralized exchange addresses - * - `Token`: Adjusts treasury balance based on transfers involving treasury addresses - * - `Token`: Adjusts total supply based on transfers involving burning addresses - * - `Token`: Recalculates circulating supply after all supply changes - * - Daily bucket metrics for all supply types (lending, CEX, DEX, treasury, total, circulating) - */ export const tokenTransfer = async ( - context: Context, + context: handlerContext, daoId: DaoIdEnum, args: { from: Address; @@ -70,58 +51,59 @@ export const tokenTransfer = async ( await ensureAccountsExist(context, [from, to]); - const { balance: currentReceiverBalance } = await context.db - .insert(accountBalance) - .values({ - accountId: normalizedTo, + // Upsert receiver balance and track current balance for history + const receiverBalanceId = `${normalizedTo}-${normalizedTokenId}`; + const existingReceiverBalance = + await context.AccountBalance.get(receiverBalanceId); + const currentReceiverBalance = existingReceiverBalance + ? existingReceiverBalance.balance + value + : value; + context.AccountBalance.set({ + id: receiverBalanceId, + accountId: normalizedTo, + tokenId: normalizedTokenId, + balance: currentReceiverBalance, + delegate: existingReceiverBalance?.delegate ?? zeroAddress, + }); + + context.BalanceHistory.set({ + id: `${transactionHash}-${normalizedTo}-${logIndex}`, + daoId, + transactionHash, + accountId: normalizedTo, + balance: currentReceiverBalance, + delta: value, + deltaMod: value > 0n ? value : -value, + timestamp, + logIndex, + }); + + if (from !== zeroAddress) { + const senderBalanceId = `${normalizedFrom}-${normalizedTokenId}`; + const existingSenderBalance = + await context.AccountBalance.get(senderBalanceId); + const currentSenderBalance = existingSenderBalance + ? existingSenderBalance.balance - value + : -value; + context.AccountBalance.set({ + id: senderBalanceId, + accountId: normalizedFrom, tokenId: normalizedTokenId, - balance: value, - delegate: zeroAddress, - }) - .onConflictDoUpdate((current) => ({ - balance: current.balance + value, - })); + balance: currentSenderBalance, + delegate: existingSenderBalance?.delegate ?? zeroAddress, + }); - await context.db - .insert(balanceHistory) - .values({ + context.BalanceHistory.set({ + id: `${transactionHash}-${normalizedFrom}-${logIndex}`, daoId, - transactionHash: transactionHash, - accountId: normalizedTo, - balance: currentReceiverBalance, - delta: value, + transactionHash, + accountId: normalizedFrom, + balance: currentSenderBalance, + delta: -value, deltaMod: value > 0n ? value : -value, timestamp, logIndex, - }) - .onConflictDoNothing(); - - if (from !== zeroAddress) { - const { balance: currentSenderBalance } = await context.db - .insert(accountBalance) - .values({ - accountId: normalizedFrom, - tokenId: normalizedTokenId, - balance: -value, - delegate: zeroAddress, - }) - .onConflictDoUpdate((current) => ({ - balance: current.balance - value, - })); - - await context.db - .insert(balanceHistory) - .values({ - daoId, - transactionHash: transactionHash, - accountId: normalizedFrom, - balance: currentSenderBalance, - delta: -value, - deltaMod: value > 0n ? value : -value, - timestamp, - logIndex, - }) - .onConflictDoNothing(); + }); } const normalizedCex = toAddressSet(cex); @@ -129,43 +111,39 @@ export const tokenTransfer = async ( const normalizedLending = toAddressSet(lending); const normalizedBurning = toAddressSet(burning); - await context.db - .insert(transfer) - .values({ - transactionHash, - daoId, - tokenId: normalizedTokenId, - amount: value, - fromAccountId: normalizedFrom, - toAccountId: normalizedTo, - timestamp, - logIndex, - isCex: - normalizedCex.has(normalizedFrom) || normalizedCex.has(normalizedTo), - isDex: - normalizedDex.has(normalizedFrom) || normalizedDex.has(normalizedTo), - isLending: - normalizedLending.has(normalizedFrom) || - normalizedLending.has(normalizedTo), - isTotal: - normalizedBurning.has(normalizedFrom) || - normalizedBurning.has(normalizedTo), - }) - .onConflictDoUpdate((current) => ({ - amount: current.amount + value, - })); + const transferId = `${transactionHash}-${normalizedFrom}-${normalizedTo}`; + const existingTransfer = await context.Transfer.get(transferId); + context.Transfer.set({ + id: transferId, + transactionHash, + daoId, + tokenId: normalizedTokenId, + amount: (existingTransfer?.amount ?? 0n) + value, + fromAccountId: normalizedFrom, + toAccountId: normalizedTo, + timestamp, + logIndex, + isCex: normalizedCex.has(normalizedFrom) || normalizedCex.has(normalizedTo), + isDex: normalizedDex.has(normalizedFrom) || normalizedDex.has(normalizedTo), + isLending: + normalizedLending.has(normalizedFrom) || + normalizedLending.has(normalizedTo), + isTotal: + normalizedBurning.has(normalizedFrom) || + normalizedBurning.has(normalizedTo), + }); - // Insert feed event for activity feed - await context.db.insert(feedEvent).values({ + context.FeedEvent.set({ + id: `${transactionHash}-${logIndex}`, txHash: transactionHash, logIndex, - type: "TRANSFER", + eventType: "TRANSFER" as EventType_t, value, timestamp, metadata: { from: normalizedFrom, to: normalizedTo, - amount: value, + amount: value.toString(), }, }); }; diff --git a/apps/indexer/src/eventHandlers/voting.ts b/apps/indexer/src/eventHandlers/voting.ts index c2ff06422..d3b82ad26 100644 --- a/apps/indexer/src/eventHandlers/voting.ts +++ b/apps/indexer/src/eventHandlers/voting.ts @@ -1,32 +1,14 @@ -import { Context } from "ponder:registry"; -import { - accountPower, - feedEvent, - proposalsOnchain, - votesOnchain, -} from "ponder:schema"; -import { Address, getAddress, Hex } from "viem"; +import type { handlerContext } from "../../generated/index.js"; +import type { EventType_t } from "../../generated/src/db/Enums.gen.ts"; +import type { Address, Hex } from "viem"; +import { getAddress } from "viem"; -import { ProposalStatus } from "@/lib/constants"; +import { ProposalStatus } from "../lib/constants.ts"; -import { ensureAccountExists } from "./shared"; +import { ensureAccountExists } from "./shared.ts"; -/** - * ### Creates: - * - New `Account` record (for voter if it doesn't exist) - * - New `AccountPower` record (if voter doesn't have one for this DAO) - * - New `votesOnchain` record with vote details (transaction hash, support, voting power, reason) - * - * ### Updates: - * - `AccountPower`: Increments voter's total vote count by 1 - * - `AccountPower`: Sets last vote timestamp to current vote timestamp - * - `AccountPower`: Sets first vote timestamp (only if voter has never voted before) - * - `proposalsOnchain`: Increments `againstVotes` if support is 0 (against) - * - `proposalsOnchain`: Increments `forVotes` if support is 1 (for) - * - `proposalsOnchain`: Increments `abstainVotes` if support is 2 (abstain) - */ export const voteCast = async ( - context: Context, + context: handlerContext, daoId: string, args: { proposalId: string; @@ -52,26 +34,26 @@ export const voteCast = async ( await ensureAccountExists(context, voter); - // Update account power with vote statistics - await context.db - .insert(accountPower) - .values({ - accountId: getAddress(voter), - daoId, - votesCount: 1, - lastVoteTimestamp: timestamp, - }) - .onConflictDoUpdate((current) => ({ - votesCount: current.votesCount + 1, - lastVoteTimestamp: timestamp, - })); + const normalizedVoter = getAddress(voter); + const powerId = normalizedVoter; + const existingPower = await context.AccountPower.get(powerId); + context.AccountPower.set({ + id: powerId, + accountId: normalizedVoter, + daoId, + votingPower: existingPower?.votingPower ?? 0n, + votesCount: (existingPower?.votesCount ?? 0) + 1, + proposalsCount: existingPower?.proposalsCount ?? 0, + delegationsCount: existingPower?.delegationsCount ?? 0, + lastVoteTimestamp: timestamp, + }); - // Create vote record - await context.db.insert(votesOnchain).values({ - txHash: txHash, + context.VoteOnchain.set({ + id: `${normalizedVoter}-${proposalId}`, + txHash, daoId, proposalId, - voterAccountId: getAddress(voter), + voterAccountId: normalizedVoter, support: support.toString(), votingPower, reason, @@ -79,61 +61,49 @@ export const voteCast = async ( }); // Update proposal vote totals - await context.db - .update(proposalsOnchain, { id: proposalId }) - .set((current) => ({ - againstVotes: current.againstVotes + (support === 0 ? votingPower : 0n), - forVotes: current.forVotes + (support === 1 ? votingPower : 0n), - abstainVotes: current.abstainVotes + (support === 2 ? votingPower : 0n), - })); - - const proposal = await context.db.find(proposalsOnchain, { id: proposalId }); + const proposal = await context.ProposalOnchain.get(proposalId); + if (proposal) { + context.ProposalOnchain.set({ + ...proposal, + againstVotes: proposal.againstVotes + (support === 0 ? votingPower : 0n), + forVotes: proposal.forVotes + (support === 1 ? votingPower : 0n), + abstainVotes: proposal.abstainVotes + (support === 2 ? votingPower : 0n), + }); + } - await context.db.insert(feedEvent).values({ + context.FeedEvent.set({ + id: `${txHash}-${logIndex}`, txHash, logIndex, - type: "VOTE", + eventType: "VOTE" as EventType_t, value: votingPower, timestamp, metadata: { - voter: getAddress(voter), + voter: normalizedVoter, reason, support, - votingPower, + votingPower: votingPower.toString(), proposalId, - title: proposal?.title ?? undefined, + title: proposal?.title ?? null, }, }); }; const MAX_TITLE_LENGTH = 200; -/** - * Extracts a proposal title from a markdown description. - * - * Strategy: - * 1. Normalize literal `\n` sequences to real newlines (some proposers - * submit descriptions with escaped newlines). - * 2. If the first non-empty line is an H1 (`# Title`), use it. - * 3. Otherwise, use the first non-empty line that is not a section header - * (H2+), truncated to MAX_TITLE_LENGTH characters. - */ function parseProposalTitle(description: string): string { - // Normalize literal "\n" (two chars) into real newlines const normalized = description.replace(/\\n/g, "\n"); const lines = normalized.split("\n"); - // Pass 1: look for an H1 among leading lines (before any content) for (const line of lines) { const trimmed = line.trim(); if (!trimmed) continue; if (/^# /.test(trimmed)) { return trimmed.replace(/^# +/, ""); } - break; // stop at first non-empty, non-H1 line + break; } - // Pass 2: no H1 found — use first non-empty, non-header line for (const line of lines) { const trimmed = line.trim(); if (!trimmed || /^#{1,6}\s/.test(trimmed)) continue; @@ -145,21 +115,8 @@ function parseProposalTitle(description: string): string { return ""; } -/** - * ### Creates: - * - New `Account` record (for proposer if it doesn't exist) - * - New `proposalsOnchain` record with proposal details (targets, values, signatures, calldatas, blocks, description, status) - * - New `AccountPower` record (if proposer doesn't have one for this DAO) - * - * ### Updates: - * - `AccountPower`: Increments proposer's total proposals count by 1 - * - * ### Calculates: - * - Proposal end timestamp based on block delta and average block time - * - Sets initial proposal status to PENDING - */ export const proposalCreated = async ( - context: Context, + context: handlerContext, daoId: string, blockTime: number, args: { @@ -199,13 +156,14 @@ export const proposalCreated = async ( const title = parseProposalTitle(description); const blockDelta = parseInt(endBlock) - Number(blockNumber); - await context.db.insert(proposalsOnchain).values({ + + context.ProposalOnchain.set({ id: proposalId, txHash, daoId, proposerAccountId: getAddress(proposer), targets: targets.map((a) => getAddress(a)), - values, + values: values.map((v) => v.toString()), signatures, calldatas, startBlock: parseInt(startBlock), @@ -217,56 +175,54 @@ export const proposalCreated = async ( status: ProposalStatus.PENDING, endTimestamp: timestamp + BigInt(blockDelta * blockTime), proposalType: args.proposalType, + forVotes: 0n, + againstVotes: 0n, + abstainVotes: 0n, }); - // Update proposer's proposal count - const { votingPower: proposerVotingPower } = await context.db - .insert(accountPower) - .values({ - accountId: getAddress(proposer), - daoId, - proposalsCount: 1, - }) - .onConflictDoUpdate((current) => ({ - proposalsCount: current.proposalsCount + 1, - })); + const powerId = getAddress(proposer); + const existingPower = await context.AccountPower.get(powerId); + const proposerVotingPower = existingPower?.votingPower ?? 0n; + context.AccountPower.set({ + id: powerId, + accountId: powerId, + daoId, + votingPower: proposerVotingPower, + votesCount: existingPower?.votesCount ?? 0, + proposalsCount: (existingPower?.proposalsCount ?? 0) + 1, + delegationsCount: existingPower?.delegationsCount ?? 0, + lastVoteTimestamp: existingPower?.lastVoteTimestamp ?? 0n, + }); - // Insert feed event for activity feed - // Proposals are always high relevance as they are significant governance actions - await context.db.insert(feedEvent).values({ + context.FeedEvent.set({ + id: `${txHash}-${logIndex}`, txHash, logIndex, - type: "PROPOSAL", + eventType: "PROPOSAL" as EventType_t, + value: 0n, timestamp, metadata: { id: proposalId, proposer: getAddress(proposer), - votingPower: proposerVotingPower, + votingPower: proposerVotingPower.toString(), title, }, }); }; -/** - * ### Updates: - * - `proposalsOnchain`: Sets the proposal status to the provided status value - */ export const updateProposalStatus = async ( - context: Context, + context: handlerContext, proposalId: string, status: string, ) => { - await context.db.update(proposalsOnchain, { id: proposalId }).set({ - status, - }); + const proposal = await context.ProposalOnchain.get(proposalId); + if (proposal) { + context.ProposalOnchain.set({ ...proposal, status }); + } }; -/** - * ### Updates: - * - `proposalsOnchain`: Sets the new deadline (endBlock) and endTimestamp - */ export const proposalExtended = async ( - context: Context, + context: handlerContext, proposalId: string, blockTime: number, extendedDeadline: bigint, @@ -274,32 +230,32 @@ export const proposalExtended = async ( logIndex: number, timestamp: bigint, ) => { - let endTimestamp: bigint | undefined; + const proposal = await context.ProposalOnchain.get(proposalId); + if (!proposal) return; - await context.db.update(proposalsOnchain, { id: proposalId }).set((row) => { - endTimestamp = - row.endTimestamp + - BigInt((Number(extendedDeadline) - row.endBlock) * blockTime); - return { - row, - endBlock: Number(extendedDeadline), - endTimestamp, - }; - }); + const endTimestamp = + proposal.endTimestamp + + BigInt((Number(extendedDeadline) - proposal.endBlock) * blockTime); - const proposal = await context.db.find(proposalsOnchain, { id: proposalId }); + context.ProposalOnchain.set({ + ...proposal, + endBlock: Number(extendedDeadline), + endTimestamp, + }); - await context.db.insert(feedEvent).values({ + context.FeedEvent.set({ + id: `${txHash}-${logIndex}`, txHash, logIndex, - type: "PROPOSAL_EXTENDED", + eventType: "PROPOSAL_EXTENDED" as EventType_t, + value: 0n, timestamp, metadata: { id: proposalId, - title: proposal?.title ?? undefined, + title: proposal.title, endBlock: Number(extendedDeadline), - endTimestamp, - proposer: getAddress(proposal!.proposerAccountId), + endTimestamp: endTimestamp.toString(), + proposer: getAddress(proposal.proposerAccountId), }, }); }; diff --git a/apps/indexer/src/lib/constants.ts b/apps/indexer/src/lib/constants.ts index 0562ff8fa..a01a4773a 100644 --- a/apps/indexer/src/lib/constants.ts +++ b/apps/indexer/src/lib/constants.ts @@ -1,6 +1,7 @@ -import { Address, zeroAddress } from "viem"; +import type { Address } from "viem"; +import { zeroAddress } from "viem"; -import { DaoIdEnum } from "./enums"; +import { DaoIdEnum } from "./enums.ts"; export const CONTRACT_ADDRESSES = { [DaoIdEnum.UNI]: { @@ -874,28 +875,34 @@ export const NonCirculatingAddresses: Record< [DaoIdEnum.SHU]: {}, }; -export enum ProposalStatus { - PENDING = "PENDING", - ACTIVE = "ACTIVE", - CANCELED = "CANCELED", - DEFEATED = "DEFEATED", - SUCCEEDED = "SUCCEEDED", - QUEUED = "QUEUED", - EXPIRED = "EXPIRED", - EXECUTED = "EXECUTED", - VETOED = "VETOED", - NO_QUORUM = "NO_QUORUM", -} +export const ProposalStatus = { + PENDING: "PENDING", + ACTIVE: "ACTIVE", + CANCELED: "CANCELED", + DEFEATED: "DEFEATED", + SUCCEEDED: "SUCCEEDED", + QUEUED: "QUEUED", + EXPIRED: "EXPIRED", + EXECUTED: "EXECUTED", + VETOED: "VETOED", + NO_QUORUM: "NO_QUORUM", +} as const; + +export type ProposalStatus = + (typeof ProposalStatus)[keyof typeof ProposalStatus]; + +export const MetricTypesEnum = { + TOTAL_SUPPLY: "TOTAL_SUPPLY", + DELEGATED_SUPPLY: "DELEGATED_SUPPLY", + CEX_SUPPLY: "CEX_SUPPLY", + DEX_SUPPLY: "DEX_SUPPLY", + LENDING_SUPPLY: "LENDING_SUPPLY", + CIRCULATING_SUPPLY: "CIRCULATING_SUPPLY", + TREASURY: "TREASURY", + NON_CIRCULATING_SUPPLY: "NON_CIRCULATING_SUPPLY", +} as const; -export enum MetricTypesEnum { - TOTAL_SUPPLY = "TOTAL_SUPPLY", - DELEGATED_SUPPLY = "DELEGATED_SUPPLY", - CEX_SUPPLY = "CEX_SUPPLY", - DEX_SUPPLY = "DEX_SUPPLY", - LENDING_SUPPLY = "LENDING_SUPPLY", - CIRCULATING_SUPPLY = "CIRCULATING_SUPPLY", - TREASURY = "TREASURY", - NON_CIRCULATING_SUPPLY = "NON_CIRCULATING_SUPPLY", -} +export type MetricTypesEnum = + (typeof MetricTypesEnum)[keyof typeof MetricTypesEnum]; export const metricTypeArray = Object.values(MetricTypesEnum); diff --git a/apps/indexer/src/lib/date-helpers.ts b/apps/indexer/src/lib/date-helpers.ts index f884e70a6..4ef8104d5 100644 --- a/apps/indexer/src/lib/date-helpers.ts +++ b/apps/indexer/src/lib/date-helpers.ts @@ -2,7 +2,7 @@ * Date and timestamp utilities for time-series data processing. */ -import { SECONDS_IN_DAY } from "./enums"; +import { SECONDS_IN_DAY } from "./enums.ts"; /** * Truncate timestamp (seconds) to midnight UTC diff --git a/apps/indexer/src/lib/enums.ts b/apps/indexer/src/lib/enums.ts index 3580fd6f3..84f040ae6 100644 --- a/apps/indexer/src/lib/enums.ts +++ b/apps/indexer/src/lib/enums.ts @@ -1,19 +1,21 @@ -export enum DaoIdEnum { - AAVE = "AAVE", - UNI = "UNI", - ENS = "ENS", - ARB = "ARB", - OP = "OP", - GTC = "GTC", - NOUNS = "NOUNS", - TEST = "TEST", - SCR = "SCR", - COMP = "COMP", - OBOL = "OBOL", - ZK = "ZK", - SHU = "SHU", - FLUID = "FLUID", - LIL_NOUNS = "LIL_NOUNS", -} +export const DaoIdEnum = { + AAVE: "AAVE", + UNI: "UNI", + ENS: "ENS", + ARB: "ARB", + OP: "OP", + GTC: "GTC", + NOUNS: "NOUNS", + TEST: "TEST", + SCR: "SCR", + COMP: "COMP", + OBOL: "OBOL", + ZK: "ZK", + SHU: "SHU", + FLUID: "FLUID", + LIL_NOUNS: "LIL_NOUNS", +} as const; + +export type DaoIdEnum = (typeof DaoIdEnum)[keyof typeof DaoIdEnum]; export const SECONDS_IN_DAY = 24 * 60 * 60; diff --git a/apps/indexer/src/lib/query-helpers.ts b/apps/indexer/src/lib/query-helpers.ts index 987cbbfa5..0d17b1c81 100644 --- a/apps/indexer/src/lib/query-helpers.ts +++ b/apps/indexer/src/lib/query-helpers.ts @@ -2,7 +2,7 @@ * Query helpers for pagination and data filtering in time-series APIs. */ -import { truncateTimestampToMidnight } from "./date-helpers"; +import { truncateTimestampToMidnight } from "./date-helpers.ts"; /** * Filter data by cutoff date with fallback to last value before cutoff. diff --git a/apps/indexer/src/lib/time-series.ts b/apps/indexer/src/lib/time-series.ts index 5776ca935..0cb1554de 100644 --- a/apps/indexer/src/lib/time-series.ts +++ b/apps/indexer/src/lib/time-series.ts @@ -4,8 +4,8 @@ * Forward-fill: Use the last known value for any missing data points. */ -import { SECONDS_IN_DAY } from "./enums"; -import { truncateTimestampToMidnight } from "./date-helpers"; +import { SECONDS_IN_DAY } from "./enums.ts"; +import { truncateTimestampToMidnight } from "./date-helpers.ts"; /** * Forward-fill sparse data across a master timeline. diff --git a/apps/indexer/tsconfig.json b/apps/indexer/tsconfig.json index c5588ac63..a7a5c1851 100644 --- a/apps/indexer/tsconfig.json +++ b/apps/indexer/tsconfig.json @@ -23,6 +23,17 @@ "@/*": ["./src/*"] } }, - "include": ["./**/*.ts"], + "ts-node": { + "compilerOptions": { + "module": "CommonJS", + "moduleResolution": "node" + } + }, + "include": [ + "src/eventHandlers/**/*.ts", + "src/lib/**/*.ts", + "src/env.ts", + "generated/**/*.ts" + ], "exclude": ["node_modules", "test"] } diff --git a/eslint.config.mjs b/eslint.config.mjs index a0f56dca2..e303951e0 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -31,6 +31,16 @@ export default [ "apps/api-gateway/schema.graphql", "**/storybook-static/**", "**/.storybook/**", + // HyperIndex: ignore generated files and old Ponder files during migration + "apps/indexer/generated/**", + "apps/indexer/src/indexer/**", + "apps/indexer/src/index.ts", + "apps/indexer/src/metrics.ts", + "apps/indexer/src/api/**", + "apps/indexer/ponder.config.ts", + "apps/indexer/ponder.schema.ts", + "apps/indexer/ponder-env.d.ts", + "apps/indexer/config/**", ], }, @@ -126,6 +136,14 @@ export default [ }, }, + // Indexer lib — allow const + type with same name (enum-as-const pattern) + { + files: ["apps/indexer/src/lib/**/*.{js,ts}"], + rules: { + "@typescript-eslint/no-redeclare": "off", + }, + }, + // API mappers - allow Zod schema + type with same name pattern { files: ["apps/api/src/mappers/**/*.{js,ts}"], diff --git a/generated@0.1.0 b/generated@0.1.0 new file mode 100644 index 000000000..e69de29bb diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7ec30b750..f6ff734ef 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -102,7 +102,7 @@ importers: version: 0.31.9 drizzle-orm: specifier: ~0.41.0 - version: 0.41.0(@electric-sql/pglite@0.3.16)(@opentelemetry/api@1.9.0)(@types/pg@8.18.0)(kysely@0.26.3)(pg@8.20.0) + version: 0.41.0(@electric-sql/pglite@0.3.16)(@opentelemetry/api@1.9.0)(@types/pg@8.18.0)(kysely@0.26.3)(pg@8.20.0)(postgres@3.4.1) hono: specifier: ^4.7.10 version: 4.12.7 @@ -163,7 +163,7 @@ importers: version: 0.31.9 drizzle-orm: specifier: ^0.45.1 - version: 0.45.1(@electric-sql/pglite@0.3.16)(@opentelemetry/api@1.9.0)(@types/pg@8.18.0)(kysely@0.26.3)(pg@8.20.0) + version: 0.45.1(@electric-sql/pglite@0.3.16)(@opentelemetry/api@1.9.0)(@types/pg@8.18.0)(kysely@0.26.3)(pg@8.20.0)(postgres@3.4.1) hono: specifier: ^4.7.10 version: 4.12.7 @@ -288,7 +288,7 @@ importers: version: link:../../packages/graphql-client "@apollo/client": specifier: ^3.13.8 - version: 3.14.0(@types/react@19.2.8)(graphql-ws@6.0.7(crossws@0.3.5)(graphql@16.13.1)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(graphql@16.13.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 3.14.0(@types/react@19.2.8)(graphql-ws@6.0.7(crossws@0.3.5)(graphql@16.13.1)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(graphql@16.13.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) "@ethersproject/providers": specifier: ^5.8.0 version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) @@ -324,7 +324,7 @@ importers: version: 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.8))(@types/react@19.2.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) "@rainbow-me/rainbowkit": specifier: ^2.2.0 - version: 2.2.10(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + version: 2.2.10(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) "@snapshot-labs/snapshot.js": specifier: ^0.12.62 version: 0.12.65(bufferutil@4.0.9)(utf-8-validate@5.0.10) @@ -408,7 +408,7 @@ importers: version: 2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) wagmi: specifier: ^2.12.25 - version: 2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + version: 2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) zod: specifier: ^3.25.76 version: 3.25.76 @@ -560,7 +560,7 @@ importers: version: 4.12.7 ponder: specifier: ^0.16.2 - version: 0.16.3(@opentelemetry/api@1.9.0)(@types/node@20.19.37)(@types/pg@8.18.0)(bufferutil@4.0.9)(hono@4.12.7)(lightningcss@1.31.1)(terser@5.46.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + version: 0.16.3(@opentelemetry/api@1.9.0)(@types/node@20.19.37)(@types/pg@8.18.0)(bufferutil@4.0.9)(hono@4.12.7)(lightningcss@1.31.1)(postgres@3.4.1)(terser@5.46.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) viem: specifier: ^2.37.11 version: 2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) @@ -577,6 +577,9 @@ importers: dotenv: specifier: ^16.5.0 version: 16.6.1 + envio: + specifier: ^2.32.12 + version: 2.32.12(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) eslint: specifier: ^9 version: 9.39.4(jiti@2.6.1) @@ -609,7 +612,7 @@ importers: version: 1.13.6 drizzle-orm: specifier: ^0.45.1 - version: 0.45.1(@electric-sql/pglite@0.3.16)(@opentelemetry/api@1.9.0)(@types/pg@8.18.0)(kysely@0.26.3)(pg@8.20.0) + version: 0.45.1(@electric-sql/pglite@0.3.16)(@opentelemetry/api@1.9.0)(@types/pg@8.18.0)(kysely@0.26.3)(pg@8.20.0)(postgres@3.4.1) pg: specifier: ^8.17.2 version: 8.20.0 @@ -689,7 +692,7 @@ importers: version: 4.9.6 forge-std: specifier: github:foundry-rs/forge-std - version: https://codeload.github.com/foundry-rs/forge-std/tar.gz/4540e4aadda88eeb19a54d2b5ad2117c2c7632ec + version: https://codeload.github.com/foundry-rs/forge-std/tar.gz/f494b0c2c045dda3df3d761bc82209b9a015c4e7 packages/observability: dependencies: @@ -756,6 +759,12 @@ packages: integrity: sha512-VQKMkwriZbaOgVCby1UDY/LDk5fIjhQicCvVPFqfe+69fWaPWydbWJ3wRt59/YzIwda1I81loas3oCoHxnqvdA==, } + "@adraffy/ens-normalize@1.10.0": + resolution: + { + integrity: sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==, + } + "@adraffy/ens-normalize@1.10.1": resolution: { @@ -2199,6 +2208,20 @@ packages: peerDependencies: "@noble/ciphers": ^1.0.0 + "@elastic/ecs-helpers@1.1.0": + resolution: + { + integrity: sha512-MDLb2aFeGjg46O5mLpdCzT5yOUDnXToJSrco2ShqGIXxNJaM8uJjX+4nd+hRYV4Vex8YJyDtOFEVBldQct6ndg==, + } + engines: { node: ">=10" } + + "@elastic/ecs-pino-format@1.4.0": + resolution: + { + integrity: sha512-eCSBUTgl8KbPyxky8cecDRLCYu2C1oFV4AZ72bEsI+TxXEvaljaL2kgttfzfu7gW+M89eCz55s49uF2t+YMTWA==, + } + engines: { node: ">=10" } + "@electric-sql/pglite@0.2.13": resolution: { @@ -2289,6 +2312,119 @@ packages: } engines: { node: ">=18.0.0" } + "@envio-dev/hyperfuel-client-darwin-arm64@1.2.2": + resolution: + { + integrity: sha512-eQyd9kJCIz/4WCTjkjpQg80DA3pdneHP7qhJIVQ2ZG+Jew9o5XDG+uI0Y16AgGzZ6KGmJSJF6wyUaaAjJfbO1Q==, + } + engines: { node: ">= 10" } + cpu: [arm64] + os: [darwin] + + "@envio-dev/hyperfuel-client-darwin-x64@1.2.2": + resolution: + { + integrity: sha512-l7lRMSoyIiIvKZgQPfgqg7H1xnrQ37A8yUp4S2ys47R8f/wSCSrmMaY1u7n6CxVYCpR9fajwy0/356UgwwhVKw==, + } + engines: { node: ">= 10" } + cpu: [x64] + os: [darwin] + + "@envio-dev/hyperfuel-client-linux-arm64-gnu@1.2.2": + resolution: + { + integrity: sha512-kNiC/1fKuXnoSxp8yEsloDw4Ot/mIcNoYYGLl2CipSIpBtSuiBH5nb6eBcxnRZdKOwf5dKZtZ7MVPL9qJocNJw==, + } + engines: { node: ">= 10" } + cpu: [arm64] + os: [linux] + + "@envio-dev/hyperfuel-client-linux-x64-gnu@1.2.2": + resolution: + { + integrity: sha512-XDkvkBG/frS+xiZkJdY4KqOaoAwyxPdi2MysDQgF8NmZdssi32SWch0r4LTqKWLLlCBg9/R55POeXL5UAjg2wQ==, + } + engines: { node: ">= 10" } + cpu: [x64] + os: [linux] + + "@envio-dev/hyperfuel-client-linux-x64-musl@1.2.2": + resolution: + { + integrity: sha512-DKnKJJSwsYtA7YT0EFGhFB5Eqoo42X0l0vZBv4lDuxngEXiiNjeLemXoKQVDzhcbILD7eyXNa5jWUc+2hpmkEg==, + } + engines: { node: ">= 10" } + cpu: [x64] + os: [linux] + + "@envio-dev/hyperfuel-client-win32-x64-msvc@1.2.2": + resolution: + { + integrity: sha512-SwIgTAVM9QhCFPyHwL+e1yQ6o3paV6q25klESkXw+r/KW9QPhOOyA6Yr8nfnur3uqMTLJHAKHTLUnkyi/Nh7Aw==, + } + engines: { node: ">= 10" } + cpu: [x64] + os: [win32] + + "@envio-dev/hyperfuel-client@1.2.2": + resolution: + { + integrity: sha512-raKA6DshYSle0sAOHBV1OkSRFMN+Mkz8sFiMmS3k+m5nP6pP56E17CRRePBL5qmR6ZgSEvGOz/44QUiKNkK9Pg==, + } + engines: { node: ">= 10" } + + "@envio-dev/hypersync-client-darwin-arm64@1.3.0": + resolution: + { + integrity: sha512-JZwiVRbMSuJnKsVUpfjTHc3YgAMvGlyuqWQxVc7Eok4Xp/sZLUCXRQUykbCh6fOUWRmoa2JG/ykP/NotoTRCBg==, + } + engines: { node: ">= 10" } + cpu: [arm64] + os: [darwin] + + "@envio-dev/hypersync-client-darwin-x64@1.3.0": + resolution: + { + integrity: sha512-2eSzQqqqFBMK2enVucYGcny5Ep4DEKYxf3Xme7z9qp2d3c6fMcbVvM4Gt8KOzb7ySjwJ2gU+qY2h545T2NiJXQ==, + } + engines: { node: ">= 10" } + cpu: [x64] + os: [darwin] + + "@envio-dev/hypersync-client-linux-arm64-gnu@1.3.0": + resolution: + { + integrity: sha512-gsjMp3WKekwnA89HvJXvcTM3BE5wVFG/qTF4rmk3rGiXhZ+MGaZQKrYRAhnzQZblueFtF/xnnBYpO35Z3ZFThg==, + } + engines: { node: ">= 10" } + cpu: [arm64] + os: [linux] + + "@envio-dev/hypersync-client-linux-x64-gnu@1.3.0": + resolution: + { + integrity: sha512-Lkvi4lRVwCyFOXf9LYH2X91zmW2l1vbfojKhTwKgqFWv6PMN5atlYjt+/NcUCAAhk5EUavWGjoikwnvLp870cg==, + } + engines: { node: ">= 10" } + cpu: [x64] + os: [linux] + + "@envio-dev/hypersync-client-linux-x64-musl@1.3.0": + resolution: + { + integrity: sha512-UIjB/gUX2sl23EMXLBxqtkgMnOjNSiaHK+CSU5vXMXkzL3fOGbz24bvyaPsSv82cxCFEE0yTwlSKkCX6/L8o6Q==, + } + engines: { node: ">= 10" } + cpu: [x64] + os: [linux] + + "@envio-dev/hypersync-client@1.3.0": + resolution: + { + integrity: sha512-wUdfZzbsFPbGq6n/1mmUMsWuiAil+m+fL/GBX5LGUyMJV86TXy2SBtAqYYNyDxWLO6gvGr6PYKrP8pLVAUZDZg==, + } + engines: { node: ">= 10" } + "@esbuild-kit/core-utils@3.3.2": resolution: { @@ -5442,6 +5578,12 @@ packages: integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==, } + "@noble/curves@1.4.0": + resolution: + { + integrity: sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==, + } + "@noble/curves@1.4.2": resolution: { @@ -9182,6 +9324,20 @@ packages: zod: optional: true + abitype@1.0.5: + resolution: + { + integrity: sha512-YzDhti7cjlfaBhHutMaboYB21Ha3rXR9QTkNJFzYC4kC8YclaiwPBBBJY8ejFdu2wnJeZCVZSMlQJ7fi8S6hsw==, + } + peerDependencies: + typescript: ">=5.0.4" + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + abitype@1.0.6: resolution: { @@ -9835,6 +9991,12 @@ packages: integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==, } + bignumber.js@9.1.2: + resolution: + { + integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==, + } + bintrees@1.0.2: resolution: { @@ -11767,6 +11929,45 @@ packages: } engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } + envio-darwin-arm64@2.32.12: + resolution: + { + integrity: sha512-TLs9jjXUHVqKcBReMHgD7C06lbfWfnMkit3uT55XmgiJYc8zS85T0XmDCnCX4BRbZN7uzMNORqnUc2J3/LR9sQ==, + } + cpu: [arm64] + os: [darwin] + + envio-darwin-x64@2.32.12: + resolution: + { + integrity: sha512-JfKU3LaqxO/aabEAIvpHGKhDGNEiVGvcmmi98cZfG1/vP4S5lO+8KDEp563CaB986N6KtGJRKnDWivvCsseZMw==, + } + cpu: [x64] + os: [darwin] + + envio-linux-arm64@2.32.12: + resolution: + { + integrity: sha512-3sBfuR6JLcAkrFcoEfw2WiaPU3VyXGy4kf26HB5BJE/iJUqha+wHoDbv46MfFGuaC0QyM34QvlG0yGRES0ohPw==, + } + cpu: [arm64] + os: [linux] + + envio-linux-x64@2.32.12: + resolution: + { + integrity: sha512-886q+yztKVrhgkwOfoFKARDStbjk1032YBtA6tqrCN8uWjqgzAf30ZDPurJGlq26hQqYNKRp2LhgxChpivsvFw==, + } + cpu: [x64] + os: [linux] + + envio@2.32.12: + resolution: + { + integrity: sha512-bk9y/AjU+kYxO1a9c/jg8RFDrKKKWU0wCffnwtoXo7KGKmPDKq1WyNzVw6sTeboSfGB0i82hJ97WgSAwRAnR1Q==, + } + hasBin: true + environment@1.1.0: resolution: { @@ -12282,6 +12483,20 @@ packages: } engines: { node: ">=0.8.x" } + eventsource-parser@3.0.6: + resolution: + { + integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==, + } + engines: { node: ">=18.0.0" } + + eventsource@4.1.0: + resolution: + { + integrity: sha512-2GuF51iuHX6A9xdTccMTsNb7VO0lHZihApxhvQzJB5A03DvHDd2FQepodbMaztPBmBcE/ox7o2gqaxGhYB9LhQ==, + } + engines: { node: ">=20.0.0" } + evp_bytestokey@1.0.3: resolution: { @@ -12344,6 +12559,12 @@ packages: } engines: { node: "> 0.1.90" } + fast-copy@3.0.2: + resolution: + { + integrity: sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==, + } + fast-copy@4.0.2: resolution: { @@ -12401,6 +12622,13 @@ packages: integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==, } + fast-json-stringify@2.7.13: + resolution: + { + integrity: sha512-ar+hQ4+OIurUGjSJD1anvYSDcUflywhKjfxnsW4TBTD7+u0tJufv6DKRWoQk3vI6YBOWMoz0TQtfbe7dxbQmvA==, + } + engines: { node: ">= 10.0.0" } + fast-json-stringify@5.16.1: resolution: { @@ -12660,10 +12888,10 @@ packages: } engines: { node: ">=14" } - forge-std@https://codeload.github.com/foundry-rs/forge-std/tar.gz/4540e4aadda88eeb19a54d2b5ad2117c2c7632ec: + forge-std@https://codeload.github.com/foundry-rs/forge-std/tar.gz/f494b0c2c045dda3df3d761bc82209b9a015c4e7: resolution: { - tarball: https://codeload.github.com/foundry-rs/forge-std/tar.gz/4540e4aadda88eeb19a54d2b5ad2117c2c7632ec, + tarball: https://codeload.github.com/foundry-rs/forge-std/tar.gz/f494b0c2c045dda3df3d761bc82209b9a015c4e7, } version: 1.15.0 @@ -12892,6 +13120,14 @@ packages: } 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 + glob@8.1.0: + resolution: + { + integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==, + } + engines: { node: ">=12" } + 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 + global-directory@4.0.1: resolution: { @@ -13195,6 +13431,12 @@ packages: integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==, } + help-me@4.2.0: + resolution: + { + integrity: sha512-TAOnTB8Tz5Dw8penUuzHVrKNKlCIbwwbHnXraNJxPwf8LRtE2HlM84RYuezMFcwOJmoYOCWVDyJ8TQGxn9PgxA==, + } + help-me@5.0.0: resolution: { @@ -13924,6 +14166,14 @@ packages: peerDependencies: ws: "*" + isows@1.0.4: + resolution: + { + integrity: sha512-hEzjY+x9u9hPmBom9IIAqdJCwNLax+xrPb51vEPpERoFlIxgmZcHzsT5jKG06nvInKOBGvReAVz80Umed5CczQ==, + } + peerDependencies: + ws: "*" + isows@1.0.6: resolution: { @@ -15225,6 +15475,13 @@ packages: integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==, } + minimatch@5.1.9: + resolution: + { + integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==, + } + engines: { node: ">=10" } + minimatch@9.0.9: resolution: { @@ -16223,6 +16480,12 @@ packages: integrity: sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==, } + pino-abstract-transport@1.1.0: + resolution: + { + integrity: sha512-lsleG3/2a/JIWUtf9Q5gUNErBqwIu1tUKTT3dUzaf5DySw9ra1wcqKjJjLX1VTY64Wk1eEOYsVGSaGfCK85ekA==, + } + pino-abstract-transport@1.2.0: resolution: { @@ -16255,6 +16518,13 @@ packages: peerDependencies: pino: ^8.21.0 || ^9.0.0 + pino-pretty@10.2.3: + resolution: + { + integrity: sha512-4jfIUc8TC1GPUfDyMSlW1STeORqkoxec71yhxIpLDQapUu8WOuoz2TTCoidrIssyz78LZC69whBMPIKCMbi3cw==, + } + hasBin: true + pino-pretty@13.1.3: resolution: { @@ -16287,6 +16557,13 @@ packages: } hasBin: true + pino@8.16.1: + resolution: + { + integrity: sha512-3bKsVhBmgPjGV9pyn4fO/8RtoVDR8ssW1ev819FsRXlRNgW8gR/9Kx+gCK4UPWd4JjrRDLWpzd/pb1AyWm3MGA==, + } + hasBin: true + pino@8.21.0: resolution: { @@ -16556,6 +16833,13 @@ packages: } engines: { node: ">=0.10.0" } + postgres@3.4.1: + resolution: + { + integrity: sha512-Wasjv6WEzrZXbwKByR2RGD7MBfj7VBqco3hYWz8ifzSAp6tb2L6MlmcKFzkmgV1jT7/vKlcSa+lxXZeTdeVMzQ==, + } + engines: { node: ">=12" } + preact@10.24.2: resolution: { @@ -16694,6 +16978,12 @@ packages: integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==, } + process-warning@2.3.2: + resolution: + { + integrity: sha512-n9wh8tvBe5sFmsqlg+XQhaQLumwpqoAUruLwjCopgTmUBjJ/fjtBsJzKleCaIGBOMXYEhp1YfKl4d7rJ5ZKJGA==, + } + process-warning@3.0.0: resolution: { @@ -16713,6 +17003,13 @@ packages: } engines: { node: ">= 0.6.0" } + prom-client@15.0.0: + resolution: + { + integrity: sha512-UocpgIrKyA2TKLVZDSfm8rGkL13C19YrQBAiG3xo3aDFWcHedxRxI3z+cIcucoxpSO0h5lff5iv/SXoxyeopeA==, + } + engines: { node: ^16 || ^18 || >=20 } + prom-client@15.1.3: resolution: { @@ -17302,6 +17599,25 @@ packages: integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==, } + rescript-schema@9.3.0: + resolution: + { + integrity: sha512-NiHAjlhFKZCmNhx/Ij40YltCEJJgVNhBWTN/ZfagTg5hdWWuvCiUacxZv+Q/QQolrAhTnHnCrL7RDvZBogHl5A==, + } + peerDependencies: + rescript: 11.x + peerDependenciesMeta: + rescript: + optional: true + + rescript@11.1.3: + resolution: + { + integrity: sha512-bI+yxDcwsv7qE34zLuXeO8Qkc2+1ng5ErlSjnUIZdrAWKoGzHXpJ6ZxiiRBUoYnoMsgRwhqvrugIFyNgWasmsw==, + } + engines: { node: ">=10" } + hasBin: true + resend@6.9.3: resolution: { @@ -17599,6 +17915,12 @@ packages: integrity: sha512-MuCAyrGZcTLfQoH2XoBlQ8C6bzwN88XT/0slOGz0pn8+gIP85BOAfYa44ZXQUTOwRwPU0QvgU+V+OSajl/59Xg==, } + secure-json-parse@2.7.0: + resolution: + { + integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==, + } + secure-json-parse@4.1.0: resolution: { @@ -18057,6 +18379,13 @@ packages: } engines: { node: ">=10" } + string-similarity@4.0.4: + resolution: + { + integrity: sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ==, + } + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + string-width@4.2.3: resolution: { @@ -19486,6 +19815,17 @@ packages: integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==, } + viem@2.21.0: + resolution: + { + integrity: sha512-9g3Gw2nOU6t4bNuoDI5vwVExzIxseU0J7Jjx10gA2RNQVrytIrLxggW++tWEe3w4mnnm/pS1WgZFjQ/QKf/nHw==, + } + peerDependencies: + typescript: ">=5.0.4" + peerDependenciesMeta: + typescript: + optional: true + viem@2.23.2: resolution: { @@ -19734,6 +20074,12 @@ packages: } engines: { node: ">= 8" } + webauthn-p256@0.0.5: + resolution: + { + integrity: sha512-drMGNWKdaixZNobeORVIqq7k5DsRC9FnG201K2QjeOoQLmtSDaSsVZdkg6n5jUALJKcAG++zBPJXmv6hy0nWFg==, + } + webextension-polyfill@0.10.0: resolution: { @@ -20289,6 +20635,8 @@ packages: snapshots: "@adobe/css-tools@4.4.3": {} + "@adraffy/ens-normalize@1.10.0": {} + "@adraffy/ens-normalize@1.10.1": {} "@adraffy/ens-normalize@1.11.1": {} @@ -20300,7 +20648,7 @@ snapshots: "@jridgewell/gen-mapping": 0.3.13 "@jridgewell/trace-mapping": 0.3.31 - "@apollo/client@3.14.0(@types/react@19.2.8)(graphql-ws@6.0.7(crossws@0.3.5)(graphql@16.13.1)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(graphql@16.13.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)": + "@apollo/client@3.14.0(@types/react@19.2.8)(graphql-ws@6.0.7(crossws@0.3.5)(graphql@16.13.1)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(graphql@16.13.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)": dependencies: "@graphql-typed-document-node/core": 3.2.0(graphql@16.13.1) "@wry/caches": 1.0.1 @@ -20317,7 +20665,7 @@ snapshots: tslib: 2.8.1 zen-observable-ts: 1.2.5 optionalDependencies: - graphql-ws: 6.0.7(crossws@0.3.5)(graphql@16.13.1)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + graphql-ws: 6.0.7(crossws@0.3.5)(graphql@16.13.1)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) react: 19.2.3 react-dom: 19.2.3(react@19.2.3) transitivePeerDependencies: @@ -21443,9 +21791,9 @@ snapshots: "@babel/helper-string-parser": 7.27.1 "@babel/helper-validator-identifier": 7.28.5 - "@base-org/account@2.4.0(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)": + "@base-org/account@2.4.0(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)": dependencies: - "@coinbase/cdp-sdk": 1.38.6(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + "@coinbase/cdp-sdk": 1.38.6(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) "@noble/hashes": 1.4.0 clsx: 1.2.1 eventemitter3: 5.0.1 @@ -21484,11 +21832,11 @@ snapshots: - "@chromatic-com/cypress" - "@chromatic-com/playwright" - "@coinbase/cdp-sdk@1.38.6(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))": + "@coinbase/cdp-sdk@1.38.6(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))": dependencies: - "@solana-program/system": 0.8.1(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))) - "@solana-program/token": 0.6.0(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))) - "@solana/kit": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + "@solana-program/system": 0.8.1(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))) + "@solana-program/token": 0.6.0(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))) + "@solana/kit": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) "@solana/web3.js": 1.98.4(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) abitype: 1.0.6(typescript@5.9.3)(zod@3.25.76) axios: 1.13.6 @@ -21685,6 +22033,14 @@ snapshots: dependencies: "@noble/ciphers": 1.3.0 + "@elastic/ecs-helpers@1.1.0": + dependencies: + fast-json-stringify: 2.7.13 + + "@elastic/ecs-pino-format@1.4.0": + dependencies: + "@elastic/ecs-helpers": 1.1.0 + "@electric-sql/pglite@0.2.13": {} "@electric-sql/pglite@0.3.16": {} @@ -21748,6 +22104,56 @@ snapshots: "@whatwg-node/promise-helpers": 1.3.2 tslib: 2.8.1 + "@envio-dev/hyperfuel-client-darwin-arm64@1.2.2": + optional: true + + "@envio-dev/hyperfuel-client-darwin-x64@1.2.2": + optional: true + + "@envio-dev/hyperfuel-client-linux-arm64-gnu@1.2.2": + optional: true + + "@envio-dev/hyperfuel-client-linux-x64-gnu@1.2.2": + optional: true + + "@envio-dev/hyperfuel-client-linux-x64-musl@1.2.2": + optional: true + + "@envio-dev/hyperfuel-client-win32-x64-msvc@1.2.2": + optional: true + + "@envio-dev/hyperfuel-client@1.2.2": + optionalDependencies: + "@envio-dev/hyperfuel-client-darwin-arm64": 1.2.2 + "@envio-dev/hyperfuel-client-darwin-x64": 1.2.2 + "@envio-dev/hyperfuel-client-linux-arm64-gnu": 1.2.2 + "@envio-dev/hyperfuel-client-linux-x64-gnu": 1.2.2 + "@envio-dev/hyperfuel-client-linux-x64-musl": 1.2.2 + "@envio-dev/hyperfuel-client-win32-x64-msvc": 1.2.2 + + "@envio-dev/hypersync-client-darwin-arm64@1.3.0": + optional: true + + "@envio-dev/hypersync-client-darwin-x64@1.3.0": + optional: true + + "@envio-dev/hypersync-client-linux-arm64-gnu@1.3.0": + optional: true + + "@envio-dev/hypersync-client-linux-x64-gnu@1.3.0": + optional: true + + "@envio-dev/hypersync-client-linux-x64-musl@1.3.0": + optional: true + + "@envio-dev/hypersync-client@1.3.0": + optionalDependencies: + "@envio-dev/hypersync-client-darwin-arm64": 1.3.0 + "@envio-dev/hypersync-client-darwin-x64": 1.3.0 + "@envio-dev/hypersync-client-linux-arm64-gnu": 1.3.0 + "@envio-dev/hypersync-client-linux-x64-gnu": 1.3.0 + "@envio-dev/hypersync-client-linux-x64-musl": 1.3.0 + "@esbuild-kit/core-utils@3.3.2": dependencies: esbuild: 0.18.20 @@ -24552,6 +24958,10 @@ snapshots: dependencies: "@noble/hashes": 1.3.2 + "@noble/curves@1.4.0": + dependencies: + "@noble/hashes": 1.4.0 + "@noble/curves@1.4.2": dependencies: "@noble/hashes": 1.4.0 @@ -25421,7 +25831,7 @@ snapshots: node-fetch: 3.3.2 tar: 6.2.1 - "@rainbow-me/rainbowkit@2.2.10(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))": + "@rainbow-me/rainbowkit@2.2.10(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))": dependencies: "@tanstack/react-query": 5.90.21(react@19.2.3) "@vanilla-extract/css": 1.17.3 @@ -25434,7 +25844,7 @@ snapshots: react-remove-scroll: 2.6.2(@types/react@19.2.8)(react@19.2.3) ua-parser-js: 1.0.40 viem: 2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - wagmi: 2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + wagmi: 2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) transitivePeerDependencies: - "@types/react" - babel-plugin-macros @@ -25867,13 +26277,13 @@ snapshots: "@socket.io/component-emitter@3.1.2": {} - "@solana-program/system@0.8.1(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)))": + "@solana-program/system@0.8.1(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))": dependencies: - "@solana/kit": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + "@solana/kit": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - "@solana-program/token@0.6.0(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)))": + "@solana-program/token@0.6.0(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))": dependencies: - "@solana/kit": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + "@solana/kit": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) "@solana/accounts@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)": dependencies: @@ -26003,7 +26413,7 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - "@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))": + "@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))": dependencies: "@solana/accounts": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/addresses": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) @@ -26017,11 +26427,11 @@ snapshots: "@solana/rpc": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/rpc-parsed-types": 3.0.3(typescript@5.9.3) "@solana/rpc-spec-types": 3.0.3(typescript@5.9.3) - "@solana/rpc-subscriptions": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + "@solana/rpc-subscriptions": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) "@solana/rpc-types": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/signers": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/sysvars": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - "@solana/transaction-confirmation": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + "@solana/transaction-confirmation": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) "@solana/transaction-messages": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/transactions": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) typescript: 5.9.3 @@ -26100,14 +26510,14 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - "@solana/rpc-subscriptions-channel-websocket@3.0.3(typescript@5.9.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))": + "@solana/rpc-subscriptions-channel-websocket@3.0.3(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))": dependencies: "@solana/errors": 3.0.3(typescript@5.9.3) "@solana/functional": 3.0.3(typescript@5.9.3) "@solana/rpc-subscriptions-spec": 3.0.3(typescript@5.9.3) "@solana/subscribable": 3.0.3(typescript@5.9.3) typescript: 5.9.3 - ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) "@solana/rpc-subscriptions-spec@3.0.3(typescript@5.9.3)": dependencies: @@ -26117,7 +26527,7 @@ snapshots: "@solana/subscribable": 3.0.3(typescript@5.9.3) typescript: 5.9.3 - "@solana/rpc-subscriptions@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))": + "@solana/rpc-subscriptions@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))": dependencies: "@solana/errors": 3.0.3(typescript@5.9.3) "@solana/fast-stable-stringify": 3.0.3(typescript@5.9.3) @@ -26125,7 +26535,7 @@ snapshots: "@solana/promises": 3.0.3(typescript@5.9.3) "@solana/rpc-spec-types": 3.0.3(typescript@5.9.3) "@solana/rpc-subscriptions-api": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - "@solana/rpc-subscriptions-channel-websocket": 3.0.3(typescript@5.9.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + "@solana/rpc-subscriptions-channel-websocket": 3.0.3(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) "@solana/rpc-subscriptions-spec": 3.0.3(typescript@5.9.3) "@solana/rpc-transformers": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/rpc-types": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) @@ -26210,7 +26620,7 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - "@solana/transaction-confirmation@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))": + "@solana/transaction-confirmation@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))": dependencies: "@solana/addresses": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/codecs-strings": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) @@ -26218,7 +26628,7 @@ snapshots: "@solana/keys": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/promises": 3.0.3(typescript@5.9.3) "@solana/rpc": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - "@solana/rpc-subscriptions": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + "@solana/rpc-subscriptions": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) "@solana/rpc-types": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/transaction-messages": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) "@solana/transactions": 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) @@ -27260,9 +27670,9 @@ snapshots: convert-source-map: 2.0.0 tinyrainbow: 3.0.3 - "@wagmi/connectors@6.2.0(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.20)(@types/react@19.2.8)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)": + "@wagmi/connectors@6.2.0(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.20)(@types/react@19.2.8)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)": dependencies: - "@base-org/account": 2.4.0(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + "@base-org/account": 2.4.0(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) "@coinbase/wallet-sdk": 4.3.6(@types/react@19.2.8)(bufferutil@4.0.9)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(zod@3.25.76) "@gemini-wallet/core": 0.3.2(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) "@metamask/sdk": 0.33.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) @@ -27271,7 +27681,7 @@ snapshots: "@wagmi/core": 2.22.1(@tanstack/query-core@5.90.20)(@types/react@19.2.8)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) "@walletconnect/ethereum-provider": 2.21.1(@types/react@19.2.8)(bufferutil@4.0.9)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) cbw-sdk: "@coinbase/wallet-sdk@3.9.3" - porto: 0.2.35(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.20)(@types/react@19.2.8)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + porto: 0.2.35(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.20)(@types/react@19.2.8)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) viem: 2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: typescript: 5.9.3 @@ -28024,6 +28434,11 @@ snapshots: typescript: 5.9.3 zod: 3.25.76 + abitype@1.0.5(typescript@5.9.3)(zod@3.25.76): + optionalDependencies: + typescript: 5.9.3 + zod: 3.25.76 + abitype@1.0.6(typescript@5.9.3)(zod@3.25.76): optionalDependencies: typescript: 5.9.3 @@ -28482,6 +28897,8 @@ snapshots: big.js@6.2.2: {} + bignumber.js@9.1.2: {} + bintrees@1.0.2: {} bl@4.1.0: @@ -29383,29 +29800,32 @@ snapshots: transitivePeerDependencies: - supports-color - drizzle-orm@0.41.0(@electric-sql/pglite@0.2.13)(@opentelemetry/api@1.9.0)(@types/pg@8.18.0)(kysely@0.26.3)(pg@8.20.0): + drizzle-orm@0.41.0(@electric-sql/pglite@0.2.13)(@opentelemetry/api@1.9.0)(@types/pg@8.18.0)(kysely@0.26.3)(pg@8.20.0)(postgres@3.4.1): optionalDependencies: "@electric-sql/pglite": 0.2.13 "@opentelemetry/api": 1.9.0 "@types/pg": 8.18.0 kysely: 0.26.3 pg: 8.20.0 + postgres: 3.4.1 - drizzle-orm@0.41.0(@electric-sql/pglite@0.3.16)(@opentelemetry/api@1.9.0)(@types/pg@8.18.0)(kysely@0.26.3)(pg@8.20.0): + drizzle-orm@0.41.0(@electric-sql/pglite@0.3.16)(@opentelemetry/api@1.9.0)(@types/pg@8.18.0)(kysely@0.26.3)(pg@8.20.0)(postgres@3.4.1): optionalDependencies: "@electric-sql/pglite": 0.3.16 "@opentelemetry/api": 1.9.0 "@types/pg": 8.18.0 kysely: 0.26.3 pg: 8.20.0 + postgres: 3.4.1 - drizzle-orm@0.45.1(@electric-sql/pglite@0.3.16)(@opentelemetry/api@1.9.0)(@types/pg@8.18.0)(kysely@0.26.3)(pg@8.20.0): + drizzle-orm@0.45.1(@electric-sql/pglite@0.3.16)(@opentelemetry/api@1.9.0)(@types/pg@8.18.0)(kysely@0.26.3)(pg@8.20.0)(postgres@3.4.1): optionalDependencies: "@electric-sql/pglite": 0.3.16 "@opentelemetry/api": 1.9.0 "@types/pg": 8.18.0 kysely: 0.26.3 pg: 8.20.0 + postgres: 3.4.1 dset@3.1.4: {} @@ -29497,6 +29917,42 @@ snapshots: env-paths@3.0.0: {} + envio-darwin-arm64@2.32.12: + optional: true + + envio-darwin-x64@2.32.12: + optional: true + + envio-linux-arm64@2.32.12: + optional: true + + envio-linux-x64@2.32.12: + optional: true + + envio@2.32.12(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76): + dependencies: + "@elastic/ecs-pino-format": 1.4.0 + "@envio-dev/hyperfuel-client": 1.2.2 + "@envio-dev/hypersync-client": 1.3.0 + bignumber.js: 9.1.2 + eventsource: 4.1.0 + pino: 8.16.1 + pino-pretty: 10.2.3 + prom-client: 15.0.0 + rescript: 11.1.3 + rescript-schema: 9.3.0(rescript@11.1.3) + viem: 2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + optionalDependencies: + envio-darwin-arm64: 2.32.12 + envio-darwin-x64: 2.32.12 + envio-linux-arm64: 2.32.12 + envio-linux-x64: 2.32.12 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + environment@1.1.0: {} error-ex@1.3.2: @@ -30106,6 +30562,12 @@ snapshots: events@3.3.0: {} + eventsource-parser@3.0.6: {} + + eventsource@4.1.0: + dependencies: + eventsource-parser: 3.0.6 + evp_bytestokey@1.0.3: dependencies: md5.js: 1.3.5 @@ -30150,6 +30612,8 @@ snapshots: eyes@0.1.8: {} + fast-copy@3.0.2: {} + fast-copy@4.0.2: {} fast-deep-equal@3.1.3: {} @@ -30182,6 +30646,13 @@ snapshots: fast-json-stable-stringify@2.1.0: {} + fast-json-stringify@2.7.13: + dependencies: + ajv: 6.14.0 + deepmerge: 4.3.1 + rfdc: 1.4.1 + string-similarity: 4.0.4 + fast-json-stringify@5.16.1: dependencies: "@fastify/merge-json-schemas": 0.1.1 @@ -30330,7 +30801,7 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 - forge-std@https://codeload.github.com/foundry-rs/forge-std/tar.gz/4540e4aadda88eeb19a54d2b5ad2117c2c7632ec: + forge-std@https://codeload.github.com/foundry-rs/forge-std/tar.gz/f494b0c2c045dda3df3d761bc82209b9a015c4e7: {} fork-ts-checker-webpack-plugin@9.1.0(typescript@5.9.3)(webpack@5.105.4): @@ -30490,6 +30961,14 @@ snapshots: once: 1.4.0 path-is-absolute: 1.0.1 + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.9 + once: 1.4.0 + global-directory@4.0.1: dependencies: ini: 4.1.1 @@ -30595,12 +31074,12 @@ snapshots: dependencies: graphql: 16.13.1 - graphql-ws@6.0.7(crossws@0.3.5)(graphql@16.13.1)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + graphql-ws@6.0.7(crossws@0.3.5)(graphql@16.13.1)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)): dependencies: graphql: 16.13.1 optionalDependencies: crossws: 0.3.5 - ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) optional: true graphql-ws@6.0.7(crossws@0.3.5)(graphql@16.13.1)(ws@8.19.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)): @@ -30712,6 +31191,11 @@ snapshots: headers-polyfill@4.0.3: {} + help-me@4.2.0: + dependencies: + glob: 8.1.0 + readable-stream: 3.6.2 + help-me@5.0.0: {} hermes-estree@0.25.1: {} @@ -31109,6 +31593,10 @@ snapshots: dependencies: ws: 8.19.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + isows@1.0.4(ws@8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + dependencies: + ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + isows@1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)): dependencies: ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) @@ -32026,6 +32514,10 @@ snapshots: dependencies: brace-expansion: 1.1.12 + minimatch@5.1.9: + dependencies: + brace-expansion: 2.0.2 + minimatch@9.0.9: dependencies: brace-expansion: 2.0.2 @@ -32057,7 +32549,7 @@ snapshots: mlly@1.8.0: dependencies: - acorn: 8.15.0 + acorn: 8.16.0 pathe: 2.0.3 pkg-types: 1.3.1 ufo: 1.6.1 @@ -32699,6 +33191,11 @@ snapshots: duplexify: 4.1.3 split2: 4.2.0 + pino-abstract-transport@1.1.0: + dependencies: + readable-stream: 4.7.0 + split2: 4.2.0 + pino-abstract-transport@1.2.0: dependencies: readable-stream: 4.7.0 @@ -32727,6 +33224,23 @@ snapshots: transitivePeerDependencies: - "@opentelemetry/api" + pino-pretty@10.2.3: + dependencies: + colorette: 2.0.20 + dateformat: 4.6.3 + fast-copy: 3.0.2 + fast-safe-stringify: 2.1.1 + help-me: 4.2.0 + joycon: 3.1.1 + minimist: 1.2.8 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 1.2.0 + pump: 3.0.3 + readable-stream: 4.7.0 + secure-json-parse: 2.7.0 + sonic-boom: 3.8.1 + strip-json-comments: 3.1.1 + pino-pretty@13.1.3: dependencies: colorette: 2.0.20 @@ -32763,6 +33277,20 @@ snapshots: sonic-boom: 2.8.0 thread-stream: 0.15.2 + pino@8.16.1: + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 1.1.0 + pino-std-serializers: 6.2.2 + process-warning: 2.3.2 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.5.0 + sonic-boom: 3.8.1 + thread-stream: 2.7.0 + pino@8.21.0: dependencies: atomic-sleep: 1.0.0 @@ -32819,7 +33347,7 @@ snapshots: pngjs@5.0.0: {} - ponder@0.16.3(@opentelemetry/api@1.9.0)(@types/node@20.19.37)(@types/pg@8.18.0)(bufferutil@4.0.9)(hono@4.12.7)(lightningcss@1.31.1)(terser@5.46.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76): + ponder@0.16.3(@opentelemetry/api@1.9.0)(@types/node@20.19.37)(@types/pg@8.18.0)(bufferutil@4.0.9)(hono@4.12.7)(lightningcss@1.31.1)(postgres@3.4.1)(terser@5.46.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76): dependencies: "@babel/code-frame": 7.27.1 "@commander-js/extra-typings": 12.1.0(commander@12.1.0) @@ -32836,7 +33364,7 @@ snapshots: dataloader: 2.2.3 detect-package-manager: 3.0.2 dotenv: 16.6.1 - drizzle-orm: 0.41.0(@electric-sql/pglite@0.2.13)(@opentelemetry/api@1.9.0)(@types/pg@8.18.0)(kysely@0.26.3)(pg@8.20.0) + drizzle-orm: 0.41.0(@electric-sql/pglite@0.2.13)(@opentelemetry/api@1.9.0)(@types/pg@8.18.0)(kysely@0.26.3)(pg@8.20.0)(postgres@3.4.1) glob: 10.5.0 graphql: 16.8.2 graphql-yoga: 5.17.1(graphql@16.8.2) @@ -32903,7 +33431,7 @@ snapshots: pony-cause@2.1.11: {} - porto@0.2.35(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.20)(@types/react@19.2.8)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)): + porto@0.2.35(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.20)(@types/react@19.2.8)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)): dependencies: "@wagmi/core": 2.22.1(@tanstack/query-core@5.90.20)(@types/react@19.2.8)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) hono: 4.12.7 @@ -32917,7 +33445,7 @@ snapshots: "@tanstack/react-query": 5.90.21(react@19.2.3) react: 19.2.3 typescript: 5.9.3 - wagmi: 2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + wagmi: 2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) transitivePeerDependencies: - "@types/react" - immer @@ -32997,6 +33525,9 @@ snapshots: dependencies: xtend: 4.0.2 + postgres@3.4.1: + optional: true + preact@10.24.2: {} preact@10.29.0: {} @@ -33036,12 +33567,19 @@ snapshots: process-warning@1.0.0: {} + process-warning@2.3.2: {} + process-warning@3.0.0: {} process-warning@5.0.0: {} process@0.11.10: {} + prom-client@15.0.0: + dependencies: + "@opentelemetry/api": 1.9.0 + tdigest: 0.1.2 + prom-client@15.1.3: dependencies: "@opentelemetry/api": 1.9.0 @@ -33464,6 +34002,12 @@ snapshots: requires-port@1.0.0: {} + rescript-schema@9.3.0(rescript@11.1.3): + optionalDependencies: + rescript: 11.1.3 + + rescript@11.1.3: {} + resend@6.9.3: dependencies: postal-mime: 2.7.3 @@ -33653,6 +34197,8 @@ snapshots: scuid@1.1.0: {} + secure-json-parse@2.7.0: {} + secure-json-parse@4.1.0: {} semver-compare@1.0.0: {} @@ -33967,6 +34513,8 @@ snapshots: char-regex: 1.0.2 strip-ansi: 6.0.1 + string-similarity@4.0.4: {} + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -34804,6 +35352,24 @@ snapshots: d3-time: 3.1.0 d3-timer: 3.0.1 + viem@2.21.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76): + dependencies: + "@adraffy/ens-normalize": 1.10.0 + "@noble/curves": 1.4.0 + "@noble/hashes": 1.4.0 + "@scure/bip32": 1.4.0 + "@scure/bip39": 1.3.0 + abitype: 1.0.5(typescript@5.9.3)(zod@3.25.76) + isows: 1.0.4(ws@8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + webauthn-p256: 0.0.5 + ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + viem@2.23.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76): dependencies: "@noble/curves": 1.8.1 @@ -35045,10 +35611,10 @@ snapshots: dependencies: xml-name-validator: 5.0.0 - wagmi@2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76): + wagmi@2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76): dependencies: "@tanstack/react-query": 5.90.21(react@19.2.3) - "@wagmi/connectors": 6.2.0(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.20)(@types/react@19.2.8)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + "@wagmi/connectors": 6.2.0(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.20)(@types/react@19.2.8)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@19.2.3))(@types/react@19.2.8)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) "@wagmi/core": 2.22.1(@tanstack/query-core@5.90.20)(@types/react@19.2.8)(react@19.2.3)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.3))(viem@2.47.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) react: 19.2.3 use-sync-external-store: 1.4.0(react@19.2.3) @@ -35106,6 +35672,11 @@ snapshots: web-streams-polyfill@3.3.3: {} + webauthn-p256@0.0.5: + dependencies: + "@noble/curves": 1.9.7 + "@noble/hashes": 1.8.0 + webextension-polyfill@0.10.0: {} webidl-conversions@3.0.1: {} diff --git a/ts-node b/ts-node new file mode 100644 index 000000000..e69de29bb