From 9396d96344c8c2ec87feeed4ccb73219119fcd07 Mon Sep 17 00:00:00 2001 From: Furkan Bilgin Date: Mon, 2 Sep 2024 18:17:34 +0300 Subject: [PATCH 1/9] refactor(backend): fetch incoming tokens in getPeer --- .../generated/graphql.ts | 3 +++ .../src/graphql/generated/graphql.schema.json | 20 +++++++++++++++++++ .../backend/src/graphql/generated/graphql.ts | 3 +++ .../backend/src/graphql/resolvers/peer.ts | 1 + packages/backend/src/graphql/schema.graphql | 2 ++ .../src/payment-method/ilp/peer/service.ts | 2 +- packages/frontend/app/generated/graphql.ts | 5 ++++- packages/frontend/app/lib/api/peer.server.ts | 1 + .../src/generated/graphql.ts | 3 +++ test/integration/lib/generated/graphql.ts | 3 +++ 10 files changed, 41 insertions(+), 2 deletions(-) diff --git a/localenv/mock-account-servicing-entity/generated/graphql.ts b/localenv/mock-account-servicing-entity/generated/graphql.ts index d5b26bbf7e..0fce5f156e 100644 --- a/localenv/mock-account-servicing-entity/generated/graphql.ts +++ b/localenv/mock-account-servicing-entity/generated/graphql.ts @@ -998,6 +998,8 @@ export type Peer = Model & { http: Http; /** Peer id */ id: Scalars['ID']['output']; + /** Incoming tokens */ + incomingTokens?: Maybe>; /** Available liquidity */ liquidity?: Maybe; /** Account Servicing Entity will be notified via a webhook event if peer liquidity falls below this value */ @@ -2130,6 +2132,7 @@ export type PeerResolvers; http?: Resolver; id?: Resolver; + incomingTokens?: Resolver>, ParentType, ContextType>; liquidity?: Resolver, ParentType, ContextType>; liquidityThreshold?: Resolver, ParentType, ContextType>; maxPacketAmount?: Resolver, ParentType, ContextType>; diff --git a/packages/backend/src/graphql/generated/graphql.schema.json b/packages/backend/src/graphql/generated/graphql.schema.json index a43aafe99d..2f3fbb840c 100644 --- a/packages/backend/src/graphql/generated/graphql.schema.json +++ b/packages/backend/src/graphql/generated/graphql.schema.json @@ -5890,6 +5890,26 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "incomingTokens", + "description": "Incoming tokens", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "liquidity", "description": "Available liquidity", diff --git a/packages/backend/src/graphql/generated/graphql.ts b/packages/backend/src/graphql/generated/graphql.ts index d5b26bbf7e..0fce5f156e 100644 --- a/packages/backend/src/graphql/generated/graphql.ts +++ b/packages/backend/src/graphql/generated/graphql.ts @@ -998,6 +998,8 @@ export type Peer = Model & { http: Http; /** Peer id */ id: Scalars['ID']['output']; + /** Incoming tokens */ + incomingTokens?: Maybe>; /** Available liquidity */ liquidity?: Maybe; /** Account Servicing Entity will be notified via a webhook event if peer liquidity falls below this value */ @@ -2130,6 +2132,7 @@ export type PeerResolvers; http?: Resolver; id?: Resolver; + incomingTokens?: Resolver>, ParentType, ContextType>; liquidity?: Resolver, ParentType, ContextType>; liquidityThreshold?: Resolver, ParentType, ContextType>; maxPacketAmount?: Resolver, ParentType, ContextType>; diff --git a/packages/backend/src/graphql/resolvers/peer.ts b/packages/backend/src/graphql/resolvers/peer.ts index b2296b7a89..247dd21c01 100644 --- a/packages/backend/src/graphql/resolvers/peer.ts +++ b/packages/backend/src/graphql/resolvers/peer.ts @@ -122,6 +122,7 @@ export const peerToGraphql = (peer: Peer): SchemaPeer => ({ id: peer.id, maxPacketAmount: peer.maxPacketAmount, http: peer.http, + incomingTokens: peer.incomingTokens?.map(incomingToken => incomingToken.token), asset: assetToGraphql(peer.asset), staticIlpAddress: peer.staticIlpAddress, name: peer.name, diff --git a/packages/backend/src/graphql/schema.graphql b/packages/backend/src/graphql/schema.graphql index cc7309c3d5..e46b85c0f7 100644 --- a/packages/backend/src/graphql/schema.graphql +++ b/packages/backend/src/graphql/schema.graphql @@ -619,6 +619,8 @@ type Peer implements Model { maxPacketAmount: UInt64 "Peering connection details" http: Http! + "Incoming tokens" + incomingTokens: [String!] "Asset of peering relationship" asset: Asset! "Peer's ILP address" diff --git a/packages/backend/src/payment-method/ilp/peer/service.ts b/packages/backend/src/payment-method/ilp/peer/service.ts index be64dcc520..c87e844557 100644 --- a/packages/backend/src/payment-method/ilp/peer/service.ts +++ b/packages/backend/src/payment-method/ilp/peer/service.ts @@ -114,7 +114,7 @@ async function getPeer( deps: ServiceDependencies, id: string ): Promise { - return Peer.query(deps.knex).findById(id).withGraphFetched('asset') + return Peer.query(deps.knex).findById(id).withGraphFetched('asset').withGraphFetched('incomingTokens') } async function createPeer( diff --git a/packages/frontend/app/generated/graphql.ts b/packages/frontend/app/generated/graphql.ts index bc7e5fabb1..ed4b20b590 100644 --- a/packages/frontend/app/generated/graphql.ts +++ b/packages/frontend/app/generated/graphql.ts @@ -998,6 +998,8 @@ export type Peer = Model & { http: Http; /** Peer id */ id: Scalars['ID']['output']; + /** Incoming tokens */ + incomingTokens?: Maybe>; /** Available liquidity */ liquidity?: Maybe; /** Account Servicing Entity will be notified via a webhook event if peer liquidity falls below this value */ @@ -2130,6 +2132,7 @@ export type PeerResolvers; http?: Resolver; id?: Resolver; + incomingTokens?: Resolver>, ParentType, ContextType>; liquidity?: Resolver, ParentType, ContextType>; liquidityThreshold?: Resolver, ParentType, ContextType>; maxPacketAmount?: Resolver, ParentType, ContextType>; @@ -2515,7 +2518,7 @@ export type GetPeerQueryVariables = Exact<{ }>; -export type GetPeerQuery = { __typename?: 'Query', peer?: { __typename?: 'Peer', id: string, name?: string | null, staticIlpAddress: string, maxPacketAmount?: bigint | null, liquidity?: bigint | null, createdAt: string, asset: { __typename?: 'Asset', id: string, code: string, scale: number, withdrawalThreshold?: bigint | null }, http: { __typename?: 'Http', outgoing: { __typename?: 'HttpOutgoing', endpoint: string, authToken: string } } } | null }; +export type GetPeerQuery = { __typename?: 'Query', peer?: { __typename?: 'Peer', id: string, name?: string | null, staticIlpAddress: string, maxPacketAmount?: bigint | null, liquidity?: bigint | null, createdAt: string, incomingTokens?: Array | null, asset: { __typename?: 'Asset', id: string, code: string, scale: number, withdrawalThreshold?: bigint | null }, http: { __typename?: 'Http', outgoing: { __typename?: 'HttpOutgoing', endpoint: string, authToken: string } } } | null }; export type ListPeersQueryVariables = Exact<{ after?: InputMaybe; diff --git a/packages/frontend/app/lib/api/peer.server.ts b/packages/frontend/app/lib/api/peer.server.ts index fd064ed0c5..b6a3d8d549 100644 --- a/packages/frontend/app/lib/api/peer.server.ts +++ b/packages/frontend/app/lib/api/peer.server.ts @@ -50,6 +50,7 @@ export const getPeer = async (args: QueryPeerArgs) => { authToken } } + incomingTokens } } `, diff --git a/packages/mock-account-service-lib/src/generated/graphql.ts b/packages/mock-account-service-lib/src/generated/graphql.ts index d5b26bbf7e..0fce5f156e 100644 --- a/packages/mock-account-service-lib/src/generated/graphql.ts +++ b/packages/mock-account-service-lib/src/generated/graphql.ts @@ -998,6 +998,8 @@ export type Peer = Model & { http: Http; /** Peer id */ id: Scalars['ID']['output']; + /** Incoming tokens */ + incomingTokens?: Maybe>; /** Available liquidity */ liquidity?: Maybe; /** Account Servicing Entity will be notified via a webhook event if peer liquidity falls below this value */ @@ -2130,6 +2132,7 @@ export type PeerResolvers; http?: Resolver; id?: Resolver; + incomingTokens?: Resolver>, ParentType, ContextType>; liquidity?: Resolver, ParentType, ContextType>; liquidityThreshold?: Resolver, ParentType, ContextType>; maxPacketAmount?: Resolver, ParentType, ContextType>; diff --git a/test/integration/lib/generated/graphql.ts b/test/integration/lib/generated/graphql.ts index d5b26bbf7e..0fce5f156e 100644 --- a/test/integration/lib/generated/graphql.ts +++ b/test/integration/lib/generated/graphql.ts @@ -998,6 +998,8 @@ export type Peer = Model & { http: Http; /** Peer id */ id: Scalars['ID']['output']; + /** Incoming tokens */ + incomingTokens?: Maybe>; /** Available liquidity */ liquidity?: Maybe; /** Account Servicing Entity will be notified via a webhook event if peer liquidity falls below this value */ @@ -2130,6 +2132,7 @@ export type PeerResolvers; http?: Resolver; id?: Resolver; + incomingTokens?: Resolver>, ParentType, ContextType>; liquidity?: Resolver, ParentType, ContextType>; liquidityThreshold?: Resolver, ParentType, ContextType>; maxPacketAmount?: Resolver, ParentType, ContextType>; From 8dc334b823c40cf962507e508fc211286d56926a Mon Sep 17 00:00:00 2001 From: Furkan Bilgin Date: Mon, 2 Sep 2024 20:16:28 +0300 Subject: [PATCH 2/9] chore(backend): format --- packages/backend/src/graphql/resolvers/peer.ts | 4 +++- packages/backend/src/payment-method/ilp/peer/service.ts | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/graphql/resolvers/peer.ts b/packages/backend/src/graphql/resolvers/peer.ts index 247dd21c01..d492026649 100644 --- a/packages/backend/src/graphql/resolvers/peer.ts +++ b/packages/backend/src/graphql/resolvers/peer.ts @@ -122,7 +122,9 @@ export const peerToGraphql = (peer: Peer): SchemaPeer => ({ id: peer.id, maxPacketAmount: peer.maxPacketAmount, http: peer.http, - incomingTokens: peer.incomingTokens?.map(incomingToken => incomingToken.token), + incomingTokens: peer.incomingTokens?.map( + (incomingToken) => incomingToken.token + ), asset: assetToGraphql(peer.asset), staticIlpAddress: peer.staticIlpAddress, name: peer.name, diff --git a/packages/backend/src/payment-method/ilp/peer/service.ts b/packages/backend/src/payment-method/ilp/peer/service.ts index c87e844557..04ecc26283 100644 --- a/packages/backend/src/payment-method/ilp/peer/service.ts +++ b/packages/backend/src/payment-method/ilp/peer/service.ts @@ -114,7 +114,10 @@ async function getPeer( deps: ServiceDependencies, id: string ): Promise { - return Peer.query(deps.knex).findById(id).withGraphFetched('asset').withGraphFetched('incomingTokens') + return Peer.query(deps.knex) + .findById(id) + .withGraphFetched('asset') + .withGraphFetched('incomingTokens') } async function createPeer( From 5aab13808e1c098525490a79e76872a82d79328c Mon Sep 17 00:00:00 2001 From: Furkan Bilgin Date: Tue, 3 Sep 2024 00:16:28 +0300 Subject: [PATCH 3/9] feat(frontend): allow editing of multiple incoming auth tokens with `EditableTable` --- .../app/components/ui/EditableTable.tsx | 154 ++++++++++++++++++ .../frontend/app/routes/peers.$peerId.tsx | 11 +- 2 files changed, 162 insertions(+), 3 deletions(-) create mode 100644 packages/frontend/app/components/ui/EditableTable.tsx diff --git a/packages/frontend/app/components/ui/EditableTable.tsx b/packages/frontend/app/components/ui/EditableTable.tsx new file mode 100644 index 0000000000..1e236da4fe --- /dev/null +++ b/packages/frontend/app/components/ui/EditableTable.tsx @@ -0,0 +1,154 @@ +import type { ReactNode } from 'react' +import { useEffect, useState } from 'react' +import { Input } from './Input' +import { Table } from './Table' +import { FieldError } from './FieldError' +import { Button } from './Button' + +type EditableTableProps = { + name: string + label: string + options: EditableTableOption[] + error?: string | string[] + description?: ReactNode + valueFormatter?: (values: string[]) => string + required?: boolean +} + +type EditableTableOption = { + label: string + value: string + canDelete?: boolean + canEdit?: boolean + showInput?: boolean +} + +export const EditableTable = ({ + name, + label, + options, + error, + description = undefined, + valueFormatter = (values) => values.join(','), + required = false +}: EditableTableProps) => { + const [optionsList, setOptionsList] = useState(options) + const [value, setValue] = useState('') + + const toggleEditInput = (index: number) => { + setOptionsList( + optionsList.map((option, i) => { + if (i === index) { + return { + ...option, + showInput: true + } + } + return option + }) + ) + } + + const editOption = (index: number, value: string) => { + if (!value) { + deleteOption(index) + return + } + setOptionsList( + optionsList.map((option, i) => { + if (i === index) { + return { + ...option, + showInput: false, + value + } + } + return option + }) + ) + } + + const deleteOption = (index: number) => { + setOptionsList(optionsList.filter((_, i) => i !== index)) + } + + const addOption = () => { + setOptionsList([ + ...optionsList, + { label: '', value: '', canDelete: true, canEdit: true, showInput: true } + ]) + } + + useEffect(() => { + setValue(getValue()) + }, [optionsList]) + + const getValue = () => { + return valueFormatter(optionsList.map((option) => option.value)) + } + + return ( + <> + + + + + {(optionsList || []).map((option, index) => ( + + + {option.showInput ? ( + + e.key === 'Enter' && + (e.preventDefault(), + editOption(index, e.currentTarget.value)) + } + defaultValue={option.value} + required={required} + /> + ) : ( + {option.value} + )} + + + {option.canEdit && !option.showInput ? ( + + ) : null} + {option.canDelete ? ( + + ) : null} + + + ))} + +
+
+ +
+ {description ? ( +
{description}
+ ) : null} + + + ) +} diff --git a/packages/frontend/app/routes/peers.$peerId.tsx b/packages/frontend/app/routes/peers.$peerId.tsx index 20885c65e9..1aff0aeeec 100644 --- a/packages/frontend/app/routes/peers.$peerId.tsx +++ b/packages/frontend/app/routes/peers.$peerId.tsx @@ -30,6 +30,7 @@ import { import type { ZodFieldErrors } from '~/shared/types' import { formatAmount } from '~/shared/utils' import { checkAuthAndRedirect } from '../lib/kratos_checks.server' +import { EditableTable } from '~/components/ui/EditableTable' export async function loader({ request, params }: LoaderFunctionArgs) { const cookies = request.headers.get('cookie') @@ -204,10 +205,15 @@ export default function ViewPeerPage() {
- ({ + label: token, + value: token, + canDelete: true, + canEdit: true + }))} error={response?.errors.http.fieldErrors.incomingAuthTokens} description={ <> @@ -435,7 +441,6 @@ export async function action({ request }: ActionFunctionArgs) { result.error.flatten().fieldErrors return json({ ...actionResponse }, { status: 400 }) } - const response = await updatePeer({ id: result.data.id, http: { From 0a1bdbfae4538684d600f5a63c3844ca260c44ec Mon Sep 17 00:00:00 2001 From: Furkan Bilgin Date: Tue, 3 Sep 2024 00:19:45 +0300 Subject: [PATCH 4/9] fix(frontend): fixed button labels in `EditableTable` --- packages/frontend/app/components/ui/EditableTable.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/frontend/app/components/ui/EditableTable.tsx b/packages/frontend/app/components/ui/EditableTable.tsx index 1e236da4fe..7f5768a004 100644 --- a/packages/frontend/app/components/ui/EditableTable.tsx +++ b/packages/frontend/app/components/ui/EditableTable.tsx @@ -120,7 +120,7 @@ export const EditableTable = ({ {option.canEdit && !option.showInput ? (
From f75bf308cc7d3a680c6b62b596c76cea2e8ebc80 Mon Sep 17 00:00:00 2001 From: Furkan Bilgin Date: Wed, 18 Sep 2024 18:05:17 +0300 Subject: [PATCH 5/9] refactor(backend): require incomingTokens in Peer model Co-authored-by: Max Kurapov --- packages/backend/src/graphql/schema.graphql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/graphql/schema.graphql b/packages/backend/src/graphql/schema.graphql index e46b85c0f7..5de35ef09c 100644 --- a/packages/backend/src/graphql/schema.graphql +++ b/packages/backend/src/graphql/schema.graphql @@ -620,7 +620,7 @@ type Peer implements Model { "Peering connection details" http: Http! "Incoming tokens" - incomingTokens: [String!] + incomingTokens: [String!]! "Asset of peering relationship" asset: Asset! "Peer's ILP address" From 2405bd3198eab69673cff7240c1f54c06dc86713 Mon Sep 17 00:00:00 2001 From: Furkan Bilgin Date: Wed, 18 Sep 2024 18:06:29 +0300 Subject: [PATCH 6/9] chore(backend): generate graphql schemas --- .../generated/graphql.ts | 4 ++-- .../src/graphql/generated/graphql.schema.json | 14 +++++++++----- packages/backend/src/graphql/generated/graphql.ts | 4 ++-- packages/frontend/app/generated/graphql.ts | 6 +++--- .../src/generated/graphql.ts | 4 ++-- test/integration/lib/generated/graphql.ts | 4 ++-- 6 files changed, 20 insertions(+), 16 deletions(-) diff --git a/localenv/mock-account-servicing-entity/generated/graphql.ts b/localenv/mock-account-servicing-entity/generated/graphql.ts index 0fce5f156e..2dc0e4bfb2 100644 --- a/localenv/mock-account-servicing-entity/generated/graphql.ts +++ b/localenv/mock-account-servicing-entity/generated/graphql.ts @@ -999,7 +999,7 @@ export type Peer = Model & { /** Peer id */ id: Scalars['ID']['output']; /** Incoming tokens */ - incomingTokens?: Maybe>; + incomingTokens: Array; /** Available liquidity */ liquidity?: Maybe; /** Account Servicing Entity will be notified via a webhook event if peer liquidity falls below this value */ @@ -2132,7 +2132,7 @@ export type PeerResolvers; http?: Resolver; id?: Resolver; - incomingTokens?: Resolver>, ParentType, ContextType>; + incomingTokens?: Resolver, ParentType, ContextType>; liquidity?: Resolver, ParentType, ContextType>; liquidityThreshold?: Resolver, ParentType, ContextType>; maxPacketAmount?: Resolver, ParentType, ContextType>; diff --git a/packages/backend/src/graphql/generated/graphql.schema.json b/packages/backend/src/graphql/generated/graphql.schema.json index 2f3fbb840c..ca49efbe3f 100644 --- a/packages/backend/src/graphql/generated/graphql.schema.json +++ b/packages/backend/src/graphql/generated/graphql.schema.json @@ -5895,15 +5895,19 @@ "description": "Incoming tokens", "args": [], "type": { - "kind": "LIST", + "kind": "NON_NULL", "name": null, "ofType": { - "kind": "NON_NULL", + "kind": "LIST", "name": null, "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } } } }, diff --git a/packages/backend/src/graphql/generated/graphql.ts b/packages/backend/src/graphql/generated/graphql.ts index 0fce5f156e..2dc0e4bfb2 100644 --- a/packages/backend/src/graphql/generated/graphql.ts +++ b/packages/backend/src/graphql/generated/graphql.ts @@ -999,7 +999,7 @@ export type Peer = Model & { /** Peer id */ id: Scalars['ID']['output']; /** Incoming tokens */ - incomingTokens?: Maybe>; + incomingTokens: Array; /** Available liquidity */ liquidity?: Maybe; /** Account Servicing Entity will be notified via a webhook event if peer liquidity falls below this value */ @@ -2132,7 +2132,7 @@ export type PeerResolvers; http?: Resolver; id?: Resolver; - incomingTokens?: Resolver>, ParentType, ContextType>; + incomingTokens?: Resolver, ParentType, ContextType>; liquidity?: Resolver, ParentType, ContextType>; liquidityThreshold?: Resolver, ParentType, ContextType>; maxPacketAmount?: Resolver, ParentType, ContextType>; diff --git a/packages/frontend/app/generated/graphql.ts b/packages/frontend/app/generated/graphql.ts index ed4b20b590..9efa296887 100644 --- a/packages/frontend/app/generated/graphql.ts +++ b/packages/frontend/app/generated/graphql.ts @@ -999,7 +999,7 @@ export type Peer = Model & { /** Peer id */ id: Scalars['ID']['output']; /** Incoming tokens */ - incomingTokens?: Maybe>; + incomingTokens: Array; /** Available liquidity */ liquidity?: Maybe; /** Account Servicing Entity will be notified via a webhook event if peer liquidity falls below this value */ @@ -2132,7 +2132,7 @@ export type PeerResolvers; http?: Resolver; id?: Resolver; - incomingTokens?: Resolver>, ParentType, ContextType>; + incomingTokens?: Resolver, ParentType, ContextType>; liquidity?: Resolver, ParentType, ContextType>; liquidityThreshold?: Resolver, ParentType, ContextType>; maxPacketAmount?: Resolver, ParentType, ContextType>; @@ -2518,7 +2518,7 @@ export type GetPeerQueryVariables = Exact<{ }>; -export type GetPeerQuery = { __typename?: 'Query', peer?: { __typename?: 'Peer', id: string, name?: string | null, staticIlpAddress: string, maxPacketAmount?: bigint | null, liquidity?: bigint | null, createdAt: string, incomingTokens?: Array | null, asset: { __typename?: 'Asset', id: string, code: string, scale: number, withdrawalThreshold?: bigint | null }, http: { __typename?: 'Http', outgoing: { __typename?: 'HttpOutgoing', endpoint: string, authToken: string } } } | null }; +export type GetPeerQuery = { __typename?: 'Query', peer?: { __typename?: 'Peer', id: string, name?: string | null, staticIlpAddress: string, maxPacketAmount?: bigint | null, liquidity?: bigint | null, createdAt: string, incomingTokens: Array, asset: { __typename?: 'Asset', id: string, code: string, scale: number, withdrawalThreshold?: bigint | null }, http: { __typename?: 'Http', outgoing: { __typename?: 'HttpOutgoing', endpoint: string, authToken: string } } } | null }; export type ListPeersQueryVariables = Exact<{ after?: InputMaybe; diff --git a/packages/mock-account-service-lib/src/generated/graphql.ts b/packages/mock-account-service-lib/src/generated/graphql.ts index 0fce5f156e..2dc0e4bfb2 100644 --- a/packages/mock-account-service-lib/src/generated/graphql.ts +++ b/packages/mock-account-service-lib/src/generated/graphql.ts @@ -999,7 +999,7 @@ export type Peer = Model & { /** Peer id */ id: Scalars['ID']['output']; /** Incoming tokens */ - incomingTokens?: Maybe>; + incomingTokens: Array; /** Available liquidity */ liquidity?: Maybe; /** Account Servicing Entity will be notified via a webhook event if peer liquidity falls below this value */ @@ -2132,7 +2132,7 @@ export type PeerResolvers; http?: Resolver; id?: Resolver; - incomingTokens?: Resolver>, ParentType, ContextType>; + incomingTokens?: Resolver, ParentType, ContextType>; liquidity?: Resolver, ParentType, ContextType>; liquidityThreshold?: Resolver, ParentType, ContextType>; maxPacketAmount?: Resolver, ParentType, ContextType>; diff --git a/test/integration/lib/generated/graphql.ts b/test/integration/lib/generated/graphql.ts index 0fce5f156e..2dc0e4bfb2 100644 --- a/test/integration/lib/generated/graphql.ts +++ b/test/integration/lib/generated/graphql.ts @@ -999,7 +999,7 @@ export type Peer = Model & { /** Peer id */ id: Scalars['ID']['output']; /** Incoming tokens */ - incomingTokens?: Maybe>; + incomingTokens: Array; /** Available liquidity */ liquidity?: Maybe; /** Account Servicing Entity will be notified via a webhook event if peer liquidity falls below this value */ @@ -2132,7 +2132,7 @@ export type PeerResolvers; http?: Resolver; id?: Resolver; - incomingTokens?: Resolver>, ParentType, ContextType>; + incomingTokens?: Resolver, ParentType, ContextType>; liquidity?: Resolver, ParentType, ContextType>; liquidityThreshold?: Resolver, ParentType, ContextType>; maxPacketAmount?: Resolver, ParentType, ContextType>; From ab51f513ce65267c7e01c67e643c6f2a57f9a07f Mon Sep 17 00:00:00 2001 From: Furkan Bilgin Date: Wed, 18 Sep 2024 18:15:50 +0300 Subject: [PATCH 7/9] refactor(frontend): convert `EditableTable` input value to `string[]` --- .../app/components/ui/EditableTable.tsx | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/packages/frontend/app/components/ui/EditableTable.tsx b/packages/frontend/app/components/ui/EditableTable.tsx index 7f5768a004..f903674bbe 100644 --- a/packages/frontend/app/components/ui/EditableTable.tsx +++ b/packages/frontend/app/components/ui/EditableTable.tsx @@ -11,7 +11,6 @@ type EditableTableProps = { options: EditableTableOption[] error?: string | string[] description?: ReactNode - valueFormatter?: (values: string[]) => string required?: boolean } @@ -29,11 +28,10 @@ export const EditableTable = ({ options, error, description = undefined, - valueFormatter = (values) => values.join(','), required = false }: EditableTableProps) => { const [optionsList, setOptionsList] = useState(options) - const [value, setValue] = useState('') + const [values, setValues] = useState() const toggleEditInput = (index: number) => { setOptionsList( @@ -79,20 +77,17 @@ export const EditableTable = ({ ]) } - useEffect(() => { - setValue(getValue()) - }, [optionsList]) - - const getValue = () => { - return valueFormatter(optionsList.map((option) => option.value)) - } + useEffect( + () => setValues(optionsList.map((option) => option.value)), + [optionsList] + ) return ( <> From 825e11d48f70a1e26b4dd45c2d33a87726119f67 Mon Sep 17 00:00:00 2001 From: Furkan Bilgin Date: Wed, 18 Sep 2024 18:17:20 +0300 Subject: [PATCH 8/9] refactor(backend): refactor `peerHttpInfoSchema` to accept `incomingAuthTokens` as `string[]` --- packages/frontend/app/lib/validate.server.ts | 2 +- packages/frontend/app/routes/peers.$peerId.tsx | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/frontend/app/lib/validate.server.ts b/packages/frontend/app/lib/validate.server.ts index ca74197fe3..c48401e800 100644 --- a/packages/frontend/app/lib/validate.server.ts +++ b/packages/frontend/app/lib/validate.server.ts @@ -47,7 +47,7 @@ export const peerGeneralInfoSchema = z export const peerHttpInfoSchema = z .object({ - incomingAuthTokens: z.string().optional(), + incomingAuthTokens: z.array(z.string()), outgoingAuthToken: z.string(), outgoingEndpoint: z .string() diff --git a/packages/frontend/app/routes/peers.$peerId.tsx b/packages/frontend/app/routes/peers.$peerId.tsx index 1aff0aeeec..b49d4d5882 100644 --- a/packages/frontend/app/routes/peers.$peerId.tsx +++ b/packages/frontend/app/routes/peers.$peerId.tsx @@ -434,8 +434,13 @@ export async function action({ request }: ActionFunctionArgs) { break } case 'http': { - const result = peerHttpInfoSchema.safeParse(Object.fromEntries(formData)) - + const formDataEntries = Object.fromEntries(formData) + const result = peerHttpInfoSchema.safeParse({ + ...formDataEntries, + incomingAuthTokens: formDataEntries.incomingAuthTokens + ? formDataEntries.incomingAuthTokens.toString().split(',') + : [] + }) if (!result.success) { actionResponse.errors.http.fieldErrors = result.error.flatten().fieldErrors @@ -448,8 +453,6 @@ export async function action({ request }: ActionFunctionArgs) { ? { incoming: { authTokens: result.data.incomingAuthTokens - ?.replace(/ /g, '') - .split(',') } } : {}), From bb3293eb3ac4ac4a10d818162a42f8d9d74df624 Mon Sep 17 00:00:00 2001 From: Furkan Bilgin Date: Wed, 18 Sep 2024 18:18:36 +0300 Subject: [PATCH 9/9] fix(backend): add incoming http tokens only if the array contains them --- .../src/payment-method/ilp/peer/service.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/backend/src/payment-method/ilp/peer/service.ts b/packages/backend/src/payment-method/ilp/peer/service.ts index 04ecc26283..a2a420644e 100644 --- a/packages/backend/src/payment-method/ilp/peer/service.ts +++ b/packages/backend/src/payment-method/ilp/peer/service.ts @@ -225,14 +225,16 @@ async function updatePeer( return await Peer.transaction(deps.knex, async (trx) => { if (options.http?.incoming) { await deps.httpTokenService.deleteByPeer(options.id, trx) - const err = await addIncomingHttpTokens({ - deps, - peerId: options.id, - tokens: options.http?.incoming?.authTokens, - trx - }) - if (err) { - throw err + if (options.http?.incoming?.authTokens.length > 0) { + const err = await addIncomingHttpTokens({ + deps, + peerId: options.id, + tokens: options.http?.incoming?.authTokens, + trx + }) + if (err) { + throw err + } } } return await Peer.query(trx)