Skip to content

Commit

Permalink
feat: mock transactions (#1242)
Browse files Browse the repository at this point in the history
Signed-off-by: drptbl <[email protected]>
Co-authored-by: drptbl <[email protected]>
  • Loading branch information
matstyler and drptbl authored Nov 17, 2024
1 parent 8b4ccff commit 4199721
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 11 deletions.
24 changes: 15 additions & 9 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions wallets/ethereum-wallet-mock/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@
},
"dependencies": {
"@depay/web3-client": "10.18.6",
"@depay/web3-mock": "14.17.0",
"@depay/web3-mock": "14.19.1",
"@depay/web3-mock-evm": "^14.17.0",
"@synthetixio/synpress-core": "0.0.4",
"viem": "2.9.9"
},
"devDependencies": {
"@depay/web3-mock": "14.17.0",
"@depay/web3-mock": "14.19.1",
"@synthetixio/synpress-tsconfig": "0.0.4",
"@types/node": "20.11.17",
"@vitest/coverage-v8": "1.2.2",
Expand Down
23 changes: 23 additions & 0 deletions wallets/ethereum-wallet-mock/src/playwright/EthereumWalletMock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { EthereumWalletMockAbstract } from '../type/EthereumWalletMockAbstract'
import type { Network } from '../type/Network'
import type { WalletMock } from '../type/WalletMock'
import { DEFAULT_NETWORK_ID } from './utils'
import { mockTransaction, sendTransaction } from './utils'

/**
* Mock implementation of an Ethereum wallet for testing purposes.
Expand Down Expand Up @@ -230,4 +231,26 @@ export default class EthereumWalletMock extends EthereumWalletMockAbstract {
[BLOCKCHAIN, [ACCOUNT_MOCK], wallet]
)
}

/**
* Sends a transaction.
* @param to - Recipient address.
* @param value - Transaction value in wei.
* @returns Promise that resolves to the transaction hash.
*/
async sendTransaction(to: string, value: string): Promise<string> {
// Mock the transaction
await mockTransaction(this.page, [
to,
ACCOUNT_MOCK, // from address
value
])

// Send the transaction
return this.page.evaluate(sendTransaction, {
to,
from: ACCOUNT_MOCK,
value
})
}
}
2 changes: 2 additions & 0 deletions wallets/ethereum-wallet-mock/src/playwright/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export { default as mockEthereum } from './mockEthereum'
export * from './mockTransaction'
export * from './sendTransaction'
export * from '../constants'
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { Page } from '@playwright/test'

/**
* Mocks an Ethereum transaction using Web3Mock
* @param page - Playwright page instance
* @param params - Array of transaction parameters [to, from, value]
* @returns Promise that resolves to the Web3Mock mock result
*/
export const mockTransaction = async (page: Page, params: [string, string, string]) => {
return page.evaluate(
([params]) => {
return Web3Mock.mock({
blockchain: 'ethereum',
transaction: {
to: params?.[0],
from: params?.[1],
value: params?.[2]
}
})
},
[params]
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
interface SendTransactionParams {
to: string
from: string
value: string
}

/**
* Sends an Ethereum transaction using Web3Mock
* @param params - Transaction parameters {to: string, from: string, value: string}
* @returns Promise that resolves to the transaction hash
*/
export const sendTransaction = (params: SendTransactionParams): Promise<string> => {
return window.ethereum.request({
method: 'eth_sendTransaction',
params: [params]
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { ACCOUNT_MOCK } from '../../../src/constants'
import test from '../../../src/playwright/synpress'

const { expect } = test

const TO_ADDRESS = '0x5Af489c8786A018EC4814194dC8048be1007e390'
const VALUE = '2000000000000000000' // 2 ETH

test('should mock and send transaction', async ({ ethereumWalletMock }) => {
// Connect wallet first
await ethereumWalletMock.connectToDapp()

// Send the transaction
const txHash = await ethereumWalletMock.sendTransaction(TO_ADDRESS, VALUE)

// Verify transaction hash format
expect(txHash).toMatch(/^0x[a-fA-F0-9]{64}$/)
})

test('should mock and send transaction with zero value', async ({ ethereumWalletMock }) => {
await ethereumWalletMock.connectToDapp()

const txHash = await ethereumWalletMock.sendTransaction(TO_ADDRESS, '0')

expect(txHash).toMatch(/^0x[a-fA-F0-9]{64}$/)
})

test('should mock and send transaction to same address', async ({ ethereumWalletMock }) => {
await ethereumWalletMock.connectToDapp()

const txHash = await ethereumWalletMock.sendTransaction(ACCOUNT_MOCK, VALUE)

expect(txHash).toMatch(/^0x[a-fA-F0-9]{64}$/)
})

test('should mock and send multiple transactions', async ({ ethereumWalletMock }) => {
await ethereumWalletMock.connectToDapp()

const transactions = [
{ to: TO_ADDRESS, value: '1000000000000000000' }, // 1 ETH
{ to: TO_ADDRESS, value: '3000000000000000000' }, // 3 ETH
{ to: TO_ADDRESS, value: '500000000000000000' } // 0.5 ETH
]

for (const tx of transactions) {
const txHash = await ethereumWalletMock.sendTransaction(tx.to, tx.value)
expect(txHash).toMatch(/^0x[a-fA-F0-9]{64}$/)
}
})

test('should fail with invalid value', async ({ ethereumWalletMock }) => {
await ethereumWalletMock.connectToDapp()

const invalidValue = 'invalid'

await expect(ethereumWalletMock.sendTransaction(TO_ADDRESS, invalidValue)).rejects.toThrow()
})

0 comments on commit 4199721

Please sign in to comment.