Skip to content

Commit

Permalink
feat(node): add ability to remove settlement schemes
Browse files Browse the repository at this point in the history
  • Loading branch information
justmoon committed Oct 4, 2024
1 parent 49c95e6 commit 6a08459
Show file tree
Hide file tree
Showing 10 changed files with 334 additions and 30 deletions.
14 changes: 0 additions & 14 deletions packages/app-dassie/src/config/rpc-routers/config-admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import { createRouter } from "@dassie/lib-rpc/server"
import { SetupUrlSignal } from "../../authentication/computed/setup-url"
import { VALID_REALMS } from "../../constants/general"
import { NodeIdSignal } from "../../ilp-connector/computed/node-id"
import { SettlementSchemesStore } from "../../ledgers/database-stores/settlement-schemes"
import type { SettlementSchemeId } from "../../peer-protocol/types/settlement-scheme-id"
import { protectedRoute } from "../../rpc-server/route-types/protected"
import { HasTlsSignal } from "../computed/has-tls"
import { DatabaseConfigStore } from "../database-config"
Expand Down Expand Up @@ -66,16 +64,4 @@ export const configAdminRouter = createRouter({
config.act.setHostname(hostname)
return true
}),
addSettlementScheme: protectedRoute
.input(
z.object({
id: z.string().transform((id) => id as SettlementSchemeId),
config: z.object({}),
}),
)
.mutation(({ context: { sig }, input: { id, config } }) => {
sig.reactor
.use(SettlementSchemesStore)
.act.addSettlementScheme(id, config)
}),
})
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,15 @@ export const SettlementSchemesStore = (reactor: Reactor) => {
config: JSON.stringify(config),
})
}),
removeSettlementScheme: (settlementSchemeId: SettlementSchemeId) =>
produce((draft) => {
const index = draft.findIndex(
(settlementScheme) => settlementScheme.id === settlementSchemeId,
)
if (index !== -1) {
draft.splice(1)
}
database.tables.settlementSchemes.delete({ id: settlementSchemeId })
}),
})
}
50 changes: 50 additions & 0 deletions packages/app-dassie/src/ledgers/rpc-routers/ledgers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { z } from "zod"

import { createRouter } from "@dassie/lib-rpc/server"

import { PeersSignal } from "../../peer-protocol/computed/peers"
import { NodeTableStore } from "../../peer-protocol/stores/node-table"
import type { SettlementSchemeId } from "../../peer-protocol/types/settlement-scheme-id"
import { protectedRoute } from "../../rpc-server/route-types/protected"
import { SettlementSchemesStore } from "../database-stores/settlement-schemes"
Expand All @@ -26,6 +28,54 @@ export const ledgersRouter = createRouter({
}),
)
}),
checkLedgerDeletePrerequisites: protectedRoute
.input(z.string())
.query(({ input: ledgerId, context: { sig } }) => {
const manageSettlementSchemeInstancesActor = sig.reactor.use(
ManageSettlementSchemeInstancesActor,
)

const settlementActor = manageSettlementSchemeInstancesActor.get(
ledgerId as SettlementSchemeId,
)

const peers = sig.read(PeersSignal)
const nodeTable = sig.reactor.use(NodeTableStore)

const isUnused = ![...peers]
.map((peerId) => nodeTable.read().get(peerId)?.peerState)
.some(
(peerInfo) =>
peerInfo?.id === "peered" &&
peerInfo.settlementSchemeId === ledgerId,
)

return {
isActive: !!settlementActor,
isUnused,
}
}),
addSettlementScheme: protectedRoute
.input(
z.object({
id: z.string().transform((id) => id as SettlementSchemeId),
config: z.object({}),
}),
)
.mutation(({ context: { sig }, input: { id, config } }) => {
sig.reactor
.use(SettlementSchemesStore)
.act.addSettlementScheme(id, config)
}),
removeSettlementScheme: protectedRoute
.input(
z.object({
id: z.string().transform((id) => id as SettlementSchemeId),
}),
)
.mutation(({ context: { sig }, input: { id } }) => {
sig.reactor.use(SettlementSchemesStore).act.removeSettlementScheme(id)
}),
stubDeposit: protectedRoute
.input(z.string())
.mutation(async ({ input: amount, context: { sig } }) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { enableMapSet, produce } from "immer"

import {
type InferActionHandlers,
type Reactor,
createComputed,
watchStoreChanges,
} from "@dassie/lib-reactive"

import type { SettlementSchemeId } from "../../peer-protocol/types/settlement-scheme-id"
Expand All @@ -21,17 +21,19 @@ export const ActiveSettlementSchemesSignal = (reactor: Reactor) =>
activeSettlementSchemes.add(settlementScheme.id)
}

settlementSchemes.changes.on(reactor, ([actionId, parameters]) => {
const handlers: InferActionHandlers<typeof settlementSchemes> = {
addSettlementScheme: (settlementSchemeId) => {
const newSet = produce(activeSettlementSchemes, (draft) => {
draft.add(settlementSchemeId)
})
reactor.use(ActiveSettlementSchemesSignal).write(newSet)
},
}

handlers[actionId](...parameters)
watchStoreChanges(reactor, settlementSchemes, {
addSettlementScheme: (settlementSchemeId) => {
const newSet = produce(activeSettlementSchemes, (draft) => {
draft.add(settlementSchemeId)
})
reactor.use(ActiveSettlementSchemesSignal).write(newSet)
},
removeSettlementScheme: (settlementSchemeId) => {
const newSet = produce(activeSettlementSchemes, (draft) => {
draft.delete(settlementSchemeId)
})
reactor.use(ActiveSettlementSchemesSignal).write(newSet)
},
})

return activeSettlementSchemes
Expand Down
2 changes: 2 additions & 0 deletions packages/gui-dassie/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { MainNavigation } from "./layout/main-navigation/main-navigation"
import { Account } from "./pages/account/account"
import { DebugPage } from "./pages/debug/debug"
import { CreateLedgerAccount } from "./pages/ledgers/create-ledger-account/create-ledger-account"
import { DeleteLedgerAccountPage } from "./pages/ledgers/delete-ledger-account/delete-ledger-account-page"
import { LedgersPage } from "./pages/ledgers/ledgers"
import { LoginPage } from "./pages/login/login"
import { PaymentStatus } from "./pages/payment-status/payment-status"
Expand Down Expand Up @@ -42,6 +43,7 @@ const App = () => {
<Switch>
<Route path="/ledgers" component={LedgersPage} />
<Route path="/ledgers/create" component={CreateLedgerAccount} />
<Route path="/ledgers/delete/:id" component={DeleteLedgerAccountPage} />
<Route path="/send" component={Send} />
<Route path="/receive" component={ReceivePage} />
<Route path="/payments/:paymentId" component={PaymentStatus} />
Expand Down
52 changes: 52 additions & 0 deletions packages/gui-dassie/src/components/ui-custom/checklist.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import {
CircleAlertIcon,
CircleCheckIcon,
CircleHelpIcon,
type LucideIcon,
} from "lucide-react"
import type { ComponentPropsWithoutRef } from "react"

import { combine, extend } from "../../utils/class-helper"

export type ChecklistItemVariant = "valid" | "invalid" | "unknown"

export interface ChecklistItemProperties
extends ComponentPropsWithoutRef<"li"> {
variant: ChecklistItemVariant
}

const ICONS: Record<ChecklistItemVariant, LucideIcon> = {
valid: CircleCheckIcon,
invalid: CircleAlertIcon,
unknown: CircleHelpIcon,
}

export function ChecklistItem({
variant,
children,
className,
...remainingProperties
}: ChecklistItemProperties) {
const Icon = ICONS[variant]

return (
<li
className={combine("flex flex-row gap-2 items-center", className)}
{...remainingProperties}
>
<Icon
className={combine(
"size-4",
{
valid: "text-green-500",
invalid: "text-red-500",
unknown: "text-slate-400",
}[variant],
)}
/>
{children}
</li>
)
}

export const Checklist = extend("Checklist", "ul", "flex flex-col gap-3 py-4")
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ArrowRight, CircleSlash, TestTube2Icon } from "lucide-react"
import { useCallback } from "react"
import { useLocation } from "wouter"

import type { SettlementSchemeId } from "@dassie/app-dassie/src/peer-protocol/types/settlement-scheme-id"

Expand All @@ -18,9 +19,10 @@ import {
import { rpc } from "../../../utils/rpc"

export const CreateLedgerAccount = () => {
const addSettlementScheme = rpc.config.addSettlementScheme.useMutation({
const [, navigate] = useLocation()
const addSettlementScheme = rpc.ledgers.addSettlementScheme.useMutation({
onSuccess: () => {
window.location.reload()
navigate("/ledgers")
},
})

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Redirect } from "wouter"

import type { SettlementSchemeId } from "@dassie/app-dassie/src/peer-protocol/types/settlement-scheme-id"

import { rpc } from "../../../utils/rpc"
import { DeleteLedgerAccount } from "./delete-ledger-account"

interface DeleteLedgerAccountProperties {
params: { id: string }
}

export function DeleteLedgerAccountPage({
params: { id },
}: DeleteLedgerAccountProperties) {
const { data: basicState } = rpc.general.getBasicState.useQuery()

if (!basicState) return <div>Loading...</div>

if (
!basicState.activeSettlementSchemes?.find((activeId) => activeId === id)
) {
return <Redirect to="/ledgers" />
}

return <DeleteLedgerAccount id={id as SettlementSchemeId} />
}
Loading

0 comments on commit 6a08459

Please sign in to comment.