Step 10: Integrating with ICRC Standard
In this step, we’ll integrate our canister with the ckETH ICRC standard to show the balance and enable ETH withdrawal.
Adding Ledger Feature to b3_utils
First, add the “ledger” feature to the b3_utils
crate in your Cargo.toml
:
b3_utils = { version = "0.8.0", features = ["ledger"] }
Setting Up Ledger and Minter Constants
Add the following lines at the top of your Rust code to specify the ledger and minter canister IDs:
const LEDGER: &str = "apia6-jaaaa-aaaar-qabma-cai";
const MINTER: &str = "jzenf-aiaaa-aaaar-qaa7q-cai";
Creating the Balance Function
Understanding the Function
The balance
function uses the ICRC1
trait from b3_utils
to fetch the balance of the canister in ckETH.
Here’s the code snippet for the function:
use b3_utils::ledger::{ICRCAccount, ICRC1};
use candid::Principal;
#[ic_cdk::update]
async fn balance() -> Nat {
let account = ICRCAccount::new(ic_cdk::id(), None);
ICRC1::from(LEDGER).balance_of(account).await.unwrap()
}
Testing the ckETH Balance Function
-
Deploy to Mainnet: Run
yarn deploy hello --network=ic
to upgrade canister. -
Open Candid UI: Navigate to the Candid UI and test the
balance
function. Note that the minting process might take some time.
Creating the Transfer Function
Understanding the Function
The transfer
function allows the canister to transfer a specified amount of ckETH to another account.
The function uses the ICRC1
trait from b3_utils
to transfer the specified amount of ckETH to the recipient.
Here’s the code snippet for the function:
use b3_utils::ledger::{ICRC1TransferArgs, ICRC1TransferResult};
use std::str::FromStr;
#[ic_cdk::update]
async fn transfer(to: String, amount: Nat) -> ICRC1TransferResult {
let to = ICRCAccount::from_str(&to).unwrap();
let transfer_args = ICRC1TransferArgs {
to,
amount,
from_subaccount: None,
fee: None,
memo: None,
created_at_time: None,
};
ICRC1::from(LEDGER).transfer(transfer_args).await.unwrap()
}
Testing the Transfer Function
-
Deploy to Mainnet: Run
yarn deploy hello --network=ic
to upgrade canister. -
Open Candid UI: Navigate to the Candid UI and test the
transfer
function by passing the recipient’s ICRCAccount comptible format string and the amount of ckETH to transfer.
Approving the Minter to Spend ckETH
Understanding the Function
The approve
function uses the ICRC2
trait from b3_utils
to approve the minter to spend your ckETH. This is a one-time action if you approve a large amount.
Here’s the code snippet for the function:
use b3_utils::ledger::{ICRC2ApproveArgs, ICRC2ApproveResult, ICRC2};
#[ic_cdk::update]
async fn approve(amount: Nat) -> ICRC2ApproveResult {
let minter = Principal::from_text(&MINTER).unwrap();
let spender = ICRCAccount::new(minter, None);
let args = ICRC2ApproveArgs {
amount,
spender,
created_at_time: None,
expected_allowance: None,
expires_at: None,
fee: None,
memo: None,
from_subaccount: None,
};
ICRC2::from(LEDGER).approve(args).await.unwrap()
}
Testing the Approve Function
-
Deploy to Mainnet: Again upgrade the canister using
yarn deploy hello --network=ic
. -
Open Candid UI: Navigate to the Candid UI and test the
approve
function.