feat(server): initial EVM functionality impl
This commit is contained in:
@@ -1,14 +1,67 @@
|
||||
#![allow(unused)]
|
||||
#![allow(clippy::all)]
|
||||
|
||||
use crate::db::schema::{self, aead_encrypted, arbiter_settings, root_key_history, tls_history};
|
||||
use crate::db::schema::{
|
||||
self, aead_encrypted, arbiter_settings, evm_basic_grant, evm_ether_transfer_grant,
|
||||
evm_ether_transfer_grant_target, evm_ether_transfer_log, evm_ether_transfer_volume_limit,
|
||||
evm_token_approval_grant, evm_token_approval_grant_target,
|
||||
evm_token_approval_log, evm_token_transfer_grant, evm_token_transfer_grant_target,
|
||||
evm_token_transfer_log, evm_token_transfer_volume_limit, evm_unknown_call_grant,
|
||||
evm_unknown_call_log, evm_wallet, root_key_history, tls_history,
|
||||
};
|
||||
use chrono::{DateTime, Utc};
|
||||
use diesel::{prelude::*, sqlite::Sqlite};
|
||||
use restructed::Models;
|
||||
|
||||
pub mod types {
|
||||
use std::os::unix;
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
pub struct SqliteTimestamp(DateTime<Utc>);
|
||||
use diesel::{
|
||||
deserialize::{FromSql, FromSqlRow},
|
||||
expression::AsExpression,
|
||||
serialize::{IsNull, ToSql},
|
||||
sql_types::Integer,
|
||||
sqlite::{Sqlite, SqliteType},
|
||||
};
|
||||
|
||||
#[derive(Debug, FromSqlRow, AsExpression)]
|
||||
#[sql_type = "Integer"]
|
||||
#[repr(transparent)] // hint compiler to optimize the wrapper struct away
|
||||
pub struct SqliteTimestamp(pub DateTime<Utc>);
|
||||
|
||||
impl ToSql<Integer, Sqlite> for SqliteTimestamp {
|
||||
fn to_sql<'b>(
|
||||
&'b self,
|
||||
out: &mut diesel::serialize::Output<'b, '_, Sqlite>,
|
||||
) -> diesel::serialize::Result {
|
||||
let unix_timestamp = self.0.timestamp() as i32;
|
||||
out.set_value(unix_timestamp);
|
||||
Ok(IsNull::No)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromSql<Integer, Sqlite> for SqliteTimestamp {
|
||||
fn from_sql(
|
||||
mut bytes: <Sqlite as diesel::backend::Backend>::RawValue<'_>,
|
||||
) -> diesel::deserialize::Result<Self> {
|
||||
let Some(SqliteType::Integer) = bytes.value_type() else {
|
||||
return Err(format!(
|
||||
"Expected Integer type for SqliteTimestamp, got {:?}",
|
||||
bytes.value_type()
|
||||
)
|
||||
.into());
|
||||
};
|
||||
|
||||
let unix_timestamp = bytes.read_integer();
|
||||
let datetime = DateTime::from_timestamp(unix_timestamp as i64, 0)
|
||||
.ok_or("Timestamp is out of bounds")?;
|
||||
|
||||
Ok(SqliteTimestamp(datetime))
|
||||
}
|
||||
}
|
||||
}
|
||||
pub use types::*;
|
||||
|
||||
#[derive(Models, Queryable, Debug, Insertable, Selectable)]
|
||||
#[view(
|
||||
@@ -58,9 +111,9 @@ pub struct TlsHistory {
|
||||
pub id: i32,
|
||||
pub cert: String,
|
||||
pub cert_key: String, // PEM Encoded private key
|
||||
pub ca_cert: String, // PEM Encoded certificate for cert signing
|
||||
pub ca_key: String, // PEM Encoded public key for cert signing
|
||||
pub created_at: i32,
|
||||
pub ca_cert: String, // PEM Encoded certificate for cert signing
|
||||
pub ca_key: String, // PEM Encoded public key for cert signing
|
||||
pub created_at: SqliteTimestamp,
|
||||
}
|
||||
|
||||
#[derive(Queryable, Debug, Insertable, Selectable)]
|
||||
@@ -68,7 +121,22 @@ pub struct TlsHistory {
|
||||
pub struct ArbiterSettings {
|
||||
pub id: i32,
|
||||
pub root_key_id: Option<i32>, // references root_key_history.id
|
||||
pub tls_id: Option<i32>, // references tls_history.id
|
||||
pub tls_id: Option<i32>, // references tls_history.id
|
||||
}
|
||||
|
||||
#[derive(Models, Queryable, Debug, Insertable, Selectable)]
|
||||
#[diesel(table_name = evm_wallet, check_for_backend(Sqlite))]
|
||||
#[view(
|
||||
NewEvmWallet,
|
||||
derive(Insertable),
|
||||
omit(id, created_at),
|
||||
attributes_with = "deriveless"
|
||||
)]
|
||||
pub struct EvmWallet {
|
||||
pub id: i32,
|
||||
pub address: Vec<u8>,
|
||||
pub aead_encrypted_id: i32,
|
||||
pub created_at: SqliteTimestamp,
|
||||
}
|
||||
|
||||
#[derive(Queryable, Debug)]
|
||||
@@ -77,8 +145,8 @@ pub struct ProgramClient {
|
||||
pub id: i32,
|
||||
pub public_key: Vec<u8>,
|
||||
pub nonce: i32,
|
||||
pub created_at: i32,
|
||||
pub updated_at: i32,
|
||||
pub created_at: SqliteTimestamp,
|
||||
pub updated_at: SqliteTimestamp,
|
||||
}
|
||||
|
||||
#[derive(Queryable, Debug)]
|
||||
@@ -87,6 +155,237 @@ pub struct UseragentClient {
|
||||
pub id: i32,
|
||||
pub public_key: Vec<u8>,
|
||||
pub nonce: i32,
|
||||
pub created_at: i32,
|
||||
pub updated_at: i32,
|
||||
pub created_at: SqliteTimestamp,
|
||||
pub updated_at: SqliteTimestamp,
|
||||
}
|
||||
|
||||
#[derive(Models, Queryable, Debug, Insertable, Selectable)]
|
||||
#[diesel(table_name = evm_basic_grant, check_for_backend(Sqlite))]
|
||||
#[view(
|
||||
NewEvmBasicGrant,
|
||||
derive(Insertable),
|
||||
omit(id, created_at),
|
||||
attributes_with = "deriveless"
|
||||
)]
|
||||
pub struct EvmBasicGrant {
|
||||
pub id: i32,
|
||||
pub wallet_id: i32, // references evm_wallet.id
|
||||
pub client_id: i32, // references program_client.id
|
||||
pub chain_id: i32,
|
||||
pub valid_from: Option<SqliteTimestamp>,
|
||||
pub valid_until: Option<SqliteTimestamp>,
|
||||
pub max_gas_fee_per_gas: Option<Vec<u8>>,
|
||||
pub max_priority_fee_per_gas: Option<Vec<u8>>,
|
||||
pub rate_limit_count: Option<i32>,
|
||||
pub rate_limit_window_secs: Option<i32>,
|
||||
pub revoked_at: Option<SqliteTimestamp>,
|
||||
pub created_at: SqliteTimestamp,
|
||||
}
|
||||
|
||||
#[derive(Models, Queryable, Debug, Insertable, Selectable)]
|
||||
#[diesel(table_name = evm_ether_transfer_grant, check_for_backend(Sqlite))]
|
||||
#[view(
|
||||
NewEvmEtherTransferGrant,
|
||||
derive(Insertable),
|
||||
omit(id),
|
||||
attributes_with = "deriveless"
|
||||
)]
|
||||
pub struct EvmEtherTransferGrant {
|
||||
pub id: i32,
|
||||
pub basic_grant_id: i32,
|
||||
}
|
||||
|
||||
#[derive(Models, Queryable, Debug, Insertable, Selectable)]
|
||||
#[diesel(table_name = evm_ether_transfer_grant_target, check_for_backend(Sqlite))]
|
||||
#[view(
|
||||
NewEvmEtherTransferGrantTarget,
|
||||
derive(Insertable),
|
||||
omit(id),
|
||||
attributes_with = "deriveless"
|
||||
)]
|
||||
pub struct EvmEtherTransferGrantTarget {
|
||||
pub id: i32,
|
||||
pub grant_id: i32,
|
||||
pub address: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Models, Queryable, Debug, Insertable, Selectable)]
|
||||
#[diesel(table_name = evm_ether_transfer_volume_limit, check_for_backend(Sqlite))]
|
||||
#[view(
|
||||
NewEvmEtherTransferVolumeLimit,
|
||||
derive(Insertable),
|
||||
omit(id),
|
||||
attributes_with = "deriveless"
|
||||
)]
|
||||
pub struct EvmEtherTransferVolumeLimit {
|
||||
pub id: i32,
|
||||
pub grant_id: i32,
|
||||
pub window_secs: i32,
|
||||
pub max_volume: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Models, Queryable, Debug, Insertable, Selectable)]
|
||||
#[diesel(table_name = evm_token_approval_grant, check_for_backend(Sqlite))]
|
||||
#[view(
|
||||
NewEvmTokenApprovalGrant,
|
||||
derive(Insertable),
|
||||
omit(id),
|
||||
attributes_with = "deriveless"
|
||||
)]
|
||||
pub struct EvmTokenApprovalGrant {
|
||||
pub id: i32,
|
||||
pub basic_grant_id: i32,
|
||||
pub token_contract: Vec<u8>,
|
||||
pub max_total_approval: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Models, Queryable, Debug, Insertable, Selectable)]
|
||||
#[diesel(table_name = evm_token_approval_grant_target, check_for_backend(Sqlite))]
|
||||
#[view(
|
||||
NewEvmTokenApprovalGrantTarget,
|
||||
derive(Insertable),
|
||||
omit(id),
|
||||
attributes_with = "deriveless"
|
||||
)]
|
||||
pub struct EvmTokenApprovalGrantTarget {
|
||||
pub id: i32,
|
||||
pub grant_id: i32,
|
||||
pub address: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Models, Queryable, Debug, Insertable, Selectable)]
|
||||
#[diesel(table_name = evm_token_transfer_grant, check_for_backend(Sqlite))]
|
||||
#[view(
|
||||
NewEvmTokenTransferGrant,
|
||||
derive(Insertable),
|
||||
omit(id),
|
||||
attributes_with = "deriveless"
|
||||
)]
|
||||
pub struct EvmTokenTransferGrant {
|
||||
pub id: i32,
|
||||
pub basic_grant_id: i32,
|
||||
pub token_contract: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Models, Queryable, Debug, Insertable, Selectable)]
|
||||
#[diesel(table_name = evm_token_transfer_grant_target, check_for_backend(Sqlite))]
|
||||
#[view(
|
||||
NewEvmTokenTransferGrantTarget,
|
||||
derive(Insertable),
|
||||
omit(id),
|
||||
attributes_with = "deriveless"
|
||||
)]
|
||||
pub struct EvmTokenTransferGrantTarget {
|
||||
pub id: i32,
|
||||
pub grant_id: i32,
|
||||
pub address: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Models, Queryable, Debug, Insertable, Selectable)]
|
||||
#[diesel(table_name = evm_token_transfer_volume_limit, check_for_backend(Sqlite))]
|
||||
#[view(
|
||||
NewEvmTokenTransferVolumeLimit,
|
||||
derive(Insertable),
|
||||
omit(id),
|
||||
attributes_with = "deriveless"
|
||||
)]
|
||||
pub struct EvmTokenTransferVolumeLimit {
|
||||
pub id: i32,
|
||||
pub grant_id: i32,
|
||||
pub window_secs: i32,
|
||||
pub max_volume: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Models, Queryable, Debug, Insertable, Selectable)]
|
||||
#[diesel(table_name = evm_unknown_call_grant, check_for_backend(Sqlite))]
|
||||
#[view(
|
||||
NewEvmUnknownCallGrant,
|
||||
derive(Insertable),
|
||||
omit(id),
|
||||
attributes_with = "deriveless"
|
||||
)]
|
||||
pub struct EvmUnknownCallGrant {
|
||||
pub id: i32,
|
||||
pub basic_grant_id: i32,
|
||||
pub contract: Vec<u8>,
|
||||
pub selector: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
#[derive(Models, Queryable, Debug, Insertable, Selectable)]
|
||||
#[diesel(table_name = evm_ether_transfer_log, check_for_backend(Sqlite))]
|
||||
#[view(
|
||||
NewEvmEtherTransferLog,
|
||||
derive(Insertable),
|
||||
omit(id, created_at),
|
||||
attributes_with = "deriveless"
|
||||
)]
|
||||
pub struct EvmEtherTransferLog {
|
||||
pub id: i32,
|
||||
pub grant_id: i32,
|
||||
pub client_id: i32,
|
||||
pub wallet_id: i32,
|
||||
pub chain_id: i32,
|
||||
pub recipient_address: Vec<u8>,
|
||||
pub value: Vec<u8>,
|
||||
pub created_at: SqliteTimestamp,
|
||||
}
|
||||
|
||||
#[derive(Models, Queryable, Debug, Insertable, Selectable)]
|
||||
#[diesel(table_name = evm_token_transfer_log, check_for_backend(Sqlite))]
|
||||
#[view(
|
||||
NewEvmTokenTransferLog,
|
||||
derive(Insertable),
|
||||
omit(id, created_at),
|
||||
attributes_with = "deriveless"
|
||||
)]
|
||||
pub struct EvmTokenTransferLog {
|
||||
pub id: i32,
|
||||
pub grant_id: i32,
|
||||
pub client_id: i32,
|
||||
pub wallet_id: i32,
|
||||
pub chain_id: i32,
|
||||
pub token_contract: Vec<u8>,
|
||||
pub recipient_address: Vec<u8>,
|
||||
pub value: Vec<u8>,
|
||||
pub created_at: SqliteTimestamp,
|
||||
}
|
||||
|
||||
#[derive(Models, Queryable, Debug, Insertable, Selectable)]
|
||||
#[diesel(table_name = evm_token_approval_log, check_for_backend(Sqlite))]
|
||||
#[view(
|
||||
NewEvmTokenApprovalLog,
|
||||
derive(Insertable),
|
||||
omit(id, created_at),
|
||||
attributes_with = "deriveless"
|
||||
)]
|
||||
pub struct EvmTokenApprovalLog {
|
||||
pub id: i32,
|
||||
pub grant_id: i32,
|
||||
pub client_id: i32,
|
||||
pub wallet_id: i32,
|
||||
pub chain_id: i32,
|
||||
pub token_contract: Vec<u8>,
|
||||
pub spender_address: Vec<u8>,
|
||||
pub value: Vec<u8>,
|
||||
pub created_at: SqliteTimestamp,
|
||||
}
|
||||
|
||||
#[derive(Models, Queryable, Debug, Insertable, Selectable)]
|
||||
#[diesel(table_name = evm_unknown_call_log, check_for_backend(Sqlite))]
|
||||
#[view(
|
||||
NewEvmUnknownCallLog,
|
||||
derive(Insertable),
|
||||
omit(id, created_at),
|
||||
attributes_with = "deriveless"
|
||||
)]
|
||||
pub struct EvmUnknownCallLog {
|
||||
pub id: i32,
|
||||
pub grant_id: i32,
|
||||
pub client_id: i32,
|
||||
pub wallet_id: i32,
|
||||
pub chain_id: i32,
|
||||
pub contract: Vec<u8>,
|
||||
pub selector: Option<Vec<u8>>,
|
||||
pub call_data: Option<Vec<u8>>,
|
||||
pub created_at: SqliteTimestamp,
|
||||
}
|
||||
|
||||
@@ -20,6 +20,162 @@ diesel::table! {
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
evm_basic_grant (id) {
|
||||
id -> Integer,
|
||||
wallet_id -> Integer,
|
||||
client_id -> Integer,
|
||||
chain_id -> Integer,
|
||||
valid_from -> Nullable<Integer>,
|
||||
valid_until -> Nullable<Integer>,
|
||||
max_gas_fee_per_gas -> Nullable<Binary>,
|
||||
max_priority_fee_per_gas -> Nullable<Binary>,
|
||||
rate_limit_count -> Nullable<Integer>,
|
||||
rate_limit_window_secs -> Nullable<Integer>,
|
||||
revoked_at -> Nullable<Integer>,
|
||||
created_at -> Integer,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
evm_ether_transfer_grant (id) {
|
||||
id -> Integer,
|
||||
basic_grant_id -> Integer,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
evm_ether_transfer_grant_target (id) {
|
||||
id -> Integer,
|
||||
grant_id -> Integer,
|
||||
address -> Binary,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
evm_ether_transfer_log (id) {
|
||||
id -> Integer,
|
||||
grant_id -> Integer,
|
||||
client_id -> Integer,
|
||||
wallet_id -> Integer,
|
||||
chain_id -> Integer,
|
||||
recipient_address -> Binary,
|
||||
value -> Binary,
|
||||
created_at -> Integer,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
evm_ether_transfer_volume_limit (id) {
|
||||
id -> Integer,
|
||||
grant_id -> Integer,
|
||||
window_secs -> Integer,
|
||||
max_volume -> Binary,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
evm_token_approval_grant (id) {
|
||||
id -> Integer,
|
||||
basic_grant_id -> Integer,
|
||||
token_contract -> Binary,
|
||||
max_total_approval -> Binary,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
evm_token_approval_grant_target (id) {
|
||||
id -> Integer,
|
||||
grant_id -> Integer,
|
||||
address -> Binary,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
evm_token_approval_log (id) {
|
||||
id -> Integer,
|
||||
grant_id -> Integer,
|
||||
client_id -> Integer,
|
||||
wallet_id -> Integer,
|
||||
chain_id -> Integer,
|
||||
token_contract -> Binary,
|
||||
spender_address -> Binary,
|
||||
value -> Binary,
|
||||
created_at -> Integer,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
evm_token_transfer_grant (id) {
|
||||
id -> Integer,
|
||||
basic_grant_id -> Integer,
|
||||
token_contract -> Binary,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
evm_token_transfer_grant_target (id) {
|
||||
id -> Integer,
|
||||
grant_id -> Integer,
|
||||
address -> Binary,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
evm_token_transfer_log (id) {
|
||||
id -> Integer,
|
||||
grant_id -> Integer,
|
||||
client_id -> Integer,
|
||||
wallet_id -> Integer,
|
||||
chain_id -> Integer,
|
||||
token_contract -> Binary,
|
||||
recipient_address -> Binary,
|
||||
value -> Binary,
|
||||
created_at -> Integer,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
evm_token_transfer_volume_limit (id) {
|
||||
id -> Integer,
|
||||
grant_id -> Integer,
|
||||
window_secs -> Integer,
|
||||
max_volume -> Binary,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
evm_unknown_call_grant (id) {
|
||||
id -> Integer,
|
||||
basic_grant_id -> Integer,
|
||||
contract -> Binary,
|
||||
selector -> Nullable<Binary>,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
evm_unknown_call_log (id) {
|
||||
id -> Integer,
|
||||
grant_id -> Integer,
|
||||
client_id -> Integer,
|
||||
wallet_id -> Integer,
|
||||
chain_id -> Integer,
|
||||
contract -> Binary,
|
||||
selector -> Nullable<Binary>,
|
||||
call_data -> Nullable<Binary>,
|
||||
created_at -> Integer,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
evm_wallet (id) {
|
||||
id -> Integer,
|
||||
address -> Binary,
|
||||
aead_encrypted_id -> Integer,
|
||||
created_at -> Integer,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
program_client (id) {
|
||||
id -> Integer,
|
||||
@@ -66,10 +222,49 @@ diesel::table! {
|
||||
diesel::joinable!(aead_encrypted -> root_key_history (associated_root_key_id));
|
||||
diesel::joinable!(arbiter_settings -> root_key_history (root_key_id));
|
||||
diesel::joinable!(arbiter_settings -> tls_history (tls_id));
|
||||
diesel::joinable!(evm_basic_grant -> evm_wallet (wallet_id));
|
||||
diesel::joinable!(evm_basic_grant -> program_client (client_id));
|
||||
diesel::joinable!(evm_ether_transfer_grant -> evm_basic_grant (basic_grant_id));
|
||||
diesel::joinable!(evm_ether_transfer_grant_target -> evm_ether_transfer_grant (grant_id));
|
||||
diesel::joinable!(evm_ether_transfer_log -> evm_ether_transfer_grant (grant_id));
|
||||
diesel::joinable!(evm_ether_transfer_log -> evm_wallet (wallet_id));
|
||||
diesel::joinable!(evm_ether_transfer_log -> program_client (client_id));
|
||||
diesel::joinable!(evm_ether_transfer_volume_limit -> evm_ether_transfer_grant (grant_id));
|
||||
diesel::joinable!(evm_token_approval_grant -> evm_basic_grant (basic_grant_id));
|
||||
diesel::joinable!(evm_token_approval_grant_target -> evm_token_approval_grant (grant_id));
|
||||
diesel::joinable!(evm_token_approval_log -> evm_token_approval_grant (grant_id));
|
||||
diesel::joinable!(evm_token_approval_log -> evm_wallet (wallet_id));
|
||||
diesel::joinable!(evm_token_approval_log -> program_client (client_id));
|
||||
diesel::joinable!(evm_token_transfer_grant -> evm_basic_grant (basic_grant_id));
|
||||
diesel::joinable!(evm_token_transfer_grant_target -> evm_token_transfer_grant (grant_id));
|
||||
diesel::joinable!(evm_token_transfer_log -> evm_token_transfer_grant (grant_id));
|
||||
diesel::joinable!(evm_token_transfer_log -> evm_wallet (wallet_id));
|
||||
diesel::joinable!(evm_token_transfer_log -> program_client (client_id));
|
||||
diesel::joinable!(evm_token_transfer_volume_limit -> evm_token_transfer_grant (grant_id));
|
||||
diesel::joinable!(evm_unknown_call_grant -> evm_basic_grant (basic_grant_id));
|
||||
diesel::joinable!(evm_unknown_call_log -> evm_unknown_call_grant (grant_id));
|
||||
diesel::joinable!(evm_unknown_call_log -> evm_wallet (wallet_id));
|
||||
diesel::joinable!(evm_unknown_call_log -> program_client (client_id));
|
||||
diesel::joinable!(evm_wallet -> aead_encrypted (aead_encrypted_id));
|
||||
|
||||
diesel::allow_tables_to_appear_in_same_query!(
|
||||
aead_encrypted,
|
||||
arbiter_settings,
|
||||
evm_basic_grant,
|
||||
evm_ether_transfer_grant,
|
||||
evm_ether_transfer_grant_target,
|
||||
evm_ether_transfer_log,
|
||||
evm_ether_transfer_volume_limit,
|
||||
evm_token_approval_grant,
|
||||
evm_token_approval_grant_target,
|
||||
evm_token_approval_log,
|
||||
evm_token_transfer_grant,
|
||||
evm_token_transfer_grant_target,
|
||||
evm_token_transfer_log,
|
||||
evm_token_transfer_volume_limit,
|
||||
evm_unknown_call_grant,
|
||||
evm_unknown_call_log,
|
||||
evm_wallet,
|
||||
program_client,
|
||||
root_key_history,
|
||||
tls_history,
|
||||
|
||||
Reference in New Issue
Block a user