11import * as sinon from 'sinon' ;
22import * as should from 'should' ;
33import * as express from 'express' ;
4- import { handlePayLightningInvoice } from '../../../src/lightning/lightningInvoiceRoutes' ;
5- import { PayInvoiceResponse } from '@bitgo/abstract-lightning' ;
4+ import { handlePayLightningInvoice , handleCreateLightningInvoice } from '../../../src/lightning/lightningInvoiceRoutes' ;
5+ import { Invoice , PayInvoiceResponse } from '@bitgo/abstract-lightning' ;
66import { BitGo } from 'bitgo' ;
7+ import * as assert from 'node:assert' ;
78
89describe ( 'Lightning Invoice Routes' , ( ) => {
910 let bitgo ;
@@ -22,6 +23,82 @@ describe('Lightning Invoice Routes', () => {
2223 sinon . restore ( ) ;
2324 } ) ;
2425
26+ describe ( 'Create Lightning Invoice' , ( ) => {
27+ it ( 'should successfully create a lightning invoice' , async ( ) => {
28+ const inputParams = {
29+ valueMsat : '10000' ,
30+ memo : 'test invoice' ,
31+ expiry : 3600 ,
32+ } ;
33+
34+ const expectedResponse = {
35+ valueMsat : 10000n ,
36+ memo : 'test invoice' ,
37+ paymentHash : 'abc123' ,
38+ invoice : 'lntb100u1p3h2jk3pp5yndyvx4zmv...' ,
39+ walletId : 'testWalletId' ,
40+ status : 'open' as const ,
41+ expiresAt : new Date ( '2025-02-21T10:00:00.000Z' ) ,
42+ } ;
43+
44+ const createInvoiceSpy = sinon . stub ( ) . resolves ( expectedResponse ) ;
45+ const mockLightningWallet = {
46+ createInvoice : createInvoiceSpy ,
47+ } ;
48+
49+ // Mock the module import
50+ const proxyquire = require ( 'proxyquire' ) ;
51+ const lightningRoutes = proxyquire ( '../../../src/lightning/lightningInvoiceRoutes' , {
52+ '@bitgo/abstract-lightning' : {
53+ getLightningWallet : ( ) => mockLightningWallet ,
54+ } ,
55+ } ) ;
56+
57+ const walletStub = { } ;
58+ const coinStub = {
59+ wallets : ( ) => ( { get : sinon . stub ( ) . resolves ( walletStub ) } ) ,
60+ } ;
61+
62+ const stubBitgo = sinon . createStubInstance ( BitGo as any , { coin : coinStub } ) ;
63+
64+ const req = mockRequestObject ( {
65+ params : { id : 'testWalletId' , coin } ,
66+ body : inputParams ,
67+ bitgo : stubBitgo ,
68+ } ) ;
69+
70+ const result = await lightningRoutes . handleCreateLightningInvoice ( req ) ;
71+
72+ should ( result ) . deepEqual ( Invoice . encode ( expectedResponse ) ) ;
73+ const decodedResult = Invoice . decode ( result ) ;
74+ assert ( 'right' in decodedResult ) ;
75+ should ( decodedResult . right ) . deepEqual ( expectedResponse ) ;
76+ should ( createInvoiceSpy ) . be . calledOnce ( ) ;
77+ const [ firstArg ] = createInvoiceSpy . getCall ( 0 ) . args ;
78+
79+ should ( firstArg ) . have . property ( 'valueMsat' , BigInt ( 10000 ) ) ;
80+ should ( firstArg ) . have . property ( 'memo' , 'test invoice' ) ;
81+ should ( firstArg ) . have . property ( 'expiry' , 3600 ) ;
82+ } ) ;
83+
84+ it ( 'should fail when valueMsat is missing from request' , async ( ) => {
85+ const inputParams = {
86+ memo : 'test invoice' ,
87+ expiry : 3600 ,
88+ } ;
89+
90+ const req = mockRequestObject ( {
91+ params : { id : 'testWalletId' , coin } ,
92+ body : inputParams ,
93+ } ) ;
94+ req . bitgo = bitgo ;
95+
96+ await should ( handleCreateLightningInvoice ( req ) ) . be . rejectedWith (
97+ / ^ I n v a l i d r e q u e s t b o d y t o c r e a t e l i g h t n i n g i n v o i c e /
98+ ) ;
99+ } ) ;
100+ } ) ;
101+
25102 describe ( 'Pay Lightning Invoice' , ( ) => {
26103 it ( 'should successfully pay a lightning invoice' , async ( ) => {
27104 const inputParams = {
0 commit comments