Skip to content

Commit

Permalink
Merge pull request #102 from invariant-labs/sdk-erc20-tests
Browse files Browse the repository at this point in the history
refactor erc20 class and add erc20 tests to sdk
  • Loading branch information
zielvna authored Mar 11, 2024
2 parents 81ffee8 + 84f3915 commit 11c8f2c
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 38 deletions.
3 changes: 2 additions & 1 deletion sdk/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};
testTimeout: 20000
}
56 changes: 36 additions & 20 deletions sdk/src/erc20.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 = '',
Expand All @@ -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'),
Expand Down Expand Up @@ -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')
Expand All @@ -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)
}

Expand Down Expand Up @@ -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)

Expand All @@ -176,7 +176,7 @@ export class Erc20 {
this.service,
this.paymentAmount,
account,
network,
this.network,
'approve',
{
spender: spenderKey,
Expand All @@ -187,7 +187,6 @@ export class Erc20 {

async transfer(
account: Keys.AsymmetricKey,
network: Network,
recipientHash: Key,
recipient: string,
amount: bigint
Expand All @@ -200,7 +199,7 @@ export class Erc20 {
this.service,
this.paymentAmount,
account,
network,
this.network,
'transfer',
{
recipient: recipientKey,
Expand All @@ -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,
Expand All @@ -228,7 +244,7 @@ export class Erc20 {
this.service,
this.paymentAmount,
account,
network,
this.network,
'transfer_from',
{
owner: ownerKey,
Expand Down
10 changes: 4 additions & 6 deletions sdk/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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!
}
Expand All @@ -120,7 +120,6 @@ const main = async () => {

const approveResult1 = await token0Contract.approve(
account,
network,
Key.Hash,
invariantContractPackage,
1000000000000000n
Expand All @@ -129,7 +128,6 @@ const main = async () => {

const approveResult2 = await token1Contract.approve(
account,
network,
Key.Hash,
invariantContractPackage,
1000000000000000n
Expand Down
63 changes: 52 additions & 11 deletions sdk/tests/erc20.test.ts
Original file line number Diff line number Diff line change
@@ -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)
})
})

0 comments on commit 11c8f2c

Please sign in to comment.