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