neo3/neo_x/bridge/
bridge_contract.rs1use async_trait::async_trait;
2use primitive_types::H160;
3use serde::{Deserialize, Serialize};
4use std::str::FromStr;
5
6use crate::{
7 neo_builder::{AccountSigner, TransactionBuilder},
8 neo_clients::{JsonRpcProvider, RpcClient},
9 neo_contract::{ContractError, SmartContractTrait},
10 neo_protocol::Account,
11 neo_types::{
12 serde_with_utils::{deserialize_script_hash, serialize_script_hash},
13 ScriptHash,
14 },
15 ContractParameter,
16};
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct NeoXBridgeContract<'a, P: JsonRpcProvider> {
21 #[serde(deserialize_with = "deserialize_script_hash")]
22 #[serde(serialize_with = "serialize_script_hash")]
23 script_hash: ScriptHash,
24 #[serde(skip)]
25 provider: Option<&'a RpcClient<P>>,
26}
27
28impl<'a, P: JsonRpcProvider + 'static> NeoXBridgeContract<'a, P> {
29 pub const CONTRACT_HASH: &'static str = "74f2dc36a68fdc4682034178eb2220729231db76";
34
35 pub const DEPOSIT: &'static str = "deposit";
38 pub const WITHDRAW: &'static str = "withdraw";
40 pub const GET_FEE: &'static str = "getFee";
42 pub const GET_CAP: &'static str = "getCap";
44
45 pub fn new(provider: Option<&'a RpcClient<P>>) -> Result<Self, ContractError> {
55 Ok(Self {
56 script_hash: ScriptHash::from_str(Self::CONTRACT_HASH).map_err(|e| {
57 ContractError::InvalidScriptHash(format!("Invalid contract hash: {}", e))
58 })?,
59 provider,
60 })
61 }
62
63 pub fn with_script_hash(script_hash: ScriptHash, provider: Option<&'a RpcClient<P>>) -> Self {
74 Self { script_hash, provider }
75 }
76
77 pub async fn deposit(
90 &self,
91 token: &ScriptHash,
92 amount: i64,
93 destination: &str,
94 account: &Account,
95 ) -> Result<TransactionBuilder<P>, ContractError> {
96 let params = vec![
97 token.into(),
98 ContractParameter::integer(amount),
99 ContractParameter::string(destination.to_string()),
100 ];
101
102 let mut builder = self.invoke_function(Self::DEPOSIT, params).await?;
103 builder.set_signers(vec![AccountSigner::called_by_entry(account)
104 .map_err(|e| {
105 ContractError::InvalidAccount(format!("Failed to create account signer: {}", e))
106 })?
107 .into()]);
108
109 Ok(builder)
110 }
111
112 pub async fn withdraw(
125 &self,
126 token: &ScriptHash,
127 amount: i64,
128 destination: &str,
129 account: &Account,
130 ) -> Result<TransactionBuilder<P>, ContractError> {
131 let params = vec![
132 token.into(),
133 ContractParameter::integer(amount),
134 ContractParameter::string(destination.to_string()),
135 ];
136
137 let mut builder = self.invoke_function(Self::WITHDRAW, params).await?;
138 builder.set_signers(vec![AccountSigner::called_by_entry(account)
139 .map_err(|e| {
140 ContractError::InvalidAccount(format!("Failed to create account signer: {}", e))
141 })?
142 .into()]);
143
144 Ok(builder)
145 }
146
147 pub async fn get_fee(&self, token: &ScriptHash) -> Result<u64, ContractError> {
157 let result = self.call_function_returning_int(Self::GET_FEE, vec![token.into()]).await?;
158 Ok(result as u64)
159 }
160
161 pub async fn get_cap(&self, token: &ScriptHash) -> Result<u64, ContractError> {
171 let result = self.call_function_returning_int(Self::GET_CAP, vec![token.into()]).await?;
172 Ok(result as u64)
173 }
174}
175
176#[async_trait]
177impl<'a, P: JsonRpcProvider> SmartContractTrait<'a> for NeoXBridgeContract<'a, P> {
178 type P = P;
179
180 fn script_hash(&self) -> H160 {
181 self.script_hash
182 }
183
184 fn set_script_hash(&mut self, script_hash: H160) {
185 self.script_hash = script_hash;
186 }
187
188 fn provider(&self) -> Option<&RpcClient<P>> {
189 self.provider
190 }
191}