Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 15 additions & 0 deletions docs/src/sdk-reference/ethers/deposits.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,21 @@ Result-style `wait`.

---

## Utility Helpers

### `getL2TransactionHashFromLogs(logs) → Hex | null`

Extracts the L2 transaction hash from L1 logs emitted by `Bridgehub` during deposit. Returns `null` if not found.

```ts
import { getL2TransactionHashFromLogs } from '@matterlabs/zksync-js/ethers';

const l1Receipt = await client.l1.waitForTransaction(l1TxHash);
const l2TxHash = l1Receipt ? getL2TransactionHashFromLogs(l1Receipt.logs) : null;
```

---

## Types (Overview)

### Deposit Params
Expand Down
17 changes: 17 additions & 0 deletions docs/src/sdk-reference/viem/deposits.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,23 @@ Result-style `wait`.
{{#include ../../../snippets/viem/reference/deposits.test.ts:create-token-deposit}}
```

---

## Utility Helpers

### `getL2TransactionHashFromLogs(logs) → Hex | null`

Extracts the L2 transaction hash from L1 logs emitted by `Bridgehub` during deposit. Returns `null` if not found.

```ts
import { getL2TransactionHashFromLogs } from '@matterlabs/zksync-js/viem';

const l1Receipt = await client.l1.waitForTransactionReceipt({ hash: l1TxHash });
const l2TxHash = getL2TransactionHashFromLogs(l1Receipt.logs);
```

---

## Types (Overview)

### Deposit Params
Expand Down
1 change: 1 addition & 0 deletions src/adapters/ethers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export * from './sdk';
export * from './resources/utils';
export { createDepositsResource } from './resources/deposits';
export type { DepositsResource } from './resources/deposits';
export { getL2TransactionHashFromLogs } from './resources/deposits/services/verification';
export { createWithdrawalsResource } from './resources/withdrawals';
export { createFinalizationServices } from './resources/withdrawals';
export type { WithdrawalsResource, FinalizationServices } from './resources/withdrawals';
Expand Down
11 changes: 7 additions & 4 deletions src/adapters/ethers/resources/deposits/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import type {
DepositStatus,
} from '../../../../core/types/flows/deposits.ts';
import type { Address, Hex } from '../../../../core/types/primitives.ts';
import { extractL2TxHashFromL1Logs, waitForL2ExecutionFromL1Tx } from './services/verification.ts';
import {
getL2TransactionHashFromLogs,
waitForL2ExecutionFromL1Tx,
} from './services/verification.ts';

import { Contract, type TransactionRequest, type TransactionReceipt, NonceManager } from 'ethers';
import { IERC20ABI } from '../../../../core/abi.ts';
Expand Down Expand Up @@ -321,14 +324,14 @@ export function createDepositsResource(

let l2TxHash: Hex | undefined;
try {
l2TxHash = extractL2TxHashFromL1Logs(l1Rcpt.logs) ?? undefined;
l2TxHash = getL2TransactionHashFromLogs(l1Rcpt.logs) ?? undefined;
} catch (e) {
throw toZKsyncError(
'INTERNAL',
{
resource: 'deposits',
operation: 'deposits.status.extractL2TxHashFromL1Logs',
context: { where: 'extractL2TxHashFromL1Logs', l1TxHash },
operation: 'deposits.status.getL2TransactionHashFromLogs',
context: { where: 'getL2TransactionHashFromLogs', l1TxHash },
message: 'Failed to derive L2 transaction hash from L1 logs.',
},
e,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { describe, it, expect } from 'bun:test';
import { type Log } from 'ethers';
import {
extractL2TxHashFromL1Logs,
getL2TransactionHashFromLogs,
waitForL2ExecutionFromL1Tx,
I_BRIDGEHUB,
TOPIC_BRIDGEHUB_NPR,
Expand Down Expand Up @@ -68,23 +68,23 @@ function makeTopicOnlyLog(topic0: string, extraTopics: string[] = []): Log {
} as unknown as Log;
}

describe('services/verification.extractL2TxHashFromL1Logs', () => {
describe('services/verification.getL2TransactionHashFromLogs', () => {
it('extracts from Bridgehub.NewPriorityRequest', () => {
const target = H.l2tx as `0x${string}`;
const log = makeNprLog({ txHash: target });
const out = extractL2TxHashFromL1Logs([log]);
const out = getL2TransactionHashFromLogs([log]);
expect(out).toBe(target);
});

it('falls back to TOPIC_CANONICAL_ASSIGNED (hash at topic[2])', () => {
const assigned = makeTopicOnlyLog(TOPIC_CANONICAL_ASSIGNED, ['0x', H.l2tx, '0xdead']);
const out = extractL2TxHashFromL1Logs([assigned]);
const out = getL2TransactionHashFromLogs([assigned]);
expect(out).toBe(H.l2tx);
});

it('falls back to TOPIC_CANONICAL_SUCCESS (hash at topic[3])', () => {
const success = makeTopicOnlyLog(TOPIC_CANONICAL_SUCCESS, ['0x1', '0x2', H.l2tx]);
const out = extractL2TxHashFromL1Logs([success]);
const out = getL2TransactionHashFromLogs([success]);
expect(out).toBe(H.l2tx);
});

Expand All @@ -94,12 +94,12 @@ describe('services/verification.extractL2TxHashFromL1Logs', () => {
data: '0x1234',
} as Log;
const success = makeTopicOnlyLog(TOPIC_CANONICAL_SUCCESS, ['0x1', '0x2', H.l2tx]);
const out = extractL2TxHashFromL1Logs([badNpr, success]);
const out = getL2TransactionHashFromLogs([badNpr, success]);
expect(out).toBe(H.l2tx);
});

it('returns null when no recognizable logs exist', () => {
const out = extractL2TxHashFromL1Logs([]);
const out = getL2TransactionHashFromLogs([]);
expect(out).toBeNull();
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const TOPIC_BRIDGEHUB_NPR = I_BRIDGEHUB.getEvent('NewPriorityRequest')!.t

// Extracts the L2 transaction hash from L1 logs emitted by Bridgehub during deposit
// Returns null if not found
export function extractL2TxHashFromL1Logs(logs: ReadonlyArray<Log>): Hex | null {
export function getL2TransactionHashFromLogs(logs: ReadonlyArray<Log>): Hex | null {
for (const lg of logs) {
if ((lg.topics?.[0] ?? '').toLowerCase() === TOPIC_BRIDGEHUB_NPR.toLowerCase()) {
try {
Expand Down Expand Up @@ -52,7 +52,7 @@ export async function waitForL2ExecutionFromL1Tx(
const l1Receipt = await l1.waitForTransaction(l1TxHash);
if (!l1Receipt) throw new Error('No L1 receipt found');

const l2TxHash = extractL2TxHashFromL1Logs(l1Receipt.logs);
const l2TxHash = getL2TransactionHashFromLogs(l1Receipt.logs);
if (!l2TxHash) {
throw createError('VERIFICATION', {
message: 'Failed to extract L2 transaction hash from L1 logs',
Expand Down
2 changes: 1 addition & 1 deletion src/adapters/ethers/resources/interop/resolvers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AbstractProvider, JsonRpcProvider } from 'ethers';
import { type AbstractProvider, JsonRpcProvider } from 'ethers';
import type { InteropWaitable as InteropWaitableBase } from '../../../../core/types/flows/interop';
import type { DstChain, InteropWaitable, InteropHandle } from './types';

Expand Down
1 change: 1 addition & 0 deletions src/adapters/viem/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export * from './sdk';
export * from './resources/utils';
export { createDepositsResource } from './resources/deposits';
export type { DepositsResource } from './resources/deposits';
export { getL2TransactionHashFromLogs } from './resources/deposits/services/verification';
export { createWithdrawalsResource } from './resources/withdrawals';
export { createFinalizationServices } from './resources/withdrawals';
export type { WithdrawalsResource, FinalizationServices } from './resources/withdrawals';
Expand Down
8 changes: 4 additions & 4 deletions src/adapters/viem/resources/deposits/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { routeEthNonBase } from './routes/eth-nonbase';
import { routeErc20Base } from './routes/erc20-base';
import type { DepositRouteStrategy, ViemPlanWriteRequest } from './routes/types';

import { extractL2TxHashFromL1Logs, waitForL2ExecutionFromL1Tx } from './services/verification';
import { getL2TransactionHashFromLogs, waitForL2ExecutionFromL1Tx } from './services/verification';
import { isZKsyncError, isReceiptNotFound, OP_DEPOSITS } from '../../../../core/types/errors';
import { createError } from '../../../../core/errors/factory';
import { toZKsyncError, createErrorHandlers } from '../../errors/error-ops';
Expand Down Expand Up @@ -382,14 +382,14 @@ export function createDepositsResource(

let l2TxHash: Hex | undefined;
try {
l2TxHash = extractL2TxHashFromL1Logs(l1Rcpt.logs) ?? undefined;
l2TxHash = getL2TransactionHashFromLogs(l1Rcpt.logs) ?? undefined;
} catch (e) {
throw toZKsyncError(
'INTERNAL',
{
resource: 'deposits',
operation: 'deposits.status.extractL2TxHashFromL1Logs',
context: { where: 'extractL2TxHashFromL1Logs', l1TxHash },
operation: 'deposits.status.getL2TransactionHashFromLogs',
context: { where: 'getL2TransactionHashFromLogs', l1TxHash },
message: 'Failed to derive L2 transaction hash from L1 logs.',
},
e,
Expand Down
4 changes: 2 additions & 2 deletions src/adapters/viem/resources/deposits/services/verification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const I_BRIDGEHUB_NEW_PRIORITY_REQUEST = {

// Extracts the L2 transaction hash from L1 logs emitted by Bridgehub during deposit
// Returns null if not found
export function extractL2TxHashFromL1Logs(logs: ReadonlyArray<Log>): Hex | null {
export function getL2TransactionHashFromLogs(logs: ReadonlyArray<Log>): Hex | null {
for (const lg of logs) {
try {
const parsed = decodeEventLog({
Expand Down Expand Up @@ -69,7 +69,7 @@ export async function waitForL2ExecutionFromL1Tx(
if (!l1Receipt) throw new Error('No L1 receipt found');

// Extract L2 tx hash from logs
const l2TxHash = extractL2TxHashFromL1Logs(l1Receipt.logs as ReadonlyArray<Log>);
const l2TxHash = getL2TransactionHashFromLogs(l1Receipt.logs as ReadonlyArray<Log>);
if (!l2TxHash) {
throw createError('VERIFICATION', {
message: 'Failed to extract L2 transaction hash from L1 logs',
Expand Down