| Crates.io | rust-sdk-4mica |
| lib.rs | rust-sdk-4mica |
| version | 0.4.0 |
| created_at | 2025-10-14 12:45:36.026345+00 |
| updated_at | 2026-01-14 14:24:35.685523+00 |
| description | Official Rust SDK for interacting with the 4Mica payment network. |
| homepage | https://4mica.xyz |
| repository | https://github.com/4mica-Network/4mica-core |
| max_upload_size | |
| id | 1882213 |
| size | 297,490 |
The official Rust SDK for interacting with the 4Mica payment network
4Mica is a payment network that enables cryptographically-enforced line of credit of autonomos payments. The SDK provides:
Add the SDK to your Cargo.toml:
[dependencies]
rust-sdk-4mica = "0.3.3"
The SDK requires a signing key and can use sensible defaults for the rest:
wallet_private_key (required): Private key for signing transactions (hex string with or without 0x prefix)rpc_url (optional): URL of the 4Mica RPC server. Defaults to https://api.4mica.xyz/; override for local development.The following parameters are optional and will be automatically fetched from the server if not provided.
ethereum_http_rpc_url: URL of the Ethereum JSON-RPC endpoint (optional)contract_address: Address of the deployed Core4Mica smart contract (optional)Note: You normally don't need to provide
ethereum_http_rpc_urlandcontract_addressas the SDK will fetch these from the server automatically. Only override these if you need to use different values than the server's defaults.The Ethereum
chain_idis fetched from the core service and validated against the connected Ethereum provider automatically.
use rust_sdk_4mica::{Config, ConfigBuilder, Client};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = ConfigBuilder::default()
.wallet_private_key("your_private_key".to_string())
.build()?;
let client = Client::new(config).await?;
Ok(())
}
Set the following environment variables:
export 4MICA_WALLET_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
# Optional (defaults to https://api.4mica.xyz/ if not set; override for local dev)
export 4MICA_RPC_URL="http://localhost:3000"
export 4MICA_ETHEREUM_HTTP_RPC_URL="http://localhost:8545"
export 4MICA_CONTRACT_ADDRESS="0x9fe46736679d2d9a65f0992f2272de9f3c7fa6e0"
Then in your code:
use rust_sdk_4mica::{ConfigBuilder, Client};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = ConfigBuilder::default()
.from_env() // Loads environment variables
.build()?;
let client = Client::new(config).await?;
Ok(())
}
The SDK provides client interfaces for both sides of the payment flow plus a helper to bridge HTTP 402 resources:
UserClient: payer controls collateral and signs paymentsRecipientClient: payment recipient creates tabs, verify guarantees, and claims collateralX402Flow: builds X-PAYMENT headers for X402-protected HTTP endpointsThe X402 helper turns the paymentRequirements emitted by a 402 Payment Required response into an X-PAYMENT header (and optional /settle call) that the facilitator will accept. The examples in https://github.com/4mica-Network/x402-4mica/examples model the expected flow: the client speaks to the resource server, and the resource server talks to the facilitator for /tabs, /verify, and /settle.
paymentRequirementsrust-sdk-4mica accepts the canonical X402 JSON (camelCase). At minimum you need:
scheme and network: scheme must contain 4mica (e.g. 4mica-credit)
X402Flow will refresh the tab by calling extra.tabEndpoint before signing.Typical sequence (as in https://github.com/4mica-Network/x402-4mica/examples/server/mock_paid_api.py):
paymentRequirementsTemplate.tabEndpoint with { userAddress, paymentRequirements } to mint requirements bound to your wallet.X402Flow::sign_payment to get the base64 X-PAYMENT header.X-PAYMENT; the resource server will call the facilitator /verify and /settle.use rust_sdk_4mica::{Client, ConfigBuilder, X402Flow};
use rust_sdk_4mica::x402::PaymentRequirements;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 1) Core client (only the payer key is required by default)
let payer = Client::new(
ConfigBuilder::default()
.wallet_private_key(std::env::var("PAYER_KEY")?)
.build()?,
)
.await?;
let payment_requirements: PaymentRequirements =
serde_json::from_value(tab_response["paymentRequirements"].clone())?;
// 3) Build the X-PAYMENT header with the SDK
let flow = X402Flow::new(payer)?;
let signed = flow
.sign_payment(payment_requirements.clone(), user_address.clone())
.await?;
let x_payment_header = signed.header; // send as `X-PAYMENT: {header}`
// 4) Call the protected resource with the header
let _paid = reqwest::Client::new()
.get("https://resource-url/resource")
.header("X-PAYMENT", &x_payment_header)
.send()
.await?
.error_for_status()?;
Ok(())
}
If your resource server proxies to the facilitator (the pattern used in examples/server/mock_paid_api.py), you can reuse the SDK to settle after verifying:
use rust_sdk_4mica::{Client, ConfigBuilder, X402Flow, X402SignedPayment};
use rust_sdk_4mica::x402::PaymentRequirements;
async fn settle(
facilitator_url: &str,
payment_requirements: PaymentRequirements,
payment: X402SignedPayment,
) -> Result<(), Box<dyn std::error::Error>> {
let core = Client::new(
ConfigBuilder::default()
.wallet_private_key(std::env::var("RESOURCE_SIGNER_KEY")?)
.build()?,
)
.await?;
let flow = X402Flow::new(core)?;
// POST /settle to the facilitator; returns the facilitator JSON body on success
let settled = flow
.settle_payment(payment, payment_requirements, facilitator_url)
.await?;
println!("settlement result: {}", settled.settlement);
Ok(())
}
Notes:
sign_payment always uses EIP-712 signing and will error if the scheme is not 4mica.settle_payment only hits /settle; resource servers should still call the facilitator /verify first when enforcing access (see the Python example for the end-to-end pattern).approve_erc20(token: String, amount: U256) -> Result<TransactionReceipt, ApproveErc20Error>: Approve the 4Mica contract to spend ERC20 tokens on behalf of the userdeposit(amount: U256, erc20_token: Option<String>) -> Result<TransactionReceipt, DepositError>: Deposit collateral in ETH or ERC20 tokenget_user() -> Result<Vec<UserInfo>, GetUserError>: Get current user information for all assetsget_tab_payment_status(tab_id: U256) -> Result<TabPaymentStatus, TabPaymentStatusError>: Get payment status for a tabsign_payment(claims: PaymentGuaranteeRequestClaims, scheme: SigningScheme) -> Result<PaymentSignature, SignPaymentError>: Sign a paymentpay_tab(tab_id: U256, req_id: U256, amount: U256, recipient_address: String, erc20_token: Option<String>) -> Result<TransactionReceipt, PayTabError>: Pay a tab directly on-chain in ETH or ERC20 tokenrequest_withdrawal(amount: U256, erc20_token: Option<String>) -> Result<TransactionReceipt, RequestWithdrawalError>: Request withdrawal of collateral in ETH or ERC20 tokencancel_withdrawal(erc20_token: Option<String>) -> Result<TransactionReceipt, CancelWithdrawalError>: Cancel pending withdrawalfinalize_withdrawal(erc20_token: Option<String>) -> Result<TransactionReceipt, FinalizeWithdrawalError>: Finalize withdrawal after waiting periodcreate_tab(user_address: String, recipient_address: String, erc20_token: Option<String>, ttl: Option<u64>) -> Result<U256, CreateTabError>: Create a new payment tab in ETH or ERC20 tokenget_tab_payment_status(tab_id: U256) -> Result<TabPaymentStatus, TabPaymentStatusError>: Get payment status for a tabissue_payment_guarantee(claims: PaymentGuaranteeRequestClaims, signature: String, scheme: SigningScheme) -> Result<BLSCert, IssuePaymentGuaranteeError>: Issue a payment guaranteeverify_payment_guarantee(cert: &BLSCert) -> Result<PaymentGuaranteeClaims, VerifyGuaranteeError>: Verify a BLS certificate and extract claimsremunerate(cert: BLSCert) -> Result<TransactionReceipt, RemunerateError>: Claim from user collateral using BLS certificatelist_settled_tabs() -> Result<Vec<TabInfo>, RecipientQueryError>: List all settled tabs for the recipientlist_pending_remunerations() -> Result<Vec<PendingRemunerationInfo>, RecipientQueryError>: List pending remunerations for the recipientget_tab(tab_id: U256) -> Result<Option<TabInfo>, RecipientQueryError>: Get tab information by IDlist_recipient_tabs(settlement_statuses: Option<Vec<String>>) -> Result<Vec<TabInfo>, RecipientQueryError>: List tabs for the recipient with optional status filterget_tab_guarantees(tab_id: U256) -> Result<Vec<GuaranteeInfo>, RecipientQueryError>: Get all guarantees for a tabget_latest_guarantee(tab_id: U256) -> Result<Option<GuaranteeInfo>, RecipientQueryError>: Get the latest guarantee for a tabget_guarantee(tab_id: U256, req_id: U256) -> Result<Option<GuaranteeInfo>, RecipientQueryError>: Get a specific guarantee by tab ID and request IDlist_recipient_payments() -> Result<Vec<RecipientPaymentInfo>, RecipientQueryError>: List all payments for the recipientget_collateral_events_for_tab(tab_id: U256) -> Result<Vec<CollateralEventInfo>, RecipientQueryError>: Get collateral events for a specific tabget_user_asset_balance(user_address: String, asset_address: String) -> Result<Option<AssetBalanceInfo>, RecipientQueryError>: Get user's asset balanceNote: Each method returns a specific error type that provides detailed information about what went wrong. See the Error Handling section for comprehensive documentation and examples.
The user client allows you to manage your collateral and sign payments in ETH or ERC20 tokens.
use rust_sdk_4mica::U256;
// Approve the 4Mica contract to spend 1000 USDC on your behalf
let token_address = "0x1234567890123456789012345678901234567890".to_string();
let amount = U256::from(1000_000_000u128); // 1000 USDC (6 decimals)
match client.user.approve_erc20(token_address, amount).await {
Ok(receipt) => {
println!("ERC20 approval successful: {:?}", receipt.transaction_hash);
}
Err(e) => {
eprintln!("ERC20 approval failed: {}", e);
}
}
use rust_sdk_4mica::U256;
// Deposit 1 ETH as collateral
let amount = U256::from(1_000_000_000_000_000_000u128); // 1 ETH in wei
match client.user.deposit(amount, None).await {
Ok(receipt) => {
println!("Deposit successful: {:?}", receipt.transaction_hash);
}
Err(e) => {
eprintln!("Deposit failed: {}", e);
}
}
// Or deposit 1000 USDC (make sure to approve first!)
let token_address = "0x1234567890123456789012345678901234567890".to_string();
let amount = U256::from(1000_000_000u128);
let receipt = client.user.deposit(amount, Some(token_address)).await?;
println!("USDC deposit successful: {:?}", receipt.transaction_hash);
// Get information about the current user for all assets
let user_assets = client.user.get_user().await?;
for user_info in user_assets {
println!("Asset: {}", user_info.asset);
println!("Collateral: {}", user_info.collateral);
println!("Withdrawal request amount: {}", user_info.withdrawal_request_amount);
println!("Withdrawal request timestamp: {}", user_info.withdrawal_request_timestamp);
println!("---");
}
use rust_sdk_4mica::U256;
let tab_id = U256::from(1);
let status = client.user.get_tab_payment_status(tab_id).await?;
println!("Paid: {}", status.paid);
println!("Remunerated: {}", status.remunerated);
println!("Asset: {}", status.asset);
use rust_sdk_4mica::{PaymentGuaranteeRequestClaims, SigningScheme, U256};
// Create payment claims for ETH payment
let claims = PaymentGuaranteeRequestClaims::new(
"0x70997970C51812dc3A010C7d01b50e0d17dc79C8".to_string(), // user_address
"0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC".to_string(), // recipient_address
U256::from(1), // tab_id
U256::ZERO, // req_id (first request)
U256::from(1_000_000_000_000_000_000u128), // amount (1 ETH)
1704067200, // timestamp
None, // erc20_token (None for ETH)
);
// Sign using EIP-712 (recommended)
match client.user.sign_payment(claims.clone(), SigningScheme::Eip712).await {
Ok(payment_sig) => {
println!("Signature: {}", payment_sig.signature);
println!("Scheme: {:?}", payment_sig.scheme);
}
Err(e) => {
eprintln!("Signing failed: {}", e);
}
}
// Or use EIP-191 (personal_sign)
let payment_sig = client.user.sign_payment(claims, SigningScheme::Eip191).await?;
// For ERC20 token payment, pass the token address
let usdc_token = "0x1234567890123456789012345678901234567890".to_string();
let claims_usdc = PaymentGuaranteeRequestClaims::new(
"0x70997970C51812dc3A010C7d01b50e0d17dc79C8".to_string(),
"0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC".to_string(),
U256::from(1),
U256::ZERO,
U256::from(1000_000_000u128), // 1000 USDC
1704067200,
Some(usdc_token),
);
let payment_sig_usdc = client.user.sign_payment(claims_usdc, SigningScheme::Eip712).await?;
use rust_sdk_4mica::U256;
// Pay 1 ETH to a tab
let tab_id = U256::from(1);
// Use the req_id that came back with the guarantee certificate (placeholder value shown)
let req_id = U256::from(1);
let amount = U256::from(1_000_000_000_000_000_000u128);
let recipient_address = "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC".to_string();
let receipt = client.user.pay_tab(tab_id, req_id, amount, recipient_address.clone(), None).await?;
println!("Payment successful: {:?}", receipt.transaction_hash);
// Or pay 1000 USDC to a tab (make sure to approve the 4Mica contract first!)
let token_address = "0x1234567890123456789012345678901234567890".to_string();
let amount_usdc = U256::from(1000_000_000u128);
let receipt = client.user.pay_tab(
tab_id,
req_id,
amount_usdc,
recipient_address,
Some(token_address)
).await?;
println!("USDC payment successful: {:?}", receipt.transaction_hash);
use rust_sdk_4mica::U256;
// Request to withdraw 0.5 ETH
let amount = U256::from(500_000_000_000_000_000u128);
let receipt = client.user.request_withdrawal(amount, None).await?;
println!("Withdrawal requested: {:?}", receipt.transaction_hash);
// Or request to withdraw 500 USDC
let token_address = "0x1234567890123456789012345678901234567890".to_string();
let amount_usdc = U256::from(500_000_000u128);
let receipt = client.user.request_withdrawal(amount_usdc, Some(token_address)).await?;
println!("USDC withdrawal requested: {:?}", receipt.transaction_hash);
// Cancel a pending ETH withdrawal request
let receipt = client.user.cancel_withdrawal(None).await?;
println!("Withdrawal cancelled: {:?}", receipt.transaction_hash);
// Cancel a pending USDC withdrawal request
let token_address = "0x1234567890123456789012345678901234567890".to_string();
let receipt = client.user.cancel_withdrawal(Some(token_address)).await?;
println!("USDC withdrawal cancelled: {:?}", receipt.transaction_hash);
// Finalize ETH withdrawal (after the waiting period)
let receipt = client.user.finalize_withdrawal(None).await?;
println!("Withdrawal finalized: {:?}", receipt.transaction_hash);
// Finalize USDC withdrawal (after the waiting period)
let token_address = "0x1234567890123456789012345678901234567890".to_string();
let receipt = client.user.finalize_withdrawal(Some(token_address)).await?;
println!("USDC withdrawal finalized: {:?}", receipt.transaction_hash);
The recipient client allows you to create payment tabs, issue payment guarantees, and claim from user collateral when payments aren't fulfilled.
use rust_sdk_4mica::U256;
// Create a new payment tab for ETH
let user_address = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8".to_string();
let recipient_address = "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC".to_string();
let ttl = Some(3600); // Tab expires in 1 hour (optional)
let tab_id = client.recipient.create_tab(
user_address.clone(),
recipient_address.clone(),
None, // None for ETH
ttl
).await?;
println!("Created ETH tab with ID: {}", tab_id);
// Create a new payment tab for USDC
let token_address = "0x1234567890123456789012345678901234567890".to_string();
let tab_id_usdc = client.recipient.create_tab(
user_address,
recipient_address,
Some(token_address),
ttl
).await?;
println!("Created USDC tab with ID: {}", tab_id_usdc);
use rust_sdk_4mica::U256;
let tab_id = U256::from(1);
let status = client.recipient.get_tab_payment_status(tab_id).await?;
println!("Paid: {}", status.paid);
println!("Remunerated: {}", status.remunerated);
println!("Asset: {}", status.asset);
use rust_sdk_4mica::{PaymentGuaranteeRequestClaims, SigningScheme, U256};
// First, the user signs the payment (see User Client example above)
let claims = PaymentGuaranteeRequestClaims::new(
"0x70997970C51812dc3A010C7d01b50e0d17dc79C8".to_string(),
"0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC".to_string(),
U256::from(1),
U256::ZERO,
U256::from(1_000_000_000_000_000_000u128), // 1 ETH
1704067200,
None, // None for ETH
);
let payment_sig = client.user.sign_payment(claims.clone(), SigningScheme::Eip712).await?;
let bls_cert = client.recipient.issue_payment_guarantee(
claims,
payment_sig.signature,
payment_sig.scheme,
).await?;
println!("BLS Certificate: {:?}", bls_cert);
// If the user doesn't fulfill the payment guarantee,
// the recipient can claim from the user's collateral on-chain
let receipt = client.recipient.remunerate(bls_cert).await?;
println!("Claimed from user collateral successfully!");
println!("Transaction hash: {:?}", receipt.transaction_hash);
Here's a complete example showing a payment flow with ETH:
use rust_sdk_4mica::{
Client, ConfigBuilder, PaymentGuaranteeRequestClaims, SigningScheme, U256,
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 1. Setup clients (user and recipient each have their own)
let user_config = ConfigBuilder::default()
.wallet_private_key("user_private_key".to_string())
.build()?;
let user_client = Client::new(user_config).await?;
let recipient_config = ConfigBuilder::default()
.wallet_private_key("recipient_private_key".to_string())
.build()?;
let recipient_client = Client::new(recipient_config).await?;
// 2. User deposits collateral
let deposit_amount = U256::from(2_000_000_000_000_000_000u128); // 2 ETH
let receipt = user_client.user.deposit(deposit_amount, None).await?;
println!("Deposited collateral: {:?}", receipt.transaction_hash);
// 3. Recipient creates a payment tab
let user_address = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8".to_string();
let recipient_address = "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC".to_string();
let tab_id = recipient_client
.recipient
.create_tab(user_address.clone(), recipient_address.clone(), None, Some(3600))
.await?;
println!("Created tab: {}", tab_id);
// 4. User signs a payment
let claims = PaymentGuaranteeRequestClaims::new(
user_address.clone(),
recipient_address.clone(),
tab_id,
U256::ZERO,
U256::from(1_000_000_000_000_000_000u128), // 1 ETH
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)?
.as_secs(),
None, // None for ETH
);
let payment_sig = user_client.user.sign_payment(claims.clone(), SigningScheme::Eip712).await?;
println!("Payment signed");
// 5. Recipient issues guarantee
let bls_cert = recipient_client
.recipient
.issue_payment_guarantee(claims, payment_sig.signature, payment_sig.scheme)
.await?;
println!("Guarantee issued");
// 6. If user doesn't pay, recipient can claim from user's collateral
let receipt = recipient_client.recipient.remunerate(bls_cert).await?;
println!("Claimed from user collateral!");
println!("Transaction hash: {:?}", receipt.transaction_hash);
Ok(())
}
Here's a complete example showing a payment flow with an ERC20 token:
use rust_sdk_4mica::{
Client, ConfigBuilder, PaymentGuaranteeRequestClaims, SigningScheme, U256,
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Setup
let user_config = ConfigBuilder::default()
.wallet_private_key("user_private_key".to_string())
.build()?;
let user_client = Client::new(user_config).await?;
let recipient_config = ConfigBuilder::default()
.wallet_private_key("recipient_private_key".to_string())
.build()?;
let recipient_client = Client::new(recipient_config).await?;
let usdc_token = "0x1234567890123456789012345678901234567890".to_string();
// 1. User approves the 4Mica contract to spend USDC
let approval_amount = U256::from(10000_000_000u128); // 10,000 USDC
user_client.user.approve_erc20(usdc_token.clone(), approval_amount).await?;
println!("Approved USDC spending");
// 2. User deposits USDC collateral
let deposit_amount = U256::from(5000_000_000u128); // 5,000 USDC
user_client.user.deposit(deposit_amount, Some(usdc_token.clone())).await?;
println!("Deposited USDC collateral");
// 3. Recipient creates a USDC payment tab
let user_address = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8".to_string();
let recipient_address = "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC".to_string();
let tab_id = recipient_client
.recipient
.create_tab(
user_address.clone(),
recipient_address.clone(),
Some(usdc_token.clone()),
Some(3600)
)
.await?;
println!("Created USDC tab: {}", tab_id);
// 4. User signs a USDC payment
let claims = PaymentGuaranteeRequestClaims::new(
user_address.clone(),
recipient_address.clone(),
tab_id,
U256::ZERO,
U256::from(1000_000_000u128), // 1,000 USDC
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)?
.as_secs(),
Some(usdc_token.clone()),
);
let payment_sig = user_client.user.sign_payment(claims.clone(), SigningScheme::Eip712).await?;
println!("Payment signed");
// 5. Recipient issues guarantee
let bls_cert = recipient_client
.recipient
.issue_payment_guarantee(claims, payment_sig.signature, payment_sig.scheme)
.await?;
println!("Guarantee issued");
// 6. If user doesn't pay, recipient can claim from user's USDC collateral
let receipt = recipient_client.recipient.remunerate(bls_cert).await?;
println!("Claimed USDC from user collateral!");
println!("Transaction hash: {:?}", receipt.transaction_hash);
Ok(())
}
The SDK provides comprehensive, type-safe error handling with specific error types for each operation. All errors are strongly typed and provide detailed context about what went wrong.
// Import specific error types when needed
use rust_sdk_4mica::error::{
ApproveErc20Error, DepositError, RemunerateError, RequestWithdrawalError,
SignPaymentError, FinalizeWithdrawalError, CreateTabError, PayTabError,
IssuePaymentGuaranteeError, VerifyGuaranteeError, RecipientQueryError,
// ... other error types as needed
};
ConfigError
InvalidValue(String): Invalid configuration valueMissing(String): Required configuration parameter is missingClientError
Rpc(String): RPC connection errorProvider(String): Provider initialization errorInitialization(String): Client initialization errorSignPaymentError
AddressMismatch { signer: Address, claims: String }: Signer address doesn't match user address in claimsInvalidUserAddress: User address in claims is invalidInvalidRecipientAddress: Recipient address in claims is invalidFailed(String): Failed to sign the payment (includes digest computation and signing errors)Rpc(rpc::ApiClientError): RPC communication errorApproveErc20Error
InvalidParams(String): Invalid parameters provided (e.g., invalid token address)UnknownRevert { selector: u32, data: Vec<u8> }: Unknown contract revertTransport(String): Provider or transport errorDepositError
InvalidParams(String): Invalid parameters provided (e.g., invalid token address)AmountZero: Cannot deposit zero amountUnknownRevert { selector: u32, data: Vec<u8> }: Unknown contract revertTransport(String): Provider or transport errorRequestWithdrawalError
InvalidParams(String): Invalid parameters provided (e.g., invalid token address)AmountZero: Cannot withdraw zero amountInsufficientAvailable: Not enough available balance to withdrawUnknownRevert { selector: u32, data: Vec<u8> }: Unknown contract revertTransport(String): Provider or transport errorCancelWithdrawalError
InvalidParams(String): Invalid parameters provided (e.g., invalid token address)NoWithdrawalRequested: No withdrawal request exists to cancelUnknownRevert { selector: u32, data: Vec<u8> }: Unknown contract revertTransport(String): Provider or transport errorFinalizeWithdrawalError
InvalidParams(String): Invalid parameters provided (e.g., invalid token address)NoWithdrawalRequested: No withdrawal request exists to finalizeGracePeriodNotElapsed: Grace period has not elapsed yetTransferFailed: Transfer of funds failedUnknownRevert { selector: u32, data: Vec<u8> }: Unknown contract revertTransport(String): Provider or transport errorCreateTabError
InvalidParams(String): Invalid parameters (e.g., signer address mismatch)Rpc(rpc::ApiClientError): RPC communication errorPayTabError
InvalidParams(String): Invalid parameters providedInvalidAsset: Asset does not match the tab assetUnknownRevert { selector: u32, data: Vec<u8> }: Unknown contract revertTransport(String): Provider or transport errorTabPaymentStatusError
UnknownRevert { selector: u32, data: Vec<u8> }: Unknown contract revertTransport(String): Provider or transport errorIssuePaymentGuaranteeError
InvalidParams(String): Invalid parameters (e.g., signer address mismatch)Rpc(rpc::ApiClientError): RPC communication errorVerifyGuaranteeError
InvalidCertificate(anyhow::Error): Invalid BLS certificateCertificateMismatch: Certificate signature mismatchGuaranteeDomainMismatch: Guarantee domain mismatchUnsupportedGuaranteeVersion(u64): Unsupported guarantee versionX402Error
InvalidScheme(String): paymentRequirements.scheme must include 4micaInvalidFacilitatorUrl(String): Invalid facilitator /settle base URLTabResolutionFailed(String) / InvalidExtra(String): Issues resolving or parsing paymentRequirements.extraInvalidNumber { field, source } / UserMismatch { found, expected }: Invalid numeric fields or wrong user in requirementsEncodeEnvelope(String): Failed to encode the X-PAYMENT envelopeSettlementFailed { status, body }: Facilitator /settle returned a non-success statusSigning(SignPaymentError) / Http(reqwest::Error): Errors while signing or making HTTP requestsRecipientQueryError
Rpc(rpc::ApiClientError): RPC communication errorRemunerateError
InvalidParams(String): Invalid parameters providedClaimsHex(anyhow::Error): Failed to decode the hex-encoded guarantee claims blobClaimsDecode(anyhow::Error): Failed to deserialize guarantee claims after decodingGuaranteeConversion(anyhow::Error): Failed to convert decoded claims into the contract call typeSignatureHex(FromHexError): Failed to decode the hex-encoded BLS signatureSignatureDecode(anyhow::Error): Failed to parse the decoded BLS signature bytesTabNotYetOverdue: Tab has not reached its due date yetTabExpired: Tab has expired and can no longer be remuneratedTabPreviouslyRemunerated: Tab has already been remuneratedTabAlreadyPaid: Tab has already been paid by userInvalidSignature: BLS signature verification failedDoubleSpendingDetected: Attempt to spend same guarantee twiceInvalidRecipient: Caller is not the recipient of this tabAmountZero: Guarantee amount is zeroTransferFailed: Transfer of funds failedCertificateInvalid(anyhow::Error): Certificate verification failedCertificateMismatch: Certificate signature mismatch before submissionGuaranteeDomainMismatch: Guarantee domain mismatchUnsupportedGuaranteeVersion(u64): Unsupported guarantee versionUnknownRevert { selector: u32, data: Vec<u8> }: Unknown contract revertTransport(String): Provider or transport errorGetUserError
UnknownRevert { selector: u32, data: Vec<u8> }: Unknown contract revertTransport(String): Provider or transport errorcargo test
cargo build --release
SignPaymentError::AddressMismatch if the signer doesn't match the claimsRecipientClient operations, ensure your signer address matches the recipient address. The SDK will return InvalidParams errors for mismatchesget_user() to view all your asset balancesThis project is licensed under the Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0).
Made with ❤️ by the 4Mica Network