@bsv/message-box-client 1.1.7 → 1.1.8

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 (78) hide show
  1. package/dist/cjs/mod.js +20 -0
  2. package/dist/cjs/mod.js.map +1 -0
  3. package/dist/cjs/package.json +69 -0
  4. package/dist/cjs/src/MessageBoxClient.js +1171 -0
  5. package/dist/cjs/src/MessageBoxClient.js.map +1 -0
  6. package/dist/cjs/src/PeerPayClient.js +309 -0
  7. package/dist/cjs/src/PeerPayClient.js.map +1 -0
  8. package/dist/cjs/src/Utils/logger.js +27 -0
  9. package/dist/cjs/src/Utils/logger.js.map +1 -0
  10. package/dist/cjs/src/__tests/MessageBoxClient.test.js +614 -0
  11. package/dist/cjs/src/__tests/MessageBoxClient.test.js.map +1 -0
  12. package/dist/cjs/src/__tests/PeerPayClientUnit.test.js +213 -0
  13. package/dist/cjs/src/__tests/PeerPayClientUnit.test.js.map +1 -0
  14. package/dist/cjs/src/__tests/integration/integrationEncrypted.test.js +84 -0
  15. package/dist/cjs/src/__tests/integration/integrationEncrypted.test.js.map +1 -0
  16. package/dist/cjs/src/__tests/integration/integrationHTTP.test.js +128 -0
  17. package/dist/cjs/src/__tests/integration/integrationHTTP.test.js.map +1 -0
  18. package/dist/cjs/src/__tests/integration/integrationOverlay.test.js +138 -0
  19. package/dist/cjs/src/__tests/integration/integrationOverlay.test.js.map +1 -0
  20. package/dist/cjs/src/__tests/integration/integrationWS.test.js +123 -0
  21. package/dist/cjs/src/__tests/integration/integrationWS.test.js.map +1 -0
  22. package/dist/cjs/src/__tests/integration/testServer.js +65 -0
  23. package/dist/cjs/src/__tests/integration/testServer.js.map +1 -0
  24. package/dist/cjs/src/types.js +3 -0
  25. package/dist/cjs/src/types.js.map +1 -0
  26. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -0
  27. package/dist/esm/mod.js +4 -0
  28. package/dist/esm/mod.js.map +1 -0
  29. package/dist/esm/src/MessageBoxClient.js +1165 -0
  30. package/dist/esm/src/MessageBoxClient.js.map +1 -0
  31. package/dist/esm/src/PeerPayClient.js +307 -0
  32. package/dist/esm/src/PeerPayClient.js.map +1 -0
  33. package/dist/esm/src/Utils/logger.js +23 -0
  34. package/dist/esm/src/Utils/logger.js.map +1 -0
  35. package/dist/esm/src/__tests/MessageBoxClient.test.js +603 -0
  36. package/dist/esm/src/__tests/MessageBoxClient.test.js.map +1 -0
  37. package/dist/esm/src/__tests/PeerPayClientUnit.test.js +211 -0
  38. package/dist/esm/src/__tests/PeerPayClientUnit.test.js.map +1 -0
  39. package/dist/esm/src/__tests/integration/integrationEncrypted.test.js +81 -0
  40. package/dist/esm/src/__tests/integration/integrationEncrypted.test.js.map +1 -0
  41. package/dist/esm/src/__tests/integration/integrationHTTP.test.js +126 -0
  42. package/dist/esm/src/__tests/integration/integrationHTTP.test.js.map +1 -0
  43. package/dist/esm/src/__tests/integration/integrationOverlay.test.js +135 -0
  44. package/dist/esm/src/__tests/integration/integrationOverlay.test.js.map +1 -0
  45. package/dist/esm/src/__tests/integration/integrationWS.test.js +121 -0
  46. package/dist/esm/src/__tests/integration/integrationWS.test.js.map +1 -0
  47. package/dist/esm/src/__tests/integration/testServer.js +61 -0
  48. package/dist/esm/src/__tests/integration/testServer.js.map +1 -0
  49. package/dist/esm/src/types.js +2 -0
  50. package/dist/esm/src/types.js.map +1 -0
  51. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -0
  52. package/dist/types/mod.d.ts +4 -0
  53. package/dist/types/mod.d.ts.map +1 -0
  54. package/dist/types/src/MessageBoxClient.d.ts +441 -0
  55. package/dist/types/src/MessageBoxClient.d.ts.map +1 -0
  56. package/dist/types/src/PeerPayClient.d.ts +144 -0
  57. package/dist/types/src/PeerPayClient.d.ts.map +1 -0
  58. package/dist/types/src/Utils/logger.d.ts +9 -0
  59. package/dist/types/src/Utils/logger.d.ts.map +1 -0
  60. package/dist/types/src/__tests/MessageBoxClient.test.d.ts +2 -0
  61. package/dist/types/src/__tests/MessageBoxClient.test.d.ts.map +1 -0
  62. package/dist/types/src/__tests/PeerPayClientUnit.test.d.ts +2 -0
  63. package/dist/types/src/__tests/PeerPayClientUnit.test.d.ts.map +1 -0
  64. package/dist/types/src/__tests/integration/integrationEncrypted.test.d.ts +2 -0
  65. package/dist/types/src/__tests/integration/integrationEncrypted.test.d.ts.map +1 -0
  66. package/dist/types/src/__tests/integration/integrationHTTP.test.d.ts +2 -0
  67. package/dist/types/src/__tests/integration/integrationHTTP.test.d.ts.map +1 -0
  68. package/dist/types/src/__tests/integration/integrationOverlay.test.d.ts +2 -0
  69. package/dist/types/src/__tests/integration/integrationOverlay.test.d.ts.map +1 -0
  70. package/dist/types/src/__tests/integration/integrationWS.test.d.ts +2 -0
  71. package/dist/types/src/__tests/integration/integrationWS.test.d.ts.map +1 -0
  72. package/dist/types/src/__tests/integration/testServer.d.ts +9 -0
  73. package/dist/types/src/__tests/integration/testServer.d.ts.map +1 -0
  74. package/dist/types/src/types.d.ts +99 -0
  75. package/dist/types/src/types.d.ts.map +1 -0
  76. package/dist/types/tsconfig.types.tsbuildinfo +1 -0
  77. package/dist/umd/bundle.js +1 -0
  78. package/package.json +5 -5
@@ -0,0 +1,211 @@
1
+ /* eslint-env jest */
2
+ import { PeerPayClient } from '../PeerPayClient.js';
3
+ import { WalletClient, PrivateKey } from '@bsv/sdk';
4
+ import { jest } from '@jest/globals';
5
+ const toArray = (msg, enc) => {
6
+ if (Array.isArray(msg))
7
+ return msg.slice();
8
+ if (msg === undefined)
9
+ return [];
10
+ if (typeof msg !== 'string') {
11
+ return Array.from(msg, (item) => item | 0);
12
+ }
13
+ switch (enc) {
14
+ case 'hex': {
15
+ const matches = msg.match(/.{1,2}/g);
16
+ return matches != null ? matches.map(byte => parseInt(byte, 16)) : [];
17
+ }
18
+ case 'base64':
19
+ return Array.from(Buffer.from(msg, 'base64'));
20
+ default:
21
+ return Array.from(Buffer.from(msg, 'utf8'));
22
+ }
23
+ };
24
+ // Mock dependencies
25
+ jest.mock('@bsv/sdk', () => {
26
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
27
+ const actualSDK = jest.requireActual('@bsv/sdk');
28
+ return {
29
+ ...actualSDK,
30
+ WalletClient: jest.fn().mockImplementation(() => ({
31
+ getPublicKey: jest.fn(),
32
+ createAction: jest.fn(),
33
+ internalizeAction: jest.fn(),
34
+ createHmac: jest.fn().mockResolvedValue({
35
+ hmac: [1, 2, 3, 4, 5]
36
+ })
37
+ }))
38
+ };
39
+ });
40
+ describe('PeerPayClient Unit Tests', () => {
41
+ let peerPayClient;
42
+ let mockWalletClient;
43
+ beforeEach(() => {
44
+ jest.clearAllMocks();
45
+ mockWalletClient = new WalletClient();
46
+ // Ensure a valid compressed public key (33 bytes, hex format)
47
+ mockWalletClient.getPublicKey.mockResolvedValue({
48
+ publicKey: PrivateKey.fromRandom().toPublicKey().toString()
49
+ });
50
+ mockWalletClient.createAction.mockResolvedValue({
51
+ tx: toArray('mockedTransaction', 'utf8')
52
+ });
53
+ peerPayClient = new PeerPayClient({
54
+ messageBoxHost: 'https://messagebox.babbage.systems',
55
+ walletClient: mockWalletClient
56
+ });
57
+ });
58
+ describe('createPaymentToken', () => {
59
+ it('should create a valid payment token', async () => {
60
+ mockWalletClient.getPublicKey.mockResolvedValue({
61
+ publicKey: PrivateKey.fromRandom().toPublicKey().toString()
62
+ });
63
+ mockWalletClient.createAction.mockResolvedValue({ tx: toArray('mockedTransaction', 'utf8') });
64
+ const payment = { recipient: PrivateKey.fromRandom().toPublicKey().toString(), amount: 5 };
65
+ const token = await peerPayClient.createPaymentToken(payment);
66
+ expect(token).toHaveProperty('amount', 5);
67
+ expect(mockWalletClient.getPublicKey).toHaveBeenCalledWith(expect.any(Object));
68
+ expect(mockWalletClient.createAction).toHaveBeenCalledWith(expect.any(Object));
69
+ });
70
+ it('should throw an error if recipient public key cannot be derived', async () => {
71
+ mockWalletClient.getPublicKey.mockResolvedValue({ publicKey: '' }); // Empty key
72
+ await expect(peerPayClient.createPaymentToken({ recipient: 'invalid', amount: 5 }))
73
+ .rejects.toThrow('Failed to derive recipient’s public key');
74
+ });
75
+ it('should throw an error if amount is <= 0', async () => {
76
+ mockWalletClient.getPublicKey
77
+ .mockResolvedValue({
78
+ publicKey: PrivateKey.fromRandom().toPublicKey().toString()
79
+ });
80
+ await expect(peerPayClient.createPaymentToken({
81
+ recipient: PrivateKey.fromRandom().toPublicKey().toString(),
82
+ amount: 0
83
+ }))
84
+ .rejects.toThrow('Invalid payment details: recipient and valid amount are required');
85
+ });
86
+ });
87
+ // Test: sendPayment
88
+ describe('sendPayment', () => {
89
+ it('should call sendMessage with valid payment', async () => {
90
+ const sendMessageSpy = jest.spyOn(peerPayClient, 'sendMessage').mockResolvedValue({
91
+ status: 'success',
92
+ messageId: 'mockedMessageId'
93
+ });
94
+ const payment = { recipient: 'recipientKey', amount: 3 };
95
+ console.log('[TEST] Calling sendPayment...');
96
+ await peerPayClient.sendPayment(payment);
97
+ console.log('[TEST] sendPayment finished.');
98
+ expect(sendMessageSpy).toHaveBeenCalledWith({
99
+ recipient: 'recipientKey',
100
+ messageBox: 'payment_inbox',
101
+ body: expect.any(String)
102
+ });
103
+ }, 10000);
104
+ });
105
+ // Test: sendLivePayment
106
+ describe('sendLivePayment', () => {
107
+ it('should call createPaymentToken and sendLiveMessage with correct parameters', async () => {
108
+ jest.spyOn(peerPayClient, 'createPaymentToken').mockResolvedValue({
109
+ customInstructions: {
110
+ derivationPrefix: 'prefix',
111
+ derivationSuffix: 'suffix'
112
+ },
113
+ transaction: Array.from(new Uint8Array([1, 2, 3, 4, 5])),
114
+ amount: 2
115
+ });
116
+ jest.spyOn(peerPayClient, 'sendLiveMessage').mockResolvedValue({
117
+ status: 'success',
118
+ messageId: 'mockedMessageId'
119
+ });
120
+ const payment = { recipient: 'recipientKey', amount: 2 };
121
+ await peerPayClient.sendLivePayment(payment);
122
+ expect(peerPayClient.createPaymentToken).toHaveBeenCalledWith(payment);
123
+ expect(peerPayClient.sendLiveMessage).toHaveBeenCalledWith({
124
+ recipient: 'recipientKey',
125
+ messageBox: 'payment_inbox',
126
+ body: "{\"customInstructions\":{\"derivationPrefix\":\"prefix\",\"derivationSuffix\":\"suffix\"},\"transaction\":[1,2,3,4,5],\"amount\":2}"
127
+ });
128
+ });
129
+ });
130
+ // Test: acceptPayment
131
+ describe('acceptPayment', () => {
132
+ it('should call internalizeAction and acknowledgeMessage', async () => {
133
+ mockWalletClient.internalizeAction.mockResolvedValue({ accepted: true });
134
+ jest.spyOn(peerPayClient, 'acknowledgeMessage').mockResolvedValue('acknowledged');
135
+ const payment = {
136
+ messageId: '123',
137
+ sender: 'senderKey',
138
+ token: {
139
+ customInstructions: { derivationPrefix: 'prefix', derivationSuffix: 'suffix' },
140
+ transaction: toArray('mockedTransaction', 'utf8'),
141
+ amount: 6
142
+ }
143
+ };
144
+ await peerPayClient.acceptPayment(payment);
145
+ expect(mockWalletClient.internalizeAction).toHaveBeenCalled();
146
+ expect(peerPayClient.acknowledgeMessage).toHaveBeenCalledWith({ messageIds: ['123'] });
147
+ });
148
+ });
149
+ // Test: rejectPayment
150
+ describe('rejectPayment', () => {
151
+ it('should refund payment minus fee', async () => {
152
+ jest.spyOn(peerPayClient, 'acceptPayment').mockResolvedValue(undefined);
153
+ jest.spyOn(peerPayClient, 'sendPayment').mockResolvedValue(undefined);
154
+ jest.spyOn(peerPayClient, 'acknowledgeMessage').mockResolvedValue('acknowledged');
155
+ const payment = {
156
+ messageId: '123',
157
+ sender: 'senderKey',
158
+ token: {
159
+ customInstructions: { derivationPrefix: 'prefix', derivationSuffix: 'suffix' },
160
+ transaction: toArray('mockedTransaction', 'utf8'),
161
+ amount: 2000
162
+ }
163
+ };
164
+ await peerPayClient.rejectPayment(payment);
165
+ expect(peerPayClient.acceptPayment).toHaveBeenCalledWith(payment);
166
+ expect(peerPayClient.sendPayment).toHaveBeenCalledWith({
167
+ recipient: 'senderKey',
168
+ amount: 1000 // Deduct satoshi fee
169
+ });
170
+ expect(peerPayClient.acknowledgeMessage).toHaveBeenCalledWith({
171
+ messageIds: ['123']
172
+ });
173
+ });
174
+ });
175
+ // Test: listIncomingPayments
176
+ describe('listIncomingPayments', () => {
177
+ it('should return parsed payment messages', async () => {
178
+ jest.spyOn(peerPayClient, 'listMessages').mockResolvedValue([
179
+ {
180
+ messageId: '1',
181
+ sender: 'sender1',
182
+ created_at: '2025-03-05T12:00:00Z',
183
+ updated_at: '2025-03-05T12:05:00Z',
184
+ body: JSON.stringify({
185
+ customInstructions: { derivationPrefix: 'prefix1', derivationSuffix: 'suffix1' },
186
+ transaction: toArray('mockedTransaction1', 'utf8'),
187
+ amount: 3
188
+ })
189
+ },
190
+ {
191
+ messageId: '2',
192
+ sender: 'sender2',
193
+ created_at: '2025-03-05T12:10:00Z',
194
+ updated_at: '2025-03-05T12:15:00Z',
195
+ body: JSON.stringify({
196
+ customInstructions: { derivationPrefix: 'prefix2', derivationSuffix: 'suffix2' },
197
+ transaction: toArray('mockedTransaction2', 'utf8'),
198
+ amount: 9
199
+ })
200
+ }
201
+ ]);
202
+ const payments = await peerPayClient.listIncomingPayments();
203
+ expect(payments).toHaveLength(2);
204
+ expect(payments[0]).toHaveProperty('sender', 'sender1');
205
+ expect(payments[0].token.amount).toBe(3);
206
+ expect(payments[1]).toHaveProperty('sender', 'sender2');
207
+ expect(payments[1].token.amount).toBe(9);
208
+ });
209
+ });
210
+ });
211
+ //# sourceMappingURL=PeerPayClientUnit.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PeerPayClientUnit.test.js","sourceRoot":"","sources":["../../../../src/__tests/PeerPayClientUnit.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ /* eslint-env jest */
2
+ import { MessageBoxClient } from '../../MessageBoxClient.js';
3
+ import { WalletClient } from '@bsv/sdk';
4
+ import { webcrypto } from 'crypto';
5
+ import { expect, test, describe, beforeAll } from '@jest/globals';
6
+ global.self = { crypto: webcrypto };
7
+ jest.setTimeout(20000);
8
+ const walletClient = new WalletClient('json-api', 'https://messagebox.babbage.systems');
9
+ const messageBoxClient = new MessageBoxClient({
10
+ host: 'https://messagebox.babbage.systems',
11
+ walletClient,
12
+ enableLogging: true,
13
+ networkPreset: 'local'
14
+ });
15
+ let identityKey;
16
+ describe('Encryption Integration Tests', () => {
17
+ const messageBox = 'testBox';
18
+ const plaintext = 'This is a secure test message.';
19
+ beforeAll(async () => {
20
+ const result = await walletClient.getPublicKey({ identityKey: true });
21
+ identityKey = result.publicKey;
22
+ await messageBoxClient.initializeConnection();
23
+ });
24
+ test('encrypts and decrypts a message to self successfully', async () => {
25
+ // Encrypt
26
+ const { ciphertext } = await walletClient.encrypt({
27
+ plaintext: Array.from(new TextEncoder().encode(plaintext)),
28
+ protocolID: [1, 'messagebox'],
29
+ keyID: '1',
30
+ counterparty: 'self'
31
+ });
32
+ expect(Array.isArray(ciphertext)).toBe(true);
33
+ expect(ciphertext.length).toBeGreaterThan(0);
34
+ // Decrypt
35
+ const { plaintext: decryptedBytes } = await walletClient.decrypt({
36
+ ciphertext,
37
+ protocolID: [1, 'messagebox'],
38
+ keyID: '1',
39
+ counterparty: 'self'
40
+ });
41
+ const decrypted = new TextDecoder().decode(Uint8Array.from(decryptedBytes));
42
+ expect(decrypted).toBe(plaintext);
43
+ });
44
+ test('sends and receives encrypted message using MessageBoxClient', async () => {
45
+ // Send message to self
46
+ const sendResult = await messageBoxClient.sendMessage({
47
+ recipient: identityKey,
48
+ messageBox,
49
+ body: plaintext
50
+ });
51
+ expect(sendResult.status).toBe('success');
52
+ expect(typeof sendResult.messageId).toBe('string');
53
+ // List and decrypt
54
+ const messages = await messageBoxClient.listMessages({ messageBox });
55
+ const last = messages.at(-1);
56
+ expect(last).toBeDefined();
57
+ expect(last?.body).toBe(plaintext);
58
+ });
59
+ test('encrypted message is not stored or transmitted as plaintext', async () => {
60
+ // Send encrypted message to self
61
+ const sendResult = await messageBoxClient.sendMessage({
62
+ recipient: identityKey,
63
+ messageBox,
64
+ body: plaintext
65
+ });
66
+ expect(sendResult.status).toBe('success');
67
+ // Manually fetch raw HTTP response
68
+ const fetch = await messageBoxClient.authFetch.fetch('https://messagebox.babbage.systems/listMessages', {
69
+ method: 'POST',
70
+ headers: { 'Content-Type': 'application/json' },
71
+ body: JSON.stringify({ messageBox })
72
+ });
73
+ const raw = await fetch.json();
74
+ const rawBody = raw.messages.at(-1)?.body;
75
+ expect(typeof rawBody).toBe('string');
76
+ const parsed = JSON.parse(rawBody);
77
+ expect(typeof parsed.encryptedMessage).toBe('string');
78
+ expect(parsed.encryptedMessage.includes(plaintext)).toBe(false);
79
+ });
80
+ });
81
+ //# sourceMappingURL=integrationEncrypted.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrationEncrypted.test.js","sourceRoot":"","sources":["../../../../../src/__tests/integration/integrationEncrypted.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,126 @@
1
+ /* eslint-env jest */
2
+ import { MessageBoxClient } from '../../MessageBoxClient.js';
3
+ import { WalletClient } from '@bsv/sdk';
4
+ import { webcrypto } from 'crypto';
5
+ // Ensure Jest doesn't mock WalletClient
6
+ jest.unmock('@bsv/sdk');
7
+ global.self = { crypto: webcrypto };
8
+ jest.setTimeout(20000);
9
+ // Explicitly initialize WalletClient with Meta Net Client (MNC)
10
+ const walletClient = new WalletClient('json-api', 'localhost');
11
+ // Initialize MessageBoxClient for HTTP-Only Testing
12
+ const messageBoxClient = new MessageBoxClient({
13
+ host: 'https://messagebox.babbage.systems',
14
+ walletClient
15
+ });
16
+ describe('MessageBoxClient HTTP Integration Tests (No WebSocket)', () => {
17
+ let recipientKey;
18
+ let testMessageId;
19
+ const messageBox = 'testBox';
20
+ const testMessage = 'Hello, this is an integration test.';
21
+ const testMessage2 = 'Another test message to avoid duplicates.';
22
+ beforeAll(async () => {
23
+ try {
24
+ console.log('[DEBUG] Retrieving public key...');
25
+ const publicKeyResponse = await walletClient.getPublicKey({ identityKey: true });
26
+ if (publicKeyResponse?.publicKey == null ||
27
+ typeof publicKeyResponse.publicKey !== 'string' ||
28
+ publicKeyResponse.publicKey.trim() === '') {
29
+ throw new Error('[ERROR] getPublicKey returned an invalid key!');
30
+ }
31
+ recipientKey = publicKeyResponse.publicKey.trim();
32
+ console.log('[DEBUG] Successfully assigned recipientKey:', recipientKey);
33
+ // Ensure identity key is set internally in MessageBoxClient
34
+ await messageBoxClient.initializeConnection();
35
+ }
36
+ catch (error) {
37
+ console.error('[ERROR] Failed to set up test:', error);
38
+ throw error;
39
+ }
40
+ });
41
+ afterAll(async () => {
42
+ try {
43
+ if (testMessageId !== undefined && testMessageId !== '') {
44
+ console.log('[DEBUG] Cleaning up test messages...');
45
+ }
46
+ }
47
+ catch (error) {
48
+ console.error('[ERROR] Failed to acknowledge test message:', error);
49
+ }
50
+ });
51
+ /** TEST 1: Send a Message with Correct Payment **/
52
+ test('should send a message successfully with correct payment', async () => {
53
+ const response = await messageBoxClient.sendMessage({
54
+ recipient: recipientKey,
55
+ messageBox,
56
+ body: testMessage,
57
+ skipEncryption: true // TEMPORARY to test if this fixes the 400
58
+ });
59
+ console.log('[DEBUG] SendMessage Response:', response);
60
+ expect(response).toHaveProperty('status', 'success');
61
+ expect(response).toHaveProperty('messageId', expect.any(String));
62
+ testMessageId = response.messageId; // Store for cleanup
63
+ }, 30000);
64
+ /** TEST 2: List Messages **/
65
+ test('should list messages from messageBox', async () => {
66
+ const messages = await messageBoxClient.listMessages({ messageBox });
67
+ expect(messages.length).toBeGreaterThan(0);
68
+ expect(messages.some(msg => msg.body === testMessage)).toBe(true);
69
+ }, 15000);
70
+ /** TEST 3: List Messages from an Empty MessageBox **/
71
+ test('should return an empty list if no messages exist', async () => {
72
+ const messages = await messageBoxClient.listMessages({ messageBox: 'emptyBox' });
73
+ expect(messages).toEqual([]);
74
+ }, 15000);
75
+ /** TEST 4: Acknowledge a Message **/
76
+ test('should acknowledge (delete) a message', async () => {
77
+ const ackResponse = await messageBoxClient.acknowledgeMessage({ messageIds: [testMessageId] });
78
+ expect(ackResponse).toBe('success');
79
+ }, 15000);
80
+ /** TEST 5: Acknowledge a Nonexistent Message **/
81
+ test('should fail to acknowledge a nonexistent message', async () => {
82
+ await expect(messageBoxClient.acknowledgeMessage({ messageIds: ['fakeMessageId'] })).rejects.toThrow('Message not found!');
83
+ }, 15000);
84
+ /** TEST 6: Send Message with Invalid Recipient **/
85
+ test('should fail if recipient is invalid', async () => {
86
+ await expect(messageBoxClient.sendMessage({
87
+ recipient: '', // Invalid recipient
88
+ messageBox,
89
+ body: testMessage
90
+ })).rejects.toThrow('You must provide a message recipient!');
91
+ }, 15000);
92
+ /** TEST 7: Send Message with Empty Body **/
93
+ test('should fail if message body is empty', async () => {
94
+ await expect(messageBoxClient.sendMessage({
95
+ recipient: recipientKey,
96
+ messageBox,
97
+ body: '' // Empty message
98
+ })).rejects.toThrow('Every message must have a body!');
99
+ }, 15000);
100
+ /** TEST 8: Send Message with Excessive Payment (Should still succeed) **/
101
+ test('should send a message even if payment is more than required', async () => {
102
+ const response = await messageBoxClient.sendMessage({
103
+ recipient: recipientKey,
104
+ messageBox,
105
+ body: testMessage2,
106
+ skipEncryption: true
107
+ });
108
+ console.log('[DEBUG] Overpayment SendMessage Response:', response);
109
+ expect(response.status).toBe('success');
110
+ }, 15000);
111
+ /** TEST: Send a message without encryption **/
112
+ test('should send a message without encryption when skipEncryption is true', async () => {
113
+ const plaintextMessage = 'Unencrypted test message';
114
+ const response = await messageBoxClient.sendMessage({
115
+ recipient: recipientKey,
116
+ messageBox,
117
+ body: plaintextMessage,
118
+ skipEncryption: true // Bypass encryption
119
+ });
120
+ expect(response).toHaveProperty('status', 'success');
121
+ expect(response).toHaveProperty('messageId', expect.any(String));
122
+ const messages = await messageBoxClient.listMessages({ messageBox });
123
+ expect(messages.some(msg => msg.body === plaintextMessage)).toBe(true);
124
+ }, 30000);
125
+ });
126
+ //# sourceMappingURL=integrationHTTP.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrationHTTP.test.js","sourceRoot":"","sources":["../../../../../src/__tests/integration/integrationHTTP.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,135 @@
1
+ /* eslint-env jest */
2
+ import { MessageBoxClient } from '../../MessageBoxClient.js';
3
+ import { WalletClient } from '@bsv/sdk';
4
+ import { webcrypto } from 'crypto';
5
+ global.self = { crypto: webcrypto };
6
+ jest.setTimeout(20000);
7
+ const MESSAGEBOX_HOST = 'http://localhost:5001';
8
+ const walletA = new WalletClient('json-api', 'localhost');
9
+ const walletB = new WalletClient('json-api', 'localhost');
10
+ const clientA = new MessageBoxClient({
11
+ host: MESSAGEBOX_HOST,
12
+ walletClient: walletA,
13
+ networkPreset: 'local',
14
+ enableLogging: true
15
+ });
16
+ const clientB = new MessageBoxClient({
17
+ host: MESSAGEBOX_HOST,
18
+ walletClient: walletB,
19
+ networkPreset: 'local',
20
+ enableLogging: true
21
+ });
22
+ let identityKeyA;
23
+ let identityKeyB;
24
+ beforeAll(async () => {
25
+ identityKeyA = (await walletA.getPublicKey({ identityKey: true })).publicKey;
26
+ identityKeyB = (await walletB.getPublicKey({ identityKey: true })).publicKey;
27
+ await clientA.initializeConnection();
28
+ await clientB.initializeConnection();
29
+ });
30
+ afterAll(async () => {
31
+ await clientA.disconnectWebSocket();
32
+ await clientB.disconnectWebSocket();
33
+ });
34
+ describe('Overlay Integration Tests', () => {
35
+ const selfBox = 'overlay_self_box';
36
+ const peerBox = 'forwarded_overlay_box';
37
+ test('clientA broadcasts overlay advertisement', async () => {
38
+ const result = await clientA.anointHost(MESSAGEBOX_HOST);
39
+ expect(result).toHaveProperty('txid');
40
+ await new Promise(resolve => setTimeout(resolve, 3000));
41
+ });
42
+ test('clientA resolves own host via overlay', async () => {
43
+ const resolved = await clientA.resolveHostForRecipient(identityKeyA);
44
+ console.log('[TEST] Resolved host:', resolved);
45
+ expect(resolved).toBe(MESSAGEBOX_HOST);
46
+ });
47
+ test('clientA sends message to self via overlay', async () => {
48
+ const response = await clientA.sendMessage({
49
+ recipient: identityKeyA,
50
+ messageBox: selfBox,
51
+ body: 'hello via overlay'
52
+ });
53
+ expect(response.status).toBe('success');
54
+ });
55
+ test('clientA lists self messages via overlay', async () => {
56
+ const messages = await clientA.listMessages({ messageBox: selfBox });
57
+ expect(messages.length).toBeGreaterThan(0);
58
+ expect(messages.at(-1)?.body).toContain('hello via overlay');
59
+ });
60
+ test('clientA acknowledges self messages via overlay', async () => {
61
+ const messages = await clientA.listMessages({ messageBox: selfBox });
62
+ const ids = messages.map(m => m.messageId).filter(Boolean);
63
+ expect(ids.length).toBeGreaterThan(0);
64
+ const status = await clientA.acknowledgeMessage({ messageIds: ids });
65
+ expect(status).toBe('success');
66
+ });
67
+ test('clientB broadcasts overlay advertisement', async () => {
68
+ const result = await clientB.anointHost(MESSAGEBOX_HOST);
69
+ expect(result).toHaveProperty('txid');
70
+ await new Promise(resolve => setTimeout(resolve, 3000));
71
+ });
72
+ test('clientA sends message to clientB via overlay', async () => {
73
+ const response = await clientA.sendMessage({
74
+ recipient: identityKeyB,
75
+ messageBox: peerBox,
76
+ body: 'delivered to peer via overlay'
77
+ });
78
+ expect(response.status).toBe('success');
79
+ });
80
+ test('clientB receives overlay message from clientA', async () => {
81
+ const messages = await clientB.listMessages({ messageBox: peerBox });
82
+ expect(messages.some(m => m.body.includes('delivered to peer via overlay'))).toBe(true);
83
+ });
84
+ test('clientB acknowledges overlay message from clientA', async () => {
85
+ const messages = await clientB.listMessages({ messageBox: peerBox });
86
+ const ids = messages.map(m => m.messageId).filter(Boolean);
87
+ const result = await clientB.acknowledgeMessage({ messageIds: ids });
88
+ expect(result).toBe('success');
89
+ });
90
+ test('clientA verifies clientB host resolution', async () => {
91
+ const resolved = await clientA.resolveHostForRecipient(identityKeyB);
92
+ expect(resolved).toBe(MESSAGEBOX_HOST);
93
+ });
94
+ test('overlay advertisement is idempotent', async () => {
95
+ const result1 = await clientA.anointHost(MESSAGEBOX_HOST);
96
+ const result2 = await clientA.anointHost(MESSAGEBOX_HOST);
97
+ expect(result1.txid).not.toBe(result2.txid);
98
+ });
99
+ test('clientA sends and acknowledges multiple messages to clientB', async () => {
100
+ const contents = ['msg1', 'msg2', 'msg3'];
101
+ for (const msg of contents) {
102
+ const response = await clientA.sendMessage({
103
+ recipient: identityKeyB,
104
+ messageBox: peerBox,
105
+ body: msg
106
+ });
107
+ expect(response.status).toBe('success');
108
+ }
109
+ await new Promise(resolve => setTimeout(resolve, 1000));
110
+ const messages = await clientB.listMessages({ messageBox: peerBox });
111
+ const matched = contents.every(c => messages.some(m => m.body.includes(c)));
112
+ expect(matched).toBe(true);
113
+ const ids = messages.map(m => m.messageId).filter(Boolean);
114
+ const status = await clientB.acknowledgeMessage({ messageIds: ids });
115
+ expect(status).toBe('success');
116
+ });
117
+ test('clientA reinitializes with init() and correctly anoints host', async () => {
118
+ const tempClient = new MessageBoxClient({
119
+ walletClient: walletA,
120
+ networkPreset: 'local',
121
+ enableLogging: true
122
+ // No host provided here!
123
+ });
124
+ // Call init manually
125
+ await tempClient.init(MESSAGEBOX_HOST);
126
+ // Verify client is initialized and host is correct
127
+ expect(tempClient.initialized).toBe(true);
128
+ expect(tempClient.host).toBe(MESSAGEBOX_HOST);
129
+ // Optionally, test that resolving our own identity also works
130
+ const resolvedHost = await tempClient.resolveHostForRecipient(identityKeyA);
131
+ expect(resolvedHost).toBe(MESSAGEBOX_HOST);
132
+ await tempClient.disconnectWebSocket();
133
+ });
134
+ });
135
+ //# sourceMappingURL=integrationOverlay.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrationOverlay.test.js","sourceRoot":"","sources":["../../../../../src/__tests/integration/integrationOverlay.test.ts"],"names":[],"mappings":"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"}