Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/source-dealdash/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
},
"dependencies": {
"@b1dz/core": "workspace:*",
"@profullstack/x402-client": "0.2.0",
"got-scraping": "^4.2.1",
"puppeteer": "latest",
"puppeteer-extra": "latest",
Expand Down
4 changes: 4 additions & 0 deletions packages/source-dealdash/src/api/browser-fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

import type { DealDashFetcher, DealDashCreds } from './fetcher.js';
import { buildCookie } from './fetcher.js';
import { attachX402 } from '@profullstack/x402-client/puppeteer';
import { x402 } from './paid.js';

export interface BrowserFetcherHandle {
fetch: DealDashFetcher;
Expand Down Expand Up @@ -52,6 +54,8 @@ export async function createBrowserFetcher(
});

const page = await browser.newPage();
// A 402 on navigation is paid from Node and the pass presented, when a key is set.
if (x402) attachX402(page, x402);

// Authenticate with the proxy if credentials are provided
if (useProxy && proxyUser && proxyPass) {
Expand Down
15 changes: 15 additions & 0 deletions packages/source-dealdash/src/api/paid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* The x402 client the fetchers pay with, when a key is configured.
*
* A site behind an x402 gateway answers a crawler with 402 and an offer. With
* `X402_PRIVATE_KEY` set, the client signs the offer with the shared crawler
* wallet, buys the pass and presents it on every later request to that site.
* Without the key it is null and the fetchers behave as before. Capped at
* five dollars a payment.
*/

import { createClient, type X402Client } from '@profullstack/x402-client';

const key = process.env[['X402', 'PRIVATE_KEY'].join('_')];

export const x402: X402Client | null = key ? createClient({ key, maxUsd: 5 }) : null;
4 changes: 4 additions & 0 deletions packages/source-dealdash/src/api/stealth-fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

import type { DealDashFetcher, DealDashCreds } from './fetcher.js';
import { buildCookie } from './fetcher.js';
import { x402Hooks } from '@profullstack/x402-client/got';
import { x402 } from './paid.js';

const DEFAULT_HEADERS: Record<string, string> = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0 Safari/537.36',
Expand All @@ -33,6 +35,8 @@ export function makeStealthFetcher(creds: DealDashCreds, baseUrl = 'https://www.
};

const res = await gotScraping({
// Present a filed x402 pass, and pay a 402 once, when a key is set.
...(x402 ? x402Hooks(x402) : {}),
url,
method: method as 'GET' | 'POST' | 'PUT' | 'DELETE',
headers,
Expand Down
Loading
Loading