Compare commits
5 Commits
check-uac-
...
4bb2c062dc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4bb2c062dc | ||
|
|
b0a3f37cea | ||
|
|
58a72da46c | ||
|
|
e287459b10 | ||
|
|
5a34463228 |
@@ -90,6 +90,7 @@ message EvmGrantCreateResponse {
|
|||||||
|
|
||||||
message EvmGrantDeleteRequest {
|
message EvmGrantDeleteRequest {
|
||||||
int32 grant_id = 1;
|
int32 grant_id = 1;
|
||||||
|
int32 wallet_access_id = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message EvmGrantDeleteResponse {
|
message EvmGrantDeleteResponse {
|
||||||
|
|||||||
@@ -158,28 +158,15 @@ impl EvmActor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[message]
|
#[message]
|
||||||
pub async fn useragent_delete_grant(&mut self, _grant_id: i32) -> Result<(), Error> {
|
pub async fn useragent_delete_grant(
|
||||||
// let mut conn = self.db.get().await.map_err(DatabaseError::from)?;
|
&mut self,
|
||||||
// let keyholder = self.keyholder.clone();
|
grant_id: i32,
|
||||||
|
wallet_access_id: i32,
|
||||||
// diesel_async::AsyncConnection::transaction(&mut conn, |conn| {
|
) -> Result<(), Error> {
|
||||||
// Box::pin(async move {
|
self.engine
|
||||||
// diesel::update(schema::evm_basic_grant::table)
|
.revoke_grant(grant_id, wallet_access_id)
|
||||||
// .filter(schema::evm_basic_grant::id.eq(grant_id))
|
.await
|
||||||
// .set(schema::evm_basic_grant::revoked_at.eq(SqliteTimestamp::now()))
|
.map_err(Error::from)
|
||||||
// .execute(conn)
|
|
||||||
// .await?;
|
|
||||||
|
|
||||||
// let signed = integrity::evm::load_signed_grant_by_basic_id(conn, grant_id).await?;
|
|
||||||
|
|
||||||
// diesel::result::QueryResult::Ok(())
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
// .await
|
|
||||||
// .map_err(DatabaseError::from)?;
|
|
||||||
|
|
||||||
// Ok(())
|
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[message]
|
#[message]
|
||||||
|
|||||||
@@ -360,12 +360,13 @@ impl UserAgentSession {
|
|||||||
pub(crate) async fn handle_grant_delete(
|
pub(crate) async fn handle_grant_delete(
|
||||||
&mut self,
|
&mut self,
|
||||||
grant_id: i32,
|
grant_id: i32,
|
||||||
|
wallet_access_id: i32,
|
||||||
) -> Result<(), GrantMutationError> {
|
) -> Result<(), GrantMutationError> {
|
||||||
// match self
|
// match self
|
||||||
// .props
|
// .props
|
||||||
// .actors
|
// .actors
|
||||||
// .evm
|
// .evm
|
||||||
// .ask(UseragentDeleteGrant { grant_id })
|
// .ask(UseragentDeleteGrant { grant_id, wallet_access_id })
|
||||||
// .await
|
// .await
|
||||||
// {
|
// {
|
||||||
// Ok(()) => Ok(()),
|
// Ok(()) => Ok(()),
|
||||||
@@ -374,7 +375,7 @@ impl UserAgentSession {
|
|||||||
// Err(GrantMutationError::Internal)
|
// Err(GrantMutationError::Internal)
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
let _ = grant_id;
|
let _ = (grant_id, wallet_access_id);
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
pub mod abi;
|
pub mod abi;
|
||||||
pub mod safe_signer;
|
pub mod safe_signer;
|
||||||
|
|
||||||
|
use alloy::primitives::Address;
|
||||||
use alloy::{
|
use alloy::{
|
||||||
consensus::TxEip1559,
|
consensus::TxEip1559,
|
||||||
primitives::{TxKind, U256},
|
primitives::{TxKind, U256},
|
||||||
};
|
};
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use diesel::{ExpressionMethods as _, QueryDsl as _, QueryResult, insert_into, sqlite::Sqlite};
|
use diesel::{
|
||||||
|
ExpressionMethods as _, OptionalExtension, QueryDsl as _, QueryResult, SelectableHelper,
|
||||||
|
insert_into, sqlite::Sqlite, update,
|
||||||
|
};
|
||||||
use diesel_async::{AsyncConnection, RunQueryDsl};
|
use diesel_async::{AsyncConnection, RunQueryDsl};
|
||||||
use kameo::actor::ActorRef;
|
use kameo::actor::ActorRef;
|
||||||
|
|
||||||
@@ -16,14 +20,16 @@ use crate::{
|
|||||||
db::{
|
db::{
|
||||||
self, DatabaseError,
|
self, DatabaseError,
|
||||||
models::{
|
models::{
|
||||||
EvmBasicGrant, EvmWalletAccess, NewEvmBasicGrant, NewEvmTransactionLog, SqliteTimestamp,
|
EvmBasicGrant, EvmEtherTransferGrant, EvmEtherTransferGrantTarget,
|
||||||
|
EvmEtherTransferLimit, EvmTokenTransferGrant, EvmTokenTransferVolumeLimit,
|
||||||
|
EvmWalletAccess, NewEvmBasicGrant, NewEvmTransactionLog, SqliteTimestamp,
|
||||||
},
|
},
|
||||||
schema::{self, evm_transaction_log},
|
schema::{self, evm_transaction_log},
|
||||||
},
|
},
|
||||||
evm::policies::{
|
evm::policies::{
|
||||||
CombinedSettings, DatabaseID, EvalContext, EvalViolation, Grant, Policy,
|
CombinedSettings, DatabaseID, EvalContext, EvalViolation, Grant, Policy,
|
||||||
SharedGrantSettings, SpecificGrant, SpecificMeaning, ether_transfer::EtherTransfer,
|
SharedGrantSettings, SpecificGrant, SpecificMeaning, VolumeRateLimit,
|
||||||
token_transfers::TokenTransfer,
|
ether_transfer::EtherTransfer, token_transfers::TokenTransfer,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -270,6 +276,156 @@ impl Engine {
|
|||||||
Ok(id)
|
Ok(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn revoke_grant(
|
||||||
|
&self,
|
||||||
|
basic_grant_id: i32,
|
||||||
|
wallet_access_id: i32,
|
||||||
|
) -> Result<(), DatabaseError> {
|
||||||
|
let mut conn = self.db.get().await.map_err(DatabaseError::from)?;
|
||||||
|
let keyholder = self.keyholder.clone();
|
||||||
|
|
||||||
|
conn.transaction(|conn| {
|
||||||
|
Box::pin(async move {
|
||||||
|
use crate::db::schema::{
|
||||||
|
evm_basic_grant, evm_ether_transfer_grant, evm_ether_transfer_grant_target,
|
||||||
|
evm_ether_transfer_limit, evm_token_transfer_grant,
|
||||||
|
evm_token_transfer_volume_limit,
|
||||||
|
};
|
||||||
|
|
||||||
|
update(evm_basic_grant::table)
|
||||||
|
.filter(evm_basic_grant::id.eq(basic_grant_id))
|
||||||
|
.filter(evm_basic_grant::wallet_access_id.eq(wallet_access_id))
|
||||||
|
.set(evm_basic_grant::revoked_at.eq(SqliteTimestamp(Utc::now())))
|
||||||
|
.execute(conn)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let basic_grant: EvmBasicGrant = evm_basic_grant::table
|
||||||
|
.filter(evm_basic_grant::id.eq(basic_grant_id))
|
||||||
|
.filter(evm_basic_grant::wallet_access_id.eq(wallet_access_id))
|
||||||
|
.select(EvmBasicGrant::as_select())
|
||||||
|
.first(conn)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let shared = SharedGrantSettings::try_from_model(basic_grant)?;
|
||||||
|
|
||||||
|
if let Some(ether_grant) = evm_ether_transfer_grant::table
|
||||||
|
.filter(evm_ether_transfer_grant::basic_grant_id.eq(basic_grant_id))
|
||||||
|
.select(EvmEtherTransferGrant::as_select())
|
||||||
|
.first(conn)
|
||||||
|
.await
|
||||||
|
.optional()?
|
||||||
|
{
|
||||||
|
let target_rows: Vec<EvmEtherTransferGrantTarget> =
|
||||||
|
evm_ether_transfer_grant_target::table
|
||||||
|
.filter(evm_ether_transfer_grant_target::grant_id.eq(ether_grant.id))
|
||||||
|
.select(EvmEtherTransferGrantTarget::as_select())
|
||||||
|
.load(conn)
|
||||||
|
.await?;
|
||||||
|
let targets: Vec<Address> = target_rows
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|target| {
|
||||||
|
let arr: [u8; 20] = target.address.try_into().ok()?;
|
||||||
|
Some(Address::from(arr))
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let limit: EvmEtherTransferLimit = evm_ether_transfer_limit::table
|
||||||
|
.filter(evm_ether_transfer_limit::id.eq(ether_grant.limit_id))
|
||||||
|
.select(EvmEtherTransferLimit::as_select())
|
||||||
|
.first(conn)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let settings = CombinedSettings {
|
||||||
|
shared: shared.clone(),
|
||||||
|
specific: crate::evm::policies::ether_transfer::Settings {
|
||||||
|
target: targets,
|
||||||
|
limit: VolumeRateLimit {
|
||||||
|
max_volume: utils::try_bytes_to_u256(&limit.max_volume).map_err(
|
||||||
|
|err| {
|
||||||
|
diesel::result::Error::DeserializationError(Box::new(err))
|
||||||
|
},
|
||||||
|
)?,
|
||||||
|
window: chrono::Duration::seconds(limit.window_secs as i64),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
integrity::sign_entity(conn, &keyholder, &settings, basic_grant_id)
|
||||||
|
.await
|
||||||
|
.map_err(|_| diesel::result::Error::RollbackTransaction)?;
|
||||||
|
|
||||||
|
return QueryResult::Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(token_grant) = evm_token_transfer_grant::table
|
||||||
|
.filter(evm_token_transfer_grant::basic_grant_id.eq(basic_grant_id))
|
||||||
|
.select(EvmTokenTransferGrant::as_select())
|
||||||
|
.first(conn)
|
||||||
|
.await
|
||||||
|
.optional()?
|
||||||
|
{
|
||||||
|
let volume_limit_rows: Vec<EvmTokenTransferVolumeLimit> =
|
||||||
|
evm_token_transfer_volume_limit::table
|
||||||
|
.filter(evm_token_transfer_volume_limit::grant_id.eq(token_grant.id))
|
||||||
|
.select(EvmTokenTransferVolumeLimit::as_select())
|
||||||
|
.load(conn)
|
||||||
|
.await?;
|
||||||
|
let volume_limits: Vec<VolumeRateLimit> = volume_limit_rows
|
||||||
|
.into_iter()
|
||||||
|
.map(|row| {
|
||||||
|
Ok(VolumeRateLimit {
|
||||||
|
max_volume: utils::try_bytes_to_u256(&row.max_volume).map_err(
|
||||||
|
|err| {
|
||||||
|
diesel::result::Error::DeserializationError(Box::new(err))
|
||||||
|
},
|
||||||
|
)?,
|
||||||
|
window: chrono::Duration::seconds(row.window_secs as i64),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect::<QueryResult<Vec<_>>>()?;
|
||||||
|
|
||||||
|
let target: Option<Address> = match token_grant.receiver {
|
||||||
|
None => None,
|
||||||
|
Some(bytes) => {
|
||||||
|
let arr: [u8; 20] = bytes.try_into().map_err(|_| {
|
||||||
|
diesel::result::Error::DeserializationError(
|
||||||
|
"Invalid receiver address length".into(),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
Some(Address::from(arr))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let token_contract: [u8; 20] =
|
||||||
|
token_grant.token_contract.clone().try_into().map_err(|_| {
|
||||||
|
diesel::result::Error::DeserializationError(
|
||||||
|
"Invalid token contract address length".into(),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let settings = CombinedSettings {
|
||||||
|
shared,
|
||||||
|
specific: crate::evm::policies::token_transfers::Settings {
|
||||||
|
token_contract: Address::from(token_contract),
|
||||||
|
target,
|
||||||
|
volume_limits,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
integrity::sign_entity(conn, &keyholder, &settings, basic_grant_id)
|
||||||
|
.await
|
||||||
|
.map_err(|_| diesel::result::Error::RollbackTransaction)?;
|
||||||
|
|
||||||
|
return QueryResult::Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(diesel::result::Error::NotFound)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.map_err(DatabaseError::from)
|
||||||
|
}
|
||||||
|
|
||||||
async fn list_one_kind<Kind: Policy, Y>(
|
async fn list_one_kind<Kind: Policy, Y>(
|
||||||
&self,
|
&self,
|
||||||
conn: &mut impl AsyncConnection<Backend = Sqlite>,
|
conn: &mut impl AsyncConnection<Backend = Sqlite>,
|
||||||
@@ -349,11 +505,15 @@ impl Engine {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use alloy::primitives::{Address, Bytes, U256, address};
|
use alloy::primitives::{Address, Bytes, U256, address};
|
||||||
|
use arbiter_crypto::safecell::{SafeCell, SafeCellHandle as _};
|
||||||
use chrono::{Duration, Utc};
|
use chrono::{Duration, Utc};
|
||||||
use diesel::{SelectableHelper, insert_into};
|
use diesel::{SelectableHelper, insert_into};
|
||||||
use diesel_async::RunQueryDsl;
|
use diesel_async::RunQueryDsl;
|
||||||
|
use kameo::{actor::ActorRef, prelude::Spawn};
|
||||||
use rstest::rstest;
|
use rstest::rstest;
|
||||||
|
|
||||||
|
use crate::actors::keyholder::{Bootstrap, KeyHolder};
|
||||||
|
use crate::crypto::integrity;
|
||||||
use crate::db::{
|
use crate::db::{
|
||||||
self, DatabaseConnection,
|
self, DatabaseConnection,
|
||||||
models::{
|
models::{
|
||||||
@@ -361,8 +521,10 @@ mod tests {
|
|||||||
},
|
},
|
||||||
schema::{evm_basic_grant, evm_transaction_log},
|
schema::{evm_basic_grant, evm_transaction_log},
|
||||||
};
|
};
|
||||||
|
use crate::evm::policies::ether_transfer::EtherTransfer;
|
||||||
use crate::evm::policies::{
|
use crate::evm::policies::{
|
||||||
EvalContext, EvalViolation, SharedGrantSettings, TransactionRateLimit,
|
CombinedSettings, EvalContext, EvalViolation, Policy, SharedGrantSettings,
|
||||||
|
TransactionRateLimit, VolumeRateLimit,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::check_shared_constraints;
|
use super::check_shared_constraints;
|
||||||
@@ -394,6 +556,7 @@ mod tests {
|
|||||||
chain: CHAIN_ID,
|
chain: CHAIN_ID,
|
||||||
valid_from: None,
|
valid_from: None,
|
||||||
valid_until: None,
|
valid_until: None,
|
||||||
|
revoked_at: None,
|
||||||
max_gas_fee_per_gas: None,
|
max_gas_fee_per_gas: None,
|
||||||
max_priority_fee_per_gas: None,
|
max_priority_fee_per_gas: None,
|
||||||
rate_limit: None,
|
rate_limit: None,
|
||||||
@@ -596,4 +759,111 @@ mod tests {
|
|||||||
assert!(violations.is_empty());
|
assert!(violations.is_empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn bootstrapped_keyholder(db: &db::DatabasePool) -> ActorRef<KeyHolder> {
|
||||||
|
let actor = KeyHolder::spawn(KeyHolder::new(db.clone()).await.unwrap());
|
||||||
|
actor
|
||||||
|
.ask(Bootstrap {
|
||||||
|
seal_key_raw: SafeCell::new(b"integrity-test-seal-key".to_vec()),
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
actor
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn revoke_grant_preserves_revoked_integrity() {
|
||||||
|
use crate::db::schema::evm_basic_grant;
|
||||||
|
use diesel::ExpressionMethods as _;
|
||||||
|
|
||||||
|
let db = db::create_test_pool().await;
|
||||||
|
let keyholder = bootstrapped_keyholder(&db).await;
|
||||||
|
let engine = super::Engine::new(db.clone(), keyholder.clone());
|
||||||
|
|
||||||
|
let full_grant = CombinedSettings {
|
||||||
|
shared: SharedGrantSettings {
|
||||||
|
wallet_access_id: WALLET_ACCESS_ID,
|
||||||
|
chain: CHAIN_ID,
|
||||||
|
valid_from: None,
|
||||||
|
valid_until: None,
|
||||||
|
revoked_at: None,
|
||||||
|
max_gas_fee_per_gas: None,
|
||||||
|
max_priority_fee_per_gas: None,
|
||||||
|
rate_limit: None,
|
||||||
|
},
|
||||||
|
specific: crate::evm::policies::ether_transfer::Settings {
|
||||||
|
target: vec![RECIPIENT],
|
||||||
|
limit: VolumeRateLimit {
|
||||||
|
max_volume: U256::from(100u64),
|
||||||
|
window: Duration::hours(1),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let grant_id = engine
|
||||||
|
.create_grant::<EtherTransfer>(full_grant)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
engine.revoke_grant(grant_id, WALLET_ACCESS_ID).await.unwrap();
|
||||||
|
|
||||||
|
let mut conn = db.get().await.unwrap();
|
||||||
|
diesel::update(evm_basic_grant::table)
|
||||||
|
.filter(evm_basic_grant::id.eq(grant_id))
|
||||||
|
.set(evm_basic_grant::revoked_at.eq::<Option<SqliteTimestamp>>(None))
|
||||||
|
.execute(&mut conn)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let wallet_access = EvmWalletAccess {
|
||||||
|
id: WALLET_ACCESS_ID,
|
||||||
|
wallet_id: 10,
|
||||||
|
client_id: 20,
|
||||||
|
created_at: SqliteTimestamp(Utc::now()),
|
||||||
|
};
|
||||||
|
let context = EvalContext {
|
||||||
|
target: wallet_access,
|
||||||
|
chain: CHAIN_ID,
|
||||||
|
to: RECIPIENT,
|
||||||
|
value: U256::ONE,
|
||||||
|
calldata: Bytes::new(),
|
||||||
|
max_fee_per_gas: 1,
|
||||||
|
max_priority_fee_per_gas: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
let grant = crate::evm::policies::ether_transfer::EtherTransfer::try_find_grant(
|
||||||
|
&context, &mut conn,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let result =
|
||||||
|
integrity::verify_entity(&mut conn, &keyholder, &grant.settings, grant.id).await;
|
||||||
|
|
||||||
|
assert!(matches!(
|
||||||
|
result,
|
||||||
|
Err(crate::crypto::integrity::Error::MacMismatch { .. })
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn shared_settings_hash_changes_when_revoked_at_changes() {
|
||||||
|
use arbiter_crypto::hashing::Hashable;
|
||||||
|
use sha2::Digest;
|
||||||
|
|
||||||
|
let active = shared_settings();
|
||||||
|
let revoked = SharedGrantSettings {
|
||||||
|
revoked_at: Some(Utc::now()),
|
||||||
|
..shared_settings()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut active_hash = sha2::Sha256::new();
|
||||||
|
active.hash(&mut active_hash);
|
||||||
|
|
||||||
|
let mut revoked_hash = sha2::Sha256::new();
|
||||||
|
revoked.hash(&mut revoked_hash);
|
||||||
|
|
||||||
|
assert_ne!(active_hash.finalize(), revoked_hash.finalize());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,6 +146,7 @@ pub struct SharedGrantSettings {
|
|||||||
|
|
||||||
pub valid_from: Option<DateTime<Utc>>,
|
pub valid_from: Option<DateTime<Utc>>,
|
||||||
pub valid_until: Option<DateTime<Utc>>,
|
pub valid_until: Option<DateTime<Utc>>,
|
||||||
|
pub revoked_at: Option<DateTime<Utc>>,
|
||||||
|
|
||||||
pub max_gas_fee_per_gas: Option<U256>,
|
pub max_gas_fee_per_gas: Option<U256>,
|
||||||
pub max_priority_fee_per_gas: Option<U256>,
|
pub max_priority_fee_per_gas: Option<U256>,
|
||||||
@@ -160,6 +161,7 @@ impl SharedGrantSettings {
|
|||||||
chain: model.chain_id as u64, // safe because chain_id is stored as i32 but is guaranteed to be a valid ChainId by the API when creating grants
|
chain: model.chain_id as u64, // safe because chain_id is stored as i32 but is guaranteed to be a valid ChainId by the API when creating grants
|
||||||
valid_from: model.valid_from.map(Into::into),
|
valid_from: model.valid_from.map(Into::into),
|
||||||
valid_until: model.valid_until.map(Into::into),
|
valid_until: model.valid_until.map(Into::into),
|
||||||
|
revoked_at: model.revoked_at.map(Into::into),
|
||||||
max_gas_fee_per_gas: model
|
max_gas_fee_per_gas: model
|
||||||
.max_gas_fee_per_gas
|
.max_gas_fee_per_gas
|
||||||
.map(|b| utils::try_bytes_to_u256(&b))
|
.map(|b| utils::try_bytes_to_u256(&b))
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ fn shared() -> SharedGrantSettings {
|
|||||||
chain: CHAIN_ID,
|
chain: CHAIN_ID,
|
||||||
valid_from: None,
|
valid_from: None,
|
||||||
valid_until: None,
|
valid_until: None,
|
||||||
|
revoked_at: None,
|
||||||
max_gas_fee_per_gas: None,
|
max_gas_fee_per_gas: None,
|
||||||
max_priority_fee_per_gas: None,
|
max_priority_fee_per_gas: None,
|
||||||
rate_limit: None,
|
rate_limit: None,
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ fn shared() -> SharedGrantSettings {
|
|||||||
chain: CHAIN_ID,
|
chain: CHAIN_ID,
|
||||||
valid_from: None,
|
valid_from: None,
|
||||||
valid_until: None,
|
valid_until: None,
|
||||||
|
revoked_at: None,
|
||||||
max_gas_fee_per_gas: None,
|
max_gas_fee_per_gas: None,
|
||||||
max_priority_fee_per_gas: None,
|
max_priority_fee_per_gas: None,
|
||||||
rate_limit: None,
|
rate_limit: None,
|
||||||
|
|||||||
@@ -170,6 +170,7 @@ async fn handle_grant_delete(
|
|||||||
let result = match actor
|
let result = match actor
|
||||||
.ask(HandleGrantDelete {
|
.ask(HandleGrantDelete {
|
||||||
grant_id: req.grant_id,
|
grant_id: req.grant_id,
|
||||||
|
wallet_access_id: req.wallet_access_id,
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ impl TryConvert for ProtoSharedSettings {
|
|||||||
.valid_until
|
.valid_until
|
||||||
.map(ProtoTimestamp::try_convert)
|
.map(ProtoTimestamp::try_convert)
|
||||||
.transpose()?,
|
.transpose()?,
|
||||||
|
revoked_at: None,
|
||||||
max_gas_fee_per_gas: self
|
max_gas_fee_per_gas: self
|
||||||
.max_gas_fee_per_gas
|
.max_gas_fee_per_gas
|
||||||
.as_deref()
|
.as_deref()
|
||||||
|
|||||||
Reference in New Issue
Block a user