diff --git a/packages/backend/src/graphql/resolvers/receiver.test.ts b/packages/backend/src/graphql/resolvers/receiver.test.ts index 2ee01cb326..caa2cb32ef 100644 --- a/packages/backend/src/graphql/resolvers/receiver.test.ts +++ b/packages/backend/src/graphql/resolvers/receiver.test.ts @@ -60,7 +60,8 @@ describe('Receiver Resolver', (): void => { incomingAmount: incomingAmount ? serializeAmount(incomingAmount) : undefined - }) + }), + false ) const createSpy = jest @@ -253,7 +254,8 @@ describe('Receiver Resolver', (): void => { id: `${walletAddress.id}/incoming-payments/${uuid()}`, walletAddress: walletAddress.id, incomingAmount: amount ? serializeAmount(amount) : undefined - }) + }), + false ) test('returns receiver', async (): Promise => { diff --git a/packages/backend/src/open_payments/receiver/model.test.ts b/packages/backend/src/open_payments/receiver/model.test.ts index c062e1370c..0255c615f0 100644 --- a/packages/backend/src/open_payments/receiver/model.test.ts +++ b/packages/backend/src/open_payments/receiver/model.test.ts @@ -42,6 +42,7 @@ describe('Receiver Model', (): void => { const incomingPayment = await createIncomingPayment(deps, { walletAddressId: walletAddress.id }) + const isLocal = true const streamCredentials = streamCredentialsService.get(incomingPayment) assert(streamCredentials) @@ -50,7 +51,8 @@ describe('Receiver Model', (): void => { incomingPayment.toOpenPaymentsTypeWithMethods( walletAddress, streamCredentials - ) + ), + isLocal ) expect(receiver).toEqual({ @@ -74,7 +76,8 @@ describe('Receiver Model', (): void => { sharedSecret: base64url(streamCredentials.sharedSecret) } ] - } + }, + isLocal }) }) @@ -96,7 +99,7 @@ describe('Receiver Model', (): void => { streamCredentials ) - expect(() => new Receiver(openPaymentsIncomingPayment)).toThrow( + expect(() => new Receiver(openPaymentsIncomingPayment, false)).toThrow( 'Cannot create receiver from completed incoming payment' ) }) @@ -116,7 +119,7 @@ describe('Receiver Model', (): void => { streamCredentials ) - expect(() => new Receiver(openPaymentsIncomingPayment)).toThrow( + expect(() => new Receiver(openPaymentsIncomingPayment, false)).toThrow( 'Cannot create receiver from expired incoming payment' ) }) @@ -137,7 +140,7 @@ describe('Receiver Model', (): void => { streamCredentials ) - expect(() => new Receiver(openPaymentsIncomingPayment)).toThrow( + expect(() => new Receiver(openPaymentsIncomingPayment, false)).toThrow( 'Invalid ILP address on ilp payment method' ) }) diff --git a/packages/backend/src/open_payments/receiver/model.ts b/packages/backend/src/open_payments/receiver/model.ts index f8b226d066..30156ee847 100644 --- a/packages/backend/src/open_payments/receiver/model.ts +++ b/packages/backend/src/open_payments/receiver/model.ts @@ -29,8 +29,12 @@ export class Receiver { public readonly assetCode: string public readonly assetScale: number public readonly incomingPayment: ReceiverIncomingPayment + public readonly isLocal: boolean - constructor(incomingPayment: OpenPaymentsIncomingPaymentWithPaymentMethod) { + constructor( + incomingPayment: OpenPaymentsIncomingPaymentWithPaymentMethod, + isLocal: boolean + ) { if (incomingPayment.completed) { throw new Error('Cannot create receiver from completed incoming payment') } @@ -76,6 +80,7 @@ export class Receiver { createdAt: new Date(incomingPayment.createdAt), updatedAt: new Date(incomingPayment.updatedAt) } + this.isLocal = isLocal } public get asset(): AssetOptions { diff --git a/packages/backend/src/open_payments/receiver/service.test.ts b/packages/backend/src/open_payments/receiver/service.test.ts index 088d6812d0..7c0c32b8c1 100644 --- a/packages/backend/src/open_payments/receiver/service.test.ts +++ b/packages/backend/src/open_payments/receiver/service.test.ts @@ -114,7 +114,8 @@ describe('Receiver Service', (): void => { sharedSecret: expect.any(String) } ] - } + }, + isLocal: true }) }) @@ -260,7 +261,8 @@ describe('Receiver Service', (): void => { sharedSecret: expect.any(String) } ] - } + }, + isLocal: false }) if (!existingGrant) { expect(clientRequestGrantSpy).toHaveBeenCalledWith( @@ -480,7 +482,8 @@ describe('Receiver Service', (): void => { sharedSecret: expect.any(String) } ] - } + }, + isLocal: false }) expect(remoteIncomingPaymentServiceSpy).toHaveBeenCalledWith({ @@ -573,7 +576,8 @@ describe('Receiver Service', (): void => { sharedSecret: expect.any(String) } ] - } + }, + isLocal: true }) expect(incomingPaymentCreateSpy).toHaveBeenCalledWith({ diff --git a/packages/backend/src/open_payments/receiver/service.ts b/packages/backend/src/open_payments/receiver/service.ts index 8f3ab7c28f..fe2cd8ca4d 100644 --- a/packages/backend/src/open_payments/receiver/service.ts +++ b/packages/backend/src/open_payments/receiver/service.ts @@ -74,8 +74,9 @@ async function createReceiver( const localWalletAddress = await deps.walletAddressService.getByUrl( args.walletAddressUrl ) + const isLocal = !!localWalletAddress - const incomingPaymentOrError = localWalletAddress + const incomingPaymentOrError = isLocal ? await createLocalIncomingPayment(deps, args, localWalletAddress) : await deps.remoteIncomingPaymentService.create(args) @@ -84,7 +85,7 @@ async function createReceiver( } try { - return new Receiver(incomingPaymentOrError) + return new Receiver(incomingPaymentOrError, isLocal) } catch (error) { const errorMessage = 'Could not create receiver from incoming payment' deps.logger.error( @@ -147,10 +148,27 @@ async function getReceiver( deps: ServiceDependencies, url: string ): Promise { - const incomingPayment = await getIncomingPayment(deps, url) - if (incomingPayment) { - return new Receiver(incomingPayment) + try { + const localIncomingPayment = await getLocalIncomingPayment({ + deps, + url + }) + if (localIncomingPayment) { + return new Receiver(localIncomingPayment, true) + } + + const remoteIncomingPayment = await getRemoteIncomingPayment(deps, url) + if (remoteIncomingPayment) { + return new Receiver(remoteIncomingPayment, false) + } + } catch (error) { + deps.logger.error( + { errorMessage: error instanceof Error && error.message }, + 'Could not get incoming payment' + ) } + + return undefined } function parseIncomingPaymentUrl( @@ -167,49 +185,33 @@ function parseIncomingPaymentUrl( } } -async function getIncomingPayment( +async function getRemoteIncomingPayment( deps: ServiceDependencies, url: string ): Promise { - try { - const urlParseResult = parseIncomingPaymentUrl(url) - if (!urlParseResult) { - return undefined - } - - const localIncomingPayment = await getLocalIncomingPayment({ - deps, - id: urlParseResult.id + const grant = await getIncomingPaymentGrant(deps, url) + if (!grant) { + throw new Error('Could not find grant') + } else { + return await deps.openPaymentsClient.incomingPayment.get({ + url, + accessToken: grant.accessToken }) - if (localIncomingPayment) { - return localIncomingPayment - } - - const grant = await getIncomingPaymentGrant(deps, url) - if (!grant) { - throw new Error('Could not find grant') - } else { - return await deps.openPaymentsClient.incomingPayment.get({ - url, - accessToken: grant.accessToken - }) - } - } catch (error) { - deps.logger.error( - { errorMessage: error instanceof Error && error.message }, - 'Could not get incoming payment' - ) - return undefined } } async function getLocalIncomingPayment({ deps, - id + url }: { deps: ServiceDependencies - id: string + url: string }): Promise { + const { id } = parseIncomingPaymentUrl(url) ?? {} + if (!id) { + return undefined + } + const incomingPayment = await deps.incomingPaymentService.get({ id }) diff --git a/packages/backend/src/tests/outgoingPayment.ts b/packages/backend/src/tests/outgoingPayment.ts index f28b38e694..451f33e6bb 100644 --- a/packages/backend/src/tests/outgoingPayment.ts +++ b/packages/backend/src/tests/outgoingPayment.ts @@ -56,7 +56,8 @@ export async function createOutgoingPayment( incomingPayment.toOpenPaymentsTypeWithMethods( walletAddress, streamCredentials - ) + ), + false ) ) } @@ -124,7 +125,8 @@ export async function createOutgoingPaymentWithReceiver( incomingPayment.toOpenPaymentsTypeWithMethods( args.receivingWalletAddress, streamCredentials - ) + ), + false ) const outgoingPayment = await createOutgoingPayment(deps, { diff --git a/packages/backend/src/tests/receiver.ts b/packages/backend/src/tests/receiver.ts index 3cd6b7a8c8..218051e70d 100644 --- a/packages/backend/src/tests/receiver.ts +++ b/packages/backend/src/tests/receiver.ts @@ -22,6 +22,7 @@ export async function createReceiver( incomingPayment.toOpenPaymentsTypeWithMethods( walletAddress, streamCredentialsService.get(incomingPayment)! - ) + ), + false ) }