@bsv/message-box-client 2.0.5 → 2.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/package.json +2 -2
- package/dist/cjs/src/PeerPayClient.js +463 -62
- package/dist/cjs/src/PeerPayClient.js.map +1 -1
- package/dist/cjs/src/__tests/PeerPayClientRequestIntegration.test.js +317 -0
- package/dist/cjs/src/__tests/PeerPayClientRequestIntegration.test.js.map +1 -0
- package/dist/cjs/src/__tests/PeerPayClientUnit.test.js +505 -1
- package/dist/cjs/src/__tests/PeerPayClientUnit.test.js.map +1 -1
- package/dist/cjs/src/types.js +5 -0
- package/dist/cjs/src/types.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/PeerPayClient.js +459 -61
- package/dist/esm/src/PeerPayClient.js.map +1 -1
- package/dist/esm/src/__tests/PeerPayClientRequestIntegration.test.js +312 -0
- package/dist/esm/src/__tests/PeerPayClientRequestIntegration.test.js.map +1 -0
- package/dist/esm/src/__tests/PeerPayClientUnit.test.js +505 -1
- package/dist/esm/src/__tests/PeerPayClientUnit.test.js.map +1 -1
- package/dist/esm/src/types.js +4 -1
- package/dist/esm/src/types.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/PeerPayClient.d.ts +160 -0
- package/dist/types/src/PeerPayClient.d.ts.map +1 -1
- package/dist/types/src/__tests/PeerPayClientRequestIntegration.test.d.ts +10 -0
- package/dist/types/src/__tests/PeerPayClientRequestIntegration.test.d.ts.map +1 -0
- package/dist/types/src/types.d.ts +88 -0
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +1 -1
- package/package.json +2 -2
- package/src/PeerPayClient.ts +526 -69
- package/src/__tests/PeerPayClientRequestIntegration.test.ts +364 -0
- package/src/__tests/PeerPayClientUnit.test.ts +594 -1
- package/src/types.ts +95 -0
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
/* eslint-env jest */
|
|
2
|
+
/**
|
|
3
|
+
* Integration tests for the PeerPayClient payment request flow.
|
|
4
|
+
*
|
|
5
|
+
* Uses a MockMessageBus to simulate the MessageBox server in memory,
|
|
6
|
+
* wiring the PeerPayClient methods (sendMessage, listMessages, acknowledgeMessage,
|
|
7
|
+
* getIdentityKey) to the mock bus so that full round-trip flows can be tested
|
|
8
|
+
* without hitting a real server.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { PeerPayClient, PAYMENT_REQUESTS_MESSAGEBOX, PAYMENT_REQUEST_RESPONSES_MESSAGEBOX, STANDARD_PAYMENT_MESSAGEBOX } from '../PeerPayClient.js'
|
|
12
|
+
import { PeerMessage } from '../types.js'
|
|
13
|
+
import { PrivateKey, CreateHmacResult, WalletClient } from '@bsv/sdk'
|
|
14
|
+
import { jest } from '@jest/globals'
|
|
15
|
+
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Mock @bsv/sdk the same way as PeerPayClientUnit.test.ts
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
jest.mock('@bsv/sdk', () => {
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
21
|
+
const actualSDK = jest.requireActual('@bsv/sdk') as any
|
|
22
|
+
return {
|
|
23
|
+
...actualSDK,
|
|
24
|
+
WalletClient: jest.fn().mockImplementation(() => ({
|
|
25
|
+
getPublicKey: jest.fn(),
|
|
26
|
+
createAction: jest.fn(),
|
|
27
|
+
internalizeAction: jest.fn(),
|
|
28
|
+
createHmac: jest.fn<() => Promise<CreateHmacResult>>().mockResolvedValue({
|
|
29
|
+
hmac: [1, 2, 3, 4, 5]
|
|
30
|
+
}),
|
|
31
|
+
verifyHmac: jest.fn<() => Promise<{ valid: true }>>().mockResolvedValue({ valid: true as const })
|
|
32
|
+
}))
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
// MockMessageBus
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
/**
|
|
40
|
+
* Stores messages per (recipient, messageBox) pair in memory.
|
|
41
|
+
* Provides send / list / ack helpers that the wired client delegates to.
|
|
42
|
+
*/
|
|
43
|
+
class MockMessageBus {
|
|
44
|
+
private counter = 0
|
|
45
|
+
// key: `${recipient}::${messageBox}`
|
|
46
|
+
private readonly store = new Map<string, PeerMessage[]>()
|
|
47
|
+
|
|
48
|
+
private key (recipient: string, messageBox: string): string {
|
|
49
|
+
return `${recipient}::${messageBox}`
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
send (params: { recipient: string, messageBox: string, body: string, sender: string }): { status: string, messageId: string } {
|
|
53
|
+
const { recipient, messageBox, body, sender } = params
|
|
54
|
+
const k = this.key(recipient, messageBox)
|
|
55
|
+
const messageId = `msg-${++this.counter}`
|
|
56
|
+
const now = new Date().toISOString()
|
|
57
|
+
const msg: PeerMessage = { messageId, sender, body, created_at: now, updated_at: now }
|
|
58
|
+
const existing = this.store.get(k)
|
|
59
|
+
if (existing != null) {
|
|
60
|
+
existing.push(msg)
|
|
61
|
+
} else {
|
|
62
|
+
this.store.set(k, [msg])
|
|
63
|
+
}
|
|
64
|
+
return { status: 'success', messageId }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
list (recipient: string, messageBox: string): PeerMessage[] {
|
|
68
|
+
return this.store.get(this.key(recipient, messageBox)) ?? []
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
ack (recipient: string, messageBox: string, messageIds: string[]): void {
|
|
72
|
+
const k = this.key(recipient, messageBox)
|
|
73
|
+
const msgs = this.store.get(k)
|
|
74
|
+
if (msgs == null) return
|
|
75
|
+
const remaining = msgs.filter(m => !messageIds.includes(m.messageId))
|
|
76
|
+
this.store.set(k, remaining)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Convenience: clear everything */
|
|
80
|
+
reset (): void {
|
|
81
|
+
this.store.clear()
|
|
82
|
+
this.counter = 0
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
// createWiredClient
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
/**
|
|
90
|
+
* Creates a PeerPayClient whose sendMessage, listMessages, acknowledgeMessage,
|
|
91
|
+
* and getIdentityKey are wired to the provided MockMessageBus instance.
|
|
92
|
+
*
|
|
93
|
+
* The identityKey is the "address" used as recipient/sender for messages
|
|
94
|
+
* sent through the bus.
|
|
95
|
+
*
|
|
96
|
+
* sendPayment is mocked to be a no-op so tests that call fulfillPaymentRequest
|
|
97
|
+
* don't need a real wallet.
|
|
98
|
+
*/
|
|
99
|
+
function createWiredClient (params: {
|
|
100
|
+
bus: MockMessageBus
|
|
101
|
+
identityKey: string
|
|
102
|
+
walletClient: jest.Mocked<WalletClient>
|
|
103
|
+
}): PeerPayClient {
|
|
104
|
+
const { bus, identityKey, walletClient } = params
|
|
105
|
+
|
|
106
|
+
const client = new PeerPayClient({
|
|
107
|
+
messageBoxHost: 'https://messagebox.babbage.systems',
|
|
108
|
+
walletClient
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
// Wire getIdentityKey
|
|
112
|
+
jest.spyOn(client, 'getIdentityKey').mockResolvedValue(identityKey)
|
|
113
|
+
|
|
114
|
+
// Wire sendMessage: route to the bus using the current client identity as sender
|
|
115
|
+
jest.spyOn(client, 'sendMessage').mockImplementation(async (sendParams: any) => {
|
|
116
|
+
const body = typeof sendParams.body === 'string' ? sendParams.body : JSON.stringify(sendParams.body)
|
|
117
|
+
return bus.send({
|
|
118
|
+
recipient: sendParams.recipient,
|
|
119
|
+
messageBox: sendParams.messageBox,
|
|
120
|
+
body,
|
|
121
|
+
sender: identityKey
|
|
122
|
+
})
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
// Wire listMessages: retrieve from bus for this identity as recipient
|
|
126
|
+
jest.spyOn(client, 'listMessages').mockImplementation(async (listParams: any) => {
|
|
127
|
+
return bus.list(identityKey, listParams.messageBox)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
// Wire acknowledgeMessage: remove messages from bus
|
|
131
|
+
// We need to know which messageBox to remove from — scan all boxes for this recipient
|
|
132
|
+
jest.spyOn(client, 'acknowledgeMessage').mockImplementation(async (ackParams: any) => {
|
|
133
|
+
const { messageIds } = ackParams
|
|
134
|
+
// Attempt to ack from all known messageBoxes
|
|
135
|
+
for (const mb of [PAYMENT_REQUESTS_MESSAGEBOX, PAYMENT_REQUEST_RESPONSES_MESSAGEBOX, STANDARD_PAYMENT_MESSAGEBOX]) {
|
|
136
|
+
bus.ack(identityKey, mb, messageIds)
|
|
137
|
+
}
|
|
138
|
+
return 'acknowledged'
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
// Mock sendPayment to be a no-op (avoids needing real wallet for tx creation)
|
|
142
|
+
jest.spyOn(client, 'sendPayment').mockResolvedValue(undefined)
|
|
143
|
+
|
|
144
|
+
return client
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// ---------------------------------------------------------------------------
|
|
148
|
+
// Tests
|
|
149
|
+
// ---------------------------------------------------------------------------
|
|
150
|
+
describe('PeerPayClient — Integration: payment request flow', () => {
|
|
151
|
+
let bus: MockMessageBus
|
|
152
|
+
let mockWalletRequester: jest.Mocked<WalletClient>
|
|
153
|
+
let mockWalletPayer: jest.Mocked<WalletClient>
|
|
154
|
+
const REQUESTER_KEY = PrivateKey.fromRandom().toPublicKey().toString()
|
|
155
|
+
const PAYER_KEY = PrivateKey.fromRandom().toPublicKey().toString()
|
|
156
|
+
|
|
157
|
+
beforeEach(() => {
|
|
158
|
+
jest.clearAllMocks()
|
|
159
|
+
bus = new MockMessageBus()
|
|
160
|
+
|
|
161
|
+
mockWalletRequester = new WalletClient() as jest.Mocked<WalletClient>
|
|
162
|
+
mockWalletRequester.getPublicKey.mockResolvedValue({ publicKey: REQUESTER_KEY })
|
|
163
|
+
|
|
164
|
+
mockWalletPayer = new WalletClient() as jest.Mocked<WalletClient>
|
|
165
|
+
mockWalletPayer.getPublicKey.mockResolvedValue({ publicKey: PAYER_KEY })
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
// -------------------------------------------------------------------------
|
|
169
|
+
// Test 1: Full round-trip — request → fulfill → requester sees paid response
|
|
170
|
+
// -------------------------------------------------------------------------
|
|
171
|
+
it('Test 1: full round-trip: request → fulfill → requester sees paid response', async () => {
|
|
172
|
+
const requester = createWiredClient({ bus, identityKey: REQUESTER_KEY, walletClient: mockWalletRequester })
|
|
173
|
+
const payer = createWiredClient({ bus, identityKey: PAYER_KEY, walletClient: mockWalletPayer })
|
|
174
|
+
|
|
175
|
+
// Requester sends a payment request to payer
|
|
176
|
+
const { requestId } = await requester.requestPayment({
|
|
177
|
+
recipient: PAYER_KEY,
|
|
178
|
+
amount: 5000,
|
|
179
|
+
description: 'Invoice #1',
|
|
180
|
+
expiresAt: Date.now() + 60000
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
expect(requestId).toBeTruthy()
|
|
184
|
+
|
|
185
|
+
// Payer lists incoming requests
|
|
186
|
+
const incoming = await payer.listIncomingPaymentRequests()
|
|
187
|
+
expect(incoming).toHaveLength(1)
|
|
188
|
+
expect(incoming[0].requestId).toBe(requestId)
|
|
189
|
+
expect(incoming[0].amount).toBe(5000)
|
|
190
|
+
|
|
191
|
+
// Payer fulfills the request
|
|
192
|
+
await payer.fulfillPaymentRequest({ request: incoming[0] })
|
|
193
|
+
|
|
194
|
+
// Requester checks for responses
|
|
195
|
+
const responses = await requester.listPaymentRequestResponses()
|
|
196
|
+
expect(responses).toHaveLength(1)
|
|
197
|
+
expect(responses[0]).toMatchObject({ requestId, status: 'paid', amountPaid: 5000 })
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
// -------------------------------------------------------------------------
|
|
201
|
+
// Test 2: Full round-trip — request → decline → requester sees declined
|
|
202
|
+
// -------------------------------------------------------------------------
|
|
203
|
+
it('Test 2: full round-trip: request → decline → requester sees declined response', async () => {
|
|
204
|
+
const requester = createWiredClient({ bus, identityKey: REQUESTER_KEY, walletClient: mockWalletRequester })
|
|
205
|
+
const payer = createWiredClient({ bus, identityKey: PAYER_KEY, walletClient: mockWalletPayer })
|
|
206
|
+
|
|
207
|
+
const { requestId } = await requester.requestPayment({
|
|
208
|
+
recipient: PAYER_KEY,
|
|
209
|
+
amount: 3000,
|
|
210
|
+
description: 'Invoice #2',
|
|
211
|
+
expiresAt: Date.now() + 60000
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
const incoming = await payer.listIncomingPaymentRequests()
|
|
215
|
+
expect(incoming).toHaveLength(1)
|
|
216
|
+
|
|
217
|
+
await payer.declinePaymentRequest({ request: incoming[0], note: 'No funds' })
|
|
218
|
+
|
|
219
|
+
const responses = await requester.listPaymentRequestResponses()
|
|
220
|
+
expect(responses).toHaveLength(1)
|
|
221
|
+
expect(responses[0]).toMatchObject({ requestId, status: 'declined', note: 'No funds' })
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
// -------------------------------------------------------------------------
|
|
225
|
+
// Test 3: Request → cancel → payer no longer sees the request
|
|
226
|
+
// -------------------------------------------------------------------------
|
|
227
|
+
it('Test 3: request → cancel → payer no longer sees the request', async () => {
|
|
228
|
+
const requester = createWiredClient({ bus, identityKey: REQUESTER_KEY, walletClient: mockWalletRequester })
|
|
229
|
+
const payer = createWiredClient({ bus, identityKey: PAYER_KEY, walletClient: mockWalletPayer })
|
|
230
|
+
|
|
231
|
+
const { requestId, requestProof } = await requester.requestPayment({
|
|
232
|
+
recipient: PAYER_KEY,
|
|
233
|
+
amount: 2000,
|
|
234
|
+
description: 'Cancellable request',
|
|
235
|
+
expiresAt: Date.now() + 60000
|
|
236
|
+
})
|
|
237
|
+
|
|
238
|
+
// Confirm payer can see it before cancellation
|
|
239
|
+
const beforeCancel = await payer.listIncomingPaymentRequests()
|
|
240
|
+
expect(beforeCancel).toHaveLength(1)
|
|
241
|
+
|
|
242
|
+
// Requester cancels the request
|
|
243
|
+
await requester.cancelPaymentRequest({ recipient: PAYER_KEY, requestId, requestProof })
|
|
244
|
+
|
|
245
|
+
// Payer should now see zero active requests (the cancel message causes filtering)
|
|
246
|
+
const afterCancel = await payer.listIncomingPaymentRequests()
|
|
247
|
+
expect(afterCancel).toHaveLength(0)
|
|
248
|
+
})
|
|
249
|
+
|
|
250
|
+
// -------------------------------------------------------------------------
|
|
251
|
+
// Test 4: Expired request is filtered out automatically
|
|
252
|
+
// -------------------------------------------------------------------------
|
|
253
|
+
it('Test 4: expired request is filtered out automatically', async () => {
|
|
254
|
+
const payer = createWiredClient({ bus, identityKey: PAYER_KEY, walletClient: mockWalletPayer })
|
|
255
|
+
|
|
256
|
+
// Inject an already-expired request directly onto the bus (expiresAt in the past)
|
|
257
|
+
const expiredBody = JSON.stringify({
|
|
258
|
+
requestId: 'expired-req-1',
|
|
259
|
+
amount: 4000,
|
|
260
|
+
description: 'Already expired',
|
|
261
|
+
expiresAt: Date.now() - 10000, // in the past
|
|
262
|
+
senderIdentityKey: REQUESTER_KEY,
|
|
263
|
+
requestProof: 'mock-proof'
|
|
264
|
+
})
|
|
265
|
+
bus.send({ recipient: PAYER_KEY, messageBox: PAYMENT_REQUESTS_MESSAGEBOX, body: expiredBody, sender: REQUESTER_KEY })
|
|
266
|
+
|
|
267
|
+
// Also inject a valid request so the filter has something to keep
|
|
268
|
+
const validBody = JSON.stringify({
|
|
269
|
+
requestId: 'valid-req-1',
|
|
270
|
+
amount: 4000,
|
|
271
|
+
description: 'Still valid',
|
|
272
|
+
expiresAt: Date.now() + 60000,
|
|
273
|
+
senderIdentityKey: REQUESTER_KEY,
|
|
274
|
+
requestProof: 'mock-proof'
|
|
275
|
+
})
|
|
276
|
+
bus.send({ recipient: PAYER_KEY, messageBox: PAYMENT_REQUESTS_MESSAGEBOX, body: validBody, sender: REQUESTER_KEY })
|
|
277
|
+
|
|
278
|
+
const requests = await payer.listIncomingPaymentRequests()
|
|
279
|
+
expect(requests).toHaveLength(1)
|
|
280
|
+
expect(requests[0].requestId).toBe('valid-req-1')
|
|
281
|
+
})
|
|
282
|
+
|
|
283
|
+
// -------------------------------------------------------------------------
|
|
284
|
+
// Test 5: Requests below minAmount are auto-acknowledged and excluded
|
|
285
|
+
// -------------------------------------------------------------------------
|
|
286
|
+
it('Test 5: requests below minAmount are auto-acknowledged and excluded', async () => {
|
|
287
|
+
const payer = createWiredClient({ bus, identityKey: PAYER_KEY, walletClient: mockWalletPayer })
|
|
288
|
+
|
|
289
|
+
// Inject a request below the minAmount threshold
|
|
290
|
+
const smallBody = JSON.stringify({
|
|
291
|
+
requestId: 'req-small',
|
|
292
|
+
amount: 100, // below minAmount of 1000
|
|
293
|
+
description: 'Too small',
|
|
294
|
+
expiresAt: Date.now() + 60000,
|
|
295
|
+
senderIdentityKey: REQUESTER_KEY,
|
|
296
|
+
requestProof: 'mock-proof'
|
|
297
|
+
})
|
|
298
|
+
bus.send({ recipient: PAYER_KEY, messageBox: PAYMENT_REQUESTS_MESSAGEBOX, body: smallBody, sender: REQUESTER_KEY })
|
|
299
|
+
|
|
300
|
+
// Inject a valid request that passes the filter
|
|
301
|
+
const okBody = JSON.stringify({
|
|
302
|
+
requestId: 'req-ok',
|
|
303
|
+
amount: 5000,
|
|
304
|
+
description: 'Just right',
|
|
305
|
+
expiresAt: Date.now() + 60000,
|
|
306
|
+
senderIdentityKey: REQUESTER_KEY,
|
|
307
|
+
requestProof: 'mock-proof'
|
|
308
|
+
})
|
|
309
|
+
bus.send({ recipient: PAYER_KEY, messageBox: PAYMENT_REQUESTS_MESSAGEBOX, body: okBody, sender: REQUESTER_KEY })
|
|
310
|
+
|
|
311
|
+
const requests = await payer.listIncomingPaymentRequests(undefined, { minAmount: 1000, maxAmount: 10000 })
|
|
312
|
+
expect(requests).toHaveLength(1)
|
|
313
|
+
expect(requests[0].requestId).toBe('req-ok')
|
|
314
|
+
|
|
315
|
+
// The small request should have been auto-acknowledged (removed from bus)
|
|
316
|
+
const remaining = bus.list(PAYER_KEY, PAYMENT_REQUESTS_MESSAGEBOX)
|
|
317
|
+
const remainingIds = remaining.map(m => {
|
|
318
|
+
const b = JSON.parse(m.body as string)
|
|
319
|
+
return b.requestId
|
|
320
|
+
})
|
|
321
|
+
expect(remainingIds).not.toContain('req-small')
|
|
322
|
+
})
|
|
323
|
+
|
|
324
|
+
// -------------------------------------------------------------------------
|
|
325
|
+
// Test 6: Requests above maxAmount are auto-acknowledged and excluded
|
|
326
|
+
// -------------------------------------------------------------------------
|
|
327
|
+
it('Test 6: requests above maxAmount are auto-acknowledged and excluded', async () => {
|
|
328
|
+
const payer = createWiredClient({ bus, identityKey: PAYER_KEY, walletClient: mockWalletPayer })
|
|
329
|
+
|
|
330
|
+
// Inject a request above the maxAmount threshold
|
|
331
|
+
const largeBody = JSON.stringify({
|
|
332
|
+
requestId: 'req-large',
|
|
333
|
+
amount: 99999, // above maxAmount of 10000
|
|
334
|
+
description: 'Too large',
|
|
335
|
+
expiresAt: Date.now() + 60000,
|
|
336
|
+
senderIdentityKey: REQUESTER_KEY,
|
|
337
|
+
requestProof: 'mock-proof'
|
|
338
|
+
})
|
|
339
|
+
bus.send({ recipient: PAYER_KEY, messageBox: PAYMENT_REQUESTS_MESSAGEBOX, body: largeBody, sender: REQUESTER_KEY })
|
|
340
|
+
|
|
341
|
+
// Inject a valid request that passes the filter
|
|
342
|
+
const okBody = JSON.stringify({
|
|
343
|
+
requestId: 'req-ok-2',
|
|
344
|
+
amount: 5000,
|
|
345
|
+
description: 'Just right',
|
|
346
|
+
expiresAt: Date.now() + 60000,
|
|
347
|
+
senderIdentityKey: REQUESTER_KEY,
|
|
348
|
+
requestProof: 'mock-proof'
|
|
349
|
+
})
|
|
350
|
+
bus.send({ recipient: PAYER_KEY, messageBox: PAYMENT_REQUESTS_MESSAGEBOX, body: okBody, sender: REQUESTER_KEY })
|
|
351
|
+
|
|
352
|
+
const requests = await payer.listIncomingPaymentRequests(undefined, { minAmount: 1000, maxAmount: 10000 })
|
|
353
|
+
expect(requests).toHaveLength(1)
|
|
354
|
+
expect(requests[0].requestId).toBe('req-ok-2')
|
|
355
|
+
|
|
356
|
+
// The large request should have been auto-acknowledged (removed from bus)
|
|
357
|
+
const remaining = bus.list(PAYER_KEY, PAYMENT_REQUESTS_MESSAGEBOX)
|
|
358
|
+
const remainingIds = remaining.map(m => {
|
|
359
|
+
const b = JSON.parse(m.body as string)
|
|
360
|
+
return b.requestId
|
|
361
|
+
})
|
|
362
|
+
expect(remainingIds).not.toContain('req-large')
|
|
363
|
+
})
|
|
364
|
+
})
|