Skip to content

Commit

Permalink
Expose MakeInvoice and LookupInvoice as iOS AppIntents
Browse files Browse the repository at this point in the history
  • Loading branch information
Vinny Fiano committed Jan 10, 2025
1 parent 75788d4 commit b9b1f5e
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 0 deletions.
41 changes: 41 additions & 0 deletions app.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,47 @@
"faceIDPermission": "Allow Alby Go to use Face ID."
}
],
[
"expo-ios-app-intents",
{
"intents": [
{
"name": "MakeInvoice",
"title": "Create Lightning Invoice",
"description": "Generate a new lightning network invoice",
"resultType": "String",
"parameters": [
{
"name": "Amount",
"type": "Int",
"description": "Amount in satoshis",
"required": true
},
{
"name": "Description",
"type": "String",
"description": "Invoice description",
"required": false
}
]
},
{
"name": "LookupInvoice",
"title": "Lookup Lightning Invoice",
"description": "Look up the status of a lightning network invoice",
"resultType": "String",
"parameters": [
{
"name": "Invoice",
"type": "String",
"description": "The invoice",
"required": true
}
]
}
]
}
],
[
"expo-camera",
{
Expand Down
2 changes: 2 additions & 0 deletions app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { swrConfiguration } from "lib/swr";
import * as React from "react";
import { SafeAreaView } from "react-native-safe-area-context";
import Toast from "react-native-toast-message";
import { setupLightningIntentHandlers } from "~/lib/appIntents/LightningIntents";
import { SWRConfig } from "swr";
import { toastConfig } from "~/components/ToastConfig";
import { UserInactivityProvider } from "~/context/UserInactivity";
Expand Down Expand Up @@ -82,6 +83,7 @@ export default function RootLayout() {
React.useEffect(() => {
const init = async () => {
try {
setupLightningIntentHandlers();
await Promise.all([loadTheme(), loadFonts(), checkBiometricStatus()]);
} finally {
setResourcesLoaded(true);
Expand Down
62 changes: 62 additions & 0 deletions lib/appIntents/LightningIntents.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import ExpoAppIntents from "expo-ios-app-intents";
import { useAppStore } from "../state/appStore";
import { Nip47Transaction } from "@getalby/sdk/dist/NWCClient";

export interface MakeInvoiceParameters {
_Amount: number;
_Description?: string;
}

export interface LookupInvoiceParameters {
_Invoice: string;
}

// Define the proper IntentEventPayload type
interface IntentEventPayload {
id: string;
name: string;
parameters: Record<string, any>;
}

async function handleIntent(event: IntentEventPayload) {
const { name, parameters, id } = event;
const nwcClient = useAppStore.getState().nwcClient;

if (!nwcClient) {
ExpoAppIntents.failIntent(id, "NWC client not connected");
return;
}

try {
if (name === "MakeInvoice") {
const { _Amount, _Description } = parameters as MakeInvoiceParameters;
const response = (await nwcClient.makeInvoice({
amount: _Amount,
...(_Description ? { description: _Description } : {}),
})) as Nip47Transaction;
// Return [invoice, paymentHash] as string array
ExpoAppIntents.completeIntent(id, { value: JSON.stringify(response) });
} else if (name === "LookupInvoice") {
const { _Invoice } = parameters as LookupInvoiceParameters;
const response = (await nwcClient.lookupInvoice({
invoice: _Invoice,
})) as Nip47Transaction;

// Return [paid, preimage, amount, description] as string array
// Determine paid status from presence of settled_at timestamp
ExpoAppIntents.completeIntent(id, { value: JSON.stringify(response) });
}
} catch (error) {
console.error("App Intent error:", error);
ExpoAppIntents.failIntent(
id,
error instanceof Error ? error.message : "Unknown error",
);
}
}

export const setupLightningIntentHandlers = () => {
ExpoAppIntents.addListener("onIntent", (event: IntentEventPayload) => {
handleIntent(event);
});
};
16 changes: 16 additions & 0 deletions lib/appIntents/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export interface MakeInvoiceResponse {
invoice: string;
paymentHash: string;
}

export interface LookupInvoiceResponse {
paid: boolean;
preimage?: string;
amount: number;
description?: string;
}

export interface NWCInvoiceError {
error: string;
message: string;
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"expo-linear-gradient": "~14.0.1",
"expo-linking": "~7.0.3",
"expo-local-authentication": "~15.0.1",
"expo-ios-app-intents": "ynniv/expo-ios-app-intents",
"expo-router": "~4.0.15",
"expo-secure-store": "~14.0.0",
"expo-splash-screen": "^0.29.18",
Expand Down

0 comments on commit b9b1f5e

Please sign in to comment.