Skip to content

Commit c9c047e

Browse files
mkurapovBlairCurreyraducristianpopa
authored
feat: accept peering request (interledger#1849)
* feat(backend): WIP - add feeid to quote table * refactor(backend): rename quote gql field * fix(backend): add fee relation * feat(backend): WIP calculate fees in quote create * refactor(backend): rename gql quote field * fix(backend): rm unused with graph fetched * feat(backend): move fee calculation to quote service * fix(backend): use quote error * fix(backend): rm unused fn * refactor(backend): rename quote send amount value * refactor(backend): rename quote send amount to debit amount * refactor(backend): rename out payment send amount to debit * chore(backend): format * chore(documentation): update gql docs * fix(backend,localenv): trx amount * fix(backend): handle cross currency fee in quote * refactor: update spec and rename more fields * fix(backend): outgoing limit test * refactor(backend): rename limits field * rename sendAmount to debitAmount * fix(localenv): postman ecommerce flow * fix(backend): remove useless checks * chore(auth): update open-payments package version * chore(backend): rm commented out code * fix(auth): migration to rename jsonb col * chore(auth): format * feat: add DuplicatePeer error * fix: pass in peerService to autoPeeringService * chore: update diff * chore: add to peer resolver test * feat: accept peering request * fix(backend): remove asset join * refactor(backend): remove variable assignment * feat: wire up router for auto peering * fix: update auto peering service * feat: correct config * config: update auto peering routes & errors * chore: prettier * chore: address comments * Update packages/backend/src/auto-peering/errors.ts Co-authored-by: Radu-Cristian Popa <[email protected]> * chore: remove axios from app * chore: fix whitespace * feature(backend): change error * reactor(documentation): update fee explanation * feat: use assetId in getByDestinationAddress * feat: update peer on duplicate peering request * chore: remove quote url references * fix(openapi): missing server warning * chore: fix route tests * feat: support maxPacketAmount and name in peering request * feat: support maxPacketAmount and name in peering request * fix: remove getter * Temporary fix * chore(token-introspection): generate types * refactor(documentation): rename sendAmount to debitAmount * Revert "Merge branch 'bc/1639/add-fees-to-quote' into mk/1802/accept-peering-request" This reverts commit 8fb0154, reversing changes made to 9619132. * ci: test heap bump * ci: logheapusage * chore: bump jest * chore: update tests * chore: update tests * Revert "ci: logheapusage" This reverts commit 66293e5. * revert fix * fix: revert pnpm lock --------- Co-authored-by: Blair Currey <[email protected]> Co-authored-by: Radu-Cristian Popa <[email protected]>
1 parent 09e813a commit c9c047e

File tree

10 files changed

+451
-74
lines changed

10 files changed

+451
-74
lines changed

packages/backend/src/app.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -588,8 +588,7 @@ export class App {
588588
const router = new Router<DefaultState, AppContext>()
589589

590590
router.use(bodyParser())
591-
592-
router.get('/', autoPeeringRoutes.get)
591+
router.post('/', autoPeeringRoutes.acceptPeerRequest)
593592

594593
koa.use(router.routes())
595594

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
export enum AutoPeeringError {
2+
InvalidIlpConfiguration = 'InvalidIlpConfiguration',
3+
InvalidPeerIlpConfiguration = 'InvalidPeerIlpConfiguration',
4+
UnknownAsset = 'UnknownAsset',
5+
PeerUnsupportedAsset = 'PeerUnsupportedAsset',
6+
InvalidPeerUrl = 'InvalidPeerUrl',
7+
InvalidPeeringRequest = 'InvalidPeeringRequest',
8+
DuplicatePeer = 'DuplicatePeer'
9+
}
10+
11+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
12+
export const isAutoPeeringError = (o: any): o is AutoPeeringError =>
13+
Object.values(AutoPeeringError).includes(o)
14+
15+
export const errorToCode: {
16+
[key in AutoPeeringError]: number
17+
} = {
18+
[AutoPeeringError.InvalidIlpConfiguration]: 400,
19+
[AutoPeeringError.InvalidPeerIlpConfiguration]: 400,
20+
[AutoPeeringError.UnknownAsset]: 404,
21+
[AutoPeeringError.PeerUnsupportedAsset]: 400,
22+
[AutoPeeringError.InvalidPeerUrl]: 400,
23+
[AutoPeeringError.InvalidPeeringRequest]: 400,
24+
[AutoPeeringError.DuplicatePeer]: 409
25+
}
26+
27+
export const errorToMessage: {
28+
[key in AutoPeeringError]: string
29+
} = {
30+
[AutoPeeringError.InvalidIlpConfiguration]:
31+
'The ILP configuration is misconfigured',
32+
[AutoPeeringError.InvalidPeerIlpConfiguration]: `Requested peer's ILP configuration is misconfigured`,
33+
[AutoPeeringError.UnknownAsset]: 'Unknown asset',
34+
[AutoPeeringError.PeerUnsupportedAsset]: 'Peer does not support asset',
35+
[AutoPeeringError.InvalidPeerUrl]: 'Peer URL is invalid',
36+
[AutoPeeringError.InvalidPeeringRequest]: 'Invalid peering request',
37+
[AutoPeeringError.DuplicatePeer]: 'Duplicate peer'
38+
}

packages/backend/src/auto-peering/routes.test.ts

+44-26
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
11
import { IocContract } from '@adonisjs/fold'
22
import { initIocContainer } from '..'
3-
import { AppContext, AppServices } from '../app'
4-
import { Config } from '../config/app'
3+
import { AppServices } from '../app'
4+
import { Config, IAppConfig } from '../config/app'
55
import { createTestApp, TestContainer } from '../tests/app'
66
import { createAsset } from '../tests/asset'
77
import { createContext } from '../tests/context'
88
import { truncateTables } from '../tests/tableManager'
9-
import { AutoPeeringRoutes } from './routes'
9+
import { AutoPeeringError, errorToCode, errorToMessage } from './errors'
10+
import { AutoPeeringRoutes, PeerRequestContext } from './routes'
1011

1112
describe('Auto Peering Routes', (): void => {
1213
let deps: IocContract<AppServices>
1314
let appContainer: TestContainer
1415
let autoPeeringRoutes: AutoPeeringRoutes
16+
let config: IAppConfig
1517

1618
beforeAll(async (): Promise<void> => {
1719
deps = initIocContainer({ ...Config, enableAutoPeering: true })
1820
appContainer = await createTestApp(deps)
1921
autoPeeringRoutes = await deps.use('autoPeeringRoutes')
22+
config = await deps.use('config')
2023
})
2124

2225
afterEach(async (): Promise<void> => {
@@ -27,41 +30,56 @@ describe('Auto Peering Routes', (): void => {
2730
await appContainer.shutdown()
2831
})
2932

30-
describe('get', (): void => {
31-
test('returns peering details with assets', async (): Promise<void> => {
32-
const assets = await Promise.all([
33-
createAsset(deps),
34-
createAsset(deps),
35-
createAsset(deps)
36-
])
33+
describe('acceptPeerRequest', (): void => {
34+
test('returns peering details', async (): Promise<void> => {
35+
const asset = await createAsset(deps)
3736

38-
const ctx = createContext<AppContext>({
37+
const ctx = createContext<PeerRequestContext>({
3938
headers: { Accept: 'application/json' },
40-
url: `/`
39+
url: `/`,
40+
body: {
41+
staticIlpAddress: 'test.rafiki-money',
42+
ilpConnectorAddress: 'http://peer.rafiki.money',
43+
asset: { code: asset.code, scale: asset.scale },
44+
httpToken: 'someHttpToken',
45+
maxPacketAmount: 1000,
46+
name: 'Rafiki Money'
47+
}
4148
})
4249

43-
await expect(autoPeeringRoutes.get(ctx)).resolves.toBeUndefined()
50+
await expect(
51+
autoPeeringRoutes.acceptPeerRequest(ctx)
52+
).resolves.toBeUndefined()
53+
expect(ctx.status).toBe(200)
4454
expect(ctx.body).toEqual({
45-
ilpAddress: Config.ilpAddress,
46-
assets: expect.arrayContaining(
47-
assets.map((asset) => ({
48-
code: asset.code,
49-
scale: asset.scale
50-
}))
51-
)
55+
staticIlpAddress: config.ilpAddress,
56+
ilpConnectorAddress: config.ilpConnectorAddress,
57+
httpToken: expect.any(String),
58+
name: config.instanceName
5259
})
5360
})
5461

55-
test('returns peering details without assets', async (): Promise<void> => {
56-
const ctx = createContext<AppContext>({
62+
test('properly handles error', async (): Promise<void> => {
63+
const ctx = createContext<PeerRequestContext>({
5764
headers: { Accept: 'application/json' },
58-
url: `/`
65+
url: `/`,
66+
body: {
67+
staticIlpAddress: 'test.rafiki-money',
68+
ilpConnectorAddress: 'http://peer.rafiki.money',
69+
asset: { code: 'ABC', scale: 2 },
70+
httpToken: 'someHttpToken'
71+
}
5972
})
6073

61-
await expect(autoPeeringRoutes.get(ctx)).resolves.toBeUndefined()
74+
await expect(
75+
autoPeeringRoutes.acceptPeerRequest(ctx)
76+
).resolves.toBeUndefined()
77+
expect(ctx.status).toBe(errorToCode[AutoPeeringError.UnknownAsset])
6278
expect(ctx.body).toEqual({
63-
ilpAddress: Config.ilpAddress,
64-
assets: []
79+
error: {
80+
code: errorToCode[AutoPeeringError.UnknownAsset],
81+
message: errorToMessage[AutoPeeringError.UnknownAsset]
82+
}
6583
})
6684
})
6785
})
+35-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,29 @@
11
import { AppContext } from '../app'
22
import { BaseService } from '../shared/baseService'
3+
import { errorToCode, errorToMessage, isAutoPeeringError } from './errors'
34
import { AutoPeeringService } from './service'
45

6+
interface PeeringRequestArgs {
7+
staticIlpAddress: string
8+
ilpConnectorAddress: string
9+
asset: { code: string; scale: number }
10+
httpToken: string
11+
maxPacketAmount?: number
12+
name?: string
13+
}
14+
15+
export type PeerRequestContext = Exclude<AppContext, 'request'> & {
16+
request: {
17+
body: PeeringRequestArgs
18+
}
19+
}
20+
521
export interface ServiceDependencies extends BaseService {
622
autoPeeringService: AutoPeeringService
723
}
824

925
export interface AutoPeeringRoutes {
10-
get(ctx: AppContext): Promise<void>
26+
acceptPeerRequest(ctx: PeerRequestContext): Promise<void>
1127
}
1228

1329
export async function createAutoPeeringRoutes(
@@ -21,15 +37,28 @@ export async function createAutoPeeringRoutes(
2137
}
2238

2339
return {
24-
get: (ctx: AppContext) => getPeeringDetails(deps, ctx)
40+
acceptPeerRequest: (ctx: PeerRequestContext) => acceptPeerRequest(deps, ctx)
2541
}
2642
}
2743

28-
async function getPeeringDetails(
44+
async function acceptPeerRequest(
2945
deps: ServiceDependencies,
30-
ctx: AppContext
46+
ctx: PeerRequestContext
3147
): Promise<void> {
32-
const peeringDetails = await deps.autoPeeringService.getPeeringDetails()
48+
const peeringDetailsOrError =
49+
await deps.autoPeeringService.acceptPeeringRequest(ctx.request.body)
3350

34-
ctx.body = peeringDetails
51+
if (isAutoPeeringError(peeringDetailsOrError)) {
52+
const errorCode = errorToCode[peeringDetailsOrError]
53+
ctx.status = errorCode
54+
ctx.body = {
55+
error: {
56+
code: errorCode,
57+
message: errorToMessage[peeringDetailsOrError]
58+
}
59+
}
60+
} else {
61+
ctx.status = 200
62+
ctx.body = peeringDetailsOrError
63+
}
3564
}

0 commit comments

Comments
 (0)