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