Skip to content

Commit 46e3ebc

Browse files
karim-enfrolvanya
andauthored
chore: improve UX of the fin transfer (#168)
* Improve UX of the fin transfer * Bump version * Use fastnear for testnet * fix clippy * docs: updated near-fin-transfer examples --------- Co-authored-by: Ivan Frolov <frolvanya@gmail.com>
1 parent c10b35e commit 46e3ebc

File tree

6 files changed

+164
-41
lines changed

6 files changed

+164
-41
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bridge-cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "bridge-cli"
3-
version = "0.2.18"
3+
version = "0.3.0"
44
edition = "2021"
55
repository = "https://github.com/Near-One/bridge-sdk-rs"
66

bridge-cli/README.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,9 @@ bridge-cli testnet evm-init-transfer \
105105
--message ""
106106

107107
# 2. Wait for the transaction to be confirmed, then finalize on NEAR
108-
bridge-cli testnet near-fin-transfer-with-evm-proof \
108+
bridge-cli testnet near-fin-transfer \
109109
--chain eth \
110110
--tx-hash 0xabc...def \
111-
--storage-deposit-actions usdc.near:alice.near:0.1
112111
```
113112

114113
### Example 3: Transfer token from NEAR to Solana
@@ -180,13 +179,12 @@ bridge-cli near-sign-transfer \
180179
--fee <FEE_AMOUNT> \
181180
--native-fee <NATIVE_FEE_AMOUNT>
182181

183-
# Finalize a transfer on NEAR (using EVM proof)
184-
bridge-cli near-fin-transfer-with-evm-proof \
182+
# Finalize a transfer on NEAR (for transfers from EVM)
183+
bridge-cli near-fin-transfer \
185184
--chain <SOURCE_CHAIN> \
186185
--tx-hash <TX_HASH> \
187-
--storage-deposit-actions <TOKEN1:ACCOUNT1:AMOUNT1,...>
188186

189-
# Finalize a transfer on NEAR (using VAA)
187+
# Finalize a transfer on NEAR (using VAA, use this method only for transfers from Solana)
190188
bridge-cli near-fin-transfer-with-vaa \
191189
--chain <SOURCE_CHAIN> \
192190
--storage-deposit-actions <TOKEN1:ACCOUNT1:AMOUNT1,...> \

bridge-cli/src/defaults.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/// Mainnet
2-
pub const NEAR_RPC_MAINNET: &str = "https://archival-rpc.mainnet.near.org/";
2+
pub const NEAR_RPC_MAINNET: &str = "https://archival-rpc.mainnet.fastnear.com/";
33
pub const NEAR_TOKEN_LOCKER_ID_MAINNET: &str = "omni.bridge.near";
44
pub const ETH_LIGHT_CLIENT_ID_MAINNET: &str = "client-eth2.bridge.near";
55

@@ -29,7 +29,7 @@ pub const BTC_MAINNET: &str = "btc-client.bridge.near";
2929
pub const SATOSHI_RELAYER_MAINNET: &str = "satoshi_optwo.near";
3030

3131
/// Testnet
32-
pub const NEAR_RPC_TESTNET: &str = "https://archival-rpc.testnet.near.org/";
32+
pub const NEAR_RPC_TESTNET: &str = "https://archival-rpc.testnet.fastnear.com/";
3333
pub const NEAR_TOKEN_LOCKER_ID_TESTNET: &str = "omni.n-bridge.testnet";
3434
pub const ETH_LIGHT_CLIENT_ID_TESTNET: &str = "client-eth2.sepolia.testnet";
3535

bridge-cli/src/omni_connector_command.rs

Lines changed: 49 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ pub enum OmniConnectorSubCommand {
101101
#[command(flatten)]
102102
config_cli: CliConfig,
103103
},
104-
#[clap(about = "Finalize a transfer on NEAR using EVM proof")]
105-
NearFinTransferWithEvmProof {
104+
#[clap(about = "Finalize a transfer on NEAR")]
105+
NearFinTransfer {
106106
#[clap(short, long, help = "Origin chain of the transfer to finalize")]
107107
chain: ChainKind,
108108
#[clap(
@@ -111,12 +111,6 @@ pub enum OmniConnectorSubCommand {
111111
help = "Transaction hash of the InitTransfer call on other chain"
112112
)]
113113
tx_hash: String,
114-
#[clap(
115-
short,
116-
long,
117-
help = "Storage deposit actions. Format: token_id1:account_id1:amount1,token_id2:account_id2:amount2,..."
118-
)]
119-
storage_deposit_actions: Vec<String>,
120114
#[command(flatten)]
121115
config_cli: CliConfig,
122116
},
@@ -506,32 +500,56 @@ pub async fn match_subcommand(cmd: OmniConnectorSubCommand, network: Network) {
506500
.await
507501
.unwrap();
508502
}
509-
OmniConnectorSubCommand::NearFinTransferWithEvmProof {
503+
OmniConnectorSubCommand::NearFinTransfer {
510504
chain,
511505
tx_hash,
512-
storage_deposit_actions,
513506
config_cli,
514-
} => {
515-
omni_connector(network, config_cli)
516-
.fin_transfer(FinTransferArgs::NearFinTransferWithEvmProof {
517-
chain_kind: chain,
518-
tx_hash: TxHash::from_str(&tx_hash).expect("Invalid tx_hash"),
519-
storage_deposit_actions: storage_deposit_actions
520-
.iter()
521-
.map(|action| {
522-
let parts: Vec<&str> = action.split(':').collect();
523-
omni_types::locker_args::StorageDepositAction {
524-
token_id: parts[0].parse().unwrap(),
525-
account_id: parts[1].parse().unwrap(),
526-
storage_deposit_amount: parts[2].parse().ok(),
527-
}
528-
})
529-
.collect(),
530-
transaction_options: TransactionOptions::default(),
531-
})
532-
.await
533-
.unwrap();
534-
}
507+
} => match chain {
508+
ChainKind::Eth => {
509+
let connector = omni_connector(network, config_cli);
510+
let storage_deposit_actions = connector
511+
.get_storage_deposit_actions_for_evm_tx(chain, tx_hash.parse().unwrap())
512+
.await
513+
.unwrap();
514+
515+
connector
516+
.fin_transfer(FinTransferArgs::NearFinTransferWithEvmProof {
517+
chain_kind: chain,
518+
tx_hash: TxHash::from_str(&tx_hash).expect("Invalid tx_hash"),
519+
storage_deposit_actions,
520+
transaction_options: TransactionOptions::default(),
521+
})
522+
.await
523+
.unwrap();
524+
}
525+
ChainKind::Arb | ChainKind::Base => {
526+
let connector = omni_connector(network, config_cli);
527+
528+
let vaa = connector
529+
.wormhole_get_vaa_by_tx_hash(tx_hash.clone())
530+
.await
531+
.unwrap();
532+
533+
let storage_deposit_actions = connector
534+
.get_storage_deposit_actions_for_evm_tx(chain, tx_hash.parse().unwrap())
535+
.await
536+
.unwrap();
537+
538+
connector
539+
.fin_transfer(FinTransferArgs::NearFinTransferWithVaa {
540+
chain_kind: chain,
541+
storage_deposit_actions,
542+
vaa,
543+
transaction_options: TransactionOptions::default(),
544+
})
545+
.await
546+
.unwrap();
547+
}
548+
_ => {
549+
// TODO: add support for Solana
550+
panic!("Unsupported chain for NearFinTransfer: {chain:?}");
551+
}
552+
},
535553
OmniConnectorSubCommand::NearFinTransferWithVaa {
536554
chain,
537555
storage_deposit_actions,

bridge-sdk/connectors/omni-connector/src/omni_connector.rs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,4 +1495,111 @@ impl OmniConnector {
14951495
.get_proof_for_event(tx_hash, proof_kind)
14961496
.await
14971497
}
1498+
1499+
pub async fn get_storage_deposit_actions_for_evm_tx(
1500+
&self,
1501+
chain: ChainKind,
1502+
tx_hash: TxHash,
1503+
) -> Result<Vec<StorageDepositAction>> {
1504+
// TODO: add fast transfer support
1505+
let transfer_event = self.evm_get_transfer_event(chain, tx_hash).await?;
1506+
1507+
let token_address =
1508+
OmniAddress::new_from_evm_address(chain, H160(transfer_event.token_address.0))
1509+
.map_err(|_| {
1510+
BridgeSdkError::InvalidArgument(format!(
1511+
"Failed to parse token address: {}",
1512+
transfer_event.token_address
1513+
))
1514+
})?;
1515+
1516+
let recipient = OmniAddress::from_str(&transfer_event.recipient).map_err(|_| {
1517+
BridgeSdkError::InvalidArgument(format!(
1518+
"Failed to parse recipient: {}",
1519+
transfer_event.recipient
1520+
))
1521+
})?;
1522+
1523+
let fee_recipient = self
1524+
.near_bridge_client()
1525+
.and_then(NearBridgeClient::account_id)
1526+
.map_err(|_| {
1527+
BridgeSdkError::ConfigError("NEAR bridge client not configured".to_string())
1528+
})?;
1529+
1530+
self.get_storage_deposit_actions(
1531+
chain,
1532+
&recipient,
1533+
&fee_recipient,
1534+
&token_address,
1535+
transfer_event.fee,
1536+
transfer_event.native_token_fee,
1537+
)
1538+
.await
1539+
}
1540+
1541+
pub async fn get_storage_deposit_actions(
1542+
&self,
1543+
chain: ChainKind,
1544+
recipient: &OmniAddress,
1545+
fee_recipient: &AccountId,
1546+
token_address: &OmniAddress,
1547+
fee: u128,
1548+
native_fee: u128,
1549+
) -> Result<Vec<StorageDepositAction>> {
1550+
let mut storage_deposit_actions = Vec::new();
1551+
if let OmniAddress::Near(near_recipient) = recipient {
1552+
self.add_storage_deposit_action(
1553+
&mut storage_deposit_actions,
1554+
self.near_get_token_id(token_address.clone()).await?,
1555+
near_recipient.clone(),
1556+
)
1557+
.await?;
1558+
}
1559+
1560+
if fee > 0 {
1561+
self.add_storage_deposit_action(
1562+
&mut storage_deposit_actions,
1563+
self.near_get_token_id(token_address.clone()).await?,
1564+
fee_recipient.clone(),
1565+
)
1566+
.await?;
1567+
}
1568+
1569+
if native_fee > 0 {
1570+
let token_id = self.near_get_native_token_id(chain).await?;
1571+
1572+
self.add_storage_deposit_action(
1573+
&mut storage_deposit_actions,
1574+
token_id,
1575+
fee_recipient.clone(),
1576+
)
1577+
.await?;
1578+
}
1579+
1580+
Ok(storage_deposit_actions)
1581+
}
1582+
1583+
async fn add_storage_deposit_action(
1584+
&self,
1585+
storage_deposit_actions: &mut Vec<StorageDepositAction>,
1586+
token_id: AccountId,
1587+
account_id: AccountId,
1588+
) -> Result<()> {
1589+
let storage_deposit_amount = match self
1590+
.near_get_required_storage_deposit(token_id.clone(), account_id.clone())
1591+
.await?
1592+
{
1593+
amount if amount > 0 => Some(amount),
1594+
_ => None,
1595+
};
1596+
1597+
storage_deposit_actions.push(StorageDepositAction {
1598+
token_id,
1599+
account_id,
1600+
storage_deposit_amount,
1601+
});
1602+
1603+
Ok(())
1604+
}
14981605
}

0 commit comments

Comments
 (0)