From 97717c4b2288c748fbef85423c3eb4642b7fa4c4 Mon Sep 17 00:00:00 2001 From: zielvna Date: Mon, 11 Mar 2024 12:25:21 +0100 Subject: [PATCH 1/2] refactor erc20 class and add erc20 tests to sdk --- sdk/jest.config.js | 3 +- sdk/src/erc20.ts | 56 +++++++++++++++++++++++------------- sdk/tests/erc20.test.ts | 63 ++++++++++++++++++++++++++++++++++------- 3 files changed, 90 insertions(+), 32 deletions(-) diff --git a/sdk/jest.config.js b/sdk/jest.config.js index b413e10..b058367 100644 --- a/sdk/jest.config.js +++ b/sdk/jest.config.js @@ -2,4 +2,5 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'node', -}; \ No newline at end of file + testTimeout: 20000 +} diff --git a/sdk/src/erc20.ts b/sdk/src/erc20.ts index 5f39042..1829551 100644 --- a/sdk/src/erc20.ts +++ b/sdk/src/erc20.ts @@ -22,15 +22,18 @@ export class Erc20 { service: CasperServiceByJsonRPC contract: Contracts.Contract paymentAmount: bigint + network: Network private constructor( client: CasperClient, service: CasperServiceByJsonRPC, + network: Network, contractHash: string, paymentAmount: bigint = DEFAULT_PAYMENT_AMOUNT ) { this.client = client this.service = service + this.network = network this.contract = new Contracts.Contract(this.client) this.contract.setContractHash(contractHash) this.paymentAmount = paymentAmount @@ -41,7 +44,7 @@ export class Erc20 { service: CasperServiceByJsonRPC, network: Network, deployer: Keys.AsymmetricKey, - nameSuffix: string, + namedKeysName: string, initial_supply: bigint = 0n, name: string = '', symbol: string = '', @@ -53,7 +56,7 @@ export class Erc20 { const wasm = await getDeploymentData(CONTRACT_NAME) const args = RuntimeArgs.fromMap({ - odra_cfg_package_hash_key_name: CLValueBuilder.string(CONTRACT_NAME + nameSuffix), + odra_cfg_package_hash_key_name: CLValueBuilder.string(namedKeysName), odra_cfg_allow_key_override: CLValueBuilder.bool(true), odra_cfg_is_upgradable: CLValueBuilder.bool(true), odra_cfg_constructor: CLValueBuilder.string('init'), @@ -93,9 +96,7 @@ export class Erc20 { throw new Error('Account not found in block state') } - const contractPackageHash = Account.namedKeys.find( - (i: any) => i.name === CONTRACT_NAME + nameSuffix - )?.key + const contractPackageHash = Account.namedKeys.find((i: any) => i.name === namedKeysName)?.key if (!contractPackageHash) { throw new Error('Contract package not found in account named keys') @@ -113,11 +114,16 @@ export class Erc20 { ] } - static async load(client: CasperClient, service: CasperServiceByJsonRPC, contractHash: string) { - return new Erc20(client, service, 'hash-' + contractHash) + static async load( + client: CasperClient, + service: CasperServiceByJsonRPC, + network: Network, + contractHash: string + ) { + return new Erc20(client, service, network, 'hash-' + contractHash) } - async setContractHash(contractHash: string) { + setContractHash(contractHash: string) { this.contract.setContractHash('hash-' + contractHash) } @@ -161,13 +167,7 @@ export class Erc20 { return BigInt(response.data._hex) } - async approve( - account: Keys.AsymmetricKey, - network: Network, - spenderHash: Key, - spender: string, - amount: bigint - ) { + async approve(account: Keys.AsymmetricKey, spenderHash: Key, spender: string, amount: bigint) { const spenderBytes = new Uint8Array([spenderHash, ...decodeBase16(spender)]) const spenderKey = new CLByteArray(spenderBytes) @@ -176,7 +176,7 @@ export class Erc20 { this.service, this.paymentAmount, account, - network, + this.network, 'approve', { spender: spenderKey, @@ -187,7 +187,6 @@ export class Erc20 { async transfer( account: Keys.AsymmetricKey, - network: Network, recipientHash: Key, recipient: string, amount: bigint @@ -200,7 +199,7 @@ export class Erc20 { this.service, this.paymentAmount, account, - network, + this.network, 'transfer', { recipient: recipientKey, @@ -209,9 +208,26 @@ export class Erc20 { ) } + async mint(account: Keys.AsymmetricKey, addressHash: Key, address: string, amount: bigint) { + const addressBytes = new Uint8Array([addressHash, ...decodeBase16(address)]) + const addressKey = new CLByteArray(addressBytes) + + return await sendTx( + this.contract, + this.service, + this.paymentAmount, + account, + this.network, + 'mint', + { + address: addressKey, + amount: CLValueBuilder.u256(BigNumber.from(amount)) + } + ) + } + async transferFrom( account: Keys.AsymmetricKey, - network: Network, ownerHash: Key, owner: string, recipientHash: Key, @@ -228,7 +244,7 @@ export class Erc20 { this.service, this.paymentAmount, account, - network, + this.network, 'transfer_from', { owner: ownerKey, diff --git a/sdk/tests/erc20.test.ts b/sdk/tests/erc20.test.ts index e5806f9..7f2be09 100644 --- a/sdk/tests/erc20.test.ts +++ b/sdk/tests/erc20.test.ts @@ -1,28 +1,69 @@ -import { ALICE, LOCAL_NODE_URL } from '../src/consts' -import { Network } from '../src/enums' +import { ALICE, BOB, LOCAL_NODE_URL } from '../src/consts' +import { Key, Network } from '../src/enums' import { Erc20 } from '../src/erc20' import { initCasperClientAndService } from '../src/utils' -describe('erc20', () => { - it('should get metadata', async () => { - const { client, service } = initCasperClientAndService(LOCAL_NODE_URL) +const { client, service } = initCasperClientAndService(LOCAL_NODE_URL) +let erc20: Erc20 +const aliceAddress = ALICE.publicKey.toAccountHashStr().replace('account-hash-', '') +const bobAddress = BOB.publicKey.toAccountHashStr().replace('account-hash-', '') - const [, erc20Hash] = await Erc20.deploy( +describe('erc20', () => { + beforeEach(async () => { + const [, erc20ContractHash] = await Erc20.deploy( client, service, Network.Local, ALICE, - '0', - 1000000000000n, + 'erc20', + 1000n, 'Coin', 'COIN', - 6n, + 12n, 150000000000n ) - const erc20 = await Erc20.load(client, service, erc20Hash) + erc20 = await Erc20.load(client, service, Network.Local, erc20ContractHash) + }) + + it('should set metadata', async () => { expect(await erc20.name()).toEqual('Coin') expect(await erc20.symbol()).toEqual('COIN') - expect(await erc20.decimals()).toEqual(6n) + expect(await erc20.decimals()).toEqual(12n) + }) + + it('should mint tokens', async () => { + await erc20.mint(ALICE, Key.Account, aliceAddress, 500n) + expect(await erc20.balanceOf(Key.Account, aliceAddress)).toEqual(1500n) + }) + + it('should transfer tokens', async () => { + await erc20.transfer(ALICE, Key.Account, bobAddress, 250n) + expect(await erc20.balanceOf(Key.Account, aliceAddress)).toEqual(750n) + expect(await erc20.balanceOf(Key.Account, bobAddress)).toEqual(250n) + }) + + it('should change instance', async () => { + const [, erc20ContractHash] = await Erc20.deploy( + client, + service, + Network.Local, + ALICE, + 'erc20', + 1000n, + 'Coin', + 'COIN', + 12n, + 150000000000n + ) + + await erc20.transfer(ALICE, Key.Account, bobAddress, 250n) + erc20.setContractHash(erc20ContractHash) + expect(await erc20.balanceOf(Key.Account, aliceAddress)).toEqual(1000n) + }) + + it('should approve tokens', async () => { + await erc20.approve(ALICE, Key.Account, bobAddress, 250n) + expect(await erc20.allowance(Key.Account, aliceAddress, Key.Account, bobAddress)).toEqual(250n) }) }) From 84f3915617d13a06a44e0737e304a6106e5e4e19 Mon Sep 17 00:00:00 2001 From: zielvna Date: Mon, 11 Mar 2024 12:28:22 +0100 Subject: [PATCH 2/2] update index file --- sdk/src/index.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/sdk/src/index.ts b/sdk/src/index.ts index dcef58d..b7d93f0 100644 --- a/sdk/src/index.ts +++ b/sdk/src/index.ts @@ -65,10 +65,10 @@ const main = async () => { let token0Address = 'a6e5a67c7834df44c1923c346dfa6cef0df4be4932cbd9102779819633b885d5' let token0ContractPackage = '8a52cb3f956a94dd89635701e2225275ddf145f26394acf2414653dbb0db8699' - let token0Contract = await Erc20.load(client, service, token0Address) + let token0Contract = await Erc20.load(client, service, network, token0Address) let token1Address = 'ff1e3e482ddb5c021386acd7af168917159f434d5302463b748693c8db1c4592' let token1ContractPackage = 'a9129e520e38ba142d81cdeebf05691b0e404206820792209ae188fbdc15428d' - let token1Contract = await Erc20.load(client, service, token1Address) + let token1Contract = await Erc20.load(client, service, network, token1Address) if (isLocal) { const [token0ContractPackageHash, token0ContractHash] = await Erc20.deploy( @@ -97,8 +97,8 @@ const main = async () => { ) token0ContractPackage = token0ContractPackageHash token1ContractPackage = token1ContractPackageHash - token0Contract = await Erc20.load(client, service, token0ContractHash) - token1Contract = await Erc20.load(client, service, token1ContractHash) + token0Contract = await Erc20.load(client, service, network, token0ContractHash) + token1Contract = await Erc20.load(client, service, network, token1ContractHash) token0Address = token0Contract.contract.contractHash! token1Address = token1Contract.contract.contractHash! } @@ -120,7 +120,6 @@ const main = async () => { const approveResult1 = await token0Contract.approve( account, - network, Key.Hash, invariantContractPackage, 1000000000000000n @@ -129,7 +128,6 @@ const main = async () => { const approveResult2 = await token1Contract.approve( account, - network, Key.Hash, invariantContractPackage, 1000000000000000n