mirror of
https://github.com/getAlby/hub.git
synced 2026-08-13 12:33:39 +02:00
feat: add readonly option for app store apps
This commit is contained in:
parent
6a15ebadad
commit
d6e417c5f7
4 changed files with 39 additions and 22 deletions
|
|
@ -19,7 +19,12 @@ import {
|
|||
SheetTitle,
|
||||
} from "src/components/ui/sheet";
|
||||
import { cn } from "src/lib/utils";
|
||||
import { Scope, WalletCapabilities, scopeDescriptions } from "src/types";
|
||||
import {
|
||||
READ_ONLY_SCOPES,
|
||||
Scope,
|
||||
WalletCapabilities,
|
||||
scopeDescriptions,
|
||||
} from "src/types";
|
||||
|
||||
const scopeGroups = ["full_access", "read_only", "isolated", "custom"] as const;
|
||||
type ScopeGroup = (typeof scopeGroups)[number];
|
||||
|
|
@ -65,17 +70,8 @@ const Scopes: React.FC<ScopesProps> = ({
|
|||
}, [capabilities.scopes]);
|
||||
|
||||
const readOnlyScopes: Scope[] = React.useMemo(() => {
|
||||
const readOnlyScopes: Scope[] = [
|
||||
"get_balance",
|
||||
"get_info",
|
||||
"make_invoice",
|
||||
"lookup_invoice",
|
||||
"list_transactions",
|
||||
"notifications",
|
||||
];
|
||||
|
||||
return capabilities.scopes.filter((scope) =>
|
||||
readOnlyScopes.includes(scope)
|
||||
READ_ONLY_SCOPES.includes(scope)
|
||||
);
|
||||
}, [capabilities.scopes]);
|
||||
|
||||
|
|
|
|||
|
|
@ -83,6 +83,9 @@ export type AppStoreApp = {
|
|||
hideConnectionQr?: boolean;
|
||||
internal?: boolean;
|
||||
superuser?: boolean;
|
||||
// Receive-only apps (e.g. merchant payment receivers) default to read-only
|
||||
// permissions in the new connection flow.
|
||||
readonly?: boolean;
|
||||
addedDate?: string;
|
||||
};
|
||||
|
||||
|
|
@ -822,6 +825,7 @@ export const appStoreApps: AppStoreApp[] = (
|
|||
},
|
||||
{
|
||||
id: "sat-sorter",
|
||||
readonly: true,
|
||||
title: "Sat Sorter",
|
||||
description: "A Bitcoin Budgeting App",
|
||||
webLink: "https://satsorter.com",
|
||||
|
|
@ -921,6 +925,7 @@ export const appStoreApps: AppStoreApp[] = (
|
|||
},
|
||||
{
|
||||
id: "bitrequest",
|
||||
readonly: true,
|
||||
title: "Bitrequest",
|
||||
description: "Non-custodial payment requests",
|
||||
webLink: "https://www.bitrequest.io",
|
||||
|
|
@ -943,17 +948,6 @@ export const appStoreApps: AppStoreApp[] = (
|
|||
</ExternalLink>{" "}
|
||||
in your browser, or download the app on iOS or Android
|
||||
</p>
|
||||
<p className="text-muted-foreground mt-4">
|
||||
In the next step, set wallet permissions to{" "}
|
||||
<span className="font-medium text-foreground">Custom</span> and
|
||||
enable:
|
||||
</p>
|
||||
<ul className="list-inside list-disc text-muted-foreground mt-1">
|
||||
<li>Read your node info</li>
|
||||
<li>Create invoices</li>
|
||||
<li>Lookup status of invoices</li>
|
||||
<li>Read transaction history</li>
|
||||
</ul>
|
||||
</div>
|
||||
</>
|
||||
),
|
||||
|
|
@ -993,6 +987,7 @@ export const appStoreApps: AppStoreApp[] = (
|
|||
},
|
||||
{
|
||||
id: "btcpay",
|
||||
readonly: true,
|
||||
title: "BTCPay Server",
|
||||
description: "Bitcoin payment processor",
|
||||
webLink: "https://btcpayserver.org/",
|
||||
|
|
@ -1481,6 +1476,7 @@ export const appStoreApps: AppStoreApp[] = (
|
|||
},
|
||||
{
|
||||
id: "clams",
|
||||
readonly: true,
|
||||
title: "Clams",
|
||||
description: "Multi wallet accounting tool",
|
||||
webLink: "https://clams.tech/",
|
||||
|
|
@ -1517,6 +1513,7 @@ export const appStoreApps: AppStoreApp[] = (
|
|||
},
|
||||
{
|
||||
id: "nostrcheck-server",
|
||||
readonly: true,
|
||||
title: "Nostrcheck Server",
|
||||
description: "Sovereign Nostr services",
|
||||
webLink: "https://github.com/quentintaranpino/nostrcheck-server",
|
||||
|
|
@ -1824,6 +1821,7 @@ export const appStoreApps: AppStoreApp[] = (
|
|||
},
|
||||
{
|
||||
id: "nakapay",
|
||||
readonly: true,
|
||||
title: "NakaPay",
|
||||
description: "Non-custodial Lightning payments for businesses via NWC",
|
||||
webLink: "https://www.nakapay.app",
|
||||
|
|
@ -2334,6 +2332,7 @@ export const appStoreApps: AppStoreApp[] = (
|
|||
},
|
||||
{
|
||||
id: "takemysats",
|
||||
readonly: true,
|
||||
title: "Take My Sats",
|
||||
description: "Create your online store and accept Bitcoin payments",
|
||||
webLink: "https://www.takemysats.com",
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import {
|
|||
CreateAppResponse,
|
||||
Nip47NotificationType,
|
||||
Nip47RequestMethod,
|
||||
READ_ONLY_SCOPES,
|
||||
Scope,
|
||||
WalletCapabilities,
|
||||
validBudgetRenewals,
|
||||
|
|
@ -105,6 +106,14 @@ const NewAppInternal = ({ capabilities }: NewAppInternalProps) => {
|
|||
|
||||
/* eslint-disable react-hooks/preserve-manual-memoization */
|
||||
const initialScopes: Scope[] = React.useMemo(() => {
|
||||
// Receive-only app store apps (e.g. merchant payment receivers) default to
|
||||
// read-only permissions, unless the deep link explicitly requests methods.
|
||||
if (appStoreApp?.readonly && !reqMethodsParam) {
|
||||
return capabilities.scopes.filter((scope) =>
|
||||
READ_ONLY_SCOPES.includes(scope)
|
||||
);
|
||||
}
|
||||
|
||||
const methods = reqMethodsParam
|
||||
? reqMethodsParam.split(" ")
|
||||
: capabilities.methods;
|
||||
|
|
@ -185,8 +194,10 @@ const NewAppInternal = ({ capabilities }: NewAppInternalProps) => {
|
|||
|
||||
return scopes;
|
||||
}, [
|
||||
appStoreApp?.readonly,
|
||||
capabilities.methods,
|
||||
capabilities.notificationTypes,
|
||||
capabilities.scopes,
|
||||
isolatedParam,
|
||||
notificationTypesParam,
|
||||
reqMethodsParam,
|
||||
|
|
|
|||
|
|
@ -80,6 +80,17 @@ export const validBudgetRenewals: BudgetRenewalType[] = [
|
|||
"never",
|
||||
];
|
||||
|
||||
// Scopes granted to a read-only connection: receive payments and view
|
||||
// balance/history, but never send/spend.
|
||||
export const READ_ONLY_SCOPES: Scope[] = [
|
||||
"get_balance",
|
||||
"get_info",
|
||||
"make_invoice",
|
||||
"lookup_invoice",
|
||||
"list_transactions",
|
||||
"notifications",
|
||||
];
|
||||
|
||||
export const scopeDescriptions: Record<Scope, string> = {
|
||||
get_balance: "Read your balance",
|
||||
get_info: "Read your node info",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue