Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 91 additions & 67 deletions packages/evm-rpc-canister-types/evm_rpc.did
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
type Auth = variant { FreeRpc; PriorityRpc; RegisterProvider; Manage };
type Block = record {
miner : text;
totalDifficulty : nat;
totalDifficulty : opt nat;
receiptsRoot : text;
stateRoot : text;
hash : text;
difficulty : nat;
difficulty : opt nat;
size : nat;
uncles : vec text;
baseFeePerGas : nat;
baseFeePerGas : opt nat;
extraData : text;
transactionsRoot : opt text;
sha3Uncles : text;
Expand Down Expand Up @@ -36,18 +35,21 @@ type EthMainnetService = variant {
BlockPi;
Cloudflare;
PublicNode;
Llama;
};
type EthSepoliaService = variant {
Alchemy;
Ankr;
BlockPi;
PublicNode;
Sepolia;
};
type L2MainnetService = variant {
Alchemy;
Ankr;
BlockPi;
PublicNode;
Llama;
};
type FeeHistory = record {
reward : vec vec nat;
Expand All @@ -67,6 +69,31 @@ type GetLogsArgs = record {
topics : opt vec Topic;
};
type GetTransactionCountArgs = record { address : text; block : BlockTag };
type CallArgs = record {
transaction : TransactionRequest;
block : opt BlockTag;
};
type TransactionRequest = record {
"type" : opt text;
nonce : opt nat;
to : opt text;
from : opt text;
gas : opt nat;
value : opt nat;
input : opt text;
gasPrice : opt nat;
maxPriorityFeePerGas : opt nat;
maxFeePerGas : opt nat;
maxFeePerBlobGas : opt nat;
accessList: opt vec AccessListEntry;
blobVersionedHashes : opt vec text;
blobs : opt vec text;
chainId : opt nat;
};
type AccessListEntry = record {
address : text;
storageKeys : vec text;
};
type HttpHeader = record { value : text; name : text };
type HttpOutcallError = variant {
IcError : record { code : RejectionCode; message : text };
Expand All @@ -76,8 +103,17 @@ type HttpOutcallError = variant {
parsingError : opt text;
};
};
type InitArgs = record {
nodesInSubnet : nat32;
type InstallArgs = record {
demo : opt bool;
manageApiKeys : opt vec principal;
logFilter : opt LogFilter;
};
type Regex = text;
type LogFilter = variant {
ShowAll;
HideAll;
ShowPattern : Regex;
HidePattern : Regex;
};
type JsonRpcError = record { code : int64; message : text };
type LogEntry = record {
Expand All @@ -91,11 +127,6 @@ type LogEntry = record {
logIndex : opt nat;
removed : bool;
};
type ManageProviderArgs = record {
providerId : nat64;
"service" : opt RpcService;
primary : opt bool;
};
type Metrics = record {
requests : vec record { record { text; text }; nat64 };
responses : vec record { record { text; text; text }; nat64 };
Expand Down Expand Up @@ -130,29 +161,37 @@ type MultiSendRawTransactionResult = variant {
Consistent : SendRawTransactionResult;
Inconsistent : vec record { RpcService; SendRawTransactionResult };
};
type MultiCallResult = variant {
Consistent : CallResult;
Inconsistent : vec record { RpcService; CallResult };
};
type ProviderError = variant {
TooFewCycles : record { expected : nat; received : nat };
MissingRequiredProvider;
ProviderNotFound;
NoPermission;
InvalidRpcConfig : text ;
};
type ProviderId = nat64;
type ProviderView = record {
cyclesPerCall : nat64;
owner : principal;
hostname : text;
primary : bool;
chainId : nat64;
cyclesPerMessageByte : nat64;
providerId : nat64;
};
type RegisterProviderArgs = record {
cyclesPerCall : nat64;
credentialPath : text;
hostname : text;
credentialHeaders : opt vec HttpHeader;
chainId : nat64;
cyclesPerMessageByte : nat64;
type ChainId = nat64;
type Provider = record {
providerId : ProviderId;
chainId : ChainId;
access : RpcAccess;
alias : opt RpcService;
};
type RpcAccess = variant {
Authenticated : record {
auth : RpcAuth;
publicUrl : opt text;
};
Unauthenticated : record {
publicUrl : text;
};
};
type RpcAuth = variant {
BearerToken : record { url : text };
UrlParameter : record { urlPattern : text };
};
type RejectionCode = variant {
NoError;
Expand All @@ -163,7 +202,7 @@ type RejectionCode = variant {
SysFatal;
CanisterReject;
};
type FeeHistoryResult = variant { Ok : opt FeeHistory; Err : RpcError };
type FeeHistoryResult = variant { Ok : FeeHistory; Err : RpcError };
type GetBlockByNumberResult = variant { Ok : Block; Err : RpcError };
type GetLogsResult = variant { Ok : vec LogEntry; Err : RpcError };
type GetTransactionCountResult = variant { Ok : nat; Err : RpcError };
Expand All @@ -175,9 +214,19 @@ type SendRawTransactionResult = variant {
Ok : SendRawTransactionStatus;
Err : RpcError;
};
type CallResult = variant { Ok : text; Err : RpcError };
type RequestResult = variant { Ok : text; Err : RpcError };
type RequestCostResult = variant { Ok : nat; Err : RpcError };
type RpcConfig = record { responseSizeEstimate : opt nat64 };
type RpcConfig = record { responseSizeEstimate : opt nat64; responseConsensus : opt ConsensusStrategy };
type ConsensusStrategy = variant {
Equality;
Threshold : record {
// Total number of providers to be queried. Can be omitted, if that number can be inferred (e.g., providers are specified in the request).
total : opt nat8;
// Minimum number of providers that must return the same (non-error) result.
min : nat8;
};
};
type RpcError = variant {
JsonRpcError : JsonRpcError;
ProviderError : ProviderError;
Expand All @@ -186,8 +235,7 @@ type RpcError = variant {
};
type RpcApi = record { url : text; headers : opt vec HttpHeader };
type RpcService = variant {
Chain : nat64;
Provider : nat64;
Provider : ProviderId;
Custom : RpcApi;
EthSepolia : EthSepoliaService;
EthMainnet : EthMainnetService;
Expand All @@ -197,7 +245,7 @@ type RpcService = variant {
};
type RpcServices = variant {
Custom : record {
chainId : nat64;
chainId : ChainId;
services : vec RpcApi;
};
EthSepolia : opt vec EthSepoliaService;
Expand All @@ -216,8 +264,8 @@ type SendRawTransactionStatus = variant {
// See https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getlogs
type Topic = vec text;
type TransactionReceipt = record {
to : text;
status : nat;
to : opt text;
status : opt nat;
transactionHash : text;
blockNumber : nat;
from : text;
Expand All @@ -230,47 +278,23 @@ type TransactionReceipt = record {
contractAddress : opt text;
gasUsed : nat;
};
type UpdateProviderArgs = record {
cyclesPerCall : opt nat64;
credentialPath : opt text;
hostname : opt text;
credentialHeaders : opt vec HttpHeader;
primary : opt bool;
cyclesPerMessageByte : opt nat64;
providerId : nat64;
};
type ValidationError = variant {
Custom : text;
HostNotAllowed : text;
UrlParseError : text;
InvalidHex : text;
CredentialPathNotAllowed;
CredentialHeaderNotAllowed;
};
service : (InitArgs) -> {
authorize : (principal, Auth) -> (success : bool);
deauthorize : (principal, Auth) -> (success : bool);
service : (InstallArgs) -> {
eth_feeHistory : (RpcServices, opt RpcConfig, FeeHistoryArgs) -> (MultiFeeHistoryResult);
eth_getBlockByNumber : (RpcServices, opt RpcConfig, BlockTag) -> (MultiGetBlockByNumberResult);
eth_getLogs : (RpcServices, opt RpcConfig, GetLogsArgs) -> (MultiGetLogsResult);
eth_getTransactionCount : (RpcServices, opt RpcConfig, GetTransactionCountArgs) -> (
MultiGetTransactionCountResult
);
eth_getTransactionCount : (RpcServices, opt RpcConfig, GetTransactionCountArgs) -> (MultiGetTransactionCountResult);
eth_getTransactionReceipt : (RpcServices, opt RpcConfig, hash : text) -> (MultiGetTransactionReceiptResult);
eth_sendRawTransaction : (RpcServices, opt RpcConfig, rawSignedTransactionHex : text) -> (MultiSendRawTransactionResult);
getAccumulatedCycleCount : (ProviderId) -> (cycles : nat) query;
getAuthorized : (Auth) -> (vec principal) query;
getMetrics : () -> (Metrics) query;
getNodesInSubnet : () -> (numberOfNodes : nat32) query;
getOpenRpcAccess : () -> (active : bool) query;
getProviders : () -> (vec ProviderView) query;
getServiceProviderMap : () -> (vec record { RpcService; nat64 }) query;
manageProvider : (ManageProviderArgs) -> ();
registerProvider : (RegisterProviderArgs) -> (nat64);
eth_call : (RpcServices, opt RpcConfig, CallArgs) -> (MultiCallResult);
request : (RpcService, json : text, maxResponseBytes : nat64) -> (RequestResult);
requestCost : (RpcService, json : text, maxResponseBytes : nat64) -> (RequestCostResult) query;
setOpenRpcAccess : (active : bool) -> ();
unregisterProvider : (ProviderId) -> (bool);
updateProvider : (UpdateProviderArgs) -> ();
withdrawAccumulatedCycles : (ProviderId, recipient : principal) -> ();
};
getMetrics : () -> (Metrics) query;
getNodesInSubnet : () -> (numberOfNodes : nat32) query;
getProviders : () -> (vec Provider) query;
getServiceProviderMap : () -> (vec record { RpcService; ProviderId }) query;
updateApiKeys : (vec record { ProviderId; opt text }) -> ();
};
41 changes: 31 additions & 10 deletions packages/evm-rpc-canister-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,11 @@ pub struct RpcApi {
#[derive(CandidType, Deserialize, Debug, Clone)]
pub enum EthMainnetService {
Alchemy,
Ankr,
BlockPi,
Cloudflare,
PublicNode,
Ankr,
Cloudflare,
Llama,
}

#[derive(CandidType, Deserialize, Debug, Clone)]
Expand All @@ -62,9 +63,29 @@ pub enum RpcServices {
EthMainnet(Option<Vec<EthMainnetService>>),
}

#[derive(CandidType, Deserialize, Debug, Clone)]
#[derive(Clone, Debug, PartialEq, Eq, Default, CandidType, Deserialize)]
pub struct RpcConfig {
pub responseSizeEstimate: Option<u64>,
pub responseConsensus: Option<ConsensusStrategy>,
}

#[derive(Clone, Debug, PartialEq, Eq, Default, CandidType, Deserialize)]
pub enum ConsensusStrategy {
/// All providers must return the same non-error result.
#[default]
Equality,

/// A subset of providers must return the same non-error result.
Threshold {
/// Total number of providers to be queried:
/// * If `None`, will be set to the number of providers manually specified in `RpcServices`.
/// * If `Some`, must correspond to the number of manually specified providers in `RpcServices`;
/// or if they are none indicating that default providers should be used, select the corresponding number of providers.
total: Option<u8>,

/// Minimum number of providers that must return the same (non-error) result.
min: u8,
},
}

#[derive(CandidType, Deserialize, Debug, Clone)]
Expand Down Expand Up @@ -159,14 +180,13 @@ pub enum FeeHistoryResult {

#[derive(CandidType, Deserialize, Debug, Clone)]
pub enum RpcService {
Provider(u64),
Custom(RpcApi),
EthMainnet(EthMainnetService),
EthSepolia(EthSepoliaService),
ArbitrumOne(L2MainnetService),
BaseMainnet(L2MainnetService),
Custom(RpcApi),
OptimismMainnet(L2MainnetService),
ArbitrumOne(L2MainnetService),
EthMainnet(EthMainnetService),
Chain(u64),
Provider(u64),
}

#[derive(CandidType, Deserialize, Debug, Clone)]
Expand Down Expand Up @@ -201,13 +221,13 @@ pub struct Block {
pub mixHash: String,
}

#[derive(CandidType, Deserialize, Debug, Clone)]
#[derive(CandidType, Deserialize, Clone)]
pub enum GetBlockByNumberResult {
Ok(Block),
Err(RpcError),
}

#[derive(CandidType, Deserialize, Debug, Clone)]
#[derive(CandidType, Deserialize, Clone)]
pub enum MultiGetBlockByNumberResult {
Consistent(GetBlockByNumberResult),
Inconsistent(Vec<(RpcService, GetBlockByNumberResult)>),
Expand Down Expand Up @@ -404,6 +424,7 @@ impl EvmRpcCanister {
arg2: BlockTag,
cycles: u128,
) -> Result<(MultiGetBlockByNumberResult,)> {
ic_cdk::println!("Calling eth_get_block_by_number. CONFIG: {:?}", arg1);
call_with_payment128(self.0, "eth_getBlockByNumber", (arg0, arg1, arg2), cycles).await
}
pub async fn eth_get_logs(
Expand Down