Skip to content

Instantly share code, notes, and snippets.

@ninegua
Last active April 8, 2024 10:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ninegua/5fe22eea4f238866c0052692b9b28095 to your computer and use it in GitHub Desktop.
Save ninegua/5fe22eea4f238866c0052692b9b28095 to your computer and use it in GitHub Desktop.
Tokens and Multi-chain programming - ICP HK Hacker House
# practice 1
# check cycle wallet balance
dfx wallet balance --ic
# if wallet has not been setup, ask for a coupon and redeem to create a cycle wallet on mainnet
# dfx wallet redeem-faucet-coupon $COUPON_CODE
# dfx.json
--------------------------------
"canisters": {
...
"cycle-ledger": {
"type": "pull",
"id": "um5iw-rqaaa-aaaaq-qaaba-cai"
},
"backend": {
"dependencies": [ "cycle-ledger" ],
"env": [ "CANISTER_ID_CYCLE_LEDGER" ],
...
}
...
}
--------------------------------
# Setup cycle ledger remote canister as a dependency by pulling from mainnet
dfx deps pull --ic
# Convert some cycles from cycle wallet to ICRC tokens in cycle ledger
dfx canister call cycle-ledger deposit \
"(record { to = record { owner = principal \"$(dfx identity get-principal)\" } })" \
--wallet $(dfx identity --ic get-wallet) --with-cycles 1_100_000_000 --ic
# Check my balance
dfx canister call cycle-ledger icrc1_balance_of \
"(record {owner = principal \"$(dfx identity get-principal)\" })" --ic
# practice 2
# backend.ts
```````````````````````````````````````````````
import { Canister, Principal, None, Some, ic, init, nat, update, query } from 'azle';
import { Account, ICRC } from "azle/canisters/icrc";
let icrc : typeof ICRC;
export default Canister({
init: init([], () => {
icrc = ICRC(Principal.fromText(getCycleLedgerPrincipal()));
}),
balance: update([], nat, async () => {
return await ic.call(icrc.icrc1_balance_of, { args: [ owner_account() ]})
}),
})
function owner_account() : Account {
return { owner: ic.id(), subaccount: None }
}
function getCycleLedgerPrincipal(): string {
return (
process.env.CANISTER_ID_CYCLE_LEDGER ??
ic.trap('process.env.CANISTER_ID_CYCLE_LEDGER is undefined')
);
}
```````````````````````````````````````````````
# deploy backend canister
dfx deploy --ic --with-cycles 1T
# deploy with reinstall mode
# dfx deploy backend --ic --mode reinstall -y
# transfer token to backend canister's address
dfx cycles transfer $(dfx canister id backend --ic) 0.0005T --ic
# check backend canister's token balance
dfx canister call backend balance --ic
# backend.ts, deposit using transfer_from
````
deposit: update([nat], TransferFromResult, async (amount) => {
let fee = await ic.call(icrc.icrc1_fee, { args: [] });
if (amount <= fee) { ic.trap(`Balance must be greater than required fee ${fee}`) };
let result = await ic.call(icrc.icrc2_transfer_from, {
args: [{
spender_subaccount: None,
from: { owner: ic.caller(), subaccount: None },
to: owner_account(),
amount: amount - fee,
fee: Some(fee),
created_at_time: None,
memo: None,
}]
});
return result
})
````
# approve backend canister to take my tokens
dfx canister call cycle-ledger icrc2_approve "(record {
spender = record { owner = principal \"$(dfx canister id backend --ic)\" };
amount = 1_000_000_000;
})" --ic
# call backend canister deposit
dfx canister call backend deposit '(1_000_000_000)' --ic
# check backend canister token balance again
dfx canister call backend balance --ic
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment