import { CopyIcon, SquareArrowOutUpRightIcon } from "lucide-react"; import React from "react"; import { toast } from "sonner"; import PasswordInput from "src/components/password/PasswordInput"; import SettingsHeader from "src/components/SettingsHeader"; import { Button } from "src/components/ui/button"; import { ExternalLinkButton } from "src/components/ui/custom/external-link-button"; import { LoadingButton } from "src/components/ui/custom/loading-button"; import { Input } from "src/components/ui/input"; import { Label } from "src/components/ui/label"; import { RadioGroup, RadioGroupItem } from "src/components/ui/radio-group"; import { Separator } from "src/components/ui/separator"; import { useAlbyMe } from "src/hooks/useAlbyMe"; import { copyToClipboard } from "src/lib/clipboard"; import { AuthTokenResponse } from "src/types"; import { isHttpMode } from "src/utils/isHttpMode"; import { request } from "src/utils/request"; export default function DeveloperSettings() { const { data: albyMe } = useAlbyMe(); const _isHttpMode = isHttpMode(); const [token, setToken] = React.useState(); const [tokenPermission, setTokenPermission] = React.useState(); const [expiryDays, setExpiryDays] = React.useState("365"); const [unlockPassword, setUnlockPassword] = React.useState(""); const [permission, setPermission] = React.useState<"full" | "readonly">( "full" ); const [showCreateTokenForm, setShowCreateTokenForm] = React.useState(); const [loading, setLoading] = React.useState(); async function createToken(e: React.FormEvent) { e.preventDefault(); try { setLoading(true); if (!expiryDays || !unlockPassword || !permission) { throw new Error("Form not filled"); } const authTokenResponse = await request( "/api/unlock", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ unlockPassword, tokenExpiryDays: +expiryDays, permission, }), } ); if (authTokenResponse) { setToken(authTokenResponse.token); setTokenPermission(permission); } } catch (error) { console.error(error); toast.error("Something went wrong", { description: "" + error, }); } setLoading(false); } return ( <>

Power your apps with NWC

Alby Hub can power your lightning apps and services in all environments using Nostr Wallet Connect, an open protocol to connect lightning wallets and apps
Learn More on nwc.dev

Experimental API access

You can use your auth token to access the Alby Hub internal API. However, whenever possible, we recommend using the NWC API directly for more stability. Please note that the internal API may change or be removed entirely in the future.
{!_isHttpMode && (
API access is not available in the desktop app because it does not expose an HTTP API. To use the API, install the Alby Hub server version instead.
)} {_isHttpMode && !token && !showCreateTokenForm && (
)} {showCreateTokenForm && !token && (
<>
{ if (v != "readonly" && v !== "full") { throw new Error("Unknown permission type"); } setPermission(v); }} className="mt-4 gap-4" >
setExpiryDays(e.target.value)} value={expiryDays} />
Create Token
)} {token && ( <>

To make requests from your application to{" "} {window.location.origin}/api {" "} add the following header{albyMe?.hub.name && "s"}:

  1. Authorization: Bearer YOUR_TOKEN {" "}
  2. {albyMe?.hub.name && (
  3. AlbyHub-Name: {albyMe.hub.name} {" "}
  4. )} {albyMe?.hub.name && (
  5. AlbyHub-Region: {albyMe.hub.config?.region || "lax"}
  6. )}

{tokenPermission === "readonly" ? ( <> This is a read-only token that can view data but cannot perform operations like sending payments. Please keep it secure. ) : ( <> This token grants full access to your hub. Please keep it secure. )}{" "} If you suspect that the token has been compromised, immediately change your unlock password.

)}
); }