Skip to content

Commit 3d4a729

Browse files
committed
feat(evm_icp_bridge): EVM API
1 parent 118bcc6 commit 3d4a729

File tree

8 files changed

+649
-102
lines changed

8 files changed

+649
-102
lines changed

Cargo.lock

Lines changed: 99 additions & 79 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ base64 = "0.22"
3838
candid = "0.10"
3939
ciborium = "0.2"
4040
log = "0.4"
41+
futures = "0.3"
4142
serde = "1"
4243
serde_bytes = "0.11"
4344
serde_json = { version = "1", features = ["preserve_order"] }

src/evm_icp_bridge/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ license.workspace = true
1515
crate-type = ["cdylib"]
1616

1717
[dependencies]
18-
alloy = { workspace = true }
18+
alloy = { workspace = true, features = ["rpc"] }
1919
base64 = { workspace = true }
2020
candid = { workspace = true }
2121
ciborium = { workspace = true }
22+
futures = { workspace = true }
2223
ic-cdk = { workspace = true }
2324
ic-cdk-timers = { workspace = true }
2425
ic-stable-structures = { workspace = true }

src/evm_icp_bridge/src/api_admin.rs

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,49 @@ use url::Url;
55
use crate::store;
66

77
#[ic_cdk::update(guard = "is_controller")]
8-
fn admin_add_evm_contract(
8+
async fn admin_add_evm_contract(
99
chain_name: String,
1010
chain_id: u64,
1111
address: String,
1212
decimals: u8,
1313
) -> Result<(), String> {
14-
let address = check_admin_add_evm_contract(&chain_name, chain_id, &address)?;
14+
let address = check_admin_add_evm_contract(&chain_name, chain_id, &address, decimals)?;
15+
let cli = store::state::evm_client(&chain_name);
16+
let now_ms = ic_cdk::api::time() / 1_000_000;
17+
let (cid, gas_price, block_number, symbol, dec) = futures::future::try_join5(
18+
cli.chain_id(now_ms),
19+
cli.gas_price(now_ms),
20+
cli.finalized_block_number(now_ms),
21+
cli.erc20_symbol(now_ms, &address),
22+
cli.erc20_decimals(now_ms, &address),
23+
)
24+
.await?;
25+
26+
if chain_id != cid {
27+
return Err(format!(
28+
"chain_id mismatch, got {}, expected {}",
29+
cid, chain_id
30+
));
31+
}
32+
if decimals != dec {
33+
return Err(format!(
34+
"decimals mismatch, got {}, expected {}",
35+
dec, decimals
36+
));
37+
}
38+
1539
store::state::with_mut(|s| {
40+
if s.token_symbol != symbol {
41+
return Err(format!(
42+
"token_symbol mismatch, got {}, expected {}",
43+
symbol, s.token_symbol
44+
));
45+
}
46+
1647
s.evm_token_contracts
17-
.insert(chain_name, (address, decimals, chain_id));
48+
.insert(chain_name.clone(), (address, decimals, chain_id));
49+
s.evm_finalized_block
50+
.insert(chain_name, (block_number, gas_price));
1851
Ok(())
1952
})
2053
}
@@ -26,14 +59,15 @@ fn validate_admin_add_evm_contract(
2659
address: String,
2760
decimals: u8,
2861
) -> Result<String, String> {
29-
check_admin_add_evm_contract(&chain_name, chain_id, &address)?;
62+
check_admin_add_evm_contract(&chain_name, chain_id, &address, decimals)?;
3063
pretty_format(&(chain_name, chain_id, address, decimals))
3164
}
3265

3366
fn check_admin_add_evm_contract(
3467
chain_name: &str,
3568
chain_id: u64,
3669
address: &str,
70+
decimals: u8,
3771
) -> Result<Address, String> {
3872
if chain_name.trim().to_ascii_uppercase() != chain_name
3973
|| chain_name.is_empty()
@@ -44,10 +78,19 @@ fn check_admin_add_evm_contract(
4478

4579
let addr = Address::parse_checksummed(address, Some(chain_id))
4680
.map_err(|err| format!("invalid address: {err:?}"))?;
81+
4782
store::state::with(|s| {
83+
if decimals < s.token_decimals {
84+
return Err(format!(
85+
"decimals must be >= {}, got {}",
86+
s.token_decimals, decimals
87+
));
88+
}
89+
4890
if s.evm_token_contracts.contains_key(chain_name) {
4991
return Err("chain_id already exists".to_string());
5092
}
93+
5194
if s.evm_token_contracts
5295
.values()
5396
.any(|(_, _, cid)| *cid == chain_id)

src/evm_icp_bridge/src/api_init.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub struct InitArgs {
1515
pub key_name: String,
1616
pub token_name: String,
1717
pub token_symbol: String,
18+
pub token_decimals: u8,
1819
pub token_logo: String,
1920
pub token_ledger: Principal,
2021
pub governance_canister: Option<Principal>,
@@ -36,6 +37,7 @@ fn init(args: Option<CanisterArgs>) {
3637
s.key_name = args.key_name;
3738
s.token_name = args.token_name;
3839
s.token_symbol = args.token_symbol;
40+
s.token_decimals = args.token_decimals;
3941
s.token_logo = args.token_logo;
4042
s.token_ledger = args.token_ledger;
4143
s.governance_canister = args.governance_canister;

0 commit comments

Comments
 (0)