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
98 changes: 87 additions & 11 deletions dongle/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions dongle/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"lint": "eslint"
},
"dependencies": {
"@stellar/freighter-api": "^6.0.1",
"next": "16.1.3",
"react": "19.2.3",
"react-dom": "19.2.3"
Expand Down
63 changes: 63 additions & 0 deletions dongle/services/wallet/wallet.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import {
getAddress,
isAllowed,
isConnected as freighterIsConnected,
requestAccess,
} from "@stellar/freighter-api";

export const walletService = {
// Opens Freighter popup and returns the user's public key on approval
async connectWallet(): Promise<string> {
const { isConnected, error: connErr } = await freighterIsConnected();
if (!isConnected || connErr) {
throw new Error(connErr?.message ?? "Freighter is not installed");
}

const { address, error } = await requestAccess();
if (!address || error) {
throw new Error(error?.message ?? "Wallet connection failed");
}

console.info("Wallet connected:", address);
return address;
},

// Silently reads the public key — requires prior approval, no popup
async getPublicKey(): Promise<string> {
const { isConnected, error: connErr } = await freighterIsConnected();
if (!isConnected || connErr) {
throw new Error(connErr?.message ?? "Freighter is not installed");
}

const { isAllowed: allowed, error: allowErr } = await isAllowed();
if (!allowed || allowErr) {
throw new Error(allowErr?.message ?? "Wallet not connected");
}

const { address, error } = await getAddress();
if (!address || error) {
throw new Error(error?.message ?? "Could not retrieve public key");
}

return address;
},

// Safe to call anywhere — never throws, returns false if anything is off
async isConnected(): Promise<boolean> {
try {
const { isConnected } = await freighterIsConnected();
if (!isConnected) return false;

const { isAllowed: allowed } = await isAllowed();
if (!allowed) return false;

const { address } = await getAddress();
return Boolean(address);
} catch {
return false;
}
},

// Freighter has no disconnect API — context handles clearing state on its end
disconnectWallet(): void {},
};