Last active
April 8, 2024 10:14
-
-
Save ninegua/5fe22eea4f238866c0052692b9b28095 to your computer and use it in GitHub Desktop.
Tokens and Multi-chain programming - ICP HK Hacker House
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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