Issues working with the ledger canister

I’m currently working with the Ledger canister pulled from Aviate Labs’ Github (GitHub - aviate-labs/icp-canister: A canister that holds ICP). Everything has deployed just fine, but when trying to call the balance() function using Candid, I get the error:

Call was rejected:
Request ID: 510f2809dd1ce281299974c80c9fcde367c654cfc17419c8d7acd1269a5ebbf1
Reject code:
Reject text: IC0302: Canister ryjl3-tyaaa-aaaaa-aaaba-cai has no update method ‘account_balance’

The error message leads me to believe that it is unable to access the ‘account_balance’ function from the Ledger.mo module it’s calling from. Any ideas as to what I’m doing wrong? Below is a look at the code for the balance() function I’m trying to call:

And this would be the code for the actor I’m importing from the Ledger.mo module:

It seems that you try to call the account_balance function from the NNS ledger which is marked as a query function (See Canlista ). Query functions can be only called from agents not from other canisters. That would explain why you get this error that there’s "no update method account_balance".

1 Like

i used the same example and i was actually able to get it to work. I’m curious as to why its not working for you here. did you ever find a solution?

This is the error i get when trying to deploy the ledger canister locally using these parameters, but i’m not quite sure what it’s referencing. Everything is properly configured in dfx.json(“Candid” value set to “ledger.private.did”). I used the same AccountIdentifier in my “initial_values” as i did for “minting_account”. That shouldn’t be a problem right?

Getting the ledger canister running locally was a bit of a hassle for me the first time. I was eventually able to get it running locally buy conducting these steps:

delete the /package-lock.json file,
delete the /node_modules file,
delete the /dist file,
delete the /.dfx file,
delete the /src/declarations file

add the follow property to the “canisters” object in the dfx.json file:

"ledger": {
      "type": "custom",
      "wasm": "ledger.wasm",
      "candid": "ledger.public.did"
    },

change the "candid": "ledger.public.did" line of the dfx.json file so that it reads "candid": "ledger.private.did"

start local replica(if its not already started) by running the following line :

dfx start --background

Create a new identity that will work as a minting account by running the following lines(note, dfx identity new minter may error out as a result of this identity already existing. if it does, thats okay. carry onto the next commands):

dfx identity new minter
dfx identity use minter
export MINT_ACC=$(dfx ledger account-id)

Switch back to your default identity and record its ledger account identifier by running the following lines:

dfx identity use default
export LEDGER_ACC=$(dfx ledger account-id)

Deploy the ledger canister to your network by running the following line:

dfx deploy ledger --argument '(record {minting_account = "'${MINT_ACC}'"; initial_values = vec { record { "'${LEDGER_ACC}'"; record { e8s=100_000_000_000 } }; }; send_whitelist = vec {}})'

change the “candid”: “ledger.private.did” line of the dfx.json file back so that it reads “candid”: “ledger.public.did” again.

Take the ledger canister-id and set it as the value of the CANISTER_ID variable in the /ledger.mo file.

run the following commands in the Digital-Time-Capsule terminal:

npm i

then, in a new terminal:
//note: dont run dfx deploy by itself, because that’ll redeploy another ledger canister for you as well.
// run the commands exactly like so:

dfx deploy dtc

dfx deploy dtc_assets

then:

npm start

Thanks for the help man. The first error was just a small syntax error in my argument, but what I didn’t know was to change the CANISTER_ID variable in Ledger.mo to that of my ledger. Seems to be working just fine now.

2 Likes

When calling for the balance of my canister, I still get 0, even though i set my canister to have a preset balance in my “initial_values”. Here are the parameters I used:

dfx deploy ledger --argument “record { minting_account=“6da4509fa7e69430d1c1aa1d43f281dafe412f30eeeabe5c6ade86378b26135d”;
initial_values=vec {record{“ryjl3-tyaaa-aaaaa-aaaba-cai”; record{e8s = 10000000 : nat64}}};
max_message_size_bytes= null;
transaction_window= null;
archive_options= null; send_whitelist= vec {}; }”

put this command in the terminal to mint coins to your LEDGER_ACC wallet:

dfx canister call ledger transfer 'record {memo = 1234; amount = record { e8s=10_000_000_000 }; fee = record { e8s=10_000 }; from_subaccount = null; to =  '$(python3 -c 'print("vec{" + ";".join([str(b) for b in bytes.fromhex("'$LEDGER_ACC'")]) + "}")')'; created_at_time = null }'

Strange that it doesn’t pick that command up

I think you’re missing the ' at the end.

Fixed it. My last question is regarding checking the account_balance of the LEDGER_ACC using the command line. It requires the the account ID be converted to a blob. Would this just have to be executed within the canister and copy/pasted? Or is there a quicker way to go about this?

run this command to check the balance:

dfx canister call ledger account_balance '(record { account = '$(python3 -c 'print("vec{" + ";".join([str(b) for b in bytes.fromhex("'$LEDGER_ACC'")]) + "}")')' })'
2 Likes

When sending ICP to another canister using the command line, where would the account ID of the destination canister be derived from?