@sapiom/browser-pay 0.0.0-stage → 0.1.0

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 (69) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/LICENSE +21 -0
  3. package/README.md +97 -2
  4. package/dist/cjs/cdp.d.ts +24 -0
  5. package/dist/cjs/cdp.d.ts.map +1 -0
  6. package/dist/cjs/cdp.js +390 -0
  7. package/dist/cjs/cdp.js.map +1 -0
  8. package/dist/cjs/contract.d.ts +30 -0
  9. package/dist/cjs/contract.d.ts.map +1 -0
  10. package/dist/cjs/contract.js +57 -0
  11. package/dist/cjs/contract.js.map +1 -0
  12. package/dist/cjs/detect.d.ts +7 -0
  13. package/dist/cjs/detect.d.ts.map +1 -0
  14. package/dist/cjs/detect.js +111 -0
  15. package/dist/cjs/detect.js.map +1 -0
  16. package/dist/cjs/guards.d.ts +2 -0
  17. package/dist/cjs/guards.d.ts.map +1 -0
  18. package/dist/cjs/guards.js +7 -0
  19. package/dist/cjs/guards.js.map +1 -0
  20. package/dist/cjs/index.d.ts +8 -0
  21. package/dist/cjs/index.d.ts.map +1 -0
  22. package/dist/cjs/index.js +8 -0
  23. package/dist/cjs/index.js.map +1 -0
  24. package/dist/cjs/interceptor.d.ts +66 -0
  25. package/dist/cjs/interceptor.d.ts.map +1 -0
  26. package/dist/cjs/interceptor.js +949 -0
  27. package/dist/cjs/interceptor.js.map +1 -0
  28. package/dist/cjs/logger.d.ts +5 -0
  29. package/dist/cjs/logger.d.ts.map +1 -0
  30. package/dist/cjs/logger.js +7 -0
  31. package/dist/cjs/logger.js.map +1 -0
  32. package/dist/cjs/relay.d.ts +19 -0
  33. package/dist/cjs/relay.d.ts.map +1 -0
  34. package/dist/cjs/relay.js +130 -0
  35. package/dist/cjs/relay.js.map +1 -0
  36. package/dist/esm/cdp.d.ts +24 -0
  37. package/dist/esm/cdp.d.ts.map +1 -0
  38. package/dist/esm/cdp.js +383 -0
  39. package/dist/esm/cdp.js.map +1 -0
  40. package/dist/esm/contract.d.ts +30 -0
  41. package/dist/esm/contract.d.ts.map +1 -0
  42. package/dist/esm/contract.js +53 -0
  43. package/dist/esm/contract.js.map +1 -0
  44. package/dist/esm/detect.d.ts +7 -0
  45. package/dist/esm/detect.d.ts.map +1 -0
  46. package/dist/esm/detect.js +107 -0
  47. package/dist/esm/detect.js.map +1 -0
  48. package/dist/esm/guards.d.ts +2 -0
  49. package/dist/esm/guards.d.ts.map +1 -0
  50. package/dist/esm/guards.js +4 -0
  51. package/dist/esm/guards.js.map +1 -0
  52. package/dist/esm/index.d.ts +8 -0
  53. package/dist/esm/index.d.ts.map +1 -0
  54. package/dist/esm/index.js +3 -0
  55. package/dist/esm/index.js.map +1 -0
  56. package/dist/esm/interceptor.d.ts +66 -0
  57. package/dist/esm/interceptor.d.ts.map +1 -0
  58. package/dist/esm/interceptor.js +946 -0
  59. package/dist/esm/interceptor.js.map +1 -0
  60. package/dist/esm/logger.d.ts +5 -0
  61. package/dist/esm/logger.d.ts.map +1 -0
  62. package/dist/esm/logger.js +4 -0
  63. package/dist/esm/logger.js.map +1 -0
  64. package/dist/esm/package.json +1 -0
  65. package/dist/esm/relay.d.ts +19 -0
  66. package/dist/esm/relay.d.ts.map +1 -0
  67. package/dist/esm/relay.js +124 -0
  68. package/dist/esm/relay.js.map +1 -0
  69. package/package.json +72 -3
package/CHANGELOG.md ADDED
@@ -0,0 +1,13 @@
1
+ # @sapiom/browser-pay
2
+
3
+ ## 0.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 9883adf: Add `@sapiom/browser-pay`. It pauses a held placeholder over CDP and posts David's relay body to `POST /v1/transactions/{id}/payment/relay`. The idempotency key is sha256 of method, URL, and body.
8
+
9
+ The placeholder is `{ number, injectionRef }`. `PayLogger` only has `warn`. `failed.reason` is a closed set, and a match seen after detach is `detached`. `HttpRelayOptions` has no `timeoutMs`. `AttachOptions.timeoutMs` is the relay deadline. A non-2xx relay HTTP status is a transport failure and is not read as an outcome.
10
+
11
+ ## 0.0.0
12
+
13
+ Initial package. The first published version is cut by Changesets. Pauses a held placeholder over CDP and relays it to `POST /v1/transactions/{id}/payment/relay`.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Sapiom
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,98 @@
1
- # Temporary Holding Version
1
+ # @sapiom/browser-pay
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Browser-side payment interceptor. The agent types a governance placeholder into checkout. This package pauses that request over CDP and hands it to David's relay. The browser is fulfilled with the processor's response, or the request fails. The placeholder is never continued.
4
+
5
+ ## Sequence
6
+
7
+ 1. The agent creates a checkout (UCP `create_checkout`).
8
+ 2. Governance arms a placeholder and returns it with `continue_url`.
9
+ 3. The agent opens a browser session and drives checkout, typing the placeholder.
10
+ 4. `attachInterceptor` pauses the card request, including inside a payment iframe.
11
+ 5. A match is `POST /v1/transactions/{transactionId}/payment/relay`.
12
+ 6. The page receives the processor status, headers, and body. A refusal, an unknown outcome, or a relay error fails the paused request.
13
+
14
+ ## Relay contract
15
+
16
+ `POST /v1/transactions/{transactionId}/payment/relay` with `x-api-key`. `transactionId` is only in the path. The JSON body is:
17
+
18
+ ```json
19
+ {
20
+ "injectionRef": "inj_…",
21
+ "profileId": "shopify-card-vault",
22
+ "pageOrigin": "https://shop.example",
23
+ "request": {
24
+ "method": "POST",
25
+ "url": "https://checkout.pci.shopifyinc.com/sessions",
26
+ "headers": { "content-type": "application/json" },
27
+ "body": "<paused request body, placeholder included>"
28
+ },
29
+ "idempotencyKey": "<sha256 hex of method, url, and body>"
30
+ }
31
+ ```
32
+
33
+ `pageOrigin` is the top-level page origin. `headers` is a lowercased string map. This client sends only `accept`, `content-type`, and `shopify-identification-signature`, and drops a value longer than 8192 characters. `idempotencyKey` is sha256 of method, URL, and body, separated by NUL. It is not sent as a header. Shopify's card iframe retries share one key. Do not log or persist `request.headers` or `request.body`.
34
+
35
+ Success:
36
+
37
+ ```json
38
+ {
39
+ "outcome": "relayed",
40
+ "response": {
41
+ "status": 200,
42
+ "headers": { "content-type": "application/json" },
43
+ "body": "<processor body>"
44
+ }
45
+ }
46
+ ```
47
+
48
+ `response.body` is the string the page should read. `response.headers` is a string map. Hop-by-hop headers are dropped because CDP sends the body bytes itself.
49
+
50
+ Refusal, nothing forwarded:
51
+
52
+ ```json
53
+ { "outcome": "refused", "reason": "already_relayed" }
54
+ ```
55
+
56
+ The reason string is passed through. Reasons David returns include `already_relayed`, `total_changed`, `key_rotated`, `card_removed`, `unknown_injection`, `injection_expired`, `payment_released`, `relay_in_progress`, `payment_not_authorized`, `destination_not_allowed`, `card_fields_invalid`, `merchant_mismatch`, and `provider_unavailable`.
57
+
58
+ No answer after the send:
59
+
60
+ ```json
61
+ { "outcome": "unknown" }
62
+ ```
63
+
64
+ The injection is consumed. The paused request fails and the same body is not sent again.
65
+
66
+ A transport error, a redirect, a non-2xx HTTP status, or an unreadable body fails the paused browser request. David's relay returns HTTP 200 for every outcome, so a 401 or 500 is not read as `unknown` or `refused`. It is not fulfilled with the error JSON. If fulfill fails, the paused request is failed and the agent event is `relayed_unfulfilled`.
67
+
68
+ ## What an agent does
69
+
70
+ ```typescript
71
+ import { attachInterceptor, httpPaymentRelay } from "@sapiom/browser-pay";
72
+
73
+ const handle = await attachInterceptor(cdpUrl, {
74
+ relay: httpPaymentRelay({
75
+ baseUrl: process.env.SAPIOM_BASE_URL ?? "https://api.sapiom.ai",
76
+ apiKey: process.env.SAPIOM_API_KEY,
77
+ transactionId,
78
+ }),
79
+ profileId: "shopify-card-vault",
80
+ placeholder,
81
+ });
82
+ ```
83
+
84
+ Call `handle.on` after `attachInterceptor` resolves. Events emitted while attach was running, including a target that could not arm Fetch, are delivered to that first subscriber.
85
+
86
+ A request is relayed when the held placeholder number appears in the URL or body. An exact match counts, and so do digits split by spaces or dashes, including the URL-encoded and JSON-escaped forms of those separators. `placeholder` is `{ number, injectionRef }`. The backend's `checkPlaceholderUse` decides whether the number is valid. A paused request that does not hold the placeholder is continued.
87
+
88
+ A relayed response fails the paused request only when that response contains the held placeholder number.
89
+
90
+ Identical in-flight retries (same method, URL, and body) share one relay call. `AttachOptions.timeoutMs` is the only deadline on that call. It defaults to 20 seconds. A relay that ignores abort still fails when the deadline passes, and one waiter's timeout does not abort a later waiter of the same flight. A refusal is logged once. A transport failure drops the key so a later retry can resend. `outcome: "unknown"` does not.
91
+
92
+ Captcha widgets, extension pages, and workers are not paused. A blank iframe, including `about:blank`, stays paused so a navigation onto the card URL cannot slip through. A placeholder that shows up on any other page or iframe is relayed.
93
+
94
+ Child iframes are auto-attached with `waitForDebuggerOnStart`. `Fetch.enable` runs on each child session before it is resumed. An iframe that already exists is attached before `attachInterceptor` resolves. A paused request whose CDP session was never attached is failed.
95
+
96
+ `detach()` fails in-flight paused requests before it disables Fetch. A process crash or a dropped CDP socket can still let Chrome continue those requests. WebSocket frames, client-side-encrypted card payloads, and worklet targets are not visible to this check.
97
+
98
+ `examples/attach.ts` is the agent-side script. It is not published.
@@ -0,0 +1,24 @@
1
+ /**
2
+ * A small CDP client so the interceptor can open its own connection to a
3
+ * browser websocket. It deliberately does not depend on Playwright or
4
+ * Puppeteer: the agent's driver is a second CDP client, and this one has to
5
+ * attach beside it.
6
+ */
7
+ export interface CdpEvent {
8
+ method: string;
9
+ params: Record<string, unknown>;
10
+ sessionId?: string;
11
+ }
12
+ export declare class CdpConnection {
13
+ private readonly socket;
14
+ private nextId;
15
+ private closed;
16
+ private readonly pending;
17
+ private readonly listeners;
18
+ private constructor();
19
+ static connect(url: string, timeoutMs?: number): Promise<CdpConnection>;
20
+ send(method: string, params?: Record<string, unknown>, sessionId?: string, timeoutMs?: number): Promise<unknown>;
21
+ onEvent(listener: (event: CdpEvent) => void): () => void;
22
+ close(): void;
23
+ }
24
+ //# sourceMappingURL=cdp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cdp.d.ts","sourceRoot":"","sources":["../../src/cdp.ts"],"names":[],"mappings":"AAMA;;;;;GAKG;AAEH,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA6SD,qBAAa,aAAa;IAMJ,OAAO,CAAC,QAAQ,CAAC,MAAM;IAL3C,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;IACtD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwC;IAElE,OAAO;WA8CM,OAAO,CAClB,GAAG,EAAE,MAAM,EACX,SAAS,SAAS,GACjB,OAAO,CAAC,aAAa,CAAC;IAIzB,IAAI,CACF,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACpC,SAAS,CAAC,EAAE,MAAM,EAClB,SAAS,SAAS,GACjB,OAAO,CAAC,OAAO,CAAC;IAmCnB,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,GAAG,MAAM,IAAI;IAKxD,KAAK,IAAI,IAAI;CAGd"}
@@ -0,0 +1,390 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CdpConnection = void 0;
7
+ const node_crypto_1 = __importDefault(require("node:crypto"));
8
+ const node_http_1 = __importDefault(require("node:http"));
9
+ const node_https_1 = __importDefault(require("node:https"));
10
+ const guards_js_1 = require("./guards.js");
11
+ function parseCdpMessage(value) {
12
+ if (!(0, guards_js_1.isRecord)(value))
13
+ return undefined;
14
+ const id = typeof value.id === "number" ? value.id : undefined;
15
+ const method = typeof value.method === "string" ? value.method : undefined;
16
+ if (id === undefined && method === undefined)
17
+ return undefined;
18
+ const params = (0, guards_js_1.isRecord)(value.params) ? value.params : {};
19
+ const sessionId = typeof value.sessionId === "string" ? value.sessionId : undefined;
20
+ let errorMessage;
21
+ if ((0, guards_js_1.isRecord)(value.error) && typeof value.error.message === "string") {
22
+ errorMessage = value.error.message;
23
+ }
24
+ else if (value.error) {
25
+ errorMessage = "CDP call failed";
26
+ }
27
+ return {
28
+ ...(id !== undefined ? { id } : {}),
29
+ ...(method !== undefined ? { method } : {}),
30
+ params,
31
+ ...(sessionId ? { sessionId } : {}),
32
+ result: value.result,
33
+ ...(errorMessage ? { errorMessage } : {}),
34
+ };
35
+ }
36
+ /** One CDP payload, including a large getRequestPostData body, stays under this. */
37
+ const MAX_FRAME_BYTES = 16 * 1024 * 1024;
38
+ class WebSocketClient {
39
+ constructor(socket) {
40
+ this.socket = socket;
41
+ this.chunks = [];
42
+ this.buffered = 0;
43
+ this.fragments = [];
44
+ this.fragmentBytes = 0;
45
+ this.closed = false;
46
+ this.onmessage = () => { };
47
+ this.onclose = () => { };
48
+ this.onerror = () => { };
49
+ this.notified = false;
50
+ socket.on("data", (chunk) => {
51
+ this.append(chunk);
52
+ });
53
+ socket.on("close", () => {
54
+ this.closed = true;
55
+ this.notifyClose();
56
+ });
57
+ socket.on("error", (error) => {
58
+ this.fail(error instanceof Error ? error : new Error("CDP websocket error"));
59
+ });
60
+ }
61
+ static connect(url, timeoutMs) {
62
+ return new Promise((resolve, reject) => {
63
+ const target = new URL(url);
64
+ const key = node_crypto_1.default.randomBytes(16).toString("base64");
65
+ const transport = target.protocol === "wss:" ? node_https_1.default : node_http_1.default;
66
+ const request = transport.request({
67
+ host: target.hostname,
68
+ port: target.port || (target.protocol === "wss:" ? 443 : 80),
69
+ path: `${target.pathname}${target.search}`,
70
+ timeout: timeoutMs,
71
+ headers: {
72
+ Connection: "Upgrade",
73
+ Upgrade: "websocket",
74
+ "Sec-WebSocket-Version": "13",
75
+ "Sec-WebSocket-Key": key,
76
+ },
77
+ });
78
+ const fail = (error) => {
79
+ request.destroy();
80
+ reject(error);
81
+ };
82
+ request.on("upgrade", (response, socket, head) => {
83
+ if (response.statusCode !== 101) {
84
+ socket.destroy();
85
+ fail(new Error(`CDP websocket upgrade refused: HTTP ${response.statusCode}`));
86
+ return;
87
+ }
88
+ const client = new WebSocketClient(socket);
89
+ if (head?.length)
90
+ client.append(Buffer.from(head));
91
+ resolve(client);
92
+ });
93
+ request.on("response", (response) => {
94
+ fail(new Error(`CDP websocket upgrade refused: HTTP ${response.statusCode}`));
95
+ });
96
+ request.on("timeout", () => fail(new Error("CDP websocket connect timeout")));
97
+ request.on("error", fail);
98
+ request.end();
99
+ });
100
+ }
101
+ fail(error) {
102
+ if (this.closed)
103
+ return;
104
+ this.closed = true;
105
+ this.onerror(error);
106
+ this.socket.destroy();
107
+ this.notifyClose();
108
+ }
109
+ notifyClose() {
110
+ if (this.notified)
111
+ return;
112
+ this.notified = true;
113
+ this.onclose();
114
+ }
115
+ append(chunk) {
116
+ if (this.closed)
117
+ return;
118
+ this.chunks.push(chunk);
119
+ this.buffered += chunk.length;
120
+ if (this.buffered > MAX_FRAME_BYTES) {
121
+ this.fail(new Error("CDP websocket frame exceeded the size cap"));
122
+ return;
123
+ }
124
+ try {
125
+ this.parse();
126
+ }
127
+ catch (error) {
128
+ this.fail(error instanceof Error
129
+ ? error
130
+ : new Error("CDP websocket parse failed"));
131
+ }
132
+ }
133
+ peek(length) {
134
+ if (this.buffered < length)
135
+ return null;
136
+ if (this.chunks[0] && this.chunks[0].length >= length) {
137
+ return this.chunks[0].subarray(0, length);
138
+ }
139
+ const out = Buffer.allocUnsafe(length);
140
+ let offset = 0;
141
+ for (const chunk of this.chunks) {
142
+ const take = Math.min(chunk.length, length - offset);
143
+ chunk.copy(out, offset, 0, take);
144
+ offset += take;
145
+ if (offset >= length)
146
+ break;
147
+ }
148
+ return out;
149
+ }
150
+ consume(length) {
151
+ if (this.buffered < length)
152
+ return null;
153
+ const out = Buffer.allocUnsafe(length);
154
+ let offset = 0;
155
+ while (offset < length) {
156
+ const head = this.chunks[0];
157
+ const need = length - offset;
158
+ if (head.length <= need) {
159
+ head.copy(out, offset);
160
+ offset += head.length;
161
+ this.chunks.shift();
162
+ }
163
+ else {
164
+ head.copy(out, offset, 0, need);
165
+ this.chunks[0] = head.subarray(need);
166
+ offset += need;
167
+ }
168
+ }
169
+ this.buffered -= length;
170
+ return out;
171
+ }
172
+ parse() {
173
+ for (;;) {
174
+ const header = this.peek(2);
175
+ if (!header)
176
+ return;
177
+ const first = header[0];
178
+ const second = header[1];
179
+ let length = second & 0x7f;
180
+ let offset = 2;
181
+ if (length === 126) {
182
+ const extended = this.peek(4);
183
+ if (!extended)
184
+ return;
185
+ length = extended.readUInt16BE(2);
186
+ offset = 4;
187
+ }
188
+ else if (length === 127) {
189
+ const extended = this.peek(10);
190
+ if (!extended)
191
+ return;
192
+ length = Number(extended.readBigUInt64BE(2));
193
+ offset = 10;
194
+ }
195
+ if (length > MAX_FRAME_BYTES) {
196
+ this.fail(new Error("CDP websocket frame exceeded the size cap"));
197
+ return;
198
+ }
199
+ const masked = (second & 0x80) !== 0;
200
+ const maskOffset = offset;
201
+ if (masked)
202
+ offset += 4;
203
+ const frame = this.consume(offset + length);
204
+ if (!frame)
205
+ return;
206
+ let payload = frame.subarray(offset, offset + length);
207
+ if (masked) {
208
+ const mask = frame.subarray(maskOffset, maskOffset + 4);
209
+ const unmasked = Buffer.allocUnsafe(payload.length);
210
+ for (let index = 0; index < payload.length; index++) {
211
+ unmasked[index] = payload[index] ^ mask[index % 4];
212
+ }
213
+ payload = unmasked;
214
+ }
215
+ const opcode = first & 0x0f;
216
+ const fin = (first & 0x80) !== 0;
217
+ if (opcode === 0x8) {
218
+ this.closed = true;
219
+ this.notifyClose();
220
+ this.socket.end();
221
+ return;
222
+ }
223
+ if (opcode === 0x9) {
224
+ this.frame(0xa, payload);
225
+ continue;
226
+ }
227
+ if (opcode === 0xa)
228
+ continue;
229
+ if (opcode !== 0x1 && opcode !== 0x0)
230
+ continue;
231
+ this.fragmentBytes += payload.length;
232
+ if (this.fragmentBytes > MAX_FRAME_BYTES) {
233
+ this.fail(new Error("CDP websocket frame exceeded the size cap"));
234
+ return;
235
+ }
236
+ this.fragments.push(Buffer.from(payload));
237
+ if (fin) {
238
+ const message = Buffer.concat(this.fragments).toString("utf8");
239
+ this.fragments = [];
240
+ this.fragmentBytes = 0;
241
+ this.onmessage(message);
242
+ }
243
+ }
244
+ }
245
+ frame(opcode, data) {
246
+ const mask = node_crypto_1.default.randomBytes(4);
247
+ const length = data.length;
248
+ let header;
249
+ if (length < 126) {
250
+ header = Buffer.from([0x80 | opcode, 0x80 | length]);
251
+ }
252
+ else if (length < 65536) {
253
+ header = Buffer.from([
254
+ 0x80 | opcode,
255
+ 0x80 | 126,
256
+ length >> 8,
257
+ length & 255,
258
+ ]);
259
+ }
260
+ else {
261
+ header = Buffer.alloc(10);
262
+ header[0] = 0x80 | opcode;
263
+ header[1] = 0x80 | 127;
264
+ header.writeBigUInt64BE(BigInt(length), 2);
265
+ }
266
+ const body = Buffer.allocUnsafe(data.length);
267
+ for (let index = 0; index < data.length; index++) {
268
+ body[index] = data[index] ^ mask[index % 4];
269
+ }
270
+ this.socket.write(Buffer.concat([header, mask, body]));
271
+ }
272
+ send(data) {
273
+ if (this.closed)
274
+ throw new Error("CDP connection closed");
275
+ this.frame(0x1, Buffer.from(data, "utf8"));
276
+ }
277
+ close() {
278
+ if (this.closed)
279
+ return;
280
+ try {
281
+ this.frame(0x8, Buffer.alloc(0));
282
+ }
283
+ catch {
284
+ // The socket may already be gone.
285
+ }
286
+ this.closed = true;
287
+ this.notifyClose();
288
+ this.socket.end();
289
+ setTimeout(() => this.socket.destroy(), 200);
290
+ }
291
+ }
292
+ class CdpConnection {
293
+ constructor(socket) {
294
+ this.socket = socket;
295
+ this.nextId = 0;
296
+ this.closed = false;
297
+ this.pending = new Map();
298
+ this.listeners = new Set();
299
+ socket.onmessage = (data) => {
300
+ let parsed;
301
+ try {
302
+ parsed = JSON.parse(data);
303
+ }
304
+ catch {
305
+ return;
306
+ }
307
+ const message = parseCdpMessage(parsed);
308
+ if (!message)
309
+ return;
310
+ const pending = message.id !== undefined ? this.pending.get(message.id) : undefined;
311
+ if (pending && message.id !== undefined) {
312
+ this.pending.delete(message.id);
313
+ clearTimeout(pending.timer);
314
+ if (message.errorMessage) {
315
+ pending.reject(new Error(`CDP ${message.errorMessage}`));
316
+ }
317
+ else {
318
+ pending.resolve(message.result);
319
+ }
320
+ return;
321
+ }
322
+ if (!message.method)
323
+ return;
324
+ const event = {
325
+ method: message.method,
326
+ params: message.params,
327
+ ...(message.sessionId ? { sessionId: message.sessionId } : {}),
328
+ };
329
+ for (const listener of this.listeners)
330
+ listener(event);
331
+ };
332
+ const rejectAll = (error) => {
333
+ for (const pending of this.pending.values()) {
334
+ clearTimeout(pending.timer);
335
+ pending.reject(error);
336
+ }
337
+ this.pending.clear();
338
+ };
339
+ socket.onerror = (error) => {
340
+ rejectAll(error);
341
+ };
342
+ socket.onclose = () => {
343
+ this.closed = true;
344
+ rejectAll(new Error("CDP connection closed"));
345
+ };
346
+ }
347
+ static async connect(url, timeoutMs = 15000) {
348
+ return new CdpConnection(await WebSocketClient.connect(url, timeoutMs));
349
+ }
350
+ send(method, params = {}, sessionId, timeoutMs = 15000) {
351
+ const id = ++this.nextId;
352
+ return new Promise((resolve, reject) => {
353
+ if (this.closed) {
354
+ reject(new Error("CDP connection closed"));
355
+ return;
356
+ }
357
+ const timer = setTimeout(() => {
358
+ this.pending.delete(id);
359
+ reject(new Error(`CDP ${method} timed out`));
360
+ }, timeoutMs);
361
+ this.pending.set(id, {
362
+ resolve,
363
+ reject,
364
+ timer,
365
+ });
366
+ try {
367
+ this.socket.send(JSON.stringify({
368
+ id,
369
+ method,
370
+ params,
371
+ ...(sessionId ? { sessionId } : {}),
372
+ }));
373
+ }
374
+ catch (error) {
375
+ clearTimeout(timer);
376
+ this.pending.delete(id);
377
+ reject(error instanceof Error ? error : new Error("CDP connection closed"));
378
+ }
379
+ });
380
+ }
381
+ onEvent(listener) {
382
+ this.listeners.add(listener);
383
+ return () => this.listeners.delete(listener);
384
+ }
385
+ close() {
386
+ this.socket.close();
387
+ }
388
+ }
389
+ exports.CdpConnection = CdpConnection;
390
+ //# sourceMappingURL=cdp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cdp.js","sourceRoot":"","sources":["../../src/cdp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ export interface RelayHttpRequest {
2
+ method: string;
3
+ url: string;
4
+ headers: Record<string, string>;
5
+ body: string;
6
+ }
7
+ export interface RelayRequest {
8
+ injectionRef: string;
9
+ profileId: string;
10
+ pageOrigin: string;
11
+ request: RelayHttpRequest;
12
+ idempotencyKey: string;
13
+ }
14
+ export interface RelayedHttpResponse {
15
+ status: number;
16
+ headers: Record<string, string>;
17
+ body: string;
18
+ }
19
+ export type RelayResponse = {
20
+ outcome: "relayed";
21
+ response: RelayedHttpResponse;
22
+ } | {
23
+ outcome: "refused";
24
+ reason: string;
25
+ } | {
26
+ outcome: "unknown";
27
+ };
28
+ export declare function paymentIdempotencyKey(method: string, url: string, body: string): string;
29
+ export declare function parseRelayResponse(value: unknown): RelayResponse;
30
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/contract.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,OAAO,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,mBAAmB,CAAA;CAAE,GACrD;IAAE,OAAO,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,OAAO,EAAE,SAAS,CAAA;CAAE,CAAC;AAE3B,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,GACX,MAAM,CAQR;AAYD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CA8BhE"}