So I usually get the ledger balance for a user using the backend but I want to use the frontend libraries available for me since they have a lot more features.
When getting a user’s account balance in motoko, I’d do this:
public func getAccountBalance(principalId : Principal) : async Nat {
let balance = await ledger.icrc1_balance_of({owner = principalId; subaccount = null});
return balance;
};
Giving me their account balance. I get an error when I try to replicate this on the frontend using the IcrcLedgerCanister type from the @dfinity/ledger-icrc library:
Specifically:
Canister called ic0.trap
with message: failed to decode call arguments: Custom(Fail to decode argument 0 from table2 to record { owner : principal; subaccount : opt blob }\n\nCaused by:\n Deserialize error: invalid length 0, expected an array of length 32)
Now again on the backend I have a function that pads the 29 byte array to make it 32 bytes, just wondering if there is an example anywhere of how to do this on the frontend?
Not exactly sure what you are looking for nor if its relates but, you can maybe have a look to the neuronSubaccount or AccountIdentifier implementation.
You can read my implement here
or use this lib the same source above but as a package
Someone deposited FPL to their OpenFPL principal ID, which is fine, it’s where the winnings will go too.
I want to show the balance, usually I do this by getting from the backend and sending a DTO to the frontend. But I’d like to try just getting the balance directly in the frontend to save the round trip.
Your original question is about left padding, so I answered your original question.
If it’s another question, please share a code snippet and some details about the values, not sure what’s your issue.
My original question and the second comment are both about getting the FPL balance using some kind of frontend library. It’s fine I’ll just use the backend.
Ok, as you wish. Feel free to provide a snippet in which you get the issue and some data. Happy to have a look.
async function getFPLBalance(): Promise<bigint> {
let identity: OptionIdentity;
authStore.subscribe(async (auth) => {
identity = auth.identity;
});
if (!identity) {
return 0n;
}
let principalId = identity.getPrincipal();
console.log(principalId);
const agent = await createAgent({
identity: identity,
host: import.meta.env.VITE_AUTH_PROVIDER_URL,
fetchRootKey: process.env.DFX_NETWORK === "local",
});
console.log(principalId);
const { balance } = IcrcLedgerCanister.create({
agent,
canisterId:
process.env.DFX_NETWORK === "ic"
? Principal.fromText("ddsp7-7iaaa-aaaaq-aacqq-cai")
: Principal.fromText("avqkn-guaaa-aaaaa-qaaea-cai"),
});
if (principalId) {
try {
let result = await balance({
owner: principalId,
subaccount: [],
certified: false,
});
console.log(result)
return result;
} catch (err: any) {
console.error(err);
}
}
return 0n;
} ``` this was what was giving me the error
Thanks for the snippet.
Not sure exactly if your extracted few parts or if it’s one to one your implementation. If the latest, their might be a race condition regarding the identity
, therefore, I would add a console.log(principalId.toText()
just before the call to balance
and do a manual test to observe if indeed the owner
is correctly set.
As a second try, I would try to not provide the subaccount
if it is not used.
console.log('Is there a race condition?', principalId.toText());
let result = await balance({
owner: principalId,
certified: false,
});
2 Likes
Hi David,
You were spot on, the way to get it working was to remove the subaccount: and just have the owner propery in the params.
Thanks for the help.
James
1 Like