diff --git a/src/contracts-wrappers/token.ts b/src/contracts-wrappers/token.ts index db900a19..636a8a4d 100644 --- a/src/contracts-wrappers/token.ts +++ b/src/contracts-wrappers/token.ts @@ -85,6 +85,27 @@ export class MRC20 extends SmartContract { return U256.fromBytes(res.value) } + async balancesOf( + addresses: string[], + final = true + ): Promise< + { + address: string + balance: bigint + }[] + > { + const res = await this.provider.readStorage( + this.address, + addresses.map((a) => `BALANCE${a}`), + final + ) + + return res.map((v, i) => ({ + address: addresses[i], + balance: v.length ? U256.fromBytes(v) : 0n, + })) + } + async transfer( to: string, amount: bigint, diff --git a/test/integration/MRC20.spec.ts b/test/integration/MRC20.spec.ts index 8ce2e238..8c42ca33 100644 --- a/test/integration/MRC20.spec.ts +++ b/test/integration/MRC20.spec.ts @@ -1,3 +1,4 @@ +import { Account } from '../../src' import { MRC20 } from '../../src/contracts-wrappers' import { provider } from './setup' @@ -80,4 +81,35 @@ describe('Generic token wrapper tests', () => { ) expect(newAllowance).toBe(previousAllowance) }) + + test('balancesOf', async () => { + const amounts = [1_000n, 2_000n] + const recipientAddresses = [ + await (await Account.generate()).address.toString(), + await (await Account.generate()).address.toString(), + ] + + const b = await usdcContract.balancesOf(recipientAddresses) + for (const { address, balance } of b) { + expect(balance).toBe(0n) + } + + await usdcContract.transfer(recipientAddresses[0], amounts[0]) + + const operation2 = await usdcContract.transfer( + recipientAddresses[1], + amounts[1] + ) + await operation2.waitSpeculativeExecution() + + const recipientBalance = await usdcContract.balancesOf( + recipientAddresses, + false + ) + + expect(recipientBalance[0].balance).toBe(amounts[0]) + expect(recipientBalance[0].address).toBe(recipientAddresses[0]) + expect(recipientBalance[1].balance).toBe(amounts[1]) + expect(recipientBalance[1].address).toBe(recipientAddresses[1]) + }) })