@warppay402/sdk 1.1.4 → 1.1.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/.env.example ADDED
@@ -0,0 +1,12 @@
1
+ # EVM / Base Mainnet Wallet Setup
2
+ # Private key for funding Base x402 USDC micropayments (must start with 0x)
3
+ CUSTOMER_BASE_KEY=0x_your_evm_private_key_here
4
+
5
+ # Solana L1 Wallet Setup
6
+ # Base58-encoded secret key for funding Solana SPL USDC micropayments
7
+ CUSTOMER_SOLANA_KEY=base58_encoded_solana_secret_key_here
8
+
9
+ # Optional Configuration Overrides
10
+ # BASE_URL=https://api.warppay402.com
11
+ # BASE_RPC_URL=https://mainnet.base.org
12
+ # SOLANA_RPC_URL=https://api.mainnet-beta.solana.com
package/README.md CHANGED
@@ -7,10 +7,10 @@ Official TypeScript SDK for **WarpPay402**—pay-per-use AI tools monetized via
7
7
  ```bash
8
8
  npm install @warppay402/sdk
9
9
  ```
10
+
10
11
  ## 🚀 Quickstart
11
- ```typescript
12
- import { WarpPayClient } from "@warppay402/sdk";
13
12
 
13
+ ```typescript
14
14
  import { WarpPayClient } from "@warppay402/sdk";
15
15
 
16
16
  // Initialize with Base EVM, Solana L1, or both
@@ -45,24 +45,33 @@ async function main() {
45
45
  console.log("ETH Balance:", analytics.ethBalance);
46
46
 
47
47
  // 6. Extract PDF Text Preview ($0.05 USDC)
48
- const pdf = await client.extractPdf("https://example.com/document.pdf");
48
+ const pdf = await client.extractPdf("https://example.com/document.pdf");
49
49
  console.log("Preview:", pdf.textPreview);
50
50
  }
51
51
 
52
52
  main();
53
53
  ```
54
+
54
55
  ## 🛠️ Available Methods & Pricing
55
56
 
56
- * **`getPublicDataFeed(filename)`** -- `$0.0001 USDC` -- Retrieves signed attestation JSON payloads.
57
- * **`getDataFeed(feedId)`** -- `$0.001 USDC` -- Fetches pre-scraped market and protocol intelligence feeds.
58
- * **`scrapeWeb(url)`** -- `$0.001 USDC` -- Extracts clean Markdown from web pages.
59
- * **`getBaseAnalytics(address)`** -- `$0.002 USDC` -- Fetches ETH balance and nonce stats.
60
- * **`browserScrape(url)`** -- `$0.005 USDC` -- Unblockable JS browser scraping via proxy workers.
61
- * **`extractPdf(pdfUrl)`** -- `$0.005 USDC` -- Parses text preview from public PDF URLs.
62
- * **`renderScreenshot(url)`** -- `$0.01 USDC` -- Renders target URL and returns full-page screenshot data.
63
- * **`extractJson(url, schema?)`** -- `$0.01 USDC` -- Parses web pages into structured JSON data.
64
- * **`verifySmartContract(address)`** -- `$0.02 USDC` -- Source code analysis, ABI fetching, and proxy validation.
57
+ - **`getPublicDataFeed(filename)`** `$0.0001 USDC` Retrieves signed attestation JSON payloads.
58
+ - **`getDataFeed(feedId)`** `$0.001 USDC` Fetches pre-scraped market and protocol intelligence feeds.
59
+ - **`scrapeWeb(url)`** `$0.001 USDC` Extracts clean Markdown from web pages.
60
+ - **`getBaseAnalytics(address)`** `$0.002 USDC` Fetches ETH balance and nonce stats.
61
+ - **`getAerodromeYields()`** `$0.003 USDC` Top live Aerodrome pool yields and APYs on Base.
62
+ - **`browserScrape(url)`** `$0.005 USDC` Unblockable JS browser scraping via proxy workers.
63
+ - **`extractPdf(pdfUrl)`** `$0.005 USDC` Parses text preview from public PDF URLs.
64
+ - **`renderScreenshot(url)`** `$0.01 USDC` Renders target URL and returns full-page screenshot data.
65
+ - **`extractJson(url, schema?)`** `$0.01 USDC` Parses web pages into structured JSON data.
66
+ - **`executeAerodromeSwap(params)`** — `$0.01 USDC` — Executes token swaps via Aerodrome Router on Base.
67
+ - **`manageAerodromeClamm(params)`** — `$0.01 USDC` — Concentrated liquidity LP management on Aerodrome Slipstream.
68
+ - **`manageAerodromeVeaero(params)`** — `$0.01 USDC` — $AERO locking, gauge voting, and bribe reward harvesting.
69
+ - **`verifySmartContract(address)`** — `$0.02 USDC` — Source code analysis, ABI fetching, and proxy validation.
70
+ - **`deployBaseContract(contractType)`** — `$5.00 USDC` — Programmatically deploys custom smart contracts to Base Mainnet.
71
+ - **`deploySolanaContract(type, params)`** — `$5.00 USDC` — Initializes SPL Escrows, cNFTs, or Raydium Vaults on Solana.
72
+
65
73
  ## 🛠️ LangChain Integration
74
+
66
75
  ```typescript
67
76
  import { WarpPayClient, createWarpPayLangChainTools } from "@warppay402/sdk";
68
77
 
@@ -73,12 +82,10 @@ const client = new WarpPayClient({
73
82
  // Pass directly into your LangChain or AutoGen agent setup
74
83
  const tools = createWarpPayLangChainTools(client);
75
84
  ```
76
- ## 🌐 API Gateway & Specs
77
-
78
- MCP Gateway Endpoint: https://api.warppay402.com/mcp
79
85
 
80
- MCP Manifest: https://api.warppay402.com/.well-known/mcp.json
81
-
82
- REST Gateway Base: https://api.warppay402.com
86
+ ## 🌐 API Gateway & Specs
83
87
 
84
- OpenAPI Spec: https://api.warppay402.com/openapi.json
88
+ - MCP Gateway Endpoint: <https://api.warppay402.com/mcp>
89
+ - MCP Manifest: <https://api.warppay402.com/.well-known/mcp.json>
90
+ - REST Gateway Base: <https://api.warppay402.com>
91
+ - OpenAPI Spec: <https://api.warppay402.com/openapi.json>
package/dist/index.cjs ADDED
@@ -0,0 +1,231 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ WarpPayClient: () => WarpPayClient
34
+ });
35
+ module.exports = __toCommonJS(index_exports);
36
+ var import_node_crypto = __toESM(require("crypto"), 1);
37
+ var import_node_buffer = require("buffer");
38
+ var import_accounts = require("viem/accounts");
39
+ var import_web3 = require("@solana/web3.js");
40
+ var import_spl_token = require("@solana/spl-token");
41
+ var import_bs58 = __toESM(require("bs58"), 1);
42
+ var bs58 = import_bs58.default.default || import_bs58.default;
43
+ var WarpPayClient = class {
44
+ baseUrl;
45
+ account;
46
+ solanaKeypair;
47
+ solanaConnection;
48
+ constructor(config) {
49
+ this.baseUrl = (config.baseUrl || "https://api.warppay402.com").replace(/\/$/, "");
50
+ this.solanaConnection = new import_web3.Connection(
51
+ config.solanaRpcUrl || "https://api.mainnet-beta.solana.com",
52
+ "confirmed"
53
+ );
54
+ if (config.privateKey) {
55
+ const rawKey = config.privateKey.trim();
56
+ const formattedKey = rawKey.startsWith("0x") ? rawKey : `0x${rawKey}`;
57
+ this.account = (0, import_accounts.privateKeyToAccount)(formattedKey);
58
+ }
59
+ if (config.solanaPrivateKey) {
60
+ const decodedSecret = bs58.decode(config.solanaPrivateKey.trim());
61
+ this.solanaKeypair = import_web3.Keypair.fromSecretKey(decodedSecret);
62
+ }
63
+ if (!this.account && !this.solanaKeypair) {
64
+ throw new Error("WarpPayClient requires either a Base privateKey or a solanaPrivateKey.");
65
+ }
66
+ }
67
+ /**
68
+ * Handles multi-chain HTTP 402 Payment Required challenges dynamically.
69
+ */
70
+ async executePaidRequest(endpoint, payload, method = "POST") {
71
+ const url = `${this.baseUrl}${endpoint}`;
72
+ console.log(`
73
+ \u{1F50D} [SDK DEBUG] Initiating ${method} request to: ${url}`);
74
+ const fetchOptions = {
75
+ method,
76
+ headers: { "Content-Type": "application/json" }
77
+ };
78
+ if (method === "POST" && payload) {
79
+ fetchOptions.body = JSON.stringify(payload);
80
+ console.log(`\u{1F50D} [SDK DEBUG] Request Payload:`, JSON.stringify(payload));
81
+ }
82
+ let response = await fetch(url, fetchOptions);
83
+ console.log(`\u{1F50D} [SDK DEBUG] Probe Response Status: ${response.status} ${response.statusText}`);
84
+ if (response.status === 402) {
85
+ const challenge = await response.json();
86
+ console.log(`\u{1F50D} [SDK DEBUG] Received 402 Challenge Payload:`, JSON.stringify(challenge, null, 2));
87
+ const accepts = challenge.x402?.accepts || challenge.accepts || [];
88
+ console.log(`\u{1F50D} [SDK DEBUG] Accepted Payment Rails (${accepts.length}):`, accepts.map((a) => a.network));
89
+ const solanaReq = accepts.find((a) => a.network?.includes("solana"));
90
+ const evmReq = accepts.find((a) => a.network?.includes("eip155"));
91
+ let paymentPayload;
92
+ if (solanaReq && this.solanaKeypair) {
93
+ console.log(`\u{1F50D} [SDK DEBUG] Processing Solana L1 SPL Payment challenge...`);
94
+ const payToPubkey = new import_web3.PublicKey(solanaReq.payTo);
95
+ const usdcMint = new import_web3.PublicKey(solanaReq.asset || "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
96
+ const amountUnits = BigInt(solanaReq.amount || solanaReq.maxAmountRequired || "10000");
97
+ const senderPubkey = this.solanaKeypair.publicKey;
98
+ const senderAta = await (0, import_spl_token.getAssociatedTokenAddress)(usdcMint, senderPubkey);
99
+ const recipientAta = await (0, import_spl_token.getAssociatedTokenAddress)(usdcMint, payToPubkey);
100
+ const tx = new import_web3.Transaction();
101
+ tx.feePayer = senderPubkey;
102
+ tx.recentBlockhash = (await this.solanaConnection.getLatestBlockhash()).blockhash;
103
+ tx.add(
104
+ (0, import_spl_token.createAssociatedTokenAccountIdempotentInstruction)(
105
+ senderPubkey,
106
+ recipientAta,
107
+ payToPubkey,
108
+ usdcMint
109
+ )
110
+ );
111
+ tx.add(
112
+ (0, import_spl_token.createTransferInstruction)(senderAta, recipientAta, senderPubkey, amountUnits)
113
+ );
114
+ tx.sign(this.solanaKeypair);
115
+ const serializedTx = import_node_buffer.Buffer.from(tx.serialize()).toString("base64");
116
+ paymentPayload = {
117
+ x402Version: 2,
118
+ scheme: solanaReq.scheme || "exact",
119
+ network: solanaReq.network || "solana:5eykt4wA89m8E5b9B5658p445VTc28",
120
+ signature: serializedTx,
121
+ paymentPayload: {
122
+ signature: serializedTx,
123
+ network: solanaReq.network
124
+ }
125
+ };
126
+ } else if (evmReq && this.account) {
127
+ console.log(`\u{1F50D} [SDK DEBUG] Processing EVM EIP-712 Payment challenge...`);
128
+ const payTo = evmReq.payToAddress || evmReq.payTo;
129
+ const assetContract = evmReq.asset || evmReq.usdcAddress;
130
+ const value = BigInt(evmReq.maxAmountRequired || evmReq.amount || "10000");
131
+ console.log(`\u{1F50D} [SDK DEBUG] Signer Wallet: ${this.account.address} -> PayTo: ${payTo} | Amount: ${value.toString()}`);
132
+ const domain = {
133
+ name: evmReq.extra?.name || "USD Coin",
134
+ version: evmReq.extra?.version || "2",
135
+ chainId: 8453,
136
+ verifyingContract: assetContract
137
+ };
138
+ const types = {
139
+ TransferWithAuthorization: [
140
+ { name: "from", type: "address" },
141
+ { name: "to", type: "address" },
142
+ { name: "value", type: "uint256" },
143
+ { name: "validAfter", type: "uint256" },
144
+ { name: "validBefore", type: "uint256" },
145
+ { name: "nonce", type: "bytes32" }
146
+ ]
147
+ };
148
+ const now = Math.floor(Date.now() / 1e3);
149
+ const nonce = `0x${import_node_crypto.default.randomBytes(32).toString("hex")}`;
150
+ const message = {
151
+ from: this.account.address,
152
+ to: payTo,
153
+ value,
154
+ validAfter: BigInt(0),
155
+ validBefore: BigInt(now + 3600),
156
+ nonce
157
+ };
158
+ const signature = await this.account.signTypedData({
159
+ domain,
160
+ types,
161
+ primaryType: "TransferWithAuthorization",
162
+ message
163
+ });
164
+ paymentPayload = {
165
+ x402Version: 2,
166
+ scheme: evmReq.scheme || "exact",
167
+ network: evmReq.network || "eip155:8453",
168
+ authorization: {
169
+ from: this.account.address,
170
+ to: payTo,
171
+ value: value.toString(),
172
+ validAfter: "0",
173
+ validBefore: (now + 3600).toString(),
174
+ nonce
175
+ },
176
+ signature
177
+ };
178
+ } else {
179
+ console.error(`\u274C [SDK DEBUG] Matching key missing! EVM Account Present: ${Boolean(this.account)} | Solana Keypair Present: ${Boolean(this.solanaKeypair)}`);
180
+ throw new Error("No matching private key configured for returned 402 networks.");
181
+ }
182
+ const encodedPayload = import_node_buffer.Buffer.from(JSON.stringify(paymentPayload)).toString("base64");
183
+ console.log(`\u{1F50D} [SDK DEBUG] Generated Signed x402 Base64 Header (Length: ${encodedPayload.length})`);
184
+ const retryHeaders = {
185
+ "Content-Type": "application/json",
186
+ "PAYMENT-SIGNATURE": encodedPayload,
187
+ "X-PAYMENT-RESPONSE": encodedPayload,
188
+ "X-PAYMENT": encodedPayload,
189
+ "authorization": `Bearer ${encodedPayload}`
190
+ };
191
+ const retryOptions = {
192
+ method,
193
+ headers: retryHeaders
194
+ };
195
+ if (method === "POST" && payload) {
196
+ retryOptions.body = JSON.stringify(payload);
197
+ }
198
+ console.log(`\u{1F50D} [SDK DEBUG] Resubmitting paid ${method} request to: ${url}`);
199
+ response = await fetch(url, retryOptions);
200
+ console.log(`\u{1F50D} [SDK DEBUG] Paid Retry Response Status: ${response.status} ${response.statusText}`);
201
+ }
202
+ if (!response.ok) {
203
+ const errText = await response.text();
204
+ console.error(`\u274C [SDK DEBUG] Request Rejection Body:`, errText);
205
+ throw new Error(`WarpPay API Error (${response.status}): ${errText}`);
206
+ }
207
+ return await response.json();
208
+ }
209
+ async scrapeWeb(url) {
210
+ return this.executePaidRequest("/api/v1/tools/web-scraper", { url });
211
+ }
212
+ async getBaseAnalytics(address) {
213
+ return this.executePaidRequest("/api/v1/tools/base-analytics", { address });
214
+ }
215
+ async extractPdf(pdfUrl) {
216
+ return this.executePaidRequest("/api/v1/tools/pdf-extractor", { pdfUrl });
217
+ }
218
+ async browserScrape(url) {
219
+ return this.executePaidRequest("/api/v1/tools/browser-scraper", { url });
220
+ }
221
+ async renderScreenshot(url) {
222
+ return this.executePaidRequest("/api/v1/tools/render-screenshot", { url });
223
+ }
224
+ async extractJson(url, schema) {
225
+ return this.executePaidRequest("/api/v1/tools/extract-json", { url, schema });
226
+ }
227
+ };
228
+ // Annotate the CommonJS export names for ESM import in node:
229
+ 0 && (module.exports = {
230
+ WarpPayClient
231
+ });
@@ -0,0 +1,29 @@
1
+ interface WarpPayConfig {
2
+ /** Base Mainnet private key of the agent's wallet funding micro-payments */
3
+ privateKey?: `0x${string}`;
4
+ /** Solana Mainnet base58 private key funding micro-payments */
5
+ solanaPrivateKey?: string;
6
+ /** Custom gateway URL (Defaults to https://api.warppay402.com) */
7
+ baseUrl?: string;
8
+ /** Custom Solana RPC URL */
9
+ solanaRpcUrl?: string;
10
+ }
11
+ declare class WarpPayClient {
12
+ private baseUrl;
13
+ private account?;
14
+ private solanaKeypair?;
15
+ private solanaConnection;
16
+ constructor(config: WarpPayConfig);
17
+ /**
18
+ * Handles multi-chain HTTP 402 Payment Required challenges dynamically.
19
+ */
20
+ executePaidRequest<T>(endpoint: string, payload?: Record<string, any>, method?: "GET" | "POST"): Promise<T>;
21
+ scrapeWeb(url: string): Promise<any>;
22
+ getBaseAnalytics(address: string): Promise<any>;
23
+ extractPdf(pdfUrl: string): Promise<any>;
24
+ browserScrape(url: string): Promise<any>;
25
+ renderScreenshot(url: string): Promise<any>;
26
+ extractJson(url: string, schema?: object): Promise<any>;
27
+ }
28
+
29
+ export { WarpPayClient, type WarpPayConfig };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export interface WarpPayConfig {
1
+ interface WarpPayConfig {
2
2
  /** Base Mainnet private key of the agent's wallet funding micro-payments */
3
3
  privateKey?: `0x${string}`;
4
4
  /** Solana Mainnet base58 private key funding micro-payments */
@@ -8,7 +8,7 @@ export interface WarpPayConfig {
8
8
  /** Custom Solana RPC URL */
9
9
  solanaRpcUrl?: string;
10
10
  }
11
- export declare class WarpPayClient {
11
+ declare class WarpPayClient {
12
12
  private baseUrl;
13
13
  private account?;
14
14
  private solanaKeypair?;
@@ -25,3 +25,5 @@ export declare class WarpPayClient {
25
25
  renderScreenshot(url: string): Promise<any>;
26
26
  extractJson(url: string, schema?: object): Promise<any>;
27
27
  }
28
+
29
+ export { WarpPayClient, type WarpPayConfig };
package/dist/index.js CHANGED
@@ -1,191 +1,200 @@
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.WarpPayClient = void 0;
7
- const node_crypto_1 = __importDefault(require("node:crypto"));
8
- const node_buffer_1 = require("node:buffer");
9
- const accounts_1 = require("viem/accounts");
10
- const web3_js_1 = require("@solana/web3.js");
11
- const spl_token_1 = require("@solana/spl-token");
12
- const bs58_1 = __importDefault(require("bs58"));
13
- class WarpPayClient {
14
- baseUrl;
15
- account;
16
- solanaKeypair;
17
- solanaConnection;
18
- constructor(config) {
19
- this.baseUrl = (config.baseUrl || "https://api.warppay402.com").replace(/\/$/, "");
20
- this.solanaConnection = new web3_js_1.Connection(config.solanaRpcUrl || "https://api.mainnet-beta.solana.com", "confirmed");
21
- // EVM Account Setup
22
- if (config.privateKey) {
23
- const rawKey = config.privateKey.trim();
24
- const formattedKey = (rawKey.startsWith("0x") ? rawKey : `0x${rawKey}`);
25
- this.account = (0, accounts_1.privateKeyToAccount)(formattedKey);
26
- }
27
- // Solana Account Setup
28
- if (config.solanaPrivateKey) {
29
- const decodedSecret = bs58_1.default.decode(config.solanaPrivateKey.trim());
30
- this.solanaKeypair = web3_js_1.Keypair.fromSecretKey(decodedSecret);
31
- }
32
- if (!this.account && !this.solanaKeypair) {
33
- throw new Error("WarpPayClient requires either a Base privateKey or a solanaPrivateKey.");
34
- }
35
- }
36
- /**
37
- * Handles multi-chain HTTP 402 Payment Required challenges dynamically.
38
- */
39
- async executePaidRequest(endpoint, payload, method = "POST") {
40
- const url = `${this.baseUrl}${endpoint}`;
41
- console.log(`\n🔍 [SDK DEBUG] Initiating ${method} request to: ${url}`);
42
- const fetchOptions = {
43
- method,
44
- headers: { "Content-Type": "application/json" },
45
- };
46
- if (method === "POST" && payload) {
47
- fetchOptions.body = JSON.stringify(payload);
48
- console.log(`🔍 [SDK DEBUG] Request Payload:`, JSON.stringify(payload));
49
- }
50
- // 1. Initial Request Probe
51
- let response = await fetch(url, fetchOptions);
52
- console.log(`🔍 [SDK DEBUG] Probe Response Status: ${response.status} ${response.statusText}`);
53
- // 2. Multi-Chain Settlement Challenge Response
54
- if (response.status === 402) {
55
- const challenge = await response.json();
56
- console.log(`🔍 [SDK DEBUG] Received 402 Challenge Payload:`, JSON.stringify(challenge, null, 2));
57
- const accepts = challenge.x402?.accepts || challenge.accepts || [];
58
- console.log(`🔍 [SDK DEBUG] Accepted Payment Rails (${accepts.length}):`, accepts.map((a) => a.network));
59
- const solanaReq = accepts.find((a) => a.network?.includes("solana"));
60
- const evmReq = accepts.find((a) => a.network?.includes("eip155"));
61
- let paymentPayload;
62
- if (solanaReq && this.solanaKeypair) {
63
- console.log(`🔍 [SDK DEBUG] Processing Solana L1 SPL Payment challenge...`);
64
- const payToPubkey = new web3_js_1.PublicKey(solanaReq.payTo);
65
- const usdcMint = new web3_js_1.PublicKey(solanaReq.asset || "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
66
- const amountUnits = BigInt(solanaReq.amount || solanaReq.maxAmountRequired || "10000");
67
- const senderPubkey = this.solanaKeypair.publicKey;
68
- const senderAta = await (0, spl_token_1.getAssociatedTokenAddress)(usdcMint, senderPubkey);
69
- const recipientAta = await (0, spl_token_1.getAssociatedTokenAddress)(usdcMint, payToPubkey);
70
- const tx = new web3_js_1.Transaction();
71
- tx.feePayer = senderPubkey;
72
- tx.recentBlockhash = (await this.solanaConnection.getLatestBlockhash()).blockhash;
73
- tx.add((0, spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(senderPubkey, recipientAta, payToPubkey, usdcMint));
74
- tx.add((0, spl_token_1.createTransferInstruction)(senderAta, recipientAta, senderPubkey, amountUnits));
75
- tx.sign(this.solanaKeypair);
76
- const serializedTx = node_buffer_1.Buffer.from(tx.serialize()).toString("base64");
77
- paymentPayload = {
78
- x402Version: 2,
79
- scheme: solanaReq.scheme || "exact",
80
- network: solanaReq.network || "solana:5eykt4wA89m8E5b9B5658p445VTc28",
81
- signature: serializedTx,
82
- paymentPayload: {
83
- signature: serializedTx,
84
- network: solanaReq.network
85
- }
86
- };
87
- }
88
- else if (evmReq && this.account) {
89
- console.log(`🔍 [SDK DEBUG] Processing EVM EIP-712 Payment challenge...`);
90
- const payTo = (evmReq.payToAddress || evmReq.payTo);
91
- const assetContract = (evmReq.asset || evmReq.usdcAddress);
92
- const value = BigInt(evmReq.maxAmountRequired || evmReq.amount || "10000");
93
- console.log(`🔍 [SDK DEBUG] Signer Wallet: ${this.account.address} -> PayTo: ${payTo} | Amount: ${value.toString()}`);
94
- const domain = {
95
- name: evmReq.extra?.name || "USD Coin",
96
- version: evmReq.extra?.version || "2",
97
- chainId: 8453,
98
- verifyingContract: assetContract,
99
- };
100
- const types = {
101
- TransferWithAuthorization: [
102
- { name: "from", type: "address" },
103
- { name: "to", type: "address" },
104
- { name: "value", type: "uint256" },
105
- { name: "validAfter", type: "uint256" },
106
- { name: "validBefore", type: "uint256" },
107
- { name: "nonce", type: "bytes32" },
108
- ],
109
- };
110
- const now = Math.floor(Date.now() / 1000);
111
- const nonce = `0x${node_crypto_1.default.randomBytes(32).toString("hex")}`;
112
- const message = {
113
- from: this.account.address,
114
- to: payTo,
115
- value,
116
- validAfter: BigInt(0),
117
- validBefore: BigInt(now + 3600),
118
- nonce,
119
- };
120
- const signature = await this.account.signTypedData({
121
- domain,
122
- types,
123
- primaryType: "TransferWithAuthorization",
124
- message,
125
- });
126
- paymentPayload = {
127
- x402Version: 2,
128
- scheme: evmReq.scheme || "exact",
129
- network: evmReq.network || "eip155:8453",
130
- authorization: {
131
- from: this.account.address,
132
- to: payTo,
133
- value: value.toString(),
134
- validAfter: "0",
135
- validBefore: (now + 3600).toString(),
136
- nonce,
137
- },
138
- signature,
139
- };
140
- }
141
- else {
142
- console.error(`❌ [SDK DEBUG] Matching key missing! EVM Account Present: ${Boolean(this.account)} | Solana Keypair Present: ${Boolean(this.solanaKeypair)}`);
143
- throw new Error("No matching private key configured for returned 402 networks.");
144
- }
145
- const encodedPayload = node_buffer_1.Buffer.from(JSON.stringify(paymentPayload)).toString("base64");
146
- console.log(`🔍 [SDK DEBUG] Generated Signed x402 Base64 Header (Length: ${encodedPayload.length})`);
147
- const retryHeaders = {
148
- "Content-Type": "application/json",
149
- "PAYMENT-SIGNATURE": encodedPayload,
150
- "X-PAYMENT-RESPONSE": encodedPayload,
151
- "X-PAYMENT": encodedPayload,
152
- "authorization": `Bearer ${encodedPayload}`,
153
- };
154
- const retryOptions = {
155
- method,
156
- headers: retryHeaders,
157
- };
158
- if (method === "POST" && payload) {
159
- retryOptions.body = JSON.stringify(payload);
160
- }
161
- console.log(`🔍 [SDK DEBUG] Resubmitting paid ${method} request to: ${url}`);
162
- response = await fetch(url, retryOptions);
163
- console.log(`🔍 [SDK DEBUG] Paid Retry Response Status: ${response.status} ${response.statusText}`);
164
- }
165
- if (!response.ok) {
166
- const errText = await response.text();
167
- console.error(`❌ [SDK DEBUG] Request Rejection Body:`, errText);
168
- throw new Error(`WarpPay API Error (${response.status}): ${errText}`);
169
- }
170
- return (await response.json());
1
+ // src/index.ts
2
+ import crypto from "crypto";
3
+ import { Buffer } from "buffer";
4
+ import { privateKeyToAccount } from "viem/accounts";
5
+ import { Keypair, Connection, Transaction, PublicKey } from "@solana/web3.js";
6
+ import {
7
+ getAssociatedTokenAddress,
8
+ createTransferInstruction,
9
+ createAssociatedTokenAccountIdempotentInstruction
10
+ } from "@solana/spl-token";
11
+ import bs58Module from "bs58";
12
+ var bs58 = bs58Module.default || bs58Module;
13
+ var WarpPayClient = class {
14
+ baseUrl;
15
+ account;
16
+ solanaKeypair;
17
+ solanaConnection;
18
+ constructor(config) {
19
+ this.baseUrl = (config.baseUrl || "https://api.warppay402.com").replace(/\/$/, "");
20
+ this.solanaConnection = new Connection(
21
+ config.solanaRpcUrl || "https://api.mainnet-beta.solana.com",
22
+ "confirmed"
23
+ );
24
+ if (config.privateKey) {
25
+ const rawKey = config.privateKey.trim();
26
+ const formattedKey = rawKey.startsWith("0x") ? rawKey : `0x${rawKey}`;
27
+ this.account = privateKeyToAccount(formattedKey);
171
28
  }
172
- async scrapeWeb(url) {
173
- return this.executePaidRequest("/api/v1/tools/web-scraper", { url });
29
+ if (config.solanaPrivateKey) {
30
+ const decodedSecret = bs58.decode(config.solanaPrivateKey.trim());
31
+ this.solanaKeypair = Keypair.fromSecretKey(decodedSecret);
174
32
  }
175
- async getBaseAnalytics(address) {
176
- return this.executePaidRequest("/api/v1/tools/base-analytics", { address });
33
+ if (!this.account && !this.solanaKeypair) {
34
+ throw new Error("WarpPayClient requires either a Base privateKey or a solanaPrivateKey.");
177
35
  }
178
- async extractPdf(pdfUrl) {
179
- return this.executePaidRequest("/api/v1/tools/pdf-extractor", { pdfUrl });
36
+ }
37
+ /**
38
+ * Handles multi-chain HTTP 402 Payment Required challenges dynamically.
39
+ */
40
+ async executePaidRequest(endpoint, payload, method = "POST") {
41
+ const url = `${this.baseUrl}${endpoint}`;
42
+ console.log(`
43
+ \u{1F50D} [SDK DEBUG] Initiating ${method} request to: ${url}`);
44
+ const fetchOptions = {
45
+ method,
46
+ headers: { "Content-Type": "application/json" }
47
+ };
48
+ if (method === "POST" && payload) {
49
+ fetchOptions.body = JSON.stringify(payload);
50
+ console.log(`\u{1F50D} [SDK DEBUG] Request Payload:`, JSON.stringify(payload));
180
51
  }
181
- async browserScrape(url) {
182
- return this.executePaidRequest("/api/v1/tools/browser-scraper", { url });
183
- }
184
- async renderScreenshot(url) {
185
- return this.executePaidRequest("/api/v1/tools/render-screenshot", { url });
52
+ let response = await fetch(url, fetchOptions);
53
+ console.log(`\u{1F50D} [SDK DEBUG] Probe Response Status: ${response.status} ${response.statusText}`);
54
+ if (response.status === 402) {
55
+ const challenge = await response.json();
56
+ console.log(`\u{1F50D} [SDK DEBUG] Received 402 Challenge Payload:`, JSON.stringify(challenge, null, 2));
57
+ const accepts = challenge.x402?.accepts || challenge.accepts || [];
58
+ console.log(`\u{1F50D} [SDK DEBUG] Accepted Payment Rails (${accepts.length}):`, accepts.map((a) => a.network));
59
+ const solanaReq = accepts.find((a) => a.network?.includes("solana"));
60
+ const evmReq = accepts.find((a) => a.network?.includes("eip155"));
61
+ let paymentPayload;
62
+ if (solanaReq && this.solanaKeypair) {
63
+ console.log(`\u{1F50D} [SDK DEBUG] Processing Solana L1 SPL Payment challenge...`);
64
+ const payToPubkey = new PublicKey(solanaReq.payTo);
65
+ const usdcMint = new PublicKey(solanaReq.asset || "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
66
+ const amountUnits = BigInt(solanaReq.amount || solanaReq.maxAmountRequired || "10000");
67
+ const senderPubkey = this.solanaKeypair.publicKey;
68
+ const senderAta = await getAssociatedTokenAddress(usdcMint, senderPubkey);
69
+ const recipientAta = await getAssociatedTokenAddress(usdcMint, payToPubkey);
70
+ const tx = new Transaction();
71
+ tx.feePayer = senderPubkey;
72
+ tx.recentBlockhash = (await this.solanaConnection.getLatestBlockhash()).blockhash;
73
+ tx.add(
74
+ createAssociatedTokenAccountIdempotentInstruction(
75
+ senderPubkey,
76
+ recipientAta,
77
+ payToPubkey,
78
+ usdcMint
79
+ )
80
+ );
81
+ tx.add(
82
+ createTransferInstruction(senderAta, recipientAta, senderPubkey, amountUnits)
83
+ );
84
+ tx.sign(this.solanaKeypair);
85
+ const serializedTx = Buffer.from(tx.serialize()).toString("base64");
86
+ paymentPayload = {
87
+ x402Version: 2,
88
+ scheme: solanaReq.scheme || "exact",
89
+ network: solanaReq.network || "solana:5eykt4wA89m8E5b9B5658p445VTc28",
90
+ signature: serializedTx,
91
+ paymentPayload: {
92
+ signature: serializedTx,
93
+ network: solanaReq.network
94
+ }
95
+ };
96
+ } else if (evmReq && this.account) {
97
+ console.log(`\u{1F50D} [SDK DEBUG] Processing EVM EIP-712 Payment challenge...`);
98
+ const payTo = evmReq.payToAddress || evmReq.payTo;
99
+ const assetContract = evmReq.asset || evmReq.usdcAddress;
100
+ const value = BigInt(evmReq.maxAmountRequired || evmReq.amount || "10000");
101
+ console.log(`\u{1F50D} [SDK DEBUG] Signer Wallet: ${this.account.address} -> PayTo: ${payTo} | Amount: ${value.toString()}`);
102
+ const domain = {
103
+ name: evmReq.extra?.name || "USD Coin",
104
+ version: evmReq.extra?.version || "2",
105
+ chainId: 8453,
106
+ verifyingContract: assetContract
107
+ };
108
+ const types = {
109
+ TransferWithAuthorization: [
110
+ { name: "from", type: "address" },
111
+ { name: "to", type: "address" },
112
+ { name: "value", type: "uint256" },
113
+ { name: "validAfter", type: "uint256" },
114
+ { name: "validBefore", type: "uint256" },
115
+ { name: "nonce", type: "bytes32" }
116
+ ]
117
+ };
118
+ const now = Math.floor(Date.now() / 1e3);
119
+ const nonce = `0x${crypto.randomBytes(32).toString("hex")}`;
120
+ const message = {
121
+ from: this.account.address,
122
+ to: payTo,
123
+ value,
124
+ validAfter: BigInt(0),
125
+ validBefore: BigInt(now + 3600),
126
+ nonce
127
+ };
128
+ const signature = await this.account.signTypedData({
129
+ domain,
130
+ types,
131
+ primaryType: "TransferWithAuthorization",
132
+ message
133
+ });
134
+ paymentPayload = {
135
+ x402Version: 2,
136
+ scheme: evmReq.scheme || "exact",
137
+ network: evmReq.network || "eip155:8453",
138
+ authorization: {
139
+ from: this.account.address,
140
+ to: payTo,
141
+ value: value.toString(),
142
+ validAfter: "0",
143
+ validBefore: (now + 3600).toString(),
144
+ nonce
145
+ },
146
+ signature
147
+ };
148
+ } else {
149
+ console.error(`\u274C [SDK DEBUG] Matching key missing! EVM Account Present: ${Boolean(this.account)} | Solana Keypair Present: ${Boolean(this.solanaKeypair)}`);
150
+ throw new Error("No matching private key configured for returned 402 networks.");
151
+ }
152
+ const encodedPayload = Buffer.from(JSON.stringify(paymentPayload)).toString("base64");
153
+ console.log(`\u{1F50D} [SDK DEBUG] Generated Signed x402 Base64 Header (Length: ${encodedPayload.length})`);
154
+ const retryHeaders = {
155
+ "Content-Type": "application/json",
156
+ "PAYMENT-SIGNATURE": encodedPayload,
157
+ "X-PAYMENT-RESPONSE": encodedPayload,
158
+ "X-PAYMENT": encodedPayload,
159
+ "authorization": `Bearer ${encodedPayload}`
160
+ };
161
+ const retryOptions = {
162
+ method,
163
+ headers: retryHeaders
164
+ };
165
+ if (method === "POST" && payload) {
166
+ retryOptions.body = JSON.stringify(payload);
167
+ }
168
+ console.log(`\u{1F50D} [SDK DEBUG] Resubmitting paid ${method} request to: ${url}`);
169
+ response = await fetch(url, retryOptions);
170
+ console.log(`\u{1F50D} [SDK DEBUG] Paid Retry Response Status: ${response.status} ${response.statusText}`);
186
171
  }
187
- async extractJson(url, schema) {
188
- return this.executePaidRequest("/api/v1/tools/extract-json", { url, schema });
172
+ if (!response.ok) {
173
+ const errText = await response.text();
174
+ console.error(`\u274C [SDK DEBUG] Request Rejection Body:`, errText);
175
+ throw new Error(`WarpPay API Error (${response.status}): ${errText}`);
189
176
  }
190
- }
191
- exports.WarpPayClient = WarpPayClient;
177
+ return await response.json();
178
+ }
179
+ async scrapeWeb(url) {
180
+ return this.executePaidRequest("/api/v1/tools/web-scraper", { url });
181
+ }
182
+ async getBaseAnalytics(address) {
183
+ return this.executePaidRequest("/api/v1/tools/base-analytics", { address });
184
+ }
185
+ async extractPdf(pdfUrl) {
186
+ return this.executePaidRequest("/api/v1/tools/pdf-extractor", { pdfUrl });
187
+ }
188
+ async browserScrape(url) {
189
+ return this.executePaidRequest("/api/v1/tools/browser-scraper", { url });
190
+ }
191
+ async renderScreenshot(url) {
192
+ return this.executePaidRequest("/api/v1/tools/render-screenshot", { url });
193
+ }
194
+ async extractJson(url, schema) {
195
+ return this.executePaidRequest("/api/v1/tools/extract-json", { url, schema });
196
+ }
197
+ };
198
+ export {
199
+ WarpPayClient
200
+ };
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "warppay402-sdk",
3
3
  "name": "warppay402-sdk",
4
- "version": "1.1.4",
4
+ "version": "1.1.6",
5
5
  "description": "Official WarpPay402 TypeScript SDK: Enabling seamless pay-per-use AI tools across Base Mainnet, Solana, and Arbitrum One."
6
6
  }
package/package.json CHANGED
@@ -1,12 +1,22 @@
1
1
  {
2
2
  "name": "@warppay402/sdk",
3
- "version": "1.1.4",
3
+ "version": "1.1.7",
4
4
  "license": "MIT",
5
5
  "description": "Official WarpPay402 TypeScript SDK: Enabling seamless pay-per-use AI tools across Base Mainnet, Solana, and Arbitrum One.",
6
- "main": "dist/index.js",
7
- "types": "dist/index.d.ts",
6
+ "type": "module",
7
+ "main": "./dist/index.cjs",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js",
14
+ "require": "./dist/index.cjs"
15
+ }
16
+ },
8
17
  "scripts": {
9
- "build": "tsc"
18
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean --external viem,@solana/web3.js,@solana/spl-token",
19
+ "prepublishOnly": "npm run build"
10
20
  },
11
21
  "repository": {
12
22
  "type": "git",
@@ -29,12 +39,13 @@
29
39
  "dependencies": {
30
40
  "@solana/spl-token": "^0.4.15",
31
41
  "@solana/web3.js": "^1.98.4",
32
- "@warppay402/server": "^1.0.0",
42
+ "@warppay402/server": "^1.2.3",
33
43
  "bs58": "^6.0.0",
34
44
  "viem": "^2.0.0"
35
45
  },
36
46
  "devDependencies": {
37
47
  "@types/node": "^26.2.0",
48
+ "tsup": "^8.5.1",
38
49
  "typescript": "^5.0.0"
39
50
  },
40
51
  "openclaw": {
@@ -1,23 +0,0 @@
1
- import { WarpPayClient } from "./index.js";
2
- /**
3
- * Generates LangChain-compatible tool definitions initialized with WarpPay402
4
- */
5
- export declare function createWarpPayLangChainTools(client: WarpPayClient): ({
6
- name: string;
7
- description: string;
8
- func: ({ url }: {
9
- url: string;
10
- }) => Promise<any>;
11
- } | {
12
- name: string;
13
- description: string;
14
- func: ({ address }: {
15
- address: string;
16
- }) => Promise<string>;
17
- } | {
18
- name: string;
19
- description: string;
20
- func: ({ pdfUrl }: {
21
- pdfUrl: string;
22
- }) => Promise<any>;
23
- })[];
package/dist/langchain.js DELETED
@@ -1,34 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createWarpPayLangChainTools = createWarpPayLangChainTools;
4
- /**
5
- * Generates LangChain-compatible tool definitions initialized with WarpPay402
6
- */
7
- function createWarpPayLangChainTools(client) {
8
- return [
9
- {
10
- name: "web_scraper",
11
- description: "Scrapes a web page URL and returns clean markdown content. Costs $0.01 USDC on Base.",
12
- func: async ({ url }) => {
13
- const result = await client.scrapeWeb(url);
14
- return result.markdown;
15
- },
16
- },
17
- {
18
- name: "base_analytics",
19
- description: "Fetches ETH balance and nonce for a Base 0x wallet address. Costs $0.02 USDC on Base.",
20
- func: async ({ address }) => {
21
- const result = await client.getBaseAnalytics(address);
22
- return JSON.stringify(result);
23
- },
24
- },
25
- {
26
- name: "pdf_extractor",
27
- description: "Extracts text preview from a public PDF URL. Costs $0.05 USDC on Base.",
28
- func: async ({ pdfUrl }) => {
29
- const result = await client.extractPdf(pdfUrl);
30
- return result.textPreview;
31
- },
32
- },
33
- ];
34
- }