Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add properties for quoting #275

Merged
merged 15 commits into from
Sep 6, 2023
5 changes: 5 additions & 0 deletions .changeset/tender-ravens-breathe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@interledger/open-payments': minor
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be major since it contains breaking changes

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I must have run the wrong command 🙃

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's technically still a major change, but it feels so minor...

Copy link
Contributor

@BlairCurrey BlairCurrey Aug 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should still be major since it's breaking, and I think we probably need to bump the resource-server.yaml and auth-server.yaml version as well. Thats how we handled it when I renamed a field here: #270. Although the spec version bump was a minor bump 🤔... don't quite remember that reasoning.

On the topic of it feeling minor, Max pointed to some relevant blog posts and hackernews discussion in this comment #270 (comment). I don't see any quick, easy wins there and think just doing a major bump still makes the most sense but it is interesting reading.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah +1 on making this a major since it is breaking.
The spec can stay minor IMO

---

Adding properties for new quoting mechanism
12 changes: 7 additions & 5 deletions openapi/auth-server.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ paths:
limits:
receiver: 'https://openpayments.guide/connections/45a0d0ee-26dc-4c66-89e0-01fbf93156f7'
interval: 'R12/2019-08-24T14:15:22Z/P1M'
sendAmount:
debitAmount:
value: '500'
assetCode: USD
assetScale: 2
Expand Down Expand Up @@ -180,7 +180,7 @@ paths:
limits:
receiver: 'https://openpayments.guide/bob/incoming-payments/48884225-b393-4872-90de-1b737e2491c2'
interval: 'R12/2019-08-24T14:15:22Z/P1M'
sendAmount:
debitAmount:
value: '500'
assetCode: USD
assetScale: 2
Expand Down Expand Up @@ -275,7 +275,7 @@ paths:
limits:
interval: 'R12/2019-08-24T14:15:22Z/P1M'
receiver: 'https://openpayments.guide/bob/incoming-payments/48884225-b393-4872-90de-1b737e2491c2'
sendAmount:
debitAmount:
value: '500'
assetCode: USD
assetScale: 2
Expand Down Expand Up @@ -515,9 +515,11 @@ components:
properties:
receiver:
$ref: './schemas.yaml#/components/schemas/receiver'
sendAmount:
debitAmount:
description: 'All amounts are maxima, i.e. multiple payments can be created under a grant as long as the total amounts of these payments do not exceed the maximum amount per interval as specified in the grant.'
$ref: './schemas.yaml#/components/schemas/amount'
receiveAmount:
description: 'All amounts are maxima, i.e. multiple payments can be created under a grant as long as the total amounts of these payments do not exceed the maximum amount per interval as specified in the grant.'
$ref: './schemas.yaml#/components/schemas/amount'
interval:
$ref: '#/components/schemas/interval'
Expand All @@ -526,7 +528,7 @@ components:
required:
- interval
- required:
- sendAmount
- debitAmount
- required:
- receiveAmount
securitySchemes:
Expand Down
181 changes: 79 additions & 102 deletions openapi/resource-server.yaml

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion openapi/schemas.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ components:
amount:
title: amount
type: object
description: 'All amounts are maxima, i.e. multiple payments can be created under a grant as long as the total amounts of these payments do not exceed the maximum amount per interval as specified in the grant.'
properties:
value:
type: string
Expand Down
14 changes: 7 additions & 7 deletions packages/open-payments/src/client/outgoing-payment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ describe('outgoing-payment', (): void => {

test('throws if outgoing payment does not pass validation', async (): Promise<void> => {
const outgoingPayment = mockOutgoingPayment({
sendAmount: {
debitAmount: {
assetCode: 'USD',
assetScale: 3,
value: '5'
Expand Down Expand Up @@ -194,7 +194,7 @@ describe('outgoing-payment', (): void => {

test('throws if an outgoing payment does not pass validation', async (): Promise<void> => {
const invalidOutgoingPayment = mockOutgoingPayment({
sendAmount: {
debitAmount: {
assetCode: 'CAD',
assetScale: 2,
value: '5'
Expand Down Expand Up @@ -291,7 +291,7 @@ describe('outgoing-payment', (): void => {

test('throws if outgoing payment does not pass validation', async (): Promise<void> => {
const outgoingPayment = mockOutgoingPayment({
sendAmount: {
debitAmount: {
assetCode: 'USD',
assetScale: 3,
value: '5'
Expand Down Expand Up @@ -361,7 +361,7 @@ describe('outgoing-payment', (): void => {

test('throws if send amount and sent amount asset scales are different', async (): Promise<void> => {
const outgoingPayment = mockOutgoingPayment({
sendAmount: {
debitAmount: {
assetCode: 'USD',
assetScale: 3,
value: '5'
Expand All @@ -380,7 +380,7 @@ describe('outgoing-payment', (): void => {

test('throws if send amount and sent amount asset codes are different', async (): Promise<void> => {
const outgoingPayment = mockOutgoingPayment({
sendAmount: {
debitAmount: {
assetCode: 'CAD',
assetScale: 2,
value: '5'
Expand All @@ -399,7 +399,7 @@ describe('outgoing-payment', (): void => {

test('throws if sent amount is larger than send amount', async (): Promise<void> => {
const outgoingPayment = mockOutgoingPayment({
sendAmount: {
debitAmount: {
assetCode: 'USD',
assetScale: 2,
value: '5'
Expand All @@ -418,7 +418,7 @@ describe('outgoing-payment', (): void => {

test('throws if sent amount equals send amount, but payment has failed', async (): Promise<void> => {
const outgoingPayment = mockOutgoingPayment({
sendAmount: {
debitAmount: {
assetCode: 'USD',
assetScale: 2,
value: '5'
Expand Down
10 changes: 5 additions & 5 deletions packages/open-payments/src/client/outgoing-payment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,19 +176,19 @@ export const listOutgoingPayments = async (
export const validateOutgoingPayment = (
payment: OutgoingPayment
): OutgoingPayment => {
const { sendAmount, sentAmount } = payment
const { debitAmount, sentAmount } = payment
if (
sendAmount.assetCode !== sentAmount.assetCode ||
sendAmount.assetScale !== sentAmount.assetScale
debitAmount.assetCode !== sentAmount.assetCode ||
debitAmount.assetScale !== sentAmount.assetScale
) {
throw new Error(
'Asset code or asset scale of sending amount does not match sent amount'
)
}
if (BigInt(sendAmount.value) < BigInt(sentAmount.value)) {
if (BigInt(debitAmount.value) < BigInt(sentAmount.value)) {
throw new Error('Amount sent is larger than maximum amount to send')
}
if (sendAmount.value === sentAmount.value && payment.failed) {
if (debitAmount.value === sentAmount.value && payment.failed) {
throw new Error('Amount to send matches sent amount but payment failed')
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,9 @@ export interface components {
*/
"limits-outgoing": Partial<unknown> & {
receiver?: external["schemas.yaml"]["components"]["schemas"]["receiver"];
sendAmount?: external["schemas.yaml"]["components"]["schemas"]["amount"];
/** @description All amounts are maxima, i.e. multiple payments can be created under a grant as long as the total amounts of these payments do not exceed the maximum amount per interval as specified in the grant. */
debitAmount?: external["schemas.yaml"]["components"]["schemas"]["amount"];
/** @description All amounts are maxima, i.e. multiple payments can be created under a grant as long as the total amounts of these payments do not exceed the maximum amount per interval as specified in the grant. */
receiveAmount?: external["schemas.yaml"]["components"]["schemas"]["amount"];
interval?: components["schemas"]["interval"];
};
Expand Down Expand Up @@ -312,10 +314,7 @@ export interface external {
paths: {};
components: {
schemas: {
/**
* amount
* @description All amounts are maxima, i.e. multiple payments can be created under a grant as long as the total amounts of these payments do not exceed the maximum amount per interval as specified in the grant.
*/
/** amount */
amount: {
/**
* Format: uint64
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,8 @@ export interface components {
receiver: external["schemas.yaml"]["components"]["schemas"]["receiver"];
/** @description The total amount that should be received by the receiver when this outgoing payment has been paid. */
receiveAmount: external["schemas.yaml"]["components"]["schemas"]["amount"];
/** @description The total amount that should be sent when this outgoing payment has been paid. */
sendAmount: external["schemas.yaml"]["components"]["schemas"]["amount"];
/** @description The total amount that should be deducted from the sender's account when this outgoing payment has been paid. */
debitAmount: external["schemas.yaml"]["components"]["schemas"]["amount"];
/** @description The total amount that has been sent under this outgoing payment. */
sentAmount: external["schemas.yaml"]["components"]["schemas"]["amount"];
/** @description Additional metadata associated with the outgoing payment. (Optional) */
Expand Down Expand Up @@ -277,9 +277,12 @@ export interface components {
* @description The URL of the payment pointer from which this quote's payment would be sent.
*/
paymentPointer: string;
/** @description The URL of the incoming payment or ILP STREAM Connection that the quote is created for. */
receiver: external["schemas.yaml"]["components"]["schemas"]["receiver"];
/** @description The total amount that should be received by the receiver when the corresponding outgoing payment has been paid. */
receiveAmount: external["schemas.yaml"]["components"]["schemas"]["amount"];
sendAmount: external["schemas.yaml"]["components"]["schemas"]["amount"];
/** @description The total amount that should be deducted from the sender's account when the corresponding outgoing payment has been paid. */
debitAmount: external["schemas.yaml"]["components"]["schemas"]["amount"];
/** @description The date and time when the calculated `sendAmount` is no longer valid. */
expiresAt?: string;
/**
Expand Down Expand Up @@ -720,10 +723,7 @@ export interface external {
paths: {};
components: {
schemas: {
/**
* amount
* @description All amounts are maxima, i.e. multiple payments can be created under a grant as long as the total amounts of these payments do not exceed the maximum amount per interval as specified in the grant.
*/
/** amount */
amount: {
/**
* Format: uint64
Expand Down
4 changes: 2 additions & 2 deletions packages/open-payments/src/test/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ export const mockOutgoingPayment = (
id: `https://example.com/.well-known/pay/outgoing-payments/${uuid()}`,
paymentPointer: 'https://example.com/.well-known/pay',
failed: false,
sendAmount: {
debitAmount: {
assetCode: 'USD',
assetScale: 2,
value: '10'
Expand Down Expand Up @@ -286,7 +286,7 @@ export const mockQuote = (overrides?: Partial<Quote>): Quote => ({
id: `https://example.com/.well-known/pay/quotes/${uuid()}`,
receiver: 'https://example.com/.well-known/peer',
paymentPointer: 'https://example.com/.well-known/pay',
sendAmount: {
debitAmount: {
value: '100',
assetCode: 'USD',
assetScale: 2
Expand Down
8 changes: 4 additions & 4 deletions packages/open-payments/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,16 @@ export type Quote = RSComponents['schemas']['quote']
type QuoteArgsBase = {
receiver: RSOperations['create-quote']['requestBody']['content']['application/json']['receiver']
}
type QuoteArgsWithSendAmount = QuoteArgsBase & {
sendAmount?: RSComponents['schemas']['quote']['sendAmount']
type QuoteArgsWithDebitAmount = QuoteArgsBase & {
debitAmount?: RSComponents['schemas']['quote']['debitAmount']
receiveAmount?: never
}
type QuoteArgsWithReceiveAmount = QuoteArgsBase & {
sendAmount?: never
debitAmount?: never
receiveAmount?: RSComponents['schemas']['quote']['receiveAmount']
}
export type CreateQuoteArgs =
| QuoteArgsWithSendAmount
| QuoteArgsWithDebitAmount
| QuoteArgsWithReceiveAmount

export const getASPath = <P extends keyof ASPaths>(path: P): string =>
Expand Down
Loading