Skip to content
Open
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
7 changes: 4 additions & 3 deletions src/wallets/adapters/FreighterAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/

import type { WalletAdapter } from "../../types.js";
import { FreighterNotInstalledError } from "../../errors.js";

type Unsubscribe = () => void;

Expand All @@ -24,7 +25,7 @@ export class FreighterAdapter implements WalletAdapter {

async connect(): Promise<string> {
if (!window.freighter) {
throw new Error("Freighter wallet not installed");
throw new FreighterNotInstalledError();
}

const address = await window.freighter.getPublicKey();
Expand All @@ -38,15 +39,15 @@ export class FreighterAdapter implements WalletAdapter {

async sign(xdr: string, network: string): Promise<string> {
if (!window.freighter) {
throw new Error("Freighter wallet not installed");
throw new FreighterNotInstalledError();
}

return await window.freighter.signTransaction(xdr, network);
}

async getAddress(): Promise<string> {
if (!window.freighter) {
throw new Error("Freighter wallet not installed");
throw new FreighterNotInstalledError();
}

return await window.freighter.getPublicKey();
Expand Down
51 changes: 51 additions & 0 deletions test/freighterAdapter.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { describe, it, expect, vi } from "vitest";
import { FreighterAdapter } from "../src/wallets/adapters/FreighterAdapter.js";
import { FreighterNotInstalledError } from "../src/errors.js";

describe("FreighterAdapter not-installed handling", () => {
it("throws FreighterNotInstalledError on connect when window.freighter is absent", async () => {
const adapter = new FreighterAdapter();
// Ensure window.freighter is undefined
(globalThis as any).window = { freighter: undefined };
await expect(adapter.connect()).rejects.toThrow(FreighterNotInstalledError);
});

it("throws FreighterNotInstalledError on sign when window.freighter is absent", async () => {
const adapter = new FreighterAdapter();
(globalThis as any).window = { freighter: undefined };
await expect(adapter.sign("xdr", "testnet")).rejects.toThrow(FreighterNotInstalledError);
});

it("throws FreighterNotInstalledError on getAddress when window.freighter is absent", async () => {
const adapter = new FreighterAdapter();
(globalThis as any).window = { freighter: undefined };
await expect(adapter.getAddress()).rejects.toThrow(FreighterNotInstalledError);
});

it("error message includes the Freighter install URL", async () => {
const adapter = new FreighterAdapter();
(globalThis as any).window = { freighter: undefined };
try {
await adapter.connect();
expect.fail("Should have thrown");
} catch (err) {
expect(err).toBeInstanceOf(FreighterNotInstalledError);
expect((err as Error).message).toContain("https://www.freighter.app");
}
});

it("connects normally when window.freighter is present", async () => {
const adapter = new FreighterAdapter();
(globalThis as any).window = {
freighter: {
isConnected: vi.fn().mockResolvedValue(true),
getPublicKey: vi.fn().mockResolvedValue("GABC..."),
signTransaction: vi.fn().mockResolvedValue("signed-xdr"),
},
};

const address = await adapter.connect();
expect(address).toBe("GABC...");
adapter.disconnect();
});
});
Loading