Skip to content

Commit 79ac07e

Browse files
authored
feat: add github test workflow (#3)
* feat: add github test workflow
1 parent a43e94f commit 79ac07e

File tree

10 files changed

+496
-12
lines changed

10 files changed

+496
-12
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name: 'CI setup'
2+
description: NPM install deps
3+
runs:
4+
using: composite
5+
steps:
6+
- uses: actions/setup-node@v4
7+
with:
8+
node-version: '18.20.2'
9+
10+
- name: Install dependencies
11+
shell: bash
12+
run: npm install

.github/workflows/test.yaml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Test Case
2+
on:
3+
pull_request:
4+
branches:
5+
- main
6+
jobs:
7+
8+
run-tests:
9+
runs-on: ubuntu-latest
10+
11+
env:
12+
ACCOUNT_ADDRESS: ${{ secrets.ACCOUNT_ADDRESS }}
13+
ACCOUNT_PRIVATEKEY: ${{ secrets.ACCOUNT_PRIVATEKEY }}
14+
OPEN_PLATFORM_PRIVATE_KEY: ${{ secrets.OPEN_PLATFORM_PRIVATE_KEY }}
15+
PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
16+
17+
steps:
18+
- uses: actions/checkout@v3
19+
with:
20+
persist-credentials: false
21+
22+
- uses: ./.github/actions/ci-setup
23+
24+
- name: Run Test
25+
run: npm run test

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# megafuel-js-sdk
22

3-
This JavaScript SDK is thin wrapper of MegaFuel clients, offering a streamlined interface to interact with the MegaFuel. For more information, please refer to the [API documentation](https://docs.nodereal.io/docs/megafuel-api).
3+
This JavaScript SDK is thin wrapper of MegaFuel clients, offering a streamlined interface to interact with the MegaFuel. For more information, please refer to the [API documentation](https://docs.nodereal.io/reference/pm-issponsorable).
44

55
## Network Endpoint
66

jest.config.js

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
1+
const { pathsToModuleNameMapper } = require('ts-jest');
2+
3+
// Assuming you have some TypeScript path aliases defined in your tsconfig.json
4+
const { compilerOptions } = require('./tsconfig');
5+
/** @type {import('ts-jest').JestConfigWithTsJest} */
16
module.exports = {
2-
roots: ['<rootDir>/src'],
3-
testMatch: [
4-
"**/__tests__/**/*.+(ts|tsx|js)",
5-
"**/?(*.)+(spec|test).+(ts|tsx|js)"
6-
],
7+
preset: 'ts-jest',
8+
testEnvironment: 'node',
9+
modulePathIgnorePatterns: ['<rootDir>/src/config.spec.ts'],
10+
moduleNameMapper: {
11+
...pathsToModuleNameMapper({ '@/*': ['./src/*'] }, { prefix: '<rootDir>/' }),
12+
'^(\\.{1,2}/.*)\\.js$': '$1',
13+
},
14+
extensionsToTreatAsEsm: ['.ts'],
715
transform: {
8-
"^.+\\.(ts|tsx)$": "ts-jest"
16+
'^.+\\.ts?$': [
17+
'ts-jest',
18+
{
19+
useESM: true,
20+
},
21+
],
922
},
10-
moduleDirectories: ['node_modules', 'src'],
11-
testTimeout: 30000,
12-
}
23+
setupFilesAfterEnv: ['<rootDir>/tests/env.ts', '<rootDir>/tests/utils.ts']
24+
};

package-lock.json

Lines changed: 37 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"devDependencies": {
2525
"@types/jest": "^29.2.4",
2626
"@types/node": "^18.11.10",
27+
"@types/ws": "^8.5.12",
2728
"@typescript-eslint/eslint-plugin": "^5.45.0",
2829
"@typescript-eslint/parser": "^5.45.0",
2930
"esbuild": "^0.15.18",
@@ -35,6 +36,7 @@
3536
"typescript": "^4.9.3"
3637
},
3738
"dependencies": {
38-
"ethers": "^6.3.0"
39+
"dotenv": "^16.4.5",
40+
"ethers": "^6.13.2"
3941
}
4042
}

tests/env.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import dotenv from 'dotenv'
2+
3+
dotenv.config({
4+
path: process.cwd() + '/tests/.env',
5+
})
6+
7+
// testnet env
8+
export const OPEN_PLATFORM_PRIVATE_KEY = process.env.OPEN_PLATFORM_PRIVATE_KEY
9+
export const SPONSOR_URL = `https://open-platform.nodereal.io/${OPEN_PLATFORM_PRIVATE_KEY}/megafuel-testnet`
10+
export const CHAIN_ID = '97'
11+
export const CHAIN_URL = `https://bsc-testnet.nodereal.io/v1/${OPEN_PLATFORM_PRIVATE_KEY}`
12+
export const PAYMASTER_URL = 'https://bsc-megafuel-testnet.nodereal.io/97'
13+
export const PRIVATE_KEY = process.env.PRIVATE_KEY as string
14+
export const POLICY_UUID = '72191372-5550-4cf6-956e-b70d1e4786cf'
15+
export const ACCOUNT_ADDRESS = '0xF9A8db17431DD8563747D6FC770297E438Aa12eB'
16+
export const CONTRACT_METHOD = '0xa9059cbb'
17+
export const TOKEN_CONTRACT_ADDRESS = '0xeD24FC36d5Ee211Ea25A80239Fb8C4Cfd80f12Ee'
18+
export const RECIPIENT_ADDRESS = '0xDE08B1Fd79b7016F8DD3Df11f7fa0FbfdF07c941'

tests/paymaster.spec.ts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import {describe, expect, test} from '@jest/globals'
2+
import {
3+
paymasterClient,
4+
wallet,
5+
tokenAbi,
6+
transformIsSponsorableResponse,
7+
transformToGaslessTransaction,
8+
delay, transformSponsorTxResponse, transformBundleResponse,
9+
} from './utils'
10+
import {TOKEN_CONTRACT_ADDRESS, CHAIN_ID, RECIPIENT_ADDRESS} from './env'
11+
import {ethers} from 'ethers'
12+
13+
let TX_HASH = ''
14+
15+
/**
16+
* Testing suite for Paymaster API functionalities.
17+
*/
18+
describe('paymasterQuery', () => {
19+
20+
/**
21+
* Test for retrieving chain ID from the paymaster provider.
22+
*/
23+
describe('chainID', () => {
24+
test('chainID should return the expected value', async () => {
25+
const res = await paymasterClient.chainID()
26+
expect(res).toEqual('0x61')
27+
})
28+
})
29+
30+
/**
31+
* Test for checking if a transaction is sponsorable.
32+
*/
33+
describe('isSponsorable', () => {
34+
test('should successfully determine if transaction is sponsorable', async () => {
35+
const tokenContract = new ethers.Contract(TOKEN_CONTRACT_ADDRESS, tokenAbi, wallet)
36+
const tokenAmount = ethers.parseUnits('0', 18)
37+
const nonce = await paymasterClient.getTransactionCount(wallet.address, 'pending')
38+
39+
const transaction = await tokenContract.transfer.populateTransaction(RECIPIENT_ADDRESS.toLowerCase(), tokenAmount)
40+
transaction.from = wallet.address
41+
transaction.nonce = nonce
42+
transaction.gasLimit = BigInt(100000)
43+
transaction.chainId = BigInt(CHAIN_ID)
44+
transaction.gasPrice = BigInt(0)
45+
46+
const safeTransaction = {
47+
...transaction,
48+
gasLimit: transaction.gasLimit.toString(),
49+
chainId: transaction.chainId.toString(),
50+
gasPrice: transaction.gasPrice.toString(),
51+
}
52+
53+
console.log('Prepared transaction:', safeTransaction)
54+
const resRaw = await paymasterClient.isSponsorable(safeTransaction)
55+
const res = transformIsSponsorableResponse(resRaw)
56+
expect(res.Sponsorable).toEqual(true)
57+
58+
const signedTx = await wallet.signTransaction(safeTransaction)
59+
try {
60+
const tx = await paymasterClient.sendRawTransaction(signedTx)
61+
TX_HASH = tx
62+
console.log('Transaction hash received:', TX_HASH)
63+
} catch (error) {
64+
console.error('Transaction failed:', error)
65+
}
66+
}, 100000) // Extends the default timeout as this test involves network calls
67+
})
68+
69+
/**
70+
* Test for retrieving a gasless transaction by its hash and verifying related transactions.
71+
*/
72+
describe('getGaslessTransactionByHash', () => {
73+
test('should confirm and retrieve transaction details', async () => {
74+
console.log('Waiting for transaction confirmation...')
75+
await delay(8000)
76+
console.log('Querying gasless transaction by hash:', TX_HASH)
77+
const resRaw = await paymasterClient.getGaslessTransactionByHash(TX_HASH)
78+
const res = transformToGaslessTransaction(resRaw)
79+
expect(res.ToAddress).toEqual(TOKEN_CONTRACT_ADDRESS.toLowerCase())
80+
console.log('Querying gasless transaction', res)
81+
82+
console.log('Retrieving sponsor transaction by bundle UUID:', res.BundleUUID)
83+
const txRaw = await paymasterClient.getSponsorTxByBundleUuid(res.BundleUUID)
84+
const tx = transformSponsorTxResponse(txRaw)
85+
expect(txRaw).not.toBeNull()
86+
console.log('Sponsor transaction details:', tx)
87+
88+
const bundleRaw = await paymasterClient.getBundleByUuid(res.BundleUUID)
89+
const bundle = transformBundleResponse(bundleRaw)
90+
expect(bundle.BundleUUID).toEqual(res.BundleUUID)
91+
console.log('Bundle details:', bundle)
92+
93+
const sponsorTxRaw = await paymasterClient.getSponsorTxByTxHash(tx.TxHash)
94+
const sponsorTx = transformSponsorTxResponse(sponsorTxRaw)
95+
console.log('Sponsor transaction:', sponsorTx)
96+
expect(sponsorTx.TxHash).toEqual(tx.TxHash)
97+
}, 13000)
98+
})
99+
})

0 commit comments

Comments
 (0)