Skip to content

Commit 81ff48a

Browse files
committed
feat: added pagination in invoice
Change response type + test cases TICKET: BTC-2110
1 parent 7de803e commit 81ff48a

File tree

4 files changed

+68
-8
lines changed

4 files changed

+68
-8
lines changed

examples/ts/btc/lightning/list-invoices.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ async function main(): Promise<void> {
5858
status,
5959
limit: limit ? BigInt(limit) : undefined,
6060
};
61-
const invoices = await lightning.listInvoices(query);
61+
const { invoices } = await lightning.listInvoices(query);
6262

6363
// Display invoice summary
6464
console.log(`\nFound ${invoices.length} invoices:`);

modules/abstract-lightning/src/codecs/api/invoice.ts

+19
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,29 @@ export const InvoiceInfo = t.intersection(
8282
);
8383
export type InvoiceInfo = t.TypeOf<typeof InvoiceInfo>;
8484

85+
export const ListInvoicesResponse = t.intersection(
86+
[
87+
t.type({
88+
invoices: t.array(InvoiceInfo),
89+
}),
90+
t.partial({
91+
/**
92+
* This is the paymentHash of the last Invoice in the last iteration.
93+
* Providing this value as the prevId in the next request will return the next batch of invoices.
94+
* */
95+
nextBatchPrevId: t.string,
96+
}),
97+
],
98+
'ListInvoicesResponse'
99+
);
100+
export type ListInvoicesResponse = t.TypeOf<typeof ListInvoicesResponse>;
101+
85102
export const InvoiceQuery = t.partial(
86103
{
87104
status: InvoiceStatus,
88105
limit: BigIntFromString,
106+
/** paymentHash provided by nextBatchPrevId in the previous list */
107+
prevId: t.string,
89108
startDate: DateFromISOString,
90109
endDate: DateFromISOString,
91110
},

modules/abstract-lightning/src/wallet/lightning.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
PaymentQuery,
2727
LightningOnchainWithdrawParams,
2828
LightningOnchainWithdrawResponse,
29+
ListInvoicesResponse,
2930
} from '../codecs';
3031
import { LightningPaymentIntent, LightningPaymentRequest } from '@bitgo/public-types';
3132

@@ -143,9 +144,10 @@ export interface ILightningWallet {
143144
* @param {bigint} [params.limit] The maximum number of invoices to return
144145
* @param {Date} [params.startDate] The start date for the query
145146
* @param {Date} [params.endDate] The end date for the query
146-
* @returns {Promise<InvoiceInfo[]>} List of invoices
147+
* @param {Date} [params.prevId] Continue iterating (provided by nextBatchPrevId in the previous list)
148+
* @returns {Promise<ListInvoicesResponse>} List of invoices and nextBatchPrevId
147149
*/
148-
listInvoices(params: InvoiceQuery): Promise<InvoiceInfo[]>;
150+
listInvoices(params: InvoiceQuery): Promise<ListInvoicesResponse>;
149151

150152
/**
151153
* Pay a lightning invoice
@@ -234,8 +236,8 @@ export class LightningWallet implements ILightningWallet {
234236
});
235237
}
236238

237-
async listInvoices(params: InvoiceQuery): Promise<InvoiceInfo[]> {
238-
const returnCodec = t.array(InvoiceInfo);
239+
async listInvoices(params: InvoiceQuery): Promise<ListInvoicesResponse> {
240+
const returnCodec = ListInvoicesResponse;
239241
const createInvoiceResponse = await this.wallet.bitgo
240242
.get(this.wallet.bitgo.url(`/wallet/${this.wallet.id()}/lightning/invoice`, 2))
241243
.query(InvoiceQuery.encode(params))

modules/bitgo/test/v2/unit/lightning/lightningWallets.ts

+42-3
Original file line numberDiff line numberDiff line change
@@ -264,10 +264,49 @@ describe('Lightning wallets', function () {
264264
const listInvoicesNock = nock(bgUrl)
265265
.get(`/api/v2/wallet/${wallet.wallet.id()}/lightning/invoice`)
266266
.query(InvoiceQuery.encode(query))
267-
.reply(200, [InvoiceInfo.encode(invoice)]);
267+
.reply(200, { invoices: [InvoiceInfo.encode(invoice)] });
268268
const invoiceResponse = await wallet.listInvoices(query);
269-
assert.strictEqual(invoiceResponse.length, 1);
270-
assert.deepStrictEqual(invoiceResponse[0], invoice);
269+
assert.strictEqual(invoiceResponse.invoices.length, 1);
270+
assert.deepStrictEqual(invoiceResponse.invoices[0], invoice);
271+
listInvoicesNock.done();
272+
});
273+
274+
it('should work properly with pagination while listing invoices', async function () {
275+
const invoice1: InvoiceInfo = {
276+
valueMsat: 1000n,
277+
paymentHash: 'foo1',
278+
invoice: 'tlnfoobar1',
279+
walletId: wallet.wallet.id(),
280+
status: 'open',
281+
expiresAt: new Date(),
282+
createdAt: new Date(),
283+
updatedAt: new Date(),
284+
};
285+
const invoice2: InvoiceInfo = {
286+
...invoice1,
287+
paymentHash: 'foo2',
288+
invoice: 'tlnfoobar2',
289+
};
290+
const invoice3: InvoiceInfo = {
291+
...invoice1,
292+
paymentHash: 'foo3',
293+
invoice: 'tlnfoobar3',
294+
};
295+
const allInvoices = [InvoiceInfo.encode(invoice1), InvoiceInfo.encode(invoice2), InvoiceInfo.encode(invoice3)];
296+
const query = {
297+
status: 'open',
298+
startDate: new Date(),
299+
limit: 2n,
300+
} as InvoiceQuery;
301+
const listInvoicesNock = nock(bgUrl)
302+
.get(`/api/v2/wallet/${wallet.wallet.id()}/lightning/invoice`)
303+
.query(InvoiceQuery.encode(query))
304+
.reply(200, { invoices: allInvoices.slice(0, 2), nextBatchPrevId: invoice2.paymentHash });
305+
const invoiceResponse = await wallet.listInvoices(query);
306+
assert.strictEqual(invoiceResponse.invoices.length, 2);
307+
assert.deepStrictEqual(invoiceResponse.invoices[0], invoice1);
308+
assert.deepStrictEqual(invoiceResponse.invoices[1], invoice2);
309+
assert.strictEqual(invoiceResponse.nextBatchPrevId, invoice2.paymentHash);
271310
listInvoicesNock.done();
272311
});
273312

0 commit comments

Comments
 (0)