import { ArrowDownUpIcon, BrickWallIcon, ChevronsUpDownIcon, LucideIcon, MoveDownIcon, SquarePenIcon, } from "lucide-react"; import React from "react"; import { Button } from "src/components/ui/button"; import { Checkbox } from "src/components/ui/checkbox"; import { Label } from "src/components/ui/label"; import { Sheet, SheetClose, SheetContent, SheetFooter, SheetHeader, SheetTitle, } from "src/components/ui/sheet"; import { cn } from "src/lib/utils"; 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]; type ScopeGroupIconMap = { [key in ScopeGroup]: LucideIcon }; const scopeGroupIconMap: ScopeGroupIconMap = { full_access: ArrowDownUpIcon, read_only: MoveDownIcon, isolated: BrickWallIcon, custom: SquarePenIcon, }; const scopeGroupTitle: Record = { full_access: "Full Access", read_only: "Read Only", isolated: "Isolated App", custom: "Custom", }; const scopeGroupDescriptions: Record = { full_access: "Send and receive payments", read_only: "Receive payments and view history", isolated: "Separate wallet with isolated balance", custom: "Define specific permissions", }; interface ScopesProps { capabilities: WalletCapabilities; scopes: Scope[]; isolated: boolean; onScopesChanged: (scopes: Scope[], isolated: boolean) => void; } const Scopes: React.FC = ({ capabilities, scopes, isolated, onScopesChanged, }) => { const [isSheetOpen, setSheetOpen] = React.useState(false); const fullAccessScopes: Scope[] = React.useMemo(() => { return [...capabilities.scopes]; }, [capabilities.scopes]); const readOnlyScopes: Scope[] = React.useMemo(() => { return capabilities.scopes.filter((scope) => READ_ONLY_SCOPES.includes(scope) ); }, [capabilities.scopes]); const isolatedScopes: Scope[] = React.useMemo(() => { const isolatedScopes: Scope[] = [ "pay_invoice", "get_balance", "get_info", "make_invoice", "lookup_invoice", "list_transactions", "notifications", ]; return capabilities.scopes.filter((scope) => isolatedScopes.includes(scope) ); }, [capabilities.scopes]); const [scopeGroup, setScopeGroup] = React.useState(() => { if ( isolated && scopes.length === isolatedScopes.length && scopes.every((scope) => isolatedScopes.includes(scope)) ) { return "isolated"; } if ( scopes.length === fullAccessScopes.length && scopes.every((scope) => fullAccessScopes.includes(scope)) ) { return "full_access"; } if ( scopes.length === readOnlyScopes.length && readOnlyScopes.every((readOnlyScope) => scopes.includes(readOnlyScope)) ) { return "read_only"; } return "custom"; }); const handleScopeGroupChange = (scopeGroup: ScopeGroup) => { setScopeGroup(scopeGroup); switch (scopeGroup) { case "full_access": onScopesChanged(fullAccessScopes, false); break; case "read_only": onScopesChanged(readOnlyScopes, false); break; case "isolated": onScopesChanged(isolatedScopes, true); break; default: { onScopesChanged([], false); break; } } }; const handleScopeChange = (scope: Scope) => { let newScopes = [...scopes]; if (newScopes.includes(scope)) { newScopes = newScopes.filter((existing) => existing !== scope); } else { newScopes.push(scope); } onScopesChanged(newScopes, isolated); }; const ActiveScopeGroupIcon = scopeGroupIconMap[scopeGroup]; return ( <> Choose wallet permissions
{scopeGroups.map((sg, index) => { const ScopeGroupIcon = scopeGroupIconMap[sg]; return ( ); })}
{scopeGroup == "custom" && (

Isolation

onScopesChanged(scopes, !isolated)} checked={isolated} />

Authorize the app to:

    {capabilities.scopes.map((scope, index) => { return (
  • handleScopeChange(scope)} checked={scopes.includes(scope)} />
  • ); })}
)} ); }; export default Scopes;