diff --git a/src/contracts-wrappers/token.ts b/src/contracts-wrappers/token.ts index c288cec7..b37c9fdc 100644 --- a/src/contracts-wrappers/token.ts +++ b/src/contracts-wrappers/token.ts @@ -1,8 +1,33 @@ -import { Args, U256 } from '../basicElements' +import { Args, bytesToStr, U256, U8 } from '../basicElements' import { Operation } from '../operation' -import { ReadSCOptions, SmartContract } from '../smartContracts' +import { CallSCOptions, ReadSCOptions, SmartContract } from '../smartContracts' export class MRC20 extends SmartContract { + async version(options?: ReadSCOptions): Promise { + const res = await this.read('version', undefined, options) + return bytesToStr(res.value) + } + + async name(options?: ReadSCOptions): Promise { + const res = await this.read('name', undefined, options) + return bytesToStr(res.value) + } + + async symbol(options?: ReadSCOptions): Promise { + const res = await this.read('symbol', undefined, options) + return bytesToStr(res.value) + } + + async decimals(options?: ReadSCOptions): Promise { + const res = await this.read('decimals', undefined, options) + return Number(U8.fromBytes(res.value)) + } + + async totalSupply(options?: ReadSCOptions): Promise { + const res = await this.read('totalSupply', undefined, options) + return U256.fromBytes(res.value) + } + async balanceOf(address: string, options?: ReadSCOptions): Promise { const res = await this.read( 'balanceOf', @@ -15,7 +40,7 @@ export class MRC20 extends SmartContract { async transfer( to: string, amount: bigint, - options?: ReadSCOptions + options?: CallSCOptions ): Promise { return this.call( 'transfer', @@ -23,5 +48,57 @@ export class MRC20 extends SmartContract { options ) } - // TODO: Implement the rest of the functions + + async allowance( + ownerAddress: string, + spenderAddress: string, + options?: ReadSCOptions + ): Promise { + const res = await this.read( + 'allowance', + new Args().addString(ownerAddress).addString(spenderAddress), + options + ) + return U256.fromBytes(res.value) + } + + async increaseAllowance( + spenderAddress: string, + amount: bigint, + options?: CallSCOptions + ): Promise { + return this.call( + 'increaseAllowance', + new Args().addString(spenderAddress).addU256(amount), + options + ) + } + + async decreaseAllowance( + spenderAddress: string, + amount: bigint, + options?: CallSCOptions + ): Promise { + return this.call( + 'decreaseAllowance', + new Args().addString(spenderAddress).addU256(amount), + options + ) + } + + async transferFrom( + spenderAddress: string, + recipientAddress: string, + amount: bigint, + options?: CallSCOptions + ): Promise { + return this.call( + 'transferFrom', + new Args() + .addString(spenderAddress) + .addString(recipientAddress) + .addU256(amount), + options + ) + } } diff --git a/test/integration/MRC20.spec.ts b/test/integration/MRC20.spec.ts index 1dedd0b6..f2e9b804 100644 --- a/test/integration/MRC20.spec.ts +++ b/test/integration/MRC20.spec.ts @@ -10,6 +10,31 @@ describe('Token wrapper tests', () => { usdcContract = new MRC20(provider, USDC) }) + test('version', async () => { + const version = await usdcContract.version() + expect(version).toBe('0.0.1') + }) + + test('name', async () => { + const name = await usdcContract.name() + expect(name).toBe('Sepolia USDC') + }) + + test('symbol', async () => { + const symbol = await usdcContract.symbol() + expect(symbol).toBe('USDC.s') + }) + + test('decimals', async () => { + const decimals = await usdcContract.decimals() + expect(decimals).toBe(6) + }) + + test('totalSupply', async () => { + const totalSupply = await usdcContract.totalSupply() + expect(totalSupply).toBeGreaterThan(0n) + }) + test('transfer', async () => { const amount = 1_000n const balance = await usdcContract.balanceOf(provider.address) @@ -23,4 +48,37 @@ describe('Token wrapper tests', () => { const newBalance = await usdcContract.balanceOf(provider.address) expect(newBalance).toBe(balance - amount) }) + + test('allowance', async () => { + const previousAllowance = await usdcContract.allowance( + provider.address, + 'AU1wN8rn4SkwYSTDF3dHFY4U28KtsqKL1NnEjDZhHnHEy6cEQm53' + ) + + const amount = 123_000_000n + let operation = await usdcContract.increaseAllowance( + 'AU1wN8rn4SkwYSTDF3dHFY4U28KtsqKL1NnEjDZhHnHEy6cEQm53', + amount + ) + await operation.waitSpeculativeExecution() + + let newAllowance = await usdcContract.allowance( + provider.address, + 'AU1wN8rn4SkwYSTDF3dHFY4U28KtsqKL1NnEjDZhHnHEy6cEQm53' + ) + + expect(newAllowance).toBe(previousAllowance + amount) + + operation = await usdcContract.decreaseAllowance( + 'AU1wN8rn4SkwYSTDF3dHFY4U28KtsqKL1NnEjDZhHnHEy6cEQm53', + amount + ) + await operation.waitSpeculativeExecution() + + newAllowance = await usdcContract.allowance( + provider.address, + 'AU1wN8rn4SkwYSTDF3dHFY4U28KtsqKL1NnEjDZhHnHEy6cEQm53' + ) + expect(newAllowance).toBe(previousAllowance) + }) })