From 6cddb8275e30c79a30eba2ad17cf16485a44cac6 Mon Sep 17 00:00:00 2001 From: Roland Bewick Date: Sun, 18 Aug 2024 12:36:29 +0700 Subject: [PATCH] feat: add info and reserves api endpoints --- .env.example | 7 +++++- README.md | 45 ++++++++++++++++++++++++++++++++++++--- app/actions.ts | 12 +++++++++++ app/api/info/route.ts | 9 ++++++++ app/api/reserves/route.ts | 9 ++++++++ 5 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 app/api/info/route.ts create mode 100644 app/api/reserves/route.ts diff --git a/.env.example b/.env.example index 93db5b8..6206490 100644 --- a/.env.example +++ b/.env.example @@ -4,4 +4,9 @@ AUTH_TOKEN="eyJhb..." DATABASE_URL="file:./jim.db" BASE_URL="http://localhost:3000" DAILY_WALLET_LIMIT=10 -#APP_NAME_PREFIX = "Alby Jim " \ No newline at end of file +#APP_NAME_PREFIX = "Alby Jim " + +# Info +NAME="Uncle Jim Demo Server" +DESCRIPTION="This demo server shows how easy it is for new users to get a wallet. For demo purposes only - this server has a small amount of liquidity and will not be increased." +IMAGE="https://upload.wikimedia.org/wikipedia/commons/thumb/c/ce/Bust_of_Satoshi_Nakamoto_in_Budapest.jpg/440px-Bust_of_Satoshi_Nakamoto_in_Budapest.jpg" \ No newline at end of file diff --git a/README.md b/README.md index 812c9a8..31d1624 100644 --- a/README.md +++ b/README.md @@ -10,17 +10,56 @@ App Connections have a 10 sat / 1% reserve to account for possible routing fees. ## API -You can also create new wallets via the API. Simply do a POST request to `/api/wallets` which will return a JSON response like: +### Create a new wallet + +`POST /api/wallets` + +returns: ```json { "connectionSecret": "nostr+walletconnect://xxx?relay=yyy&secret=zzz&lud16=123456@alby-jim.fly.dev", - "lightningAddress": "123456@alby-jim.fly.dev" + "lightningAddress": "123456@alby-jim.fly.dev", + "valueTag": "" } ``` If a password is required, specify it in the `Authorization` header in the basic auth format, where the ID is an empty string. e.g. `"Authorization": "Basic OjEyMw=="` for password `123`. +### Get reserves + +`GET /api/reserves` + +returns: + +```json +{ + "numApps": 4, + "totalAppBalance": 114000, + "numChannels": 1, + "hasPublicChannels": false, + "totalOutgoingCapacity": 4821836, + "totalChannelCapacity": 198000000 +} +``` + +### Get instance info + +> See `.env.example` on how to set this info. + +returns: + +```json +{ + "name": "Uncle Jim Demo Server", + "description": "This demo server shows how easy it is for new users to get a wallet. For demo purposes only - this server has a small amount of liquidity and will not be increased.", + "image": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/ce/Bust_of_Satoshi_Nakamoto_in_Budapest.jpg/440px-Bust_of_Satoshi_Nakamoto_in_Budapest.jpg", + "dailyWalletLimit": 10 +} +``` + +`GET /api/info` + ## Development Copy .env.example to .env.local and update the ALBYHUB_URL and AUTH_TOKEN properties. @@ -68,7 +107,7 @@ You can get the ALBYHUB_URL, AUTH_TOKEN and ALBYHUB_NAME by logging into Alby Hu - [x] podcasting value tag - [x] daily wallet creation rate limit - [x] scan QR -- [ ] get Jim instance info via REST API +- [x] get Jim reserves and instance info via REST API - [ ] daily record of reserves + charts - [ ] per-connection limits (so one user cannot use all the liquidity provided by the service) - [ ] extra open actions (Alby Account, Mobile Wallet, Web Wallet, Nostrudel?, ...) & instructions diff --git a/app/actions.ts b/app/actions.ts index 257cc21..9cc24df 100644 --- a/app/actions.ts +++ b/app/actions.ts @@ -9,6 +9,7 @@ export type Reserves = { totalChannelCapacity: number; numApps: number; totalAppBalance: number; + hasPublicChannels: boolean; }; export type Wallet = { @@ -146,6 +147,7 @@ export async function getReserves(): Promise { localSpendableBalance: number; localBalance: number; remoteBalance: number; + public: boolean; }[]; const relevantApps = apps.filter( @@ -166,6 +168,7 @@ export async function getReserves(): Promise { numApps: relevantApps.length, totalAppBalance, numChannels: channels.length, + hasPublicChannels: channels.some((channel) => channel.public), totalOutgoingCapacity, totalChannelCapacity, }; @@ -175,6 +178,15 @@ export async function getReserves(): Promise { } } +export async function getInfo() { + return { + name: process.env.NAME, + description: process.env.DESCRIPTION, + image: process.env.IMAGE, + dailyWalletLimit: getDailyWalletLimit(), + }; +} + function getHeaders() { return { Authorization: `Bearer ${process.env.AUTH_TOKEN}`, diff --git a/app/api/info/route.ts b/app/api/info/route.ts new file mode 100644 index 0000000..73a1e68 --- /dev/null +++ b/app/api/info/route.ts @@ -0,0 +1,9 @@ +import { getInfo } from "@/app/actions"; + +export const dynamic = "force-dynamic"; + +export async function GET(request: Request) { + const info = await getInfo(); + + return Response.json(info); +} diff --git a/app/api/reserves/route.ts b/app/api/reserves/route.ts new file mode 100644 index 0000000..da12c9d --- /dev/null +++ b/app/api/reserves/route.ts @@ -0,0 +1,9 @@ +import { getReserves } from "@/app/actions"; + +export const dynamic = "force-dynamic"; + +export async function GET(request: Request) { + const reserves = await getReserves(); + + return Response.json(reserves); +}