Skip to content

Commit

Permalink
Problem: Missing examples of using the cpp sdk (fix #103)
Browse files Browse the repository at this point in the history
Close:
- #103

Solution:
- Add examples
  • Loading branch information
damoncro committed Jul 11, 2022
1 parent 3e412f5 commit c4fbf16
Show file tree
Hide file tree
Showing 13 changed files with 697 additions and 0 deletions.
2 changes: 2 additions & 0 deletions demo/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,5 @@ if (UNIX AND NOT APPLE)
# link library play_cpp_sdk built from subdirectory
target_link_libraries(demo PUBLIC play_cpp_sdk)
endif()

add_subdirectory(examples)
36 changes: 36 additions & 0 deletions demo/examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# add examples
include_directories(../sdk/include/)
include_directories(../third_party/)

add_executable(new_wallet src/new_wallet.cc)
target_link_libraries(new_wallet PUBLIC play_cpp_sdk)

add_executable(restore_wallet src/restore_wallet.cc)
target_link_libraries(restore_wallet PUBLIC play_cpp_sdk)

add_executable(eth src/eth.cc)
target_link_libraries(eth PUBLIC play_cpp_sdk)

add_executable(erc20 src/erc20.cc)
target_link_libraries(erc20 PUBLIC play_cpp_sdk)

add_executable(erc721 src/erc721.cc)
target_link_libraries(erc721 PUBLIC play_cpp_sdk)

add_executable(erc1155 src/erc1155.cc)
target_link_libraries(erc1155 PUBLIC play_cpp_sdk)

add_executable(get_erc20_transfer_history_blocking src/get_erc20_transfer_history_blocking.cc)
target_link_libraries(get_erc20_transfer_history_blocking PUBLIC play_cpp_sdk)

add_executable(get_erc721_transfer_history_blocking src/get_erc721_transfer_history_blocking.cc)
target_link_libraries(get_erc721_transfer_history_blocking PUBLIC play_cpp_sdk)

add_executable(get_tokens_blocking src/get_tokens_blocking.cc)
target_link_libraries(get_tokens_blocking PUBLIC play_cpp_sdk)

add_executable(get_token_transfers_blocking src/get_token_transfers_blocking.cc)
target_link_libraries(get_token_transfers_blocking PUBLIC play_cpp_sdk)

add_executable(create_payment src/create_payment.cc ../third_party/easywsclient/easywsclient.cpp)
target_link_libraries(create_payment PUBLIC play_cpp_sdk)
93 changes: 93 additions & 0 deletions demo/examples/src/create_payment.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#include <easywsclient/easywsclient.hpp>
#include <extra-cpp-bindings/src/lib.rs.h>
#include <iostream>
#include <json/single_include/nlohmann/json.hpp>
#include <rust/cxx.h>
#include <thread>
using namespace com::crypto::game_sdk;
using namespace nlohmann;

void websocket_client_thread(std::atomic<bool> &stop_thread, rust::String &id);

inline rust::String getEnv(rust::String key);

inline rust::String getEnv(rust::String key) {
rust::String ret;
if (getenv(key.c_str()) != nullptr) {
ret = getenv(key.c_str());
}
return ret;
}

// Read pay api key in env
const rust::String PAY_API_KEY = getEnv("PAY_API_KEY");
// Read websocket port in env
const rust::String PAY_WEBSOCKET_PORT = getEnv("PAY_WEBSOCKET_PORT");

int main(int argc, char *argv[]) {
if (PAY_API_KEY == "")
return -1;

std::atomic<bool> stop_thread_1{false};
rust::String id = "";
std::thread t1(websocket_client_thread, std::ref(stop_thread_1),
std::ref(id));

OptionalArguments opiton_args;
opiton_args.description = "Crypto.com Tee (Unisex)";
CryptoComPaymentResponse resp =
create_payment(PAY_API_KEY, "2500", "USD", opiton_args);
std::cout << "create payment:" << resp.id << " ";
std::cout << resp.main_app_qr_code << " ";
std::cout << resp.onchain_deposit_address << " ";
std::cout << resp.base_amount << " ";
std::cout << resp.currency << " ";
std::cout << resp.expiration << " ";
std::cout << resp.status << std::endl;

std::this_thread::sleep_for(std::chrono::milliseconds(3000));
stop_thread_1 = true; // force stopping websocket thread after timeout
id = resp.id; // pass the id to the thread
t1.join(); // pauses until t1 finishes

return 0;
}

// A simple websocket client thread
void websocket_client_thread(std::atomic<bool> &stop_thread, rust::String &id) {
using easywsclient::WebSocket;
rust::String r_port = PAY_WEBSOCKET_PORT;
std::string port = r_port.c_str();
std::unique_ptr<WebSocket> ws(WebSocket::from_url("ws://127.0.0.1:" + port));
if (ws == nullptr)
return;
while (ws->getReadyState() != WebSocket::CLOSED) {
WebSocket::pointer wsp =
&*ws; // <-- because a unique_ptr cannot be copied into a lambda
ws->poll();
ws->dispatch([wsp](std::string msg) {
// std::cout << "Receive webhook event: " << msg << std::endl;
try {
auto message = json::parse(msg);
assert(message.at("type") == "payment.created");
rust::String id = message.at("data").at("object").at("id");
CryptoComPaymentResponse resp = get_payment(PAY_API_KEY, id);
std::cout << "get payment: " << resp.id << " ";
std::cout << resp.main_app_qr_code << " ";
std::cout << resp.onchain_deposit_address << " ";
std::cout << resp.base_amount << " ";
std::cout << resp.currency << " ";
std::cout << resp.expiration << " ";
std::cout << resp.status << std::endl;
wsp->close();
} catch (const nlohmann::detail::parse_error &e) {
std::cout << e.what() << std::endl;
wsp->close();
}
});
if (stop_thread) {
return;
}
}
std::cout << "websocket client thread ends" << std::endl;
}
128 changes: 128 additions & 0 deletions demo/examples/src/erc1155.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#include <cassert>
#include <defi-wallet-core-cpp/src/contract.rs.h>
#include <defi-wallet-core-cpp/src/lib.rs.h>
#include <defi-wallet-core-cpp/src/uint.rs.h>
#include <iostream>
#include <rust/cxx.h>
using namespace org::defi_wallet_core;

int main(int argc, char *argv[]) {
rust::Box<Wallet> signer1_wallet =
restore_wallet("shed crumble dismiss loyal latin million oblige gesture "
"shrug still oxygen custom remove ribbon disorder palace "
"addict again blanket sad flock consider obey popular",
"");
rust::String signer1_address = signer1_wallet->get_eth_address(0);
rust::Box<PrivateKey> signer1_privatekey =
signer1_wallet->get_key("m/44'/60/0'/0/0");

rust::Box<Wallet> signer2_wallet =
restore_wallet("night renew tonight dinner shaft scheme domain oppose "
"echo summer broccoli agent face guitar surface belt "
"veteran siren poem alcohol menu custom crunch index",
"");
rust::String signer2_address = signer2_wallet->get_eth_address(0);
rust::Box<PrivateKey> signer2_privatekey =
signer2_wallet->get_key("m/44'/60/0'/0/0");

rust::Box<Wallet> validator1_wallet =
restore_wallet("visit craft resemble online window solution west chuckle "
"music diesel vital settle comic tribe project blame bulb "
"armed flower region sausage mercy arrive release",
"");
rust::String validator1_address = validator1_wallet->get_eth_address(0);
rust::Box<PrivateKey> validator1_privatekey =
validator1_wallet->get_key("m/44'/60/0'/0/0");

Erc1155 erc1155 = new_erc1155("0x939D7350c54228e4958e05b65512C4a5BB6A2ACc",
"http://127.0.0.1:26651", 777)
.legacy();
// To be improved in the contract, now all uri are the same
assert(erc1155.uri("0") == "https://game.example/api/item/{id}.json");
assert(erc1155.uri("1") == "https://game.example/api/item/{id}.json");
assert(erc1155.uri("2") == "https://game.example/api/item/{id}.json");
assert(erc1155.uri("3") == "https://game.example/api/item/{id}.json");
assert(erc1155.uri("4") == "https://game.example/api/item/{id}.json");
assert(erc1155.balance_of(signer1_address, "0") ==
u256("1000000000000000000"));
assert(erc1155.balance_of(signer1_address, "1") ==
u256("1000000000000000000000000000"));
assert(erc1155.balance_of(signer1_address, "2") == u256("1"));
assert(erc1155.balance_of(signer1_address, "3") == u256("1000000000"));
assert(erc1155.balance_of(signer1_address, "4") == u256("1000000000"));

// safe transfer erc1155 from signer1 to signer2
rust::Vec<uint8_t> erc1155_data;
rust::String status =
erc1155.interval(3000)
.safe_transfer_from(signer1_address, signer2_address, "0", "150",
erc1155_data, *signer1_privatekey)
.status;
assert(status == "1");
assert(erc1155.balance_of(signer1_address, "0") ==
u256("999999999999999850"));

// safe batch transfer erc1155 from signer1 to signer2
rust::Vec<rust::String> token_ids, amounts;
token_ids.push_back("1");
token_ids.push_back("2");
token_ids.push_back("3");
token_ids.push_back("4");

amounts.push_back("200");
amounts.push_back("1");
amounts.push_back("300");
amounts.push_back("400");
status =
erc1155
.safe_batch_transfer_from(signer1_address, signer2_address, token_ids,
amounts, erc1155_data, *signer1_privatekey)
.status;
assert(status == "1");
assert(erc1155.balance_of(signer1_address, "1") ==
u256("999999999999999999999999800"));
assert(erc1155.balance_of(signer1_address, "2") == u256("0"));
assert(erc1155.balance_of(signer1_address, "3") == u256("999999700"));
assert(erc1155.balance_of(signer1_address, "4") == u256("999999600"));

// toggle set_approval_for_all
assert(erc1155.is_approved_for_all(signer1_address, signer2_address) == 0);
erc1155.set_approval_for_all(signer2_address, true, *signer1_privatekey);
assert(erc1155.is_approved_for_all(signer1_address, signer2_address) == 1);
erc1155.set_approval_for_all(signer2_address, false, *signer1_privatekey);
assert(erc1155.is_approved_for_all(signer1_address, signer2_address) == 0);
// set approval for signer2
erc1155.set_approval_for_all(signer2_address, true, *signer1_privatekey);
assert(erc1155.is_approved_for_all(signer1_address, signer2_address) == 1);
token_ids.push_back("1");
token_ids.push_back("3");
token_ids.push_back("4");

amounts.push_back("500");
amounts.push_back("600");
amounts.push_back("700");
// and safe batch transfer from signer1 to validator1
status = erc1155
.safe_batch_transfer_from(signer1_address, validator1_address,
token_ids, amounts, erc1155_data,
*signer2_privatekey)
.status;
assert(status == "1");
assert(erc1155.balance_of(signer1_address, "1") ==
u256("999999999999999999999999300"));
assert(erc1155.balance_of(signer1_address, "2") == u256("0"));
assert(erc1155.balance_of(signer1_address, "3") == u256("999999100"));
assert(erc1155.balance_of(signer1_address, "4") == u256("999998900"));

assert(erc1155.balance_of(signer2_address, "1") == u256("200"));
assert(erc1155.balance_of(signer2_address, "2") == u256("1"));
assert(erc1155.balance_of(signer2_address, "3") == u256("300"));
assert(erc1155.balance_of(signer2_address, "4") == u256("400"));

assert(erc1155.balance_of(validator1_address, "1") == u256("500"));
assert(erc1155.balance_of(validator1_address, "2") == u256("0"));
assert(erc1155.balance_of(validator1_address, "3") == u256("600"));
assert(erc1155.balance_of(validator1_address, "4") == u256("700"));

return 0;
}
63 changes: 63 additions & 0 deletions demo/examples/src/erc20.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#include <cassert>
#include <defi-wallet-core-cpp/src/contract.rs.h>
#include <defi-wallet-core-cpp/src/lib.rs.h>
#include <defi-wallet-core-cpp/src/uint.rs.h>
#include <iostream>
#include <rust/cxx.h>
using namespace org::defi_wallet_core;

int main(int argc, char *argv[]) {
rust::Box<Wallet> signer1_wallet =
restore_wallet("shed crumble dismiss loyal latin million oblige gesture "
"shrug still oxygen custom remove ribbon disorder palace "
"addict again blanket sad flock consider obey popular",
"");
rust::String signer1_address = signer1_wallet->get_eth_address(0);
rust::Box<PrivateKey> signer1_privatekey =
signer1_wallet->get_key("m/44'/60/0'/0/0");

rust::Box<Wallet> signer2_wallet =
restore_wallet("night renew tonight dinner shaft scheme domain oppose "
"echo summer broccoli agent face guitar surface belt "
"veteran siren poem alcohol menu custom crunch index",
"");
rust::String signer2_address = signer2_wallet->get_eth_address(0);
rust::Box<PrivateKey> signer2_privatekey =
signer2_wallet->get_key("m/44'/60/0'/0/0");

rust::Box<Wallet> validator1_wallet =
restore_wallet("visit craft resemble online window solution west chuckle "
"music diesel vital settle comic tribe project blame bulb "
"armed flower region sausage mercy arrive release",
"");
rust::String validator1_address = validator1_wallet->get_eth_address(0);

Erc20 erc20 = new_erc20("0x5003c1fcc043D2d81fF970266bf3fa6e8C5a1F3A",
"http://127.0.0.1:26651", 777)
.legacy();
assert(erc20.name() == "Gold");
assert(erc20.symbol() == "GLD");
assert(erc20.decimals() == 18);
U256 erc20_total_supply = erc20.total_supply();
assert(erc20_total_supply == u256("100000000000000000000000000"));
U256 erc20_balance = erc20.balance_of(signer1_address);
assert(erc20_balance == erc20_total_supply);

// transfer erc20 token from signer1 to signer2
rust::String status = erc20.transfer(signer2_address, "100", *signer1_privatekey).status;
assert(status == "1");
assert(erc20.balance_of(signer1_address) == erc20_balance.sub(u256("100")));

// signer1 approve singer2 allowance
erc20.interval(3000).approve(signer2_address, "1000", *signer1_privatekey);
rust::String allowance = erc20.allowance(signer1_address, signer2_address);
assert(allowance == "1000");

// transfer from signer1 to validator1 using the allowance mechanism
erc20.transfer_from(signer1_address, validator1_address, "100",
*signer2_privatekey);
allowance = erc20.allowance(signer1_address, signer2_address);
assert(allowance == "900");

return 0;
}
Loading

0 comments on commit c4fbf16

Please sign in to comment.