Skip to content

Commit

Permalink
Merge pull request #1 from ovidiuolteanu/framework-upgrade
Browse files Browse the repository at this point in the history
updated framework, syntax, tests &  added blackbox test
  • Loading branch information
ovidiuolteanu authored Jun 28, 2024
2 parents 47e5730 + 80b1101 commit a795e17
Show file tree
Hide file tree
Showing 21 changed files with 4,078 additions and 1,017 deletions.
2,313 changes: 1,860 additions & 453 deletions dummy-proxy/Cargo.lock

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions dummy-proxy/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "dummy-proxy"
version = "0.0.0"
authors = [ "you",]
authors = ["you"]
edition = "2018"
publish = false

Expand All @@ -12,7 +12,10 @@ path = "src/lib.rs"
num-bigint = "0.4.2"

[dependencies.multiversx-sc]
version = "0.39.8"
version = "0.50.5"

[dev-dependencies.multiversx-sc-scenario]
version = "0.39.8"
version = "0.50.5"

[workspace]
members = [".", "meta", "interact-rs"]
2 changes: 2 additions & 0 deletions dummy-proxy/interact-rs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Pem files are used for interactions, but shouldn't be committed
*.pem
27 changes: 27 additions & 0 deletions dummy-proxy/interact-rs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[package]
name = "rust-interact"
version = "0.0.0"
authors = ["you"]
edition = "2021"
publish = false

[[bin]]
name = "rust-interact"
path = "src/interactor_main.rs"

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

[dependencies.multiversx-sc-snippets]
version = "0.50.5"

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

[dependencies]
clap = { version = "4.4.7", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
toml = "0.8.6"

# [workspace]

207 changes: 207 additions & 0 deletions dummy-proxy/interact-rs/src/interactor_main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
#![allow(non_snake_case)]

mod proxy;

use multiversx_sc_snippets::imports::*;
use multiversx_sc_snippets::sdk;
use serde::{Deserialize, Serialize};
use std::{
io::{Read, Write},
path::Path,
};

const GATEWAY: &str = sdk::blockchain::DEVNET_GATEWAY;
const STATE_FILE: &str = "state.toml";

#[tokio::main]
async fn main() {
env_logger::init();

let mut args = std::env::args();
let _ = args.next();
let cmd = args.next().expect("at least one argument required");
let mut interact = ContractInteract::new().await;
match cmd.as_str() {
"deploy" => interact.deploy().await,
"callEndpoint" => interact.call_endpoint().await,
"callInternalTransferEndpoint" => interact.call_int_transfer_endpoint().await,
"callTransferEndpoint" => interact.call_transfer_endpoint().await,
_ => panic!("unknown command: {}", &cmd),
}
}

#[derive(Debug, Default, Serialize, Deserialize)]
struct State {
contract_address: Option<Bech32Address>,
}

impl State {
// Deserializes state from file
pub fn load_state() -> Self {
if Path::new(STATE_FILE).exists() {
let mut file = std::fs::File::open(STATE_FILE).unwrap();
let mut content = String::new();
file.read_to_string(&mut content).unwrap();
toml::from_str(&content).unwrap()
} else {
Self::default()
}
}

/// Sets the contract address
pub fn set_address(&mut self, address: Bech32Address) {
self.contract_address = Some(address);
}

/// Returns the contract address
pub fn current_address(&self) -> &Bech32Address {
self.contract_address
.as_ref()
.expect("no known contract, deploy first")
}
}

impl Drop for State {
// Serializes state to file
fn drop(&mut self) {
let mut file = std::fs::File::create(STATE_FILE).unwrap();
file.write_all(toml::to_string(self).unwrap().as_bytes())
.unwrap();
}
}

struct ContractInteract {
interactor: Interactor,
wallet_address: Address,
contract_code: BytesValue,
state: State,
}

impl ContractInteract {
async fn new() -> Self {
let mut interactor = Interactor::new(GATEWAY).await;
let wallet_address = interactor.register_wallet(test_wallets::alice());

let contract_code = BytesValue::interpret_from(
"mxsc:../output/dummy-proxy.mxsc.json",
&InterpreterContext::default(),
);

ContractInteract {
interactor,
wallet_address,
contract_code,
state: State::load_state(),
}
}

async fn deploy(&mut self) {
let new_address = self
.interactor
.tx()
.from(&self.wallet_address)
.gas(20_000_000u64)
.typed(proxy::DummyProxyContractProxy)
.init()
.code(&self.contract_code)
.returns(ReturnsNewAddress)
.prepare_async()
.run()
.await;
let new_address_bech32 = bech32::encode(&new_address);
self.state.set_address(Bech32Address::from_bech32_string(
new_address_bech32.clone(),
));

println!("new address: {new_address_bech32}");
}

async fn call_endpoint(&mut self) {
let contract_address = bech32::decode("");
let function_name = ManagedBuffer::new_from_bytes(&b""[..]);
let args = MultiValueVec::from(vec![ManagedBuffer::new_from_bytes(&b""[..])]);

let response = self
.interactor
.tx()
.from(&self.wallet_address)
.to(self.state.current_address())
.gas(20_000_000u64)
.typed(proxy::DummyProxyContractProxy)
.call_endpoint(contract_address, function_name, args)
.returns(ReturnsResultUnmanaged)
.prepare_async()
.run()
.await;

println!("Result: {response:?}");
}

async fn call_int_transfer_endpoint(&mut self) {
let token_id = TokenIdentifier::from_esdt_bytes(&b""[..]);
let nonce = 0u64;
let amount = BigUint::<StaticApi>::from(0u128);
let contract_address = bech32::decode("");
let function_name = ManagedBuffer::new_from_bytes(&b""[..]);
let args = MultiValueVec::from(vec![ManagedBuffer::new_from_bytes(&b""[..])]);

let response = self
.interactor
.tx()
.from(&self.wallet_address)
.to(self.state.current_address())
.gas(20_000_000u64)
.typed(proxy::DummyProxyContractProxy)
.call_int_transfer_endpoint(
token_id,
nonce,
amount,
contract_address,
function_name,
args,
)
.returns(ReturnsResultUnmanaged)
.prepare_async()
.run()
.await;

println!("Result: {response:?}");
}

async fn call_transfer_endpoint(&mut self) {
let token_id = String::new();
let token_nonce = 0u64;
let token_amount = BigUint::<StaticApi>::from(0u128);

let contract_address = bech32::decode("");
let function_name = ManagedBuffer::new_from_bytes(&b""[..]);
let args = MultiValueVec::from(vec![ManagedBuffer::new_from_bytes(&b""[..])]);

let response = self
.interactor
.tx()
.from(&self.wallet_address)
.to(self.state.current_address())
.gas(20_000_000u64)
.typed(proxy::DummyProxyContractProxy)
.call_transfer_endpoint(contract_address, function_name, args)
.payment((
TokenIdentifier::from(token_id.as_str()),
token_nonce,
token_amount,
))
.returns(ReturnsResultUnmanaged)
.prepare_async()
.run()
.await;

println!("Result: {response:?}");
}
}

#[tokio::test]
async fn integration_test() {
let mut interact = ContractInteract::new().await;

interact.deploy().await;
}
129 changes: 129 additions & 0 deletions dummy-proxy/interact-rs/src/proxy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// Code generated by the multiversx-sc proxy generator. DO NOT EDIT.

////////////////////////////////////////////////////
////////////////// AUTO-GENERATED //////////////////
////////////////////////////////////////////////////

#![allow(dead_code)]
#![allow(clippy::all)]

use multiversx_sc::proxy_imports::*;

pub struct DummyProxyContractProxy;

impl<Env, From, To, Gas> TxProxyTrait<Env, From, To, Gas> for DummyProxyContractProxy
where
Env: TxEnv,
From: TxFrom<Env>,
To: TxTo<Env>,
Gas: TxGas<Env>,
{
type TxProxyMethods = DummyProxyContractProxyMethods<Env, From, To, Gas>;

fn proxy_methods(self, tx: Tx<Env, From, To, (), Gas, (), ()>) -> Self::TxProxyMethods {
DummyProxyContractProxyMethods { wrapped_tx: tx }
}
}

pub struct DummyProxyContractProxyMethods<Env, From, To, Gas>
where
Env: TxEnv,
From: TxFrom<Env>,
To: TxTo<Env>,
Gas: TxGas<Env>,
{
wrapped_tx: Tx<Env, From, To, (), Gas, (), ()>,
}

#[rustfmt::skip]
impl<Env, From, Gas> DummyProxyContractProxyMethods<Env, From, (), Gas>
where
Env: TxEnv,
Env::Api: VMApi,
From: TxFrom<Env>,
Gas: TxGas<Env>,
{
pub fn init(
self,
) -> TxTypedDeploy<Env, From, NotPayable, Gas, ()> {
self.wrapped_tx
.payment(NotPayable)
.raw_deploy()
.original_result()
}
}

#[rustfmt::skip]
impl<Env, From, To, Gas> DummyProxyContractProxyMethods<Env, From, To, Gas>
where
Env: TxEnv,
Env::Api: VMApi,
From: TxFrom<Env>,
To: TxTo<Env>,
Gas: TxGas<Env>,
{
pub fn call_endpoint<
Arg0: ProxyArg<ManagedAddress<Env::Api>>,
Arg1: ProxyArg<ManagedBuffer<Env::Api>>,
Arg2: ProxyArg<MultiValueEncoded<Env::Api, ManagedBuffer<Env::Api>>>,
>(
self,
contract_address: Arg0,
function_name: Arg1,
args: Arg2,
) -> TxTypedCall<Env, From, To, NotPayable, Gas, ()> {
self.wrapped_tx
.payment(NotPayable)
.raw_call("callEndpoint")
.argument(&contract_address)
.argument(&function_name)
.argument(&args)
.original_result()
}

pub fn call_int_transfer_endpoint<
Arg0: ProxyArg<TokenIdentifier<Env::Api>>,
Arg1: ProxyArg<u64>,
Arg2: ProxyArg<BigUint<Env::Api>>,
Arg3: ProxyArg<ManagedAddress<Env::Api>>,
Arg4: ProxyArg<ManagedBuffer<Env::Api>>,
Arg5: ProxyArg<MultiValueEncoded<Env::Api, ManagedBuffer<Env::Api>>>,
>(
self,
token_id: Arg0,
nonce: Arg1,
amount: Arg2,
contract_address: Arg3,
function_name: Arg4,
args: Arg5,
) -> TxTypedCall<Env, From, To, NotPayable, Gas, ()> {
self.wrapped_tx
.payment(NotPayable)
.raw_call("callInternalTransferEndpoint")
.argument(&token_id)
.argument(&nonce)
.argument(&amount)
.argument(&contract_address)
.argument(&function_name)
.argument(&args)
.original_result()
}

pub fn call_transfer_endpoint<
Arg0: ProxyArg<ManagedAddress<Env::Api>>,
Arg1: ProxyArg<ManagedBuffer<Env::Api>>,
Arg2: ProxyArg<MultiValueEncoded<Env::Api, ManagedBuffer<Env::Api>>>,
>(
self,
contract_address: Arg0,
function_name: Arg1,
args: Arg2,
) -> TxTypedCall<Env, From, To, (), Gas, ()> {
self.wrapped_tx
.raw_call("callTransferEndpoint")
.argument(&contract_address)
.argument(&function_name)
.argument(&args)
.original_result()
}
}
1 change: 1 addition & 0 deletions dummy-proxy/interact-rs/state.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
contract_address = "erd1qqqqqqqqqqqqqpgqssfwuh0m4ff5jgvz05garzgn2xmj3jrdd8ss9thn2g"
Loading

0 comments on commit a795e17

Please sign in to comment.