1use std::{rc::Rc, str::FromStr};
2
3use eth_rpc::call_contract;
4use ethers_core::{
5 abi::{Contract, Token},
6 types::{Address, RecoveryMessage, Signature},
7};
8use util::to_hex;
9
10mod eth_rpc;
11mod util;
12
13thread_local! {
15 static ERC_721: Rc<Contract> = Rc::new(include_abi!("../abi/erc721.json"));
16 static ERC_1155: Rc<Contract> = Rc::new(include_abi!("../abi/erc1155.json"));
17}
18
19#[cfg(feature = "canpack")]
20canpack::export! {
21 #[canpack(update)]
23 pub fn ecdsa_verify(eth_address: String, message: String, signature: String) -> bool {
24 Signature::from_str(&signature)
25 .unwrap()
26 .verify(
27 RecoveryMessage::Data(message.into_bytes()),
28 Address::from_str(ð_address).unwrap(),
29 )
30 .is_ok()
31 }
32
33 #[canpack(update)]
35 pub async fn erc721_owner_of(network: String, contract_address: String, token_id: u64) -> String {
36 let abi = &ERC_721.with(Rc::clone);
40 let result = call_contract(
41 &network,
42 contract_address,
43 abi,
44 "ownerOf",
45 &[Token::Uint(token_id.into())],
46 )
47 .await;
48 match result.get(0) {
49 Some(Token::Address(a)) => to_hex(a.as_bytes()),
50 _ => panic!("Unexpected result"),
51 }
52 }
53
54 #[canpack(update)]
56 pub async fn erc1155_balance_of(
57 network: String,
58 contract_address: String,
59 owner_address: String,
60 token_id: u64,
61 ) -> u128 {
62 let owner_address =
63 ethers_core::types::Address::from_str(&owner_address).expect("Invalid owner address");
64
65 let abi = &ERC_1155.with(Rc::clone);
66 let result = call_contract(
67 &network,
68 contract_address,
69 abi,
70 "balanceOf",
71 &[
72 Token::Address(owner_address.into()),
73 Token::Uint(token_id.into()),
74 ],
75 )
76 .await;
77 match result.get(0) {
78 Some(Token::Uint(n)) => n.as_u128(),
79 _ => panic!("Unexpected result"),
80 }
81 }
82}