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
40 changes: 40 additions & 0 deletions packages/passport/sdk/src/zkEvm/relayerClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ describe('relayerClient', () => {
const data = '0x123';

(global.fetch as jest.Mock).mockResolvedValue({
ok: true,
text: () => Promise.resolve(JSON.stringify({ result: transactionHash })),
json: () => ({
result: transactionHash,
}),
Expand All @@ -69,6 +71,36 @@ describe('relayerClient', () => {
}],
});
});

it('throws HTTP error for non-ok response', async () => {
const to = '0xd64b0d2d72bb1b3f18046b8a7fc6c9ee6bccd287';
const data = '0x123';

(global.fetch as jest.Mock).mockResolvedValue({
ok: false,
status: 401,
statusText: 'Unauthorized',
text: () => Promise.resolve('{"error":"invalid_token"}'),
});

await expect(relayerClient.ethSendTransaction(to, data)).rejects.toThrow(
'Relayer HTTP error: 401. Content: "{"error":"invalid_token"}"',
);
});

it('throws JSON parse error for invalid response', async () => {
const to = '0xd64b0d2d72bb1b3f18046b8a7fc6c9ee6bccd287';
const data = '0x123';

(global.fetch as jest.Mock).mockResolvedValue({
ok: true,
text: () => Promise.resolve('invalid json'),
});

await expect(relayerClient.ethSendTransaction(to, data)).rejects.toThrow(
'Relayer JSON parse error: Unexpected token \'i\', "invalid json" is not valid JSON. Content: "invalid json"',
);
});
});

describe('imGetTransactionByHash', () => {
Expand All @@ -82,6 +114,8 @@ describe('relayerClient', () => {
};

(global.fetch as jest.Mock).mockResolvedValue({
ok: true,
text: () => Promise.resolve(JSON.stringify({ result: relayerTransaction })),
json: () => ({
result: relayerTransaction,
}),
Expand Down Expand Up @@ -118,6 +152,8 @@ describe('relayerClient', () => {
}];

(global.fetch as jest.Mock).mockResolvedValue({
ok: true,
text: () => Promise.resolve(JSON.stringify({ result: feeOptions })),
json: () => ({
result: feeOptions,
}),
Expand Down Expand Up @@ -152,6 +188,8 @@ describe('relayerClient', () => {
const relayerSignature = '0x123';

(global.fetch as jest.Mock).mockResolvedValue({
ok: true,
text: () => Promise.resolve(JSON.stringify({ result: relayerSignature })),
json: () => ({
result: relayerSignature,
}),
Expand Down Expand Up @@ -186,6 +224,8 @@ describe('relayerClient', () => {
const relayerSignature = '0x123';

(global.fetch as jest.Mock).mockResolvedValue({
ok: true,
text: () => Promise.resolve(JSON.stringify({ result: relayerSignature })),
json: () => ({
result: relayerSignature,
}),
Expand Down
22 changes: 19 additions & 3 deletions packages/passport/sdk/src/zkEvm/relayerClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ export class RelayerClient {
this.authManager = authManager;
}

private static getResponsePreview(text: string): string {
return text.length > 100
? `${text.substring(0, 50)}...${text.substring(text.length - 50)}`
: text;
}

private async postToRelayer<T>(request: RelayerTransactionRequest): Promise<T> {
const body: RelayerTransactionRequest & JsonRpc = {
id: 1,
Expand All @@ -120,9 +126,19 @@ export class RelayerClient {
body: JSON.stringify(body),
});

const jsonResponse = await response.json();
if (jsonResponse.error) {
throw jsonResponse.error;
if (!response.ok) {
const responseText = await response.text();
const preview = RelayerClient.getResponsePreview(responseText);
throw new Error(`Relayer HTTP error: ${response.status}. Content: "${preview}"`);
}

const responseText = await response.text();
let jsonResponse;
try {
jsonResponse = JSON.parse(responseText);
} catch (parseError) {
const preview = RelayerClient.getResponsePreview(responseText);
throw new Error(`Relayer JSON parse error: ${parseError instanceof Error ? parseError.message : 'Unknown error'}. Content: "${preview}"`);
}

return jsonResponse;
Expand Down