@d20dao/vrf-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/abi.js ADDED
@@ -0,0 +1,3 @@
1
+ // Generated from canonical protocol sources with solc 0.8.28+commit.7893614a.Emscripten.clang.
2
+ export const coordinatorAbi = [{ "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, { "inputs": [{ "internalType": "address", "name": "target", "type": "address" }], "name": "AddressEmptyCode", "type": "error" }, { "inputs": [], "name": "AlreadyDelivered", "type": "error" }, { "inputs": [], "name": "AlreadyFulfilled", "type": "error" }, { "inputs": [], "name": "BlockHashUnavailable", "type": "error" }, { "inputs": [], "name": "ContractConsumerRequired", "type": "error" }, { "inputs": [{ "internalType": "address", "name": "implementation", "type": "address" }], "name": "ERC1967InvalidImplementation", "type": "error" }, { "inputs": [], "name": "ERC1967NonPayable", "type": "error" }, { "inputs": [], "name": "EpochUnavailable", "type": "error" }, { "inputs": [], "name": "EvidencePacketTooLarge", "type": "error" }, { "inputs": [], "name": "FailedCall", "type": "error" }, { "inputs": [{ "internalType": "uint256", "name": "expected", "type": "uint256" }, { "internalType": "uint256", "name": "actual", "type": "uint256" }], "name": "IncorrectFee", "type": "error" }, { "inputs": [], "name": "InsufficientCallbackGas", "type": "error" }, { "inputs": [], "name": "InvalidCallbackGas", "type": "error" }, { "inputs": [], "name": "InvalidConfig", "type": "error" }, { "inputs": [], "name": "InvalidInitialization", "type": "error" }, { "inputs": [], "name": "InvalidMapping", "type": "error" }, { "inputs": [], "name": "InvalidPublicKey", "type": "error" }, { "inputs": [], "name": "InvalidRefundAddress", "type": "error" }, { "inputs": [], "name": "InvalidScan", "type": "error" }, { "inputs": [], "name": "NoKeeperCredit", "type": "error" }, { "inputs": [], "name": "NoRefundCredit", "type": "error" }, { "inputs": [], "name": "NotFulfilled", "type": "error" }, { "inputs": [], "name": "NotInitializing", "type": "error" }, { "inputs": [], "name": "NotReady", "type": "error" }, { "inputs": [], "name": "NotRefunded", "type": "error" }, { "inputs": [], "name": "OnlyFeeRecipient", "type": "error" }, { "inputs": [{ "internalType": "address", "name": "owner", "type": "address" }], "name": "OwnableInvalidOwner", "type": "error" }, { "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], "name": "OwnableUnauthorizedAccount", "type": "error" }, { "inputs": [], "name": "ReentrancyGuardReentrantCall", "type": "error" }, { "inputs": [], "name": "RefundCallbackAlreadyDelivered", "type": "error" }, { "inputs": [], "name": "RefundNotAvailable", "type": "error" }, { "inputs": [], "name": "RequestExpired", "type": "error" }, { "inputs": [], "name": "RequestRefunded", "type": "error" }, { "inputs": [], "name": "TransferFailed", "type": "error" }, { "inputs": [], "name": "UUPSUnauthorizedCallContext", "type": "error" }, { "inputs": [{ "internalType": "bytes32", "name": "slot", "type": "bytes32" }], "name": "UUPSUnsupportedProxiableUUID", "type": "error" }, { "inputs": [], "name": "UnknownRequest", "type": "error" }, { "inputs": [], "name": "WrongPublicKey", "type": "error" }, { "inputs": [], "name": "WrongSeed", "type": "error" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "uint256", "name": "requestId", "type": "uint256" }, { "indexed": false, "internalType": "uint64", "name": "targetBlock", "type": "uint64" }, { "indexed": false, "internalType": "bytes32", "name": "blockHash", "type": "bytes32" }], "name": "BlockHashStored", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "uint256", "name": "requestId", "type": "uint256" }, { "indexed": false, "internalType": "bool", "name": "success", "type": "bool" }, { "indexed": false, "internalType": "uint32", "name": "gasLimit", "type": "uint32" }], "name": "CallbackAttempted", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "previousRecipient", "type": "address" }, { "indexed": true, "internalType": "address", "name": "newRecipient", "type": "address" }], "name": "FeeRecipientChanged", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "recipient", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }], "name": "FeesWithdrawn", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "uint256", "name": "requestId", "type": "uint256" }, { "indexed": true, "internalType": "bytes32", "name": "transcriptHash", "type": "bytes32" }, { "indexed": false, "internalType": "bytes", "name": "packet", "type": "bytes" }], "name": "FulfillmentEvidence", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "internalType": "uint64", "name": "version", "type": "uint64" }], "name": "Initialized", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "keeper", "type": "address" }, { "indexed": true, "internalType": "address", "name": "recipient", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }], "name": "KeeperCreditWithdrawn", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "internalType": "uint16", "name": "previousBps", "type": "uint16" }, { "indexed": false, "internalType": "uint16", "name": "newBps", "type": "uint16" }], "name": "KeeperFeeBpsChanged", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "uint256", "name": "requestId", "type": "uint256" }, { "indexed": true, "internalType": "address", "name": "keeper", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }, { "indexed": false, "internalType": "bool", "name": "paid", "type": "bool" }], "name": "KeeperFeePaid", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "uint256", "name": "requestId", "type": "uint256" }, { "indexed": true, "internalType": "bytes32", "name": "mappingHash", "type": "bytes32" }, { "components": [{ "internalType": "enum RandomnessMapping.Operation", "name": "operation", "type": "uint8" }, { "internalType": "uint256", "name": "lower", "type": "uint256" }, { "internalType": "uint256", "name": "upper", "type": "uint256" }, { "internalType": "uint32", "name": "count", "type": "uint32" }, { "internalType": "uint32", "name": "population", "type": "uint32" }], "indexed": false, "internalType": "struct RandomnessMapping.Spec", "name": "spec", "type": "tuple" }], "name": "MappingRequested", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "previousOwner", "type": "address" }, { "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" }], "name": "OwnershipTransferStarted", "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": "uint256", "name": "requestId", "type": "uint256" }, { "indexed": true, "internalType": "bytes32", "name": "keyHash", "type": "bytes32" }, { "indexed": false, "internalType": "uint256", "name": "seed", "type": "uint256" }, { "indexed": false, "internalType": "bytes32", "name": "proofHash", "type": "bytes32" }], "name": "ProofVerified", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "uint256", "name": "requestId", "type": "uint256" }, { "indexed": false, "internalType": "bytes32", "name": "randomness", "type": "bytes32" }, { "indexed": true, "internalType": "address", "name": "submitter", "type": "address" }], "name": "RandomnessFulfilled", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "uint256", "name": "requestId", "type": "uint256" }, { "indexed": true, "internalType": "address", "name": "consumer", "type": "address" }, { "indexed": true, "internalType": "bytes32", "name": "keyHash", "type": "bytes32" }, { "indexed": false, "internalType": "bytes32", "name": "clientSeed", "type": "bytes32" }, { "indexed": false, "internalType": "uint64", "name": "requestBlock", "type": "uint64" }, { "indexed": false, "internalType": "uint32", "name": "callbackGasLimit", "type": "uint32" }, { "indexed": false, "internalType": "uint256", "name": "feePaid", "type": "uint256" }, { "indexed": false, "internalType": "address", "name": "refundAddress", "type": "address" }, { "indexed": false, "internalType": "uint64", "name": "deadline", "type": "uint64" }], "name": "RandomnessRequested", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "uint256", "name": "requestId", "type": "uint256" }, { "indexed": true, "internalType": "address", "name": "consumer", "type": "address" }, { "indexed": false, "internalType": "bool", "name": "success", "type": "bool" }, { "indexed": false, "internalType": "uint32", "name": "gasLimit", "type": "uint32" }], "name": "RefundCallbackAttempted", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, { "indexed": true, "internalType": "address", "name": "recipient", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }], "name": "RefundCreditWithdrawn", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "uint256", "name": "requestId", "type": "uint256" }, { "indexed": true, "internalType": "address", "name": "refundAddress", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }, { "indexed": false, "internalType": "bool", "name": "paid", "type": "bool" }], "name": "RequestRefundedTo", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "uint256", "name": "requestId", "type": "uint256" }, { "indexed": true, "internalType": "uint256", "name": "serveIndex", "type": "uint256" }], "name": "RequestServed", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "implementation", "type": "address" }], "name": "Upgraded", "type": "event" }, { "inputs": [], "name": "CONFIG_DOMAIN", "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "MAX_CALLBACK_GAS", "outputs": [{ "internalType": "uint32", "name": "", "type": "uint32" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "MAX_EVIDENCE_PACKET_BYTES", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "MIN_CALLBACK_GAS", "outputs": [{ "internalType": "uint32", "name": "", "type": "uint32" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "REFUND_CALLBACK_GAS", "outputs": [{ "internalType": "uint32", "name": "", "type": "uint32" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "RESPONSE_TIMEOUT", "outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "SEED_DOMAIN", "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "TRANSCRIPT_DOMAIN", "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "UPGRADE_INTERFACE_VERSION", "outputs": [{ "internalType": "string", "name": "", "type": "string" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "acceptOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "confirmationBlocks", "outputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "earnedFees", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "epochRegistry", "outputs": [{ "internalType": "contract EpochEntropy", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "feeRecipient", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "requestId", "type": "uint256" }, { "components": [{ "internalType": "uint256[2]", "name": "pk", "type": "uint256[2]" }, { "internalType": "uint256[2]", "name": "gamma", "type": "uint256[2]" }, { "internalType": "uint256", "name": "c", "type": "uint256" }, { "internalType": "uint256", "name": "s", "type": "uint256" }, { "internalType": "uint256", "name": "seed", "type": "uint256" }, { "internalType": "address", "name": "uWitness", "type": "address" }, { "internalType": "uint256[2]", "name": "cGammaWitness", "type": "uint256[2]" }, { "internalType": "uint256[2]", "name": "sHashWitness", "type": "uint256[2]" }, { "internalType": "uint256", "name": "zInv", "type": "uint256" }], "internalType": "struct VRF.Proof", "name": "proof", "type": "tuple" }], "name": "fulfillRandomness", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "requestId", "type": "uint256" }], "name": "getMappedResult", "outputs": [{ "internalType": "uint256[]", "name": "", "type": "uint256[]" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "requestId", "type": "uint256" }], "name": "getMapping", "outputs": [{ "components": [{ "internalType": "enum RandomnessMapping.Operation", "name": "operation", "type": "uint8" }, { "internalType": "uint256", "name": "lower", "type": "uint256" }, { "internalType": "uint256", "name": "upper", "type": "uint256" }, { "internalType": "uint32", "name": "count", "type": "uint32" }, { "internalType": "uint32", "name": "population", "type": "uint32" }], "internalType": "struct RandomnessMapping.Spec", "name": "", "type": "tuple" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "fromId", "type": "uint256" }, { "internalType": "uint256", "name": "limit", "type": "uint256" }], "name": "getPendingRequestIds", "outputs": [{ "internalType": "uint256[]", "name": "ids", "type": "uint256[]" }, { "internalType": "uint256", "name": "nextCursor", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "requestId", "type": "uint256" }], "name": "getProofContext", "outputs": [{ "internalType": "uint256", "name": "seed", "type": "uint256" }, { "internalType": "uint64", "name": "deadline", "type": "uint64" }, { "internalType": "bool", "name": "fulfilled", "type": "bool" }, { "internalType": "bool", "name": "refunded", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "requestId", "type": "uint256" }], "name": "getRequest", "outputs": [{ "components": [{ "internalType": "address", "name": "consumer", "type": "address" }, { "internalType": "uint32", "name": "callbackGasLimit", "type": "uint32" }, { "internalType": "uint64", "name": "requestBlock", "type": "uint64" }, { "internalType": "uint64", "name": "targetBlock", "type": "uint64" }, { "internalType": "uint64", "name": "deadline", "type": "uint64" }, { "internalType": "address", "name": "refundAddress", "type": "address" }, { "internalType": "bytes32", "name": "clientSeed", "type": "bytes32" }, { "internalType": "bytes32", "name": "mappingHash", "type": "bytes32" }, { "internalType": "bytes32", "name": "blockHash", "type": "bytes32" }, { "internalType": "bytes32", "name": "randomness", "type": "bytes32" }, { "internalType": "bytes32", "name": "proofHash", "type": "bytes32" }, { "internalType": "bytes32", "name": "transcriptHash", "type": "bytes32" }, { "internalType": "bool", "name": "fulfilled", "type": "bool" }, { "internalType": "bool", "name": "delivered", "type": "bool" }, { "internalType": "bool", "name": "refunded", "type": "bool" }, { "internalType": "uint64", "name": "epochId", "type": "uint64" }, { "internalType": "bytes32", "name": "epochHash", "type": "bytes32" }], "internalType": "struct D20VRFCoordinator.Request", "name": "result", "type": "tuple" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "initialFeeRecipient", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint256[2]", "name": "publicKey", "type": "uint256[2]" }, { "internalType": "address", "name": "initialOwner", "type": "address" }, { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "fee", "type": "uint256" }, { "internalType": "uint16", "name": "confirmations", "type": "uint16" }, { "internalType": "contract EpochEntropy", "name": "registry", "type": "address" }, { "internalType": "uint16", "name": "keeperBps", "type": "uint16" }], "name": "initialize", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "", "type": "address" }], "name": "keeperCredits", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "keeperFeeBps", "outputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "keyHash", "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "lastServedIndex", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "lastServedRequestId", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "bytes32", "name": "randomness", "type": "bytes32" }, { "components": [{ "internalType": "enum RandomnessMapping.Operation", "name": "operation", "type": "uint8" }, { "internalType": "uint256", "name": "lower", "type": "uint256" }, { "internalType": "uint256", "name": "upper", "type": "uint256" }, { "internalType": "uint32", "name": "count", "type": "uint32" }, { "internalType": "uint32", "name": "population", "type": "uint32" }], "internalType": "struct RandomnessMapping.Spec", "name": "spec", "type": "tuple" }], "name": "mapRandomness", "outputs": [{ "internalType": "uint256[]", "name": "", "type": "uint256[]" }], "stateMutability": "pure", "type": "function" }, { "inputs": [], "name": "nextRequestId", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "owner", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "pendingOwner", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "protocolConfigurationHash", "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "proxiableUUID", "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "publicKeyX", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "publicKeyY", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "name": "refundCallbackDelivered", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "", "type": "address" }], "name": "refundCredits", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "requestId", "type": "uint256" }], "name": "refundRequest", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "requestFee", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "bytes32", "name": "clientSeed", "type": "bytes32" }, { "internalType": "uint32", "name": "callbackGasLimit", "type": "uint32" }, { "internalType": "address", "name": "_refundAddress", "type": "address" }, { "components": [{ "internalType": "enum RandomnessMapping.Operation", "name": "operation", "type": "uint8" }, { "internalType": "uint256", "name": "lower", "type": "uint256" }, { "internalType": "uint256", "name": "upper", "type": "uint256" }, { "internalType": "uint32", "name": "count", "type": "uint32" }, { "internalType": "uint32", "name": "population", "type": "uint32" }], "internalType": "struct RandomnessMapping.Spec", "name": "spec", "type": "tuple" }], "name": "requestMappedRandomness", "outputs": [{ "internalType": "uint256", "name": "requestId", "type": "uint256" }], "stateMutability": "payable", "type": "function" }, { "inputs": [{ "internalType": "bytes32", "name": "clientSeed", "type": "bytes32" }, { "internalType": "uint32", "name": "callbackGasLimit", "type": "uint32" }, { "internalType": "address", "name": "_refundAddress", "type": "address" }], "name": "requestRandomness", "outputs": [{ "internalType": "uint256", "name": "requestId", "type": "uint256" }], "stateMutability": "payable", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "requestId", "type": "uint256" }], "name": "requestSeed", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "requestId", "type": "uint256" }, { "internalType": "uint32", "name": "gasLimit", "type": "uint32" }], "name": "retryCallback", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "requestId", "type": "uint256" }, { "internalType": "uint32", "name": "gasLimit", "type": "uint32" }], "name": "retryRefundCallback", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "name": "servedRequestAt", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "next", "type": "address" }], "name": "setFeeRecipient", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "uint16", "name": "next", "type": "uint16" }], "name": "setKeeperFeeBps", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "requestId", "type": "uint256" }], "name": "storeBlockHash", "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "totalKeeperCredits", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "totalRefundCredits", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }], "name": "transferOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "newImplementation", "type": "address" }, { "internalType": "bytes", "name": "data", "type": "bytes" }], "name": "upgradeToAndCall", "outputs": [], "stateMutability": "payable", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "requestId", "type": "uint256" }, { "components": [{ "internalType": "uint256[2]", "name": "pk", "type": "uint256[2]" }, { "internalType": "uint256[2]", "name": "gamma", "type": "uint256[2]" }, { "internalType": "uint256", "name": "c", "type": "uint256" }, { "internalType": "uint256", "name": "s", "type": "uint256" }, { "internalType": "uint256", "name": "seed", "type": "uint256" }, { "internalType": "address", "name": "uWitness", "type": "address" }, { "internalType": "uint256[2]", "name": "cGammaWitness", "type": "uint256[2]" }, { "internalType": "uint256[2]", "name": "sHashWitness", "type": "uint256[2]" }, { "internalType": "uint256", "name": "zInv", "type": "uint256" }], "internalType": "struct VRF.Proof", "name": "proof", "type": "tuple" }], "name": "verifyRequestProof", "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address payable", "name": "recipient", "type": "address" }], "name": "withdrawFees", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address payable", "name": "recipient", "type": "address" }], "name": "withdrawKeeperCredit", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address payable", "name": "recipient", "type": "address" }], "name": "withdrawRefundCredit", "outputs": [], "stateMutability": "nonpayable", "type": "function" }];
3
+ export const epochEntropyAbi = [{ "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, { "inputs": [{ "internalType": "address", "name": "target", "type": "address" }], "name": "AddressEmptyCode", "type": "error" }, { "inputs": [], "name": "AlreadyCommitted", "type": "error" }, { "inputs": [], "name": "AnchorUnavailable", "type": "error" }, { "inputs": [], "name": "ECDSAInvalidSignature", "type": "error" }, { "inputs": [{ "internalType": "uint256", "name": "length", "type": "uint256" }], "name": "ECDSAInvalidSignatureLength", "type": "error" }, { "inputs": [{ "internalType": "bytes32", "name": "s", "type": "bytes32" }], "name": "ECDSAInvalidSignatureS", "type": "error" }, { "inputs": [{ "internalType": "address", "name": "implementation", "type": "address" }], "name": "ERC1967InvalidImplementation", "type": "error" }, { "inputs": [], "name": "ERC1967NonPayable", "type": "error" }, { "inputs": [], "name": "FailedCall", "type": "error" }, { "inputs": [], "name": "InvalidConfig", "type": "error" }, { "inputs": [], "name": "InvalidData", "type": "error" }, { "inputs": [], "name": "InvalidEpoch", "type": "error" }, { "inputs": [], "name": "InvalidInitialization", "type": "error" }, { "inputs": [], "name": "InvalidSigner", "type": "error" }, { "inputs": [], "name": "InvalidTime", "type": "error" }, { "inputs": [], "name": "NotInitializing", "type": "error" }, { "inputs": [], "name": "OnlyCommitter", "type": "error" }, { "inputs": [{ "internalType": "address", "name": "owner", "type": "address" }], "name": "OwnableInvalidOwner", "type": "error" }, { "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], "name": "OwnableUnauthorizedAccount", "type": "error" }, { "inputs": [], "name": "PacketTooLarge", "type": "error" }, { "inputs": [], "name": "PreparationClosed", "type": "error" }, { "inputs": [], "name": "UUPSUnauthorizedCallContext", "type": "error" }, { "inputs": [{ "internalType": "bytes32", "name": "slot", "type": "bytes32" }], "name": "UUPSUnsupportedProxiableUUID", "type": "error" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "previousCommitter", "type": "address" }, { "indexed": true, "internalType": "address", "name": "newCommitter", "type": "address" }], "name": "CommitterChanged", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "uint64", "name": "epochId", "type": "uint64" }, { "indexed": true, "internalType": "bytes32", "name": "epochHash", "type": "bytes32" }, { "indexed": false, "internalType": "bytes", "name": "packet", "type": "bytes" }], "name": "EpochCommitted", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "internalType": "uint64", "name": "version", "type": "uint64" }], "name": "Initialized", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "previousOwner", "type": "address" }, { "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" }], "name": "OwnershipTransferStarted", "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": "implementation", "type": "address" }], "name": "Upgraded", "type": "event" }, { "inputs": [], "name": "EPOCH_DOMAIN", "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "EPOCH_LENGTH", "outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "MAX_PACKET_BYTES", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "RECIPE_DOMAIN", "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "SELECT_DOMAIN", "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "UPGRADE_INTERFACE_VERSION", "outputs": [{ "internalType": "string", "name": "", "type": "string" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "acceptOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "anuSigner", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "btcTradeSigner", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "catalogHash", "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint64", "name": "epochId", "type": "uint64" }], "name": "checkpointEpoch", "outputs": [{ "internalType": "bytes32", "name": "anchor", "type": "bytes32" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "uint64", "name": "epochId", "type": "uint64" }, { "components": [{ "internalType": "uint256", "name": "timestamp", "type": "uint256" }, { "internalType": "bytes", "name": "data", "type": "bytes" }, { "internalType": "bytes", "name": "signature", "type": "bytes" }], "internalType": "struct EpochEntropy.Attestation", "name": "a", "type": "tuple" }], "name": "commitEpoch", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "committer", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }], "name": "epochAnchors", "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "number", "type": "uint256" }], "name": "epochForBlock", "outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint64", "name": "epochId", "type": "uint64" }], "name": "epochStart", "outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "ethTradeSigner", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "firstEpochStart", "outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint64", "name": "epochId", "type": "uint64" }], "name": "getEpoch", "outputs": [{ "components": [{ "internalType": "bytes32", "name": "epochHash", "type": "bytes32" }, { "internalType": "bytes32", "name": "catalogHash", "type": "bytes32" }, { "internalType": "bytes32", "name": "anchorHash", "type": "bytes32" }, { "internalType": "uint8", "name": "source", "type": "uint8" }, { "internalType": "bytes32", "name": "queryHash", "type": "bytes32" }, { "internalType": "bytes32", "name": "dataHash", "type": "bytes32" }, { "internalType": "bytes32", "name": "attestationHash", "type": "bytes32" }, { "internalType": "uint256", "name": "signedAt", "type": "uint256" }, { "internalType": "uint64", "name": "committedBlock", "type": "uint64" }], "internalType": "struct EpochEntropy.Epoch", "name": "", "type": "tuple" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint64", "name": "epochId", "type": "uint64" }], "name": "getEpochSelection", "outputs": [{ "components": [{ "internalType": "uint8", "name": "source", "type": "uint8" }, { "internalType": "address", "name": "airnode", "type": "address" }, { "internalType": "bytes32", "name": "selector", "type": "bytes32" }, { "internalType": "bytes32", "name": "queryHash", "type": "bytes32" }, { "internalType": "string", "name": "canonicalRequest", "type": "string" }], "internalType": "struct EpochEntropy.Selection", "name": "s", "type": "tuple" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "hyperliquidSigner", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address[4]", "name": "signers", "type": "address[4]" }, { "internalType": "address", "name": "initialOwner", "type": "address" }, { "internalType": "address", "name": "initialCommitter", "type": "address" }], "name": "initialize", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "number", "type": "uint256" }], "name": "nextEpochToPrepare", "outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "owner", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "pendingOwner", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "proxiableUUID", "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "next", "type": "address" }], "name": "setCommitter", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }], "name": "transferOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "newImplementation", "type": "address" }, { "internalType": "bytes", "name": "data", "type": "bytes" }], "name": "upgradeToAndCall", "outputs": [], "stateMutability": "payable", "type": "function" }];
@@ -0,0 +1,189 @@
1
+ import { type ApiAttestation } from "./sources.js";
2
+ import { type VRFProof, type RequestContext } from "./verification.js";
3
+ import type { XY } from "./verification.js";
4
+ export declare const EPOCH_LENGTH = 200n;
5
+ export declare const EPOCH_RECIPE_DOMAIN: string;
6
+ export type EpochSigners = readonly [string, string, string, string];
7
+ export interface EpochCatalog {
8
+ signers: EpochSigners;
9
+ registry: string;
10
+ chainId: bigint;
11
+ firstEpochStart: bigint;
12
+ }
13
+ export interface EpochRecord {
14
+ epochHash: string;
15
+ catalogHash: string;
16
+ anchorHash: string;
17
+ source: number | bigint;
18
+ queryHash: string;
19
+ dataHash: string;
20
+ attestationHash: string;
21
+ signedAt: bigint;
22
+ committedBlock: bigint;
23
+ }
24
+ export type EpochRequestContext = RequestContext;
25
+ export interface EpochProtocolConfiguration {
26
+ publicKey: XY;
27
+ feeRecipient: string;
28
+ requestFee: bigint;
29
+ confirmationBlocks: number;
30
+ registry: string;
31
+ catalogHash: string;
32
+ firstEpochStart: bigint;
33
+ }
34
+ export declare function epochCatalogHash(signers: EpochSigners): string;
35
+ export declare function epochStart(firstEpochStart: bigint, epochId: bigint): bigint;
36
+ export declare function epochForBlock(firstEpochStart: bigint, block: bigint): bigint;
37
+ export declare function selectEpoch(catalog: EpochCatalog, epochId: bigint, anchorHash: string): {
38
+ source: number;
39
+ airnode: string;
40
+ selector: string;
41
+ canonicalRequest: string;
42
+ queryHash: string;
43
+ request: {
44
+ operation: string;
45
+ parameters: {
46
+ dex: string;
47
+ type?: undefined;
48
+ length?: undefined;
49
+ size?: undefined;
50
+ assetClass?: undefined;
51
+ symbol?: undefined;
52
+ };
53
+ responseProjection: {
54
+ symbol: string;
55
+ value: string;
56
+ };
57
+ } | {
58
+ operation: string;
59
+ parameters: {
60
+ type: string;
61
+ length: number;
62
+ size: number;
63
+ dex?: undefined;
64
+ assetClass?: undefined;
65
+ symbol?: undefined;
66
+ };
67
+ responseProjection?: undefined;
68
+ } | {
69
+ operation: string;
70
+ parameters: {
71
+ assetClass: string;
72
+ symbol: string;
73
+ dex?: undefined;
74
+ type?: undefined;
75
+ length?: undefined;
76
+ size?: undefined;
77
+ };
78
+ responseProjection?: undefined;
79
+ };
80
+ };
81
+ export declare function verifyEpochAttestation(selected: ReturnType<typeof selectEpoch>, a: ApiAttestation, commitTimestamp: bigint): {
82
+ dataHash: string;
83
+ attestationHash: string;
84
+ signer: string;
85
+ };
86
+ export declare function epochCommitmentHash(catalog: EpochCatalog, epochId: bigint, anchorHash: string, source: number, queryHash: string, dataHash: string, attestationHash: string): string;
87
+ export declare function encodeEpochEvidencePacket(canonicalRequest: string, attestation: ApiAttestation): string;
88
+ export declare function decodeEpochEvidencePacket(packet: string): {
89
+ canonicalRequest: string;
90
+ attestation: ApiAttestation;
91
+ };
92
+ export declare function replayEpochCommitment(input: {
93
+ catalog: EpochCatalog;
94
+ epochId: bigint;
95
+ record: EpochRecord;
96
+ commitTimestamp: bigint;
97
+ packet: string;
98
+ }): {
99
+ dataHash: string;
100
+ attestationHash: string;
101
+ signer: string;
102
+ epochHash: string;
103
+ selected: {
104
+ source: number;
105
+ airnode: string;
106
+ selector: string;
107
+ canonicalRequest: string;
108
+ queryHash: string;
109
+ request: {
110
+ operation: string;
111
+ parameters: {
112
+ dex: string;
113
+ type?: undefined;
114
+ length?: undefined;
115
+ size?: undefined;
116
+ assetClass?: undefined;
117
+ symbol?: undefined;
118
+ };
119
+ responseProjection: {
120
+ symbol: string;
121
+ value: string;
122
+ };
123
+ } | {
124
+ operation: string;
125
+ parameters: {
126
+ type: string;
127
+ length: number;
128
+ size: number;
129
+ dex?: undefined;
130
+ assetClass?: undefined;
131
+ symbol?: undefined;
132
+ };
133
+ responseProjection?: undefined;
134
+ } | {
135
+ operation: string;
136
+ parameters: {
137
+ assetClass: string;
138
+ symbol: string;
139
+ dex?: undefined;
140
+ type?: undefined;
141
+ length?: undefined;
142
+ size?: undefined;
143
+ };
144
+ responseProjection?: undefined;
145
+ };
146
+ };
147
+ };
148
+ export declare function epochProtocolConfigurationHash(c: EpochProtocolConfiguration): string;
149
+ export declare function epochTranscriptHash(c: EpochRequestContext, configurationHash: string, proofHash: string, randomness: string): string;
150
+ export declare function replayEpochCoordinator(input: {
151
+ context: EpochRequestContext;
152
+ configuration: EpochProtocolConfiguration;
153
+ protocolConfigurationHash: string;
154
+ epoch: {
155
+ catalog: EpochCatalog;
156
+ record: EpochRecord;
157
+ commitTimestamp: bigint;
158
+ packet: string;
159
+ };
160
+ requestedAt: bigint;
161
+ deadline: bigint;
162
+ acceptanceTimestamp: bigint;
163
+ acceptanceBlock: bigint;
164
+ vrfProof: VRFProof;
165
+ recorded: {
166
+ fulfilled: boolean;
167
+ randomness: string;
168
+ proofHash: string;
169
+ transcriptHash: string;
170
+ };
171
+ }): {
172
+ request: {
173
+ seed: bigint;
174
+ epochId: bigint;
175
+ epochHash: string;
176
+ };
177
+ reveal: {
178
+ randomness: string;
179
+ };
180
+ map: {
181
+ values: bigint[];
182
+ mappingHash: string;
183
+ };
184
+ proof: {
185
+ proofHash: string;
186
+ transcriptHash: string;
187
+ matchesRecordedState: boolean;
188
+ };
189
+ };
package/dist/epoch.js ADDED
@@ -0,0 +1,107 @@
1
+ import { AbiCoder, id, keccak256, getBytes, toUtf8Bytes, toUtf8String, verifyMessage } from "ethers";
2
+ import { canonicalApiRequest, attestationDigest, hashAttestation, validateApiSignatureEncoding } from "./sources.js";
3
+ import { deriveRequestSeed, hashPublicKey, hashProof, verifyVRFProof } from "./verification.js";
4
+ import { hashMapping, mapRandomness } from "./mapping.js";
5
+ const abi = AbiCoder.defaultAbiCoder();
6
+ export const EPOCH_LENGTH = 200n;
7
+ export const EPOCH_RECIPE_DOMAIN = id("D20_EPOCH_RECIPES");
8
+ export function epochCatalogHash(signers) {
9
+ return keccak256(abi.encode(["bytes32", "address[4]"], [EPOCH_RECIPE_DOMAIN, signers]));
10
+ }
11
+ export function epochStart(firstEpochStart, epochId) {
12
+ if (epochId < 1n)
13
+ throw new Error("Invalid epoch");
14
+ return firstEpochStart + (epochId - 1n) * EPOCH_LENGTH;
15
+ }
16
+ export function epochForBlock(firstEpochStart, block) { return block < firstEpochStart ? 0n : 1n + (block - firstEpochStart) / EPOCH_LENGTH; }
17
+ export function selectEpoch(catalog, epochId, anchorHash) {
18
+ if (epochId < 1n || BigInt(anchorHash) === 0n)
19
+ throw new Error("Invalid epoch anchor");
20
+ const catalogHash = epochCatalogHash(catalog.signers);
21
+ const selector = keccak256(abi.encode(["bytes32", "bytes32", "uint64", "bytes32"], [id("D20_EPOCH_SELECT"), catalogHash, epochId, anchorHash]));
22
+ const source = Number(BigInt(selector) % 4n);
23
+ const request = source === 0 ? { operation: "metaAndAssetCtxs", parameters: { dex: "" }, responseProjection: { symbol: "/0/universe/0/name", value: "/1/0/dayNtlVlm" } }
24
+ : source === 1 ? { operation: "randomNumbers", parameters: { type: "hex8", length: 4, size: 8 } }
25
+ : { operation: "lastTrade", parameters: { assetClass: "crypto", symbol: source === 2 ? "BTCUSD" : "ETHUSD" } };
26
+ const canonicalRequest = canonicalApiRequest(request);
27
+ return { source, airnode: catalog.signers[source], selector, canonicalRequest, queryHash: keccak256(toUtf8Bytes(canonicalRequest)), request };
28
+ }
29
+ export function verifyEpochAttestation(selected, a, commitTimestamp) {
30
+ validateApiSignatureEncoding(a.signature);
31
+ if (a.timestamp > commitTimestamp || commitTimestamp - a.timestamp > 120n)
32
+ throw new Error("Invalid epoch attestation time");
33
+ const body = toUtf8String(a.data);
34
+ const number = "(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?";
35
+ const pattern = selected.source === 0 ? /^\{"symbol":"BTC","value":"(?:0|[1-9][0-9]*)(?:\.[0-9]+)?"\}$/
36
+ : selected.source === 1 ? /^\{"success":true,"type":"hex8","length":"4","data":\["[0-9a-f]{16}","[0-9a-f]{16}","[0-9a-f]{16}","[0-9a-f]{16}"\]\}$/
37
+ : new RegExp(`^\\{"symbol":"${selected.source === 2 ? "BTCUSD" : "ETHUSD"}","price":${number},"size":${number},"timestamp":[1-9][0-9]{0,15}\\}$`);
38
+ if (getBytes(a.data).length > 128 || !pattern.test(body))
39
+ throw new Error("Invalid exact epoch data");
40
+ const signer = verifyMessage(getBytes(attestationDigest(selected.queryHash, a)), a.signature);
41
+ if (signer.toLowerCase() !== selected.airnode.toLowerCase())
42
+ throw new Error("Wrong epoch signer/query");
43
+ return { dataHash: keccak256(a.data), attestationHash: hashAttestation(selected.queryHash, a), signer };
44
+ }
45
+ export function epochCommitmentHash(catalog, epochId, anchorHash, source, queryHash, dataHash, attestationHash) {
46
+ return keccak256(abi.encode(["bytes32", "uint256", "address", "bytes32", "uint64", "uint64", "bytes32", "uint8", "bytes32", "bytes32", "bytes32"], [id("D20_EPOCH"), catalog.chainId, catalog.registry, epochCatalogHash(catalog.signers), epochId, epochStart(catalog.firstEpochStart, epochId), anchorHash, source, queryHash, dataHash, attestationHash]));
47
+ }
48
+ const packetTypes = ["string", "tuple(uint256 timestamp,bytes data,bytes signature)"];
49
+ export function encodeEpochEvidencePacket(canonicalRequest, attestation) {
50
+ const packet = abi.encode(packetTypes, [canonicalRequest, attestation]);
51
+ if (getBytes(packet).length > 2048)
52
+ throw new Error("Epoch packet exceeds 2048 bytes");
53
+ return packet;
54
+ }
55
+ export function decodeEpochEvidencePacket(packet) {
56
+ if (getBytes(packet).length > 2048)
57
+ throw new Error("Epoch packet exceeds 2048 bytes");
58
+ const [canonicalRequest, a] = abi.decode(packetTypes, packet);
59
+ const attestation = { timestamp: a.timestamp, data: a.data, signature: a.signature };
60
+ if (keccak256(encodeEpochEvidencePacket(canonicalRequest, attestation)) !== keccak256(packet))
61
+ throw new Error("Noncanonical epoch packet");
62
+ return { canonicalRequest: canonicalRequest, attestation };
63
+ }
64
+ export function replayEpochCommitment(input) {
65
+ const { catalog, epochId, record } = input, start = epochStart(catalog.firstEpochStart, epochId);
66
+ if (record.committedBlock < start)
67
+ throw new Error("Invalid epoch commit block");
68
+ const selected = selectEpoch(catalog, epochId, record.anchorHash), evidence = decodeEpochEvidencePacket(input.packet);
69
+ if (evidence.canonicalRequest !== selected.canonicalRequest)
70
+ throw new Error("Epoch recipe mismatch");
71
+ const verified = verifyEpochAttestation(selected, evidence.attestation, input.commitTimestamp);
72
+ const epochHash = epochCommitmentHash(catalog, epochId, record.anchorHash, selected.source, selected.queryHash, verified.dataHash, verified.attestationHash);
73
+ if (record.epochHash !== epochHash || record.catalogHash !== epochCatalogHash(catalog.signers) || Number(record.source) !== selected.source || record.queryHash !== selected.queryHash ||
74
+ record.dataHash !== verified.dataHash || record.attestationHash !== verified.attestationHash || record.signedAt !== evidence.attestation.timestamp)
75
+ throw new Error("Epoch record mismatch");
76
+ return { epochHash, selected, ...verified };
77
+ }
78
+ export function epochProtocolConfigurationHash(c) {
79
+ return keccak256(abi.encode(["bytes32", "uint256[2]", "address", "uint256", "uint16", "address", "bytes32", "uint64", "uint64"], [id("D20_VRF_CONFIG"), c.publicKey, c.feeRecipient, c.requestFee, c.confirmationBlocks, c.registry, c.catalogHash, c.firstEpochStart, EPOCH_LENGTH]));
80
+ }
81
+ export function epochTranscriptHash(c, configurationHash, proofHash, randomness) {
82
+ return keccak256(abi.encode(["bytes32", "uint256", "address", "uint256", "bytes32", "bytes32", "bytes32", "bytes32", "bytes32", "uint64", "bytes32"], [id("D20_VRF_TRANSCRIPT"), c.chainId, c.coordinator, c.requestId, configurationHash, c.blockHash, proofHash, randomness, hashMapping(c.mapping), c.epochId, c.epochHash]));
83
+ }
84
+ /// Canonical blocks, transaction inclusion/timestamps and the proxy implementation code active
85
+ /// at each receipt must be independently trusted chain context. A proxy code hash alone is insufficient.
86
+ export function replayEpochCoordinator(input) {
87
+ const c = input.context, cfg = input.configuration, e = input.epoch;
88
+ const epoch = replayEpochCommitment({ ...e, epochId: c.epochId });
89
+ if (e.catalog.registry.toLowerCase() !== cfg.registry.toLowerCase() || e.catalog.chainId !== c.chainId || e.catalog.firstEpochStart !== cfg.firstEpochStart || epochCatalogHash(e.catalog.signers) !== cfg.catalogHash || epoch.epochHash !== c.epochHash || epochForBlock(cfg.firstEpochStart, c.requestBlock) !== c.epochId)
90
+ throw new Error("Epoch request binding mismatch");
91
+ const expectedTarget = c.requestBlock > e.record.committedBlock + 1n ? c.requestBlock : e.record.committedBlock + 1n;
92
+ if (c.targetBlock !== expectedTarget || e.record.committedBlock >= c.targetBlock)
93
+ throw new Error("Invalid future randomness block");
94
+ if (hashPublicKey(cfg.publicKey) !== c.keyHash || epochProtocolConfigurationHash(cfg) !== input.protocolConfigurationHash)
95
+ throw new Error("Protocol configuration mismatch");
96
+ if (cfg.confirmationBlocks < 1 || cfg.confirmationBlocks > 64 || input.acceptanceBlock < c.targetBlock + BigInt(cfg.confirmationBlocks))
97
+ throw new Error("Invalid acceptance block");
98
+ if (input.deadline !== input.requestedAt + 60n || input.acceptanceTimestamp < input.requestedAt || input.acceptanceTimestamp > input.deadline || e.commitTimestamp > input.acceptanceTimestamp)
99
+ throw new Error("Invalid acceptance time");
100
+ const seed = deriveRequestSeed(c), vrf = verifyVRFProof(input.vrfProof, cfg.publicKey, seed);
101
+ if (!vrf.valid)
102
+ throw new Error(vrf.reason);
103
+ const proofHash = hashProof(input.vrfProof), transcriptHash = epochTranscriptHash(c, input.protocolConfigurationHash, proofHash, vrf.randomness), r = input.recorded;
104
+ if (!r.fulfilled || r.randomness !== vrf.randomness || r.proofHash !== proofHash || r.transcriptHash !== transcriptHash)
105
+ throw new Error("Recorded coordinator state mismatch");
106
+ return { request: { seed, epochId: c.epochId, epochHash: c.epochHash }, reveal: { randomness: vrf.randomness }, map: { values: mapRandomness(vrf.randomness, c.mapping), mappingHash: hashMapping(c.mapping) }, proof: { proofHash, transcriptHash, matchesRecordedState: true } };
107
+ }
@@ -0,0 +1,6 @@
1
+ import type { VRFProof } from "./verification.js";
2
+ export declare const EVIDENCE_PACKET_BYTES = 416;
3
+ export declare function encodeEvidencePacket(proof: VRFProof): string;
4
+ export declare function decodeEvidencePacket(packet: string): {
5
+ proof: VRFProof;
6
+ };
@@ -0,0 +1,16 @@
1
+ import { AbiCoder, getBytes, keccak256 } from "ethers";
2
+ const abi = AbiCoder.defaultAbiCoder();
3
+ const types = ["tuple(uint256[2] pk,uint256[2] gamma,uint256 c,uint256 s,uint256 seed,address uWitness,uint256[2] cGammaWitness,uint256[2] sHashWitness,uint256 zInv)"];
4
+ export const EVIDENCE_PACKET_BYTES = 416;
5
+ export function encodeEvidencePacket(proof) { return abi.encode(types, [proof]); }
6
+ /// Decoding is not verification. Replay with independently trusted chain context.
7
+ export function decodeEvidencePacket(packet) {
8
+ if (getBytes(packet).length !== EVIDENCE_PACKET_BYTES)
9
+ throw new Error("Evidence packet must be exactly 416 bytes");
10
+ const [p] = abi.decode(types, packet);
11
+ const pair = (v) => [v[0], v[1]];
12
+ const proof = { pk: pair(p.pk), gamma: pair(p.gamma), c: p.c, s: p.s, seed: p.seed, uWitness: p.uWitness, cGammaWitness: pair(p.cGammaWitness), sHashWitness: pair(p.sHashWitness), zInv: p.zInv };
13
+ if (keccak256(encodeEvidencePacket(proof)) !== keccak256(packet))
14
+ throw new Error("Noncanonical evidence packet");
15
+ return { proof };
16
+ }
@@ -0,0 +1,10 @@
1
+ export { builtins, Operation, validateMapping, hashMapping, mapRandomness } from "./mapping.js";
2
+ export type { MappingSpec } from "./mapping.js";
3
+ export { deriveRequestSeed, hashPublicKey, hashProof, verifyVRFProof } from "./verification.js";
4
+ export type { RequestContext, VRFProof, XY } from "./verification.js";
5
+ export { canonicalApiRequest, attestationDigest, hashAttestation, validateApiSignatureEncoding } from "./sources.js";
6
+ export type { ApiRequest, ApiAttestation } from "./sources.js";
7
+ export { replayCoordinator, transcriptHash } from "./replay.js";
8
+ export { encodeEvidencePacket, decodeEvidencePacket, EVIDENCE_PACKET_BYTES } from "./evidence.js";
9
+ export { EPOCH_LENGTH, EPOCH_RECIPE_DOMAIN, epochCatalogHash, epochStart, epochForBlock, selectEpoch, verifyEpochAttestation, epochCommitmentHash, encodeEpochEvidencePacket, decodeEpochEvidencePacket, replayEpochCommitment, epochProtocolConfigurationHash } from "./epoch.js";
10
+ export type { EpochCatalog, EpochSigners, EpochRecord, EpochProtocolConfiguration } from "./epoch.js";
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ export { builtins, Operation, validateMapping, hashMapping, mapRandomness } from "./mapping.js";
2
+ export { deriveRequestSeed, hashPublicKey, hashProof, verifyVRFProof } from "./verification.js";
3
+ export { canonicalApiRequest, attestationDigest, hashAttestation, validateApiSignatureEncoding } from "./sources.js";
4
+ export { replayCoordinator, transcriptHash } from "./replay.js";
5
+ export { encodeEvidencePacket, decodeEvidencePacket, EVIDENCE_PACKET_BYTES } from "./evidence.js";
6
+ export { EPOCH_LENGTH, EPOCH_RECIPE_DOMAIN, epochCatalogHash, epochStart, epochForBlock, selectEpoch, verifyEpochAttestation, epochCommitmentHash, encodeEpochEvidencePacket, decodeEpochEvidencePacket, replayEpochCommitment, epochProtocolConfigurationHash } from "./epoch.js";
@@ -0,0 +1,35 @@
1
+ export declare const Operation: {
2
+ readonly Raw: 0;
3
+ readonly DiceRoll: 1;
4
+ readonly CoinFlip: 2;
5
+ readonly NumberRange: 3;
6
+ readonly ChooseOne: 4;
7
+ readonly ChooseMany: 5;
8
+ readonly Shuffle: 6;
9
+ };
10
+ export interface MappingSpec {
11
+ operation: number;
12
+ lower: bigint;
13
+ upper: bigint;
14
+ count: number;
15
+ population: number;
16
+ }
17
+ export declare const builtins: {
18
+ raw: () => MappingSpec;
19
+ diceRoll: (sides: bigint, count?: number) => MappingSpec;
20
+ dN: (sides: bigint) => MappingSpec;
21
+ d20: () => MappingSpec;
22
+ d12: () => MappingSpec;
23
+ d10: () => MappingSpec;
24
+ d8: () => MappingSpec;
25
+ d6: () => MappingSpec;
26
+ d4: () => MappingSpec;
27
+ coinFlip: () => MappingSpec;
28
+ numberRange: (min: bigint, max: bigint) => MappingSpec;
29
+ chooseOne: (size: number) => MappingSpec;
30
+ chooseMany: (size: number, count: number) => MappingSpec;
31
+ shuffle: (size: number) => MappingSpec;
32
+ };
33
+ export declare function validateMapping(s: MappingSpec): void;
34
+ export declare function hashMapping(s: MappingSpec): string;
35
+ export declare function mapRandomness(randomness: string, s: MappingSpec): bigint[];
@@ -0,0 +1,97 @@
1
+ import { AbiCoder, id, keccak256 } from "ethers";
2
+ export const Operation = { Raw: 0, DiceRoll: 1, CoinFlip: 2, NumberRange: 3, ChooseOne: 4, ChooseMany: 5, Shuffle: 6 };
3
+ const MAX = (1n << 256n) - 1n;
4
+ const abi = AbiCoder.defaultAbiCoder();
5
+ const MAP_DOMAIN = id("D20_MAP");
6
+ function spec(operation, lower = 0n, upper = 0n, count = 1, population = 0) {
7
+ const result = { operation, lower, upper, count, population };
8
+ validateMapping(result);
9
+ return result;
10
+ }
11
+ export const builtins = {
12
+ raw: () => spec(Operation.Raw, 0n, 0n, 0),
13
+ diceRoll: (sides, count = 1) => spec(Operation.DiceRoll, 0n, sides, count),
14
+ dN: (sides) => spec(Operation.DiceRoll, 0n, sides),
15
+ d20: () => spec(Operation.DiceRoll, 0n, 20n),
16
+ d12: () => spec(Operation.DiceRoll, 0n, 12n),
17
+ d10: () => spec(Operation.DiceRoll, 0n, 10n),
18
+ d8: () => spec(Operation.DiceRoll, 0n, 8n),
19
+ d6: () => spec(Operation.DiceRoll, 0n, 6n),
20
+ d4: () => spec(Operation.DiceRoll, 0n, 4n),
21
+ coinFlip: () => spec(Operation.CoinFlip),
22
+ numberRange: (min, max) => spec(Operation.NumberRange, min, max),
23
+ chooseOne: (size) => spec(Operation.ChooseOne, 0n, 0n, 1, size),
24
+ chooseMany: (size, count) => spec(Operation.ChooseMany, 0n, 0n, count, size),
25
+ shuffle: (size) => spec(Operation.Shuffle, 0n, 0n, size, size),
26
+ };
27
+ export function validateMapping(s) {
28
+ const bad = () => { throw new Error("Invalid mapping parameters"); };
29
+ if (!Number.isInteger(s.operation) || s.operation < 0 || s.operation > 6 ||
30
+ !Number.isInteger(s.count) || !Number.isInteger(s.population) ||
31
+ s.count < 0 || s.population < 0 || s.lower < 0n || s.upper < 0n || s.lower > MAX || s.upper > MAX)
32
+ bad();
33
+ switch (s.operation) {
34
+ case Operation.Raw:
35
+ if (s.lower !== 0n || s.upper !== 0n || s.count !== 0 || s.population !== 0)
36
+ bad();
37
+ break;
38
+ case Operation.DiceRoll:
39
+ if (s.lower !== 0n || s.upper < 2n || s.count < 1 || s.count > 128 || s.population !== 0)
40
+ bad();
41
+ break;
42
+ case Operation.CoinFlip:
43
+ if (s.lower !== 0n || s.upper !== 0n || s.count !== 1 || s.population !== 0)
44
+ bad();
45
+ break;
46
+ case Operation.NumberRange:
47
+ if (s.lower > s.upper || s.count !== 1 || s.population !== 0)
48
+ bad();
49
+ break;
50
+ default:
51
+ if (s.lower !== 0n || s.upper !== 0n || s.population < 1 || s.population > 256)
52
+ bad();
53
+ if (s.operation === Operation.ChooseOne && s.count !== 1)
54
+ bad();
55
+ if (s.operation === Operation.ChooseMany && (s.count < 1 || s.count > s.population))
56
+ bad();
57
+ if (s.operation === Operation.Shuffle && s.count !== s.population)
58
+ bad();
59
+ }
60
+ }
61
+ export function hashMapping(s) {
62
+ validateMapping(s);
63
+ return keccak256(abi.encode(["uint8", "uint256", "uint256", "uint32", "uint32"], [s.operation, s.lower, s.upper, s.count, s.population]));
64
+ }
65
+ export function mapRandomness(randomness, s) {
66
+ validateMapping(s);
67
+ if (!/^0x[0-9a-fA-F]{64}$/.test(randomness))
68
+ throw new Error("Expected bytes32 randomness");
69
+ let cursor = 0n;
70
+ const next = () => BigInt(keccak256(abi.encode(["bytes32", "bytes32", "uint256"], [MAP_DOMAIN, randomness, cursor++])));
71
+ const sample = (bound) => {
72
+ const threshold = (1n << 256n) % bound;
73
+ let word;
74
+ do {
75
+ word = next();
76
+ } while (word < threshold);
77
+ return word % bound;
78
+ };
79
+ switch (s.operation) {
80
+ case Operation.Raw: return [BigInt(randomness)];
81
+ case Operation.DiceRoll: return Array.from({ length: s.count }, () => sample(s.upper) + 1n);
82
+ case Operation.CoinFlip: return [sample(2n)];
83
+ case Operation.NumberRange:
84
+ return [s.lower === 0n && s.upper === MAX ? next() : s.lower + sample(s.upper - s.lower + 1n)];
85
+ case Operation.ChooseOne: return [sample(BigInt(s.population))];
86
+ default: {
87
+ const pool = Array.from({ length: s.population }, (_, i) => BigInt(i));
88
+ const output = [];
89
+ for (let i = 0; i < s.count; i++) {
90
+ const j = i + Number(sample(BigInt(s.population - i)));
91
+ [pool[i], pool[j]] = [pool[j], pool[i]];
92
+ output.push(pool[i]);
93
+ }
94
+ return output;
95
+ }
96
+ }
97
+ }
@@ -0,0 +1 @@
1
+ export { replayEpochCoordinator as replayCoordinator, epochTranscriptHash as transcriptHash } from "./epoch.js";
package/dist/replay.js ADDED
@@ -0,0 +1 @@
1
+ export { replayEpochCoordinator as replayCoordinator, epochTranscriptHash as transcriptHash } from "./epoch.js";