Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e7018da
fix: confirmations correction and improved polling logic
mohammeds1992 Dec 24, 2025
2e5d9a3
release(core): bump to 4.0.2
mohammeds1992 Dec 25, 2025
a2b5ae3
fix: rpc url fix
mohammeds1992 Jan 7, 2026
ca5ee36
release(core): bump to 4.0.3
mohammeds1992 Jan 7, 2026
3e3b815
fix: fast confirmations for gas types
mohammeds1992 Jan 11, 2026
b772b90
fix: progressHook fixes
mohammeds1992 Jan 12, 2026
62e5eee
release(core): bump to 4.0.5
mohammeds1992 Jan 12, 2026
510a68b
fix: confirmations fixes
mohammeds1992 Jan 16, 2026
a8dec4c
release(core): bump to 4.0.6
mohammeds1992 Jan 16, 2026
9d4b233
fix: progress hooks fixes
mohammeds1992 Jan 16, 2026
6ee8055
release(core): bump to 4.0.7
mohammeds1992 Jan 16, 2026
9b446d6
fixes
mohammeds1992 Jan 19, 2026
4ec7e16
release(core): bump to 4.0.8
mohammeds1992 Jan 19, 2026
13a435b
fixes
mohammeds1992 Jan 30, 2026
40c9406
fix: trackTransaction function
mohammeds1992 Feb 3, 2026
4c4abea
fix: BigInt conversion error
mohammeds1992 Feb 3, 2026
7710728
fix: multiple bug fixes
mohammeds1992 Feb 5, 2026
3937692
fix: bug fixes
mohammeds1992 Feb 5, 2026
e94db92
fix: bug fixes
mohammeds1992 Feb 5, 2026
f8b9a1b
release(core): bump to 4.0.9
mohammeds1992 Feb 6, 2026
a608a94
fix: phantom.ts to fix version error
mohammeds1992 Feb 6, 2026
174bf4f
fix: self svm bridge bug fix
mohammeds1992 Feb 6, 2026
8ee9583
release(core): bump to 4.0.10
mohammeds1992 Feb 6, 2026
14cba5e
fix: pick up the last pc transaction
mohammeds1992 Feb 10, 2026
b880a63
release(core): bump to 4.0.11
mohammeds1992 Feb 10, 2026
8b17133
Update orchestrator.ts
mohammeds1992 Feb 10, 2026
f20ca7e
fix: debug logs and bug fixes
mohammeds1992 Feb 11, 2026
1d8059d
feat: improvements and bug fixes
mohammeds1992 Feb 12, 2026
583b6cc
Update pctx-last-transaction.spec.ts
mohammeds1992 Feb 12, 2026
a2c7e9f
fixes
mohammeds1992 Feb 12, 2026
c8a619e
Merge pull request #240 from pushchain/feb-11-2026-alpha-publish
mohammeds1992 Feb 12, 2026
5536028
Merge branch 'main' into new-sendUniversalTx
mohammeds1992 Feb 12, 2026
a39f367
fix: one more scenario fixed
mohammeds1992 Feb 17, 2026
95658a4
fix: track transaction and few more changes
mohammeds1992 Feb 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
312 changes: 312 additions & 0 deletions packages/core/__e2e__/bridge-hooks.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,312 @@
import { PushChain } from '../src';
import { PUSH_NETWORK, CHAIN } from '../src/lib/constants/enums';
import { CHAIN_INFO } from '../src/lib/constants/chain';
import { MOVEABLE_TOKENS } from '../src/lib/constants/tokens';
import { createWalletClient, http, Hex } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { Keypair } from '@solana/web3.js';
import bs58 from 'bs58';
import dotenv from 'dotenv';
import path from 'path';

dotenv.config({ path: path.resolve(__dirname, '../.env') });

describe('Bridge Progress Hooks (e2e)', () => {
it('should emit all progress hooks and measure timing', async () => {
const privateKey = process.env['EVM_PRIVATE_KEY'] as Hex;
if (!privateKey) throw new Error('EVM_PRIVATE_KEY not set');

const originChain = CHAIN.ETHEREUM_SEPOLIA;
const account = privateKeyToAccount(privateKey);
const walletClient = createWalletClient({
account,
transport: http(CHAIN_INFO[originChain].defaultRPC[0]),
});

const universalSigner = await PushChain.utils.signer.toUniversalFromKeypair(
walletClient,
{
chain: originChain,
library: PushChain.CONSTANTS.LIBRARY.ETHEREUM_VIEM,
}
);

console.log('\n=== PROGRESS HOOKS TIMING TEST ===\n');

const progressEvents: { event: any; timestamp: number }[] = [];
const startTime = Date.now();

const pushClient = await PushChain.initialize(universalSigner, {
network: PUSH_NETWORK.TESTNET_DONUT,
progressHook: (val: any) => {
const now = Date.now();
progressEvents.push({ event: val, timestamp: now });
const elapsed = ((now - startTime) / 1000).toFixed(2);
console.log(`[${elapsed}s] ${val.id}: ${val.title}`);
},
});

const UEA = pushClient.universal.account;
console.log(`\nUEA Address: ${UEA}`);

// Get ETH token
const tokens = MOVEABLE_TOKENS[originChain] || [];
const ethToken = tokens.find(t => t.symbol === 'ETH');
if (!ethToken) throw new Error('ETH token not found');

console.log(`\nBridging 0.0001 ETH to self...\n`);

const tx = await pushClient.universal.sendTransaction({
to: UEA as `0x${string}`,
funds: {
amount: PushChain.utils.helpers.parseUnits('0.0001', 18),
token: ethToken,
},
});

const totalTime = ((Date.now() - startTime) / 1000).toFixed(2);
console.log(`\n=== TRANSACTION COMPLETE (Total: ${totalTime}s) ===`);
console.log(`Hash: ${tx.hash}`);

// Calculate time between each step
console.log(`\n=== STEP DURATIONS (sorted by time DESC) ===\n`);

const durations: { step: string; duration: number; from: string; to: string }[] = [];

for (let i = 1; i < progressEvents.length; i++) {
const prev = progressEvents[i - 1];
const curr = progressEvents[i];
const duration = (curr.timestamp - prev.timestamp) / 1000;
durations.push({
step: `${prev.event.id} → ${curr.event.id}`,
duration,
from: prev.event.title,
to: curr.event.title,
});
}

// Sort by duration descending
durations.sort((a, b) => b.duration - a.duration);

durations.forEach((d, i) => {
console.log(`${i + 1}. ${d.duration.toFixed(2)}s: ${d.step}`);
console.log(` (${d.from} → ${d.to})\n`);
});

// Count confirmations
const confirmationHooks = progressEvents.filter(
p => p.event.id.startsWith('SEND-TX-06-03')
);
console.log(`\n=== CONFIRMATION INFO ===`);
console.log(`Total confirmation hooks: ${confirmationHooks.length}`);
confirmationHooks.forEach(c => {
console.log(` - ${c.event.id}: ${c.event.message}`);
});

// Verify expected hooks were emitted
const hookIds = progressEvents.map(e => e.event.id);
expect(hookIds).toContain('SEND-TX-01');
expect(hookIds).toContain('SEND-TX-06-04'); // Funds Confirmed
expect(hookIds).toContain('SEND-TX-06-05'); // Syncing with Push Chain
expect(hookIds).toContain('SEND-TX-06-06'); // Funds Credited on Push Chain
expect(hookIds).toContain('SEND-TX-99-01');
}, 300000);

it('should emit all progress hooks for Solana bridge and measure timing', async () => {
const privateKeyHex = process.env['SOLANA_PRIVATE_KEY'];
if (!privateKeyHex) throw new Error('SOLANA_PRIVATE_KEY not set');

const privateKey = bs58.decode(privateKeyHex);
const originChain = CHAIN.SOLANA_DEVNET;
const account = Keypair.fromSecretKey(privateKey);

const universalSigner = await PushChain.utils.signer.toUniversalFromKeypair(
account,
{
chain: originChain,
library: PushChain.CONSTANTS.LIBRARY.SOLANA_WEB3JS,
}
);

console.log('\n=== SOLANA PROGRESS HOOKS TIMING TEST ===\n');

const progressEvents: { event: any; timestamp: number }[] = [];
const startTime = Date.now();

const pushClient = await PushChain.initialize(universalSigner, {
network: PUSH_NETWORK.TESTNET_DONUT,
progressHook: (val: any) => {
const now = Date.now();
progressEvents.push({ event: val, timestamp: now });
const elapsed = ((now - startTime) / 1000).toFixed(2);
console.log(`[${elapsed}s] ${val.id}: ${val.title}`);
},
});

const UEA = pushClient.universal.account;
console.log(`\nUEA Address: ${UEA}`);

// Get SOL token
const tokens = MOVEABLE_TOKENS[originChain] || [];
const solToken = tokens.find(t => t.symbol === 'SOL');
if (!solToken) throw new Error('SOL token not found');

// Use a different recipient address (not self)
const differentRecipient = '0x742d35Cc6634C0532925a3b844Bc9e7595f5bE21' as `0x${string}`;

console.log(`\nBridging 0.001 SOL to different address: ${differentRecipient}\n`);

console.log('SOL token', UEA as `0x${string}`);

const tx = await pushClient.universal.sendTransaction({
to: differentRecipient,
funds: {
amount: PushChain.utils.helpers.parseUnits('0.001', 9), // SOL has 9 decimals
token: solToken,
},
});

const totalTime = ((Date.now() - startTime) / 1000).toFixed(2);
console.log(`\n=== SOLANA TRANSACTION COMPLETE (Total: ${totalTime}s) ===`);
console.log(`Hash: ${tx.hash}`);

// Calculate time between each step
console.log(`\n=== STEP DURATIONS (sorted by time DESC) ===\n`);

const durations: { step: string; duration: number; from: string; to: string }[] = [];

for (let i = 1; i < progressEvents.length; i++) {
const prev = progressEvents[i - 1];
const curr = progressEvents[i];
const duration = (curr.timestamp - prev.timestamp) / 1000;
durations.push({
step: `${prev.event.id} → ${curr.event.id}`,
duration,
from: prev.event.title,
to: curr.event.title,
});
}

// Sort by duration descending
durations.sort((a, b) => b.duration - a.duration);

durations.forEach((d, i) => {
console.log(`${i + 1}. ${d.duration.toFixed(2)}s: ${d.step}`);
console.log(` (${d.from} → ${d.to})\n`);
});

// Count confirmations
const confirmationHooks = progressEvents.filter(
p => p.event.id.startsWith('SEND-TX-06-03')
);
console.log(`\n=== CONFIRMATION INFO ===`);
console.log(`Total confirmation hooks: ${confirmationHooks.length}`);
confirmationHooks.forEach(c => {
console.log(` - ${c.event.id}: ${c.event.message}`);
});

// Verify expected hooks were emitted
const hookIds = progressEvents.map(e => e.event.id);
expect(hookIds).toContain('SEND-TX-01');
expect(hookIds).toContain('SEND-TX-06-04'); // Funds Confirmed
expect(hookIds).toContain('SEND-TX-06-05'); // Syncing with Push Chain
expect(hookIds).toContain('SEND-TX-06-06'); // Funds Credited on Push Chain
expect(hookIds).toContain('SEND-TX-99-01');
}, 300000);

it('should emit all progress hooks for Solana bridge self-send and measure timing', async () => {
const privateKeyHex = process.env['SOLANA_PRIVATE_KEY'];
if (!privateKeyHex) throw new Error('SOLANA_PRIVATE_KEY not set');

const privateKey = bs58.decode(privateKeyHex);
const originChain = CHAIN.SOLANA_DEVNET;
const account = Keypair.fromSecretKey(privateKey);

const universalSigner = await PushChain.utils.signer.toUniversalFromKeypair(
account,
{
chain: originChain,
library: PushChain.CONSTANTS.LIBRARY.SOLANA_WEB3JS,
}
);

console.log('\n=== SOLANA SELF-SEND PROGRESS HOOKS TIMING TEST ===\n');

const progressEvents: { event: any; timestamp: number }[] = [];
const startTime = Date.now();

const pushClient = await PushChain.initialize(universalSigner, {
network: PUSH_NETWORK.TESTNET_DONUT,
progressHook: (val: any) => {
const now = Date.now();
progressEvents.push({ event: val, timestamp: now });
const elapsed = ((now - startTime) / 1000).toFixed(2);
console.log(`[${elapsed}s] ${val.id}: ${val.title}`);
},
});

const UEA = pushClient.universal.account;
console.log(`\nUEA Address: ${UEA}`);

// Get SOL token
const tokens = MOVEABLE_TOKENS[originChain] || [];
const solToken = tokens.find(t => t.symbol === 'SOL');
if (!solToken) throw new Error('SOL token not found');

console.log(`\nBridging 0.001 SOL to self (UEA)...\n`);

const tx = await pushClient.universal.sendTransaction({
to: UEA as `0x${string}`,
funds: {
amount: PushChain.utils.helpers.parseUnits('0.001', 9),
token: solToken,
},
});

const totalTime = ((Date.now() - startTime) / 1000).toFixed(2);
console.log(`\n=== SOLANA SELF-SEND COMPLETE (Total: ${totalTime}s) ===`);
console.log(`Hash: ${tx.hash}`);

// Calculate time between each step
console.log(`\n=== STEP DURATIONS (sorted by time DESC) ===\n`);

const durations: { step: string; duration: number; from: string; to: string }[] = [];

for (let i = 1; i < progressEvents.length; i++) {
const prev = progressEvents[i - 1];
const curr = progressEvents[i];
const duration = (curr.timestamp - prev.timestamp) / 1000;
durations.push({
step: `${prev.event.id} → ${curr.event.id}`,
duration,
from: prev.event.title,
to: curr.event.title,
});
}

durations.sort((a, b) => b.duration - a.duration);

durations.forEach((d, i) => {
console.log(`${i + 1}. ${d.duration.toFixed(2)}s: ${d.step}`);
console.log(` (${d.from} → ${d.to})\n`);
});

// Count confirmations
const confirmationHooks = progressEvents.filter(
p => p.event.id.startsWith('SEND-TX-06-03')
);
console.log(`\n=== CONFIRMATION INFO ===`);
console.log(`Total confirmation hooks: ${confirmationHooks.length}`);
confirmationHooks.forEach(c => {
console.log(` - ${c.event.id}: ${c.event.message}`);
});

// Verify expected hooks were emitted
const hookIds = progressEvents.map(e => e.event.id);
expect(hookIds).toContain('SEND-TX-01');
expect(hookIds).toContain('SEND-TX-06-04'); // Funds Confirmed
expect(hookIds).toContain('SEND-TX-06-05'); // Syncing with Push Chain
expect(hookIds).toContain('SEND-TX-06-06'); // Funds Credited on Push Chain
expect(hookIds).toContain('SEND-TX-99-01');
}, 300000);
});
Loading