+
+```bash
+cargo add cma-rust-parser
+```
+
+
+
+```rust
+use cma_rust_parser::{
+ Ledger, AssetType, RetrieveOperation, AccountType, U256, Address
+};
+
+let address_one = "0x0000000000000000000000000000000000000001";
+let address_two = "0x0000000000000000000000000000000000000002";
+let erc_20_token = "0x92C6bcA388E99d6B304f1Af3c3Cd749Ff0b591e2";
+let erc_721_token = "0xc6582A9b48F211Fa8c2B5b16CB615eC39bcA653B";
+
+// Initialize the ledger
+let mut ledger = Ledger::new()?;
+
+// Retrieve or create an asset
+let token_address = Address::from_str_hex(erc_721_token).unwrap();
+let token_id = U256::from_u64(1); // Used for NFTs
+
+let asset_id = ledger.retrieve_asset(
+ None,
+ Some(token_address),
+ Some(token_id),
+ AssetType::TokenAddressId,
+ RetrieveOperation::FindOrCreate,
+)?;
+
+// Retrieve or create an account
+let wallet_address = Address::from_str_hex(address_one).unwrap();
+
+let account_id = ledger.retrieve_account(
+ None,
+ AccountType::WalletAddress,
+ RetrieveOperation::FindOrCreate,
+ Some(wallet_address.as_bytes())
+)?;
+
+// Deposit tokens
+ledger.deposit(asset_id, account_id, U256::from_u64(1000)).unwrap();
+
+// Transfer tokens
+let recipient_address = Address::from_str_hex(address_two).unwrap();
+let receipient_id = ledger.retrieve_account_via_address(recipient_address).unwrap();
+
+let transfer_result = ledger.transfer(asset_id, account_id, recipient_id, U256::from_u64(1)).unwrap();
+
+// Query balances and supply
+let balance = ledger.get_balance(asset_id, account_id).unwrap();
+let supply = ledger.get_total_supply(asset_id).unwrap();
+
+// Retrieve ERC20 asset ID
+let erc20_address = Address::from_str_hex(erc_20_token).unwrap();
+let erc20_token_id = ledger.retrieve_erc20_asset_via_address(erc20_address).unwrap();
+
+// Withdraw Token
+let withdraw_result = ledger.withdraw(erc20_token_id, account_id, U256::from_u64(100000000000000000000))
+
+// Retrieve Ether ID
+let ether_id = ledger.retrieve_ether_assets(); // Ether has no contract address hence there's no need to pass an address
+```
+
+
+
+```rust
+fn cma_decode_advance(req_type: CmaParserInputType, input: JsonValue) -> Result;
+```
+
+
+
+```cpp
+cma_parser_error_t cma_decode_advance(cma_parser_input_type_t type, const cmt_rollup_advance_t *input, cma_parser_input_t *parser_input);
+```
+
+
+
+
+
+
+```rust
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum CmaParserInputType {
+ CmaParserInputTypeNone,
+ CmaParserInputTypeAuto,
+ CmaParserInputTypeUnidentified,
+ CmaParserInputTypeEtherDeposit,
+ CmaParserInputTypeErc20Deposit,
+ CmaParserInputTypeErc721Deposit,
+ CmaParserInputTypeErc1155SingleDeposit,
+ CmaParserInputTypeErc1155BatchDeposit,
+ CmaParserInputTypeEtherWithdrawal,
+ CmaParserInputTypeErc20Withdrawal,
+ CmaParserInputTypeErc721Withdrawal,
+ CmaParserInputTypeErc1155SingleWithdrawal,
+ CmaParserInputTypeErc1155BatchWithdrawal,
+ CmaParserInputTypeEtherTransfer,
+ CmaParserInputTypeErc20Transfer,
+ CmaParserInputTypeErc721Transfer,
+ CmaParserInputTypeErc1155SingleTransfer,
+ CmaParserInputTypeErc1155BatchTransfer,
+ CmaParserInputTypeBalance,
+ CmaParserInputTypeSupply,
+}
+```
+
+
+
+```cpp
+enum cma_parser_input_type_t {
+ CMA_PARSER_INPUT_TYPE_NONE,
+ CMA_PARSER_INPUT_TYPE_AUTO,
+ CMA_PARSER_INPUT_TYPE_ETHER_DEPOSIT,
+ CMA_PARSER_INPUT_TYPE_ERC20_DEPOSIT,
+ CMA_PARSER_INPUT_TYPE_ERC721_DEPOSIT,
+ CMA_PARSER_INPUT_TYPE_ERC1155_SINGLE_DEPOSIT,
+ CMA_PARSER_INPUT_TYPE_ERC1155_BATCH_DEPOSIT,
+ CMA_PARSER_INPUT_TYPE_ETHER_WITHDRAWAL,
+ CMA_PARSER_INPUT_TYPE_ERC20_WITHDRAWAL,
+ CMA_PARSER_INPUT_TYPE_ERC721_WITHDRAWAL,
+ CMA_PARSER_INPUT_TYPE_ERC1155_SINGLE_WITHDRAWAL,
+ CMA_PARSER_INPUT_TYPE_ERC1155_BATCH_WITHDRAWAL,
+ CMA_PARSER_INPUT_TYPE_ETHER_TRANSFER,
+ CMA_PARSER_INPUT_TYPE_ERC20_TRANSFER,
+ CMA_PARSER_INPUT_TYPE_ERC721_TRANSFER,
+ CMA_PARSER_INPUT_TYPE_ERC1155_SINGLE_TRANSFER,
+ CMA_PARSER_INPUT_TYPE_ERC1155_BATCH_TRANSFER,
+ CMA_PARSER_INPUT_TYPE_BALANCE,
+ CMA_PARSER_INPUT_TYPE_SUPPLY,
+};
+```
+
+
+
+
+
+
+
+
+
+
+
+
+```rust
+fn cma_decode_inspect(input: JsonValue) -> Result;
+```
+
+
+
+```cpp
+int cma_parser_decode_inspect(cma_parser_input_type_t type, const cmt_rollup_inspect_t *input, cma_parser_input_t *parser_input);
+```
+
+
+
+```rust
+fn cma_encode_voucher( req_type: CmaParserVoucherType, voucher_request: CmaVoucherFieldType) -> Result
+```
+
+
+
+```cpp
+cma_parser_error_t cma_encode_voucher(cma_parser_voucher_type_t type, cma_abi_address_t *app_address, const cma_parser_voucher_data_t *voucher_request, cma_voucher_t *voucher);
+```
+
+
+
+```rust
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum CmaParserVoucherType {
+ CmaParserVoucherTypeNone,
+ CmaParserVoucherTypeEther,
+ CmaParserVoucherTypeErc20,
+ CmaParserVoucherTypeErc721,
+ CmaParserVoucherTypeErc1155Single,
+ CmaParserVoucherTypeErc1155Batch,
+}
+```
+
+
+
+```cpp
+enum cma_parser_voucher_type_t {
+ CMA_PARSER_VOUCHER_TYPE_NONE,
+ CMA_PARSER_VOUCHER_TYPE_ETHER,
+ CMA_PARSER_VOUCHER_TYPE_ERC20,
+ CMA_PARSER_VOUCHER_TYPE_ERC721,
+ CMA_PARSER_VOUCHER_TYPE_ERC1155_SINGLE,
+ CMA_PARSER_VOUCHER_TYPE_ERC1155_BATCH,
+};
+```
+
+
+
+
+
+
+```rust
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum CmaVoucherFieldType {
+ EtherVoucherFields(CmaParserEtherVoucherFields),
+ Erc20VoucherFields(CmaParserErc20VoucherFields),
+ Erc721VoucherFields(CmaParserErc721VoucherFields),
+ Erc1155SingleVoucherFields(CmaParserErc1155SingleVoucherFields),
+ Erc1155BatchVoucherFields(CmaParserErc1155BatchVoucherFields),
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct CmaParserEtherVoucherFields {
+ pub amount: U256,
+ pub receiver: Address,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct CmaParserErc20VoucherFields {
+ pub token: Address,
+ pub receiver: Address,
+ pub amount: U256,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct CmaParserErc721VoucherFields {
+ pub token: Address,
+ pub token_id: U256,
+ pub receiver: Address,
+ pub application_address: Address,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct CmaParserErc1155SingleVoucherFields {
+ pub token: Address,
+ pub token_id: U256,
+ pub receiver: Address,
+ pub value: U256,
+ pub amount: U256,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct CmaParserErc1155BatchVoucherFields {
+ pub token: Address,
+ pub receiver: Address,
+ pub count: usize,
+ pub token_ids: Vec,
+ pub value: U256,
+ pub amounts: Vec,
+}
+```
+
+
+
+```cpp
+typedef struct cma_parser_voucher_data {
+ cma_abi_address_t *receiver;
+ union {
+ struct cma_parser_ether_voucher_fields_t ether_voucher_fields;
+ struct cma_parser_erc20_voucher_fields_t erc20_voucher_fields;
+ struct cma_parser_erc721_voucher_fields_t erc721_voucher_fields;
+ struct cma_parser_erc1155_single_voucher_fields_t erc1155_single_voucher_fields;
+ struct cma_parser_erc1155_batch_voucher_fields_t erc1155_batch_voucher_fields;
+ } u;
+} cma_parser_voucher_data_t;
+
+struct cma_parser_ether_voucher_fields_t {
+ cma_amount_t amount;
+};
+struct cma_parser_erc20_voucher_fields_t {
+ cma_token_address_t token;
+ cma_amount_t amount;
+};
+struct cma_parser_erc721_voucher_fields_t {
+ cma_token_address_t token;
+ cma_token_id_t token_id;
+ cma_abi_bytes_t exec_layer_data;
+};
+struct cma_parser_erc1155_single_voucher_fields_t {
+ cma_token_address_t token;
+ cma_token_id_t token_id;
+ cma_amount_t amount;
+};
+struct cma_parser_erc1155_batch_voucher_fields_t {
+ cma_token_address_t token;
+ size_t count;
+ cma_token_id_t *token_ids;
+ cma_amount_t *amounts;
+};
+```
+
+
+
+```rust
+fn cma_encode_voucher( req_type: CmaParserVoucherType, voucher_request: CmaVoucherFieldType) -> Result
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct CmaVoucher {
+ pub destination: String,
+ pub payload: String,
+}
+```
+
+
+
+```cpp
+cma_parser_error_t cma_encode_voucher(cma_parser_voucher_type_t type, cma_abi_address_t *app_address, const cma_parser_voucher_data_t *voucher_request, cma_voucher_t *voucher);
+
+typedef struct cma_voucher {
+ cmt_abi_address_t address;
+ cmt_abi_bytes_t data;
+} cma_voucher_t;
+```
+
+
+
+```bash
+cargo add cma-rust-parser
+```
+
+
+
+```rust
+use cma_rust_parser::{
+ CmaParserInputType, cma_decode_advance, cma_encode_voucher, CmaParserVoucherType, CmaVoucherFieldType, CmaParserEtherVoucherFields, CmaParserInputData, CmaParserErc721VoucherFields
+};
+use cma_rust_parser::helpers::{ToAddress, ToJson};
+
+pub struct Storage {
+ pub erc721_portal_address: String,
+ pub dapp_address_relay: String,
+ pub erc721_token: String,
+ pub app_address: String,
+}
+
+pub async fn handle_advance( _client: &hyper::Client, _server_addr: &str, request: JsonValue, storage: &mut Storage
+) -> Result<&'static str, Box> {
+ let zero_address = "0x0000000000000000000000000000000000000000".to_string();
+ let msg_sender = request["data"]["metadata"]["msg_sender"].as_str().ok_or("Invalid msg_sender address")?;
+ let mut decoded_req = Err(CmaParserError::Unknown);
+
+ match msg_sender {
+ s if s.to_lowercase() == storage.erc721_portal_address.to_lowercase() => {
+ let req_type = CmaParserInputType::CmaParserInputTypeErc721Deposit;
+ // CALL THE PARSER LIBRARY TO DECODE THE ERC721 TOKEN DEPOSIT
+ decoded_req = cma_decode_advance(req_type, request.clone());
+ },
+ s if s.to_lowercase() == storage.dapp_address_relay.to_lowercase() => {
+ if storage.app_address == zero_address {
+ let _payload = request["data"]["payload"].as_str().ok_or("Missing payload")?;
+ storage.app_address = _payload.to_string();
+ }
+ },
+ _ => { // IF THE MSG_SENDER IS NOT ANY OF THE PORTALS OR THE ADDRESS RELAYER, IT'S SAFE TO ASSUME IT'S A REGULAR USER INTERACTION
+ let req_type: CmaParserInputType = CmaParserInputType::CmaParserInputTypeAuto;
+ // CALL THE PARSER LIBRARY TO DECODE A USER INTERACTION (PARSER LIB MATCHES FUNCTION SELECTOR)
+ decoded_req = cma_decode_advance(req_type, request.clone());
+ }
+ }
+
+ match decoded_req { // MATCH ON THE RESPONSE FROM THE PARSER LIB SO AS TO HANDLE ERRORS OR CONSUME RESPONSE OBJECT
+ Ok(decoded) => {
+ match decoded.req_type { // MATCH ON A SUCCESFUL RESPONSE TO IDENTIFY WHICH OBJECT WAS RETURNED (ERC721)
+ CmaParserInputType::CmaParserInputTypeErc721Deposit => {
+ if let CmaParserInputData::Erc721Deposit(data) = input {
+ // BUILD A STRUCT WHICH CONTAINS ALL NECESSARY DATA TO BUILD A VOUCHER
+ let voucher_request = CmaParserErc721VoucherFields{
+ token: format!("{:?}", data.token).to_address().unwrap(),
+ token_id: data.token_id.into(),
+ receiver: format!("{:?}", data.sender).to_address().unwrap(),
+ application_address: storage.app_address.to_address().unwrap()
+ };
+ // CALL THE PARSER LIB TO BUILD AN ERC721 VOUCHER
+ if let Ok(voucher) = cma_encode_voucher(CmaParserVoucherType::CmaParserVoucherTypeErc721, CmaVoucherFieldType::Erc721VoucherFields(voucher_request)) {
+ emit_voucher(voucher.to_json()).await;
+ }
+ }
+ },
+ CmaParserInputType::CmaParserInputTypeUnidentified => {
+ // HANDLE THE RESULT STRUCT FOR USER DEFINED INPUTS
+ }
+ _ => {
+ // HANDLE ANY OTHER POSSIBLE RESPONSE STRUCTURE THE APPLICAITON EXPECTS
+ }
+ }
+ },
+ Err(e) => {
+ emit_report(format!("Could'nt decoding advance request: {:?}", e)).await;
+ }
+ }
+ Ok("accept")
+}
+```
+
+