Skip to content

Commit

Permalink
Merge pull request #153 from multiversx/feat/tx-with-SC-call
Browse files Browse the repository at this point in the history
Feat/tx with sc call
  • Loading branch information
sasurobert authored Jan 22, 2024
2 parents 8c1438e + bae95ea commit 1596483
Show file tree
Hide file tree
Showing 121 changed files with 4,151 additions and 971 deletions.
11 changes: 7 additions & 4 deletions .github/workflows/actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ on:
push:
branches:
- main
- feat/*
pull_request:
branches: [ main ]
branches:
- main
- feat/*

permissions:
checks: write
Expand All @@ -14,9 +17,9 @@ permissions:
jobs:
contracts:
name: Contracts
uses: multiversx/mx-sc-actions/.github/workflows/[email protected].0
uses: multiversx/mx-sc-actions/.github/workflows/[email protected].5
with:
rust-toolchain: nightly-2023-04-24
vmtools-version: v1.4.60
rust-toolchain: nightly-2023-12-11
vmtools-version: v1.5.19
secrets:
token: ${{ secrets.GITHUB_TOKEN }}
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
[workspace]
members = [
"bridge-proxy",
"bridge-proxy/meta",
"esdt-safe",
"esdt-safe/meta",
"multi-transfer-esdt",
Expand Down
7 changes: 7 additions & 0 deletions bridge-proxy/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Generated by Cargo
# will have compiled files and executables
/target/
*/target/

# The mxpy output
/output*/
28 changes: 28 additions & 0 deletions bridge-proxy/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[package]
name = "bridge-proxy"
version = "0.0.0"
authors = ["Costin Carabaș <[email protected]>"]
edition = "2018"
publish = false

[lib]
path = "src/bridge-proxy.rs"

[dependencies.transaction]
path = "../common/transaction"

[dependencies.eth-address]
path = "../common/eth-address"

[dependencies.multiversx-sc]
version = "0.46.1"

[dependencies.adder]
git = "https://github.com/multiversx/mx-contracts-rs"
rev = "64e8926"

[dev-dependencies]
num-bigint = "0.4.2"

[dev-dependencies.multiversx-sc-scenario]
version = "0.46.1"
14 changes: 14 additions & 0 deletions bridge-proxy/meta/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "bridge-proxy-meta"
version = "0.0.0"
edition = "2018"
publish = false
authors = ["you"]

[dev-dependencies]

[dependencies.bridge-proxy]
path = ".."

[dependencies.multiversx-sc-meta]
version = "0.46.1"
3 changes: 3 additions & 0 deletions bridge-proxy/meta/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
multiversx_sc_meta::cli_main::<bridge_proxy::AbiProvider>();
}
3 changes: 3 additions & 0 deletions bridge-proxy/multiversx.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"language": "rust"
}
78 changes: 78 additions & 0 deletions bridge-proxy/src/bridge-proxy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#![no_std]

multiversx_sc::imports!();
multiversx_sc::derive_imports!();

pub mod config;

use transaction::{EthTransaction, EthTransactionPayment};

#[multiversx_sc::contract]
pub trait BridgeProxyContract: config::ConfigModule {
#[init]
fn init(&self, opt_multi_transfer_address: OptionalValue<ManagedAddress>) {
self.set_multi_transfer_contract_address(opt_multi_transfer_address);
}

#[payable("*")]
#[endpoint]
fn deposit(&self, eth_tx: EthTransaction<Self::Api>) {
let (token_id, nonce, amount) = self.call_value().single_esdt().into_tuple();
self.eth_transaction_list()
.push_back(EthTransactionPayment {
token_id,
nonce,
amount,
eth_tx,
});
}

#[endpoint(executeWithAsnyc)]
fn execute_with_async(&self, tx_id: u32) {
let tx_node = self
.eth_transaction_list()
.remove_node_by_id(tx_id)
.unwrap_or_else(|| sc_panic!("Invalid ETH transaction!"));
let tx = tx_node.get_value_as_ref();

self.send()
.contract_call::<IgnoreValue>(tx.eth_tx.to.clone(), tx.eth_tx.data.clone())
.with_raw_arguments(tx.eth_tx.args.clone().into())
.with_esdt_transfer((tx.token_id.clone(), tx.nonce, tx.amount.clone()))
.with_gas_limit(tx.eth_tx.gas_limit)
.async_call()
.with_callback(self.callbacks().failed_execution_callback(tx))
.call_and_exit();
}

#[callback]
fn failed_execution_callback(&self, tx: &EthTransactionPayment<Self::Api>) {
self.eth_failed_transaction_list().push_back(tx.clone());
}

#[endpoint(refundTransactions)]
fn refund_transactions(&self) -> MultiValueEncoded<EthTransactionPayment<Self::Api>> {
// Send Failed Tx Structure
let mut result = MultiValueEncoded::new();
for tx_loop in self.eth_failed_transaction_list().iter() {
let tx = tx_loop.get_value_cloned();
result.push(tx);
}

// Send Funds
let mut all_payments = ManagedVec::new();
for failed_tx_loop in self.eth_failed_transaction_list().into_iter() {
let failed_tx = failed_tx_loop.get_value_as_ref();

all_payments.push(EsdtTokenPayment::new(
failed_tx.token_id.clone(),
failed_tx.nonce,
failed_tx.amount.clone(),
));
}
self.send()
.direct_multi(&self.multi_transfer_address().get(), &all_payments);

result
}
}
46 changes: 46 additions & 0 deletions bridge-proxy/src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
multiversx_sc::imports!();
multiversx_sc::derive_imports!();

use transaction::{EthTransaction, EthTransactionPayment};

#[multiversx_sc::module]
pub trait ConfigModule {
#[only_owner]
#[endpoint(setupMultiTransfer)]
fn set_multi_transfer_contract_address(
&self,
opt_multi_transfer_address: OptionalValue<ManagedAddress>,
) {
match opt_multi_transfer_address {
OptionalValue::Some(sc_addr) => {
require!(
self.blockchain().is_smart_contract(&sc_addr),
"Invalid multi-transfer address"
);
self.multi_transfer_address().set(&sc_addr);
}
OptionalValue::None => self.multi_transfer_address().clear(),
}
}

#[view(getEthTransactionById)]
fn get_eth_transaction_by_id(&self, id: u32) -> EthTransaction<Self::Api> {
let eth_tx_list = self.eth_transaction_list();
match eth_tx_list.get_node_by_id(id) {
Some(tx) => tx.get_value_cloned().eth_tx,
None => sc_panic!("No transaction with this id!"),
}
}

#[view(getMultiTransferAddress)]
#[storage_mapper("multiTransferAddress")]
fn multi_transfer_address(&self) -> SingleValueMapper<ManagedAddress>;

#[view(getEthTransactionList)]
#[storage_mapper("eth_transaction_list")]
fn eth_transaction_list(&self) -> LinkedListMapper<EthTransactionPayment<Self::Api>>;

#[view(getEthFailedTransactionList)]
#[storage_mapper("eth_failed_transaction_list")]
fn eth_failed_transaction_list(&self) -> LinkedListMapper<EthTransactionPayment<Self::Api>>;
}
Loading

0 comments on commit 1596483

Please sign in to comment.