Skip to main content

Spend

Mystiko Spend Related APIs.

Data Structures

quote

Retrieve quote information for a spend.

use mystiko_protos::api::handler::v1::{SpendQuoteRequest, SpendQuoteResponse};
use mystiko_protos::core::handler::v1::QuoteSpendOptions;
use mystiko_protos::common::v1::BridgeType;
use mystiko_protos::core::v1::SpendType;
use mystiko_lib::spend::quote;
use mystiko_protos::api::v1::api_response;

let options = QuoteSpendOptions::builder()
.chain_id(11155111_u64)
.asset_symbol("MTT".to_string())
.bridge_type(BridgeType::Loop as i32)
.spend_type(SpendType::Withdraw as i32)
.build();
let request = SpendQuoteRequest::builder().options(options).build();
let response = quote(request);
let spendQuote = match response.result {
Some(api_response::Result::Data(data)) => match SpendQuoteResponse::try_from(data) {
Ok(spendQuote) => spendQuote,
Err(e) => return Err(anyhow!(format!("Failed to parse response: {}", e))),
},
Some(api_response::Result::ErrorMessage(error)) => {
return Err(anyhow!(format!("API error: {}", error)));
}
None => {
return Err(anyhow!("No result found in response"));
}
};

QuoteSpendOptions:

ParameterRequiredDescription
chain_idtrue
The chain ID of the asset.
asset_symboltrue
The asset symbol.
versionfalse
The version of the spend.
amountfalse
The amount of the spend.
use_relayerfalse
Whether to use a relayer.
query_timeout_msfalse
The query timeout in milliseconds.
spend_typefalse
The type of spend.
bridge_typefalse
The bridge type.

SpendQuote data structure is as follows:

PropertyTypeDescription
validbool
Whether the quote is valid.
asset_symbolString
The asset symbol.
asset_decimalsu32
The asset decimals.
current_balancef64
The current balance.
current_decimal_balanceString
The current decimal balance.
num_of_inputsu64
The number of inputs.
num_of_outputsu64
The number of outputs.
min_rollup_feef64
The minimum rollup fee.
min_rollup_fee_decimalString
The minimum rollup fee decimal.
rollup_fee_asset_symbolString
The rollup fee asset symbol.
rollup_fee_asset_decimalsu32
The rollup fee asset decimals.
fixed_amountsVec<f64>
The fixed amounts.
fixed_decimal_amountsVec<String>
The fixed decimal amounts.
selected_commitmentsVec<String>
The selected commitments.
gas_relayersVec<GasRelayer>
The gas relayers.
max_gas_relayer_feeOption<f64>
The maximum gas relayer fee.
max_gas_relayer_fee_decimalOption<String>
The maximum gas relayer fee decimal.
gas_relayer_fee_asset_symbolOption<String>
The gas relayer fee asset symbol.
gas_relayer_fee_asset_decimalsOption<u32>
The gas relayer fee asset decimals.
invalid_codeOption<SpendInvalidCode>
The invalid code.
amount_rangeOption<AmountRange>
The amount range.

summary

Retrieve summary information for a spend.

use mystiko_protos::api::handler::v1::{SpendSummaryRequest, SpendSummaryResponse};
use mystiko_protos::core::handler::v1::CreateSpendOptions;
use mystiko_protos::common::v1::BridgeType;
use mystiko_protos::core::v1::SpendType;
use mystiko_lib::spend::summary;
use mystiko_protos::api::v1::api_response;

let options = CreateSpendOptions::builder()
.chain_id(11155111_u64)
.asset_symbol("MTT".to_string())
.bridge_type(BridgeType::Loop as i32)
.spend_type(SpendType::Withdraw as i32)
.amount(12)
.recipient("0xFE500c274F72f1d1a9978c903d97E6d45CD9121B".to_string())
.wallet_password("password".to_string())
.build();
let request = SpendSummaryRequest::builder().options(options).build();
let response = summary(request);
let spendSummary = match response.result {
Some(api_response::Result::Data(data)) => match SpendSummaryResponse::try_from(data) {
Ok(spendSummary) => spendSummary,
Err(e) => return Err(anyhow!(format!("Failed to parse response: {}", e))),
},
Some(api_response::Result::ErrorMessage(error)) => {
return Err(anyhow!(format!("API error: {}", error)));
}
None => {
return Err(anyhow!("No result found in response"));
}
};

CreateSpendOptions:

ParameterRequiredDescription
chain_idtrue
The chain ID of the asset.
asset_symboltrue
The asset symbol.
amounttrue
The amount of the spend.
recipienttrue
The recipient address.
wallet_passwordtrue
The wallet password.
versionfalse
The version of the spend.
rollup_fee_amountfalse
The rollup fee amount.
gas_relayerfalse
The gas relayer.
query_timeout_msfalse
The query timeout in milliseconds.
spend_quotefalse
The spend quote.
spend_typefalse
The type of spend.
bridge_typefalse
The bridge type.

SpendSummary data structure is as follows:

PropertyTypeDescription
asset_symbolString
The asset symbol.
asset_decimalsu32
The asset decimals.
current_balancef64
The current balance.
current_Decimal_BalanceString
The current decimal balance.
new_Balancef64
The new balance.
new_Decimal_BalanceString
The new decimal balance.
amountf64
The amount.
decimal_AmountString
The decimal amount.
recipientString
The recipient address.
rollup_Fee_Amountf64
The rollup fee amount.
rollup_Fee_Decimal_AmountString
The rollup fee decimal amount.
rollup_Fee_Total_Amountf64
The rollup fee total amount.
rollup_Fee_Total_Decimal_AmountString
The rollup fee total decimal amount.
rollup_Fee_Asset_SymbolString
The rollup fee asset symbol.
rollup_Fee_Asset_Decimalsu32
The rollup fee asset decimals.
gas_Relayer_Fee_AmountOption<f64>
The gas relayer fee amount.
gas_Relayer_Fee_Decimal_AmountOption<String>
The gas relayer fee decimal amount.
gas_Relayer_Fee_Asset_SymbolOption<String>
The gas relayer fee asset symbol.
gas_Relayer_Fee_Asset_DecimalsOption<u32>
The gas relayer fee asset decimals.
gas_Relayer_AddressOption<String>
The gas relayer address.
gas_Relayer_NameOption<String>
The gas relayer name.
gas_Relayer_UrlOption<String>
The gas relayer URL.

create

Create a Spend request.

use mystiko_protos::api::handler::v1::{CreateSpendRequest, CreateSpendResponse};
use mystiko_protos::core::handler::v1::CreateSpendOptions;
use mystiko_protos::common::v1::BridgeType;
use mystiko_protos::core::v1::SpendType;
use mystiko_lib::spend::create;
use mystiko_protos::api::v1::api_response;

let options = CreateSpendOptions::builder()
.chain_id(11155111_u64)
.asset_symbol("MTT".to_string())
.bridge_type(BridgeType::Loop as i32)
.spend_type(SpendType::Withdraw as i32)
.amount(12)
.rollup_fee_amount(4.0)
.recipient("0xFE500c274F72f1d1a9978c903d97E6d45CD9121B".to_string())
.wallet_password("password".to_string())
.build();
let request = CreateSpendRequest::builder().options(options).build();
let response = create(request);
let spend = match response.result {
Some(api_response::Result::Data(data)) => match CreateSpendResponse::try_from(data) {
Ok(spend) => spend,
Err(e) => return Err(anyhow!(format!("Failed to parse response: {}", e))),
},
Some(api_response::Result::ErrorMessage(error)) => {
return Err(anyhow!(format!("API error: {}", error)));
}
None => {
return Err(anyhow!("No result found in response"));
}
};

Spend data structure is as follows:

PropertyTypeDescription
idString
The ID of the spend.
created_atu64
The creation time of the spend.
updated_atu64
The update time of the spend.
chain_idu64
The chain ID of the asset.
contract_addressString
The contract address.
asset_symbolString
The asset symbol.
asset_decimalsu32
The asset decimals.
amountf64
The amount.
decimal_amountString
The decimal amount.
recipientString
The recipient address.
wallet_idString
The wallet ID.
input_commitmentsVec<String>
The input commitments.
output_commitmentsVec<String>
The output commitments.
nullifiersVec<String>
The nullifiers.
signature_public_key_hashesVec<String>
The signature public key hashes.
encrypted_auditor_notesVec<String>
The encrypted auditor notes.
rollup_fee_amountOption<f64>
The rollup fee amount.
rollup_fee_decimal_amountOption<String>
The rollup fee decimal amount.
rollup_fee_total_amountOption<f64>
The rollup fee total amount.
rollup_fee_total_decimal_amountOption<String>
The rollup fee total decimal amount.
gas_relayer_fee_amountOption<f64>
The gas relayer fee amount.
gas_relayer_fee_decimal_amountOption<String>
The gas relayer fee decimal amount.
signature_public_keyOption<String>
The signature public key.
asset_addressOption<String>
The asset address.
proofOption<String>
The proof.
root_hashOption<String>
The root hash.
gas_relayer_addressOption<String>
The gas relayer address.
gas_relayer_urlOption<String>
The gas relayer URL.
signatureOption<String>
The signature.
random_auditing_public_keyOption<String>
The random auditing public key.
error_messageOption<String>
The error message.
transaction_hashOption<String>
The transaction hash.
bridge_typeBridgeType
The bridge type.
spend_typeSpendType
The spend type.
statusSpendStatus
The spend status.

send

Send a spend transaction using a private key.

use mystiko_protos::api::handler::v1::{SendSpendRequest, SendSpendResponse};
use mystiko_protos::core::handler::v1::SendSpendOptions;
use mystiko_protos::common::v1::BridgeType;
use mystiko_protos::core::v1::SpendType;
use mystiko_lib::spend::send;
use mystiko_protos::api::v1::api_response;

let send_options = SendSpendOptions::builder()
.spend_id("spend id".to_string())
.wallet_password("P@ssw0rd".to_string())
.private_key("signer private key".to_string())
.query_timeout_ms(100_u64)
.spend_confirmations(10_u64)
.tx_send_timeout_ms(200_u64)
.tx_wait_interval_ms(10_u64)
.tx_wait_timeout_ms(300_u64)
.build();
let request = SendSpendRequest::builder().options(send_options).build();
let response = send(request);
let spend = match response.result {
Some(api_response::Result::Data(data)) => match SendSpendResponse::try_from(data) {
Ok(spend) => spend,
Err(e) => return Err(anyhow!(format!("Failed to parse response: {}", e))),
},
Some(api_response::Result::ErrorMessage(error)) => {
return Err(anyhow!(format!("API error: {}", error)));
}
None => {
return Err(anyhow!("No result found in response"));
}
};

SendSpendOptions:

ParameterRequiredDescription
spend_idtrue
The ID of the spend.
wallet_passwordtrue
The wallet password.
private_keyfalse
The private key.
signer_providerfalse
The signer provider.
query_timeout_msfalse
The query timeout in milliseconds.
spend_confirmationsfalse
The spend confirmations.
tx_send_timeout_msfalse
The transaction send timeout in milliseconds.
tx_wait_timeout_msfalse
The transaction wait timeout in milliseconds.
tx_wait_interval_msfalse
The transaction wait interval in milliseconds.
relayer_wait_timeout_msfalse
The relayer wait timeout in milliseconds.
relayer_wait_interval_msfalse
The relayer wait interval in milliseconds.
txfalse
The transaction.
raw_merkle_treefalse
The raw Merkle tree.
raw_zk_programfalse
The raw ZK program.
raw_zk_proving_keyfalse
The raw ZK proving key.
raw_zk_verifying_keyfalse
The raw ZK verifying key.
raw_zk_abifalse
The raw ZK ABI.

send_with_grpc

Send a spend transaction by signing through the given gRPC interface.

use mystiko_protos::api::handler::v1::{SendSpendWithGrpcRequest, SendSpendResponse};
use mystiko_protos::core::handler::v1::SendSpendOptions;
use mystiko_protos::service::v1::ClientOptions;
use mystiko_protos::common::v1::BridgeType;
use mystiko_protos::core::v1::SpendType;
use mystiko_lib::spend::send_with_grpc;
use mystiko_protos::api::v1::api_response;

let send_options = SendSpendOptions::builder()
.spend_id("spend id".to_string())
.wallet_password("P@ssw0rd".to_string())
.query_timeout_ms(100_u64)
.spend_confirmations(10_u64)
.tx_send_timeout_ms(200_u64)
.tx_wait_interval_ms(10_u64)
.tx_wait_timeout_ms(300_u64)
.build();
let client_options = ClientOptions::builder().build();
let request = SendSpendWithGrpcRequest::builder().send_options(send_options).client_options(client_options).build();
let response = send_with_grpc(request);
let spend = match response.result {
Some(api_response::Result::Data(data)) => match SendSpendResponse::try_from(data) {
Ok(spend) => spend,
Err(e) => return Err(anyhow!(format!("Failed to parse response: {}", e))),
},
Some(api_response::Result::ErrorMessage(error)) => {
return Err(anyhow!(format!("API error: {}", error)));
}
None => {
return Err(anyhow!("No result found in response"));
}
};

ClientOptions:

ParameterRequiredDescription
hosttrue
Host.
porttrue
Port.
is_sslfalse
Is SSL.
ssl_certfalse
SSL cert.
ssl_cert_pathfalse
SSL cert path.
ssl_server_namefalse
SSL server name.

find

Query Spend data using Filter.

use mystiko_protos::storage::v1::{QueryFilter, SubFilter};
use mystiko_protos::api::handler::v1::{FindSpendRequest, FindSpendResponse};
use mystiko_lib::spend::find;
use mystiko_protos::api::v1::api_response;

let filter = QueryFilter::from(SubFilter::equal(DocumentColumn::Id, "spend id".to_string()))
let request = FindSpendRequest::builder().filter(filter).build();
let response = find(request);
let spends = match response.result {
Some(api_response::Result::Data(data)) => match FindSpendResponse::try_from(data) {
Ok(spends) => spends,
Err(e) => return Err(anyhow!(format!("Failed to parse response: {}", e))),
},
Some(api_response::Result::ErrorMessage(error)) => {
return Err(anyhow!(format!("API error: {}", error)));
}
None => {
return Err(anyhow!("No result found in response"));
}
};

find_all

Query all Spend data.

use mystiko_protos::api::handler::v1::FindSpendResponse;
use mystiko_lib::spend::find_all;
use mystiko_protos::api::v1::api_response;

let response = find_all();
let spends = match response.result {
Some(api_response::Result::Data(data)) => match FindSpendResponse::try_from(data) {
Ok(spends) => spends,
Err(e) => return Err(anyhow!(format!("Failed to parse response: {}", e))),
},
Some(api_response::Result::ErrorMessage(error)) => {
return Err(anyhow!(format!("API error: {}", error)));
}
None => {
return Err(anyhow!("No result found in response"));
}
};

find_one

Find a single Spend record using Filter.

use mystiko_protos::storage::v1::{QueryFilter, SubFilter};
use mystiko_protos::api::handler::v1::{FindSpendRequest, FindOneSpendResponse};
use mystiko_lib::spend::find_one;
use mystiko_protos::api::v1::api_response;

let filter = QueryFilter::from(SubFilter::equal(DocumentColumn::Id, "spend id".to_string()))
let request = FindSpendRequest::builder().filter(filter).build();
let response = find_one(request);
let spend = match response.result {
Some(api_response::Result::Data(data)) => match FindOneSpendResponse::try_from(data) {
Ok(spend) => spend,
Err(e) => return Err(anyhow!(format!("Failed to parse response: {}", e))),
},
Some(api_response::Result::ErrorMessage(error)) => {
return Err(anyhow!(format!("API error: {}", error)));
}
None => {
return Err(anyhow!("No result found in response"));
}
};

find_by_id

Find a single Spend record by its ID.

use mystiko_protos::api::handler::v1::FindOneSpendResponse;
use mystiko_lib::spend::find_by_id;
use mystiko_protos::api::v1::api_response;

let response = find_by_id("spend id".to_string());
let spend = match response.result {
Some(api_response::Result::Data(data)) => match FindOneSpendResponse::try_from(data) {
Ok(spend) => spend,
Err(e) => return Err(anyhow!(format!("Failed to parse response: {}", e))),
},
Some(api_response::Result::ErrorMessage(error)) => {
return Err(anyhow!(format!("API error: {}", error)));
}
None => {
return Err(anyhow!("No result found in response"));
}
};

count

Query the count of data that matches the Filter criteria.

use mystiko_protos::storage::v1::{QueryFilter, SubFilter};
use mystiko_protos::api::handler::v1::CountSpendResponse;
use mystiko_lib::spend::count;
use mystiko_protos::api::v1::api_response;

let filter = QueryFilter::from(SubFilter::equal(DocumentColumn::Id, "spend id".to_string()))
let request = FindSpendRequest::builder().filter(filter).build();
let response = count(request);
let total = match response.result {
Some(api_response::Result::Data(data)) => match CountSpendResponse::try_from(data) {
Ok(total) => total,
Err(e) => return Err(anyhow!(format!("Failed to parse response: {}", e))),
},
Some(api_response::Result::ErrorMessage(error)) => {
return Err(anyhow!(format!("API error: {}", error)));
}
None => {
return Err(anyhow!("No result found in response"));
}
};

count_all

Query the total count of all Spend data.

use mystiko_protos::api::handler::v1::CountSpendResponse;
use mystiko_lib::spend::count_all;
use mystiko_protos::api::v1::api_response;

let response = count_all();
let total = match response.result {
Some(api_response::Result::Data(data)) => match CountSpendResponse::try_from(data) {
Ok(total) => total,
Err(e) => return Err(anyhow!(format!("Failed to parse response: {}", e))),
},
Some(api_response::Result::ErrorMessage(error)) => {
return Err(anyhow!(format!("API error: {}", error)));
}
None => {
return Err(anyhow!("No result found in response"));
}
};

update

Update a Spend record.

use mystiko_protos::api::handler::v1::{FindOneSpendResponse, UpdateSpendRequest, UpdateSpendResponse};
use mystiko_lib::spend::find_by_id;
use mystiko_lib::spend::update;
use mystiko_protos::api::v1::api_response;

let response = find_by_id("spend id".to_string());
let mut spend = match response.result {
Some(api_response::Result::Data(data)) => match FindOneSpendResponse::try_from(data) {
Ok(d) => d.spend.unwrap(),
Err(e) => return Err(anyhow!(format!("Failed to parse response: {}", e))),
},
Some(api_response::Result::ErrorMessage(error)) => {
return Err(anyhow!(format!("API error: {}", error)));
}
None => {
return Err(anyhow!("No result found in response"));
}
};
spend.amount = 2000;
let request = UpdateSpendRequest::builder().spend(spend).build();
let response = update(request);
let spend = match response.result {
Some(api_response::Result::Data(data)) => match UpdateSpendResponse::try_from(data) {
Ok(spend) => spend,
Err(e) => return Err(anyhow!(format!("Failed to parse response: {}", e))),
},
Some(api_response::Result::ErrorMessage(error)) => {
return Err(anyhow!(format!("API error: {}", error)));
}
None => {
return Err(anyhow!("No result found in response"));
}
};

update_batch

Batch update Spend records.

use mystiko_protos::api::handler::v1::{FindOneSpendResponse, UpdateSpendBatchRequest, UpdateSpendBatchResponse};
use mystiko_lib::spend::find_by_id;
use mystiko_lib::spend::update_batch;
use mystiko_protos::api::v1::api_response;

let response = find_by_id("spend id".to_string());
let mut spend = match response.result {
Some(api_response::Result::Data(data)) => match FindOneSpendResponse::try_from(data) {
Ok(d) => d.spend.unwrap(),
Err(e) => return Err(anyhow!(format!("Failed to parse response: {}", e))),
},
Some(api_response::Result::ErrorMessage(error)) => {
return Err(anyhow!(format!("API error: {}", error)));
}
None => {
return Err(anyhow!("No result found in response"));
}
};
spend.amount = 2000;
let request = UpdateSpendBatchRequest::builder().spends(vec![spend]).build();
let response = update_batch(request);
let spends = match response.result {
Some(api_response::Result::Data(data)) => match UpdateSpendBatchResponse::try_from(data) {
Ok(spends) => spends,
Err(e) => return Err(anyhow!(format!("Failed to parse response: {}", e))),
},
Some(api_response::Result::ErrorMessage(error)) => {
return Err(anyhow!(format!("API error: {}", error)));
}
None => {
return Err(anyhow!("No result found in response"));
}
};

update_by_filter

Update Spend records based on the conditions specified in the Filter.

use mystiko_protos::storage::v1::{QueryFilter, SubFilter, ColumnValuePair};
use mystiko_protos::storage::v1::UpdateSpendByFilterRequest;
use mystiko_lib::spend::update_by_filter;

let filter = QueryFilter::from(SubFilter::equal(DocumentColumn::Id, "spend id".to_string()));
let values = vec![ColumnValuePair::builder().column("amount").value(2000_f64).build()];
let request = UpdateSpendByFilterRequest::builder().column_values(values).filter(filter).build();
let response = update_by_filter(request);
assert!(response.code.unwrap().success);

update_all

Update all Spend records.

use mystiko_protos::storage::v1::ColumnValuePair;
use mystiko_protos::storage::v1::UpdateAllSpendRequest;
use mystiko_lib::spend::update_all;

let values = vec![ColumnValuePair::builder().column("amount").value(2000_f64).build()];
let request = UpdateAllSpendRequest::builder().column_values(values).build();
let response = update_all(request);
assert!(response.code.unwrap().success);

delete

Delete a Spend record.

use mystiko_protos::storage::v1::DeleteSpendRequest;
use mystiko_lib::spend::delete;

let request = DeleteSpendRequest::builder().spend(spend).build();
let response = delete(request);
assert!(response.code.unwrap().success);

delete_batch

Batch delete Spend records.

use mystiko_protos::storage::v1::DeleteSpendBatchRequest;
use mystiko_lib::spend::delete_batch;

let request = DeleteSpendBatchRequest::builder().deposits(vec![spend]).build();
let response = delete_batch(request);
assert!(response.code.unwrap().success);

delete_by_filter

Delete Spend records based on the conditions specified in the Filter.

use mystiko_protos::storage::v1::{QueryFilter, SubFilter};
use mystiko_protos::storage::v1::DeleteSpendByFilterRequest;
use mystiko_lib::spend::delete_by_filter;

let filter = QueryFilter::from(SubFilter::equal(DocumentColumn::Id, "spend id".to_string()));
let request = DeleteSpendByFilterRequest::builder().filter(filter).build();
let response = delete_by_filter(request);
assert!(response.code.unwrap().success);

delete_all

Delete all Spend records.

use mystiko_lib::spend::delete_all;

let response = delete_all();
assert!(response.code.unwrap().success);