@warppay402/sdk 1.1.3 → 1.1.4

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/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 WarpPay402
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/dist/index.d.ts CHANGED
@@ -17,7 +17,7 @@ export declare class WarpPayClient {
17
17
  /**
18
18
  * Handles multi-chain HTTP 402 Payment Required challenges dynamically.
19
19
  */
20
- private executePaidRequest;
20
+ executePaidRequest<T>(endpoint: string, payload?: Record<string, any>, method?: "GET" | "POST"): Promise<T>;
21
21
  scrapeWeb(url: string): Promise<any>;
22
22
  getBaseAnalytics(address: string): Promise<any>;
23
23
  extractPdf(pdfUrl: string): Promise<any>;
package/dist/index.js CHANGED
@@ -36,36 +36,41 @@ class WarpPayClient {
36
36
  /**
37
37
  * Handles multi-chain HTTP 402 Payment Required challenges dynamically.
38
38
  */
39
- async executePaidRequest(endpoint, payload) {
39
+ async executePaidRequest(endpoint, payload, method = "POST") {
40
40
  const url = `${this.baseUrl}${endpoint}`;
41
- // 1. Initial Request Probe
42
- let response = await fetch(url, {
43
- method: "POST",
41
+ console.log(`\nšŸ” [SDK DEBUG] Initiating ${method} request to: ${url}`);
42
+ const fetchOptions = {
43
+ method,
44
44
  headers: { "Content-Type": "application/json" },
45
- body: JSON.stringify(payload),
46
- });
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}`);
47
53
  // 2. Multi-Chain Settlement Challenge Response
48
54
  if (response.status === 402) {
49
55
  const challenge = await response.json();
56
+ console.log(`šŸ” [SDK DEBUG] Received 402 Challenge Payload:`, JSON.stringify(challenge, null, 2));
50
57
  const accepts = challenge.x402?.accepts || challenge.accepts || [];
51
- // Check for Solana offer if solanaKeypair is available
58
+ console.log(`šŸ” [SDK DEBUG] Accepted Payment Rails (${accepts.length}):`, accepts.map((a) => a.network));
52
59
  const solanaReq = accepts.find((a) => a.network?.includes("solana"));
53
60
  const evmReq = accepts.find((a) => a.network?.includes("eip155"));
54
61
  let paymentPayload;
55
62
  if (solanaReq && this.solanaKeypair) {
56
- // Execute Solana L1 SPL-USDC Transaction Authorization
63
+ console.log(`šŸ” [SDK DEBUG] Processing Solana L1 SPL Payment challenge...`);
57
64
  const payToPubkey = new web3_js_1.PublicKey(solanaReq.payTo);
58
65
  const usdcMint = new web3_js_1.PublicKey(solanaReq.asset || "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
59
- const amountUnits = BigInt(solanaReq.amount || solanaReq.maxAmountRequired || "10000"); // $0.01 USDC
66
+ const amountUnits = BigInt(solanaReq.amount || solanaReq.maxAmountRequired || "10000");
60
67
  const senderPubkey = this.solanaKeypair.publicKey;
61
68
  const senderAta = await (0, spl_token_1.getAssociatedTokenAddress)(usdcMint, senderPubkey);
62
69
  const recipientAta = await (0, spl_token_1.getAssociatedTokenAddress)(usdcMint, payToPubkey);
63
70
  const tx = new web3_js_1.Transaction();
64
71
  tx.feePayer = senderPubkey;
65
72
  tx.recentBlockhash = (await this.solanaConnection.getLatestBlockhash()).blockhash;
66
- // Idempotently create recipient ATA if required
67
73
  tx.add((0, spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(senderPubkey, recipientAta, payToPubkey, usdcMint));
68
- // Append SPL-USDC Transfer instruction
69
74
  tx.add((0, spl_token_1.createTransferInstruction)(senderAta, recipientAta, senderPubkey, amountUnits));
70
75
  tx.sign(this.solanaKeypair);
71
76
  const serializedTx = node_buffer_1.Buffer.from(tx.serialize()).toString("base64");
@@ -81,10 +86,11 @@ class WarpPayClient {
81
86
  };
82
87
  }
83
88
  else if (evmReq && this.account) {
84
- // EVM EIP-712 Base Path
89
+ console.log(`šŸ” [SDK DEBUG] Processing EVM EIP-712 Payment challenge...`);
85
90
  const payTo = (evmReq.payToAddress || evmReq.payTo);
86
91
  const assetContract = (evmReq.asset || evmReq.usdcAddress);
87
92
  const value = BigInt(evmReq.maxAmountRequired || evmReq.amount || "10000");
93
+ console.log(`šŸ” [SDK DEBUG] Signer Wallet: ${this.account.address} -> PayTo: ${payTo} | Amount: ${value.toString()}`);
88
94
  const domain = {
89
95
  name: evmReq.extra?.name || "USD Coin",
90
96
  version: evmReq.extra?.version || "2",
@@ -121,36 +127,44 @@ class WarpPayClient {
121
127
  x402Version: 2,
122
128
  scheme: evmReq.scheme || "exact",
123
129
  network: evmReq.network || "eip155:8453",
124
- payload: {
125
- authorization: {
126
- from: this.account.address,
127
- to: payTo,
128
- value: value.toString(),
129
- validAfter: "0",
130
- validBefore: (now + 3600).toString(),
131
- nonce,
132
- },
133
- signature,
130
+ authorization: {
131
+ from: this.account.address,
132
+ to: payTo,
133
+ value: value.toString(),
134
+ validAfter: "0",
135
+ validBefore: (now + 3600).toString(),
136
+ nonce,
134
137
  },
138
+ signature,
135
139
  };
136
140
  }
137
141
  else {
142
+ console.error(`āŒ [SDK DEBUG] Matching key missing! EVM Account Present: ${Boolean(this.account)} | Solana Keypair Present: ${Boolean(this.solanaKeypair)}`);
138
143
  throw new Error("No matching private key configured for returned 402 networks.");
139
144
  }
140
145
  const encodedPayload = node_buffer_1.Buffer.from(JSON.stringify(paymentPayload)).toString("base64");
141
- // Resubmit request with signed x402 headers
142
- response = await fetch(url, {
143
- method: "POST",
144
- headers: {
145
- "Content-Type": "application/json",
146
- "X-PAYMENT": encodedPayload,
147
- "PAYMENT-SIGNATURE": encodedPayload,
148
- },
149
- body: JSON.stringify(payload),
150
- });
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}`);
151
164
  }
152
165
  if (!response.ok) {
153
166
  const errText = await response.text();
167
+ console.error(`āŒ [SDK DEBUG] Request Rejection Body:`, errText);
154
168
  throw new Error(`WarpPay API Error (${response.status}): ${errText}`);
155
169
  }
156
170
  return (await response.json());
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "warppay402-sdk",
3
3
  "name": "warppay402-sdk",
4
- "version": "1.1.1",
5
- "description": "Official WarpPay402 TypeScript SDK: Enabling seamless pay-per-use AI tools across both Base Mainnet and Solana."
6
- }
4
+ "version": "1.1.4",
5
+ "description": "Official WarpPay402 TypeScript SDK: Enabling seamless pay-per-use AI tools across Base Mainnet, Solana, and Arbitrum One."
6
+ }
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@warppay402/sdk",
3
- "version": "1.1.3",
4
- "description": "Official WarpPay402 TypeScript SDK: Enabling seamless pay-per-use AI tools across both Base Mainnet and Solana.",
3
+ "version": "1.1.4",
4
+ "license": "MIT",
5
+ "description": "Official WarpPay402 TypeScript SDK: Enabling seamless pay-per-use AI tools across Base Mainnet, Solana, and Arbitrum One.",
5
6
  "main": "dist/index.js",
6
7
  "types": "dist/index.d.ts",
7
8
  "scripts": {
@@ -9,15 +10,17 @@
9
10
  },
10
11
  "repository": {
11
12
  "type": "git",
12
- "url": "git+https://github.com/golfgolfgolf200/warppay402-sdk.git"
13
+ "url": "git+https://github.com/Warppay402/warppay402-sdk.git"
13
14
  },
14
15
  "bugs": {
15
- "url": "https://github.com/golfgolfgolf200/warppay402-sdk/issues"
16
+ "url": "https://github.com/Warppay402/warppay402-sdk/issues"
16
17
  },
17
- "homepage": "https://github.com/golfgolfgolf200/warppay402-sdk#readme",
18
+ "homepage": "https://github.com/Warppay402/warppay402-sdk#readme",
18
19
  "keywords": [
19
20
  "x402",
20
21
  "base",
22
+ "solana",
23
+ "arbitrum",
21
24
  "ai-agents",
22
25
  "mcp",
23
26
  "monetization",
@@ -50,7 +53,7 @@
50
53
  "properties": {
51
54
  "privateKey": {
52
55
  "type": "string",
53
- "description": "Base wallet private key for paying x402 micropayments"
56
+ "description": "Base/Arbitrum wallet private key for paying x402 micropayments"
54
57
  }
55
58
  }
56
59
  }
package/src/index.ts DELETED
@@ -1,228 +0,0 @@
1
- import crypto from "node:crypto";
2
- import { Buffer } from "node:buffer";
3
- import { privateKeyToAccount } from "viem/accounts";
4
- import { Keypair, Connection, Transaction, PublicKey } from "@solana/web3.js";
5
- import {
6
- getAssociatedTokenAddress,
7
- createTransferInstruction,
8
- createAssociatedTokenAccountIdempotentInstruction
9
- } from "@solana/spl-token";
10
- import bs58 from "bs58";
11
-
12
- export interface WarpPayConfig {
13
- /** Base Mainnet private key of the agent's wallet funding micro-payments */
14
- privateKey?: `0x${string}`;
15
- /** Solana Mainnet base58 private key funding micro-payments */
16
- solanaPrivateKey?: string;
17
- /** Custom gateway URL (Defaults to https://api.warppay402.com) */
18
- baseUrl?: string;
19
- /** Custom Solana RPC URL */
20
- solanaRpcUrl?: string;
21
- }
22
-
23
- export class WarpPayClient {
24
- private baseUrl: string;
25
- private account?: ReturnType<typeof privateKeyToAccount>;
26
- private solanaKeypair?: Keypair;
27
- private solanaConnection: Connection;
28
-
29
- constructor(config: WarpPayConfig) {
30
- this.baseUrl = (config.baseUrl || "https://api.warppay402.com").replace(/\/$/, "");
31
- this.solanaConnection = new Connection(
32
- config.solanaRpcUrl || "https://api.mainnet-beta.solana.com",
33
- "confirmed"
34
- );
35
-
36
- // EVM Account Setup
37
- if (config.privateKey) {
38
- const rawKey = config.privateKey.trim();
39
- const formattedKey = (rawKey.startsWith("0x") ? rawKey : `0x${rawKey}`) as `0x${string}`;
40
- this.account = privateKeyToAccount(formattedKey);
41
- }
42
-
43
- // Solana Account Setup
44
- if (config.solanaPrivateKey) {
45
- const decodedSecret = bs58.decode(config.solanaPrivateKey.trim());
46
- this.solanaKeypair = Keypair.fromSecretKey(decodedSecret);
47
- }
48
-
49
- if (!this.account && !this.solanaKeypair) {
50
- throw new Error("WarpPayClient requires either a Base privateKey or a solanaPrivateKey.");
51
- }
52
- }
53
-
54
- /**
55
- * Handles multi-chain HTTP 402 Payment Required challenges dynamically.
56
- */
57
- private async executePaidRequest<T>(endpoint: string, payload: Record<string, any>): Promise<T> {
58
- const url = `${this.baseUrl}${endpoint}`;
59
-
60
- // 1. Initial Request Probe
61
- let response = await fetch(url, {
62
- method: "POST",
63
- headers: { "Content-Type": "application/json" },
64
- body: JSON.stringify(payload),
65
- });
66
-
67
- // 2. Multi-Chain Settlement Challenge Response
68
- if (response.status === 402) {
69
- const challenge = await response.json();
70
- const accepts: Array<any> = challenge.x402?.accepts || challenge.accepts || [];
71
-
72
- // Check for Solana offer if solanaKeypair is available
73
- const solanaReq = accepts.find((a) => a.network?.includes("solana"));
74
- const evmReq = accepts.find((a) => a.network?.includes("eip155"));
75
-
76
- let paymentPayload: any;
77
-
78
- if (solanaReq && this.solanaKeypair) {
79
- // Execute Solana L1 SPL-USDC Transaction Authorization
80
- const payToPubkey = new PublicKey(solanaReq.payTo);
81
- const usdcMint = new PublicKey(solanaReq.asset || "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
82
- const amountUnits = BigInt(solanaReq.amount || solanaReq.maxAmountRequired || "10000"); // $0.01 USDC
83
-
84
- const senderPubkey = this.solanaKeypair.publicKey;
85
- const senderAta = await getAssociatedTokenAddress(usdcMint, senderPubkey);
86
- const recipientAta = await getAssociatedTokenAddress(usdcMint, payToPubkey);
87
-
88
- const tx = new Transaction();
89
- tx.feePayer = senderPubkey;
90
- tx.recentBlockhash = (await this.solanaConnection.getLatestBlockhash()).blockhash;
91
-
92
- // Idempotently create recipient ATA if required
93
- tx.add(
94
- createAssociatedTokenAccountIdempotentInstruction(
95
- senderPubkey,
96
- recipientAta,
97
- payToPubkey,
98
- usdcMint
99
- )
100
- );
101
-
102
- // Append SPL-USDC Transfer instruction
103
- tx.add(
104
- createTransferInstruction(senderAta, recipientAta, senderPubkey, amountUnits)
105
- );
106
-
107
- tx.sign(this.solanaKeypair);
108
- const serializedTx = Buffer.from(tx.serialize()).toString("base64");
109
-
110
- paymentPayload = {
111
- x402Version: 2,
112
- scheme: solanaReq.scheme || "exact",
113
- network: solanaReq.network || "solana:5eykt4wA89m8E5b9B5658p445VTc28",
114
- signature: serializedTx,
115
- paymentPayload: {
116
- signature: serializedTx,
117
- network: solanaReq.network
118
- }
119
- };
120
- } else if (evmReq && this.account) {
121
- // EVM EIP-712 Base Path
122
- const payTo = (evmReq.payToAddress || evmReq.payTo) as `0x${string}`;
123
- const assetContract = (evmReq.asset || evmReq.usdcAddress) as `0x${string}`;
124
- const value = BigInt(evmReq.maxAmountRequired || evmReq.amount || "10000");
125
-
126
- const domain = {
127
- name: evmReq.extra?.name || "USD Coin",
128
- version: evmReq.extra?.version || "2",
129
- chainId: 8453,
130
- verifyingContract: assetContract,
131
- };
132
-
133
- const types = {
134
- TransferWithAuthorization: [
135
- { name: "from", type: "address" },
136
- { name: "to", type: "address" },
137
- { name: "value", type: "uint256" },
138
- { name: "validAfter", type: "uint256" },
139
- { name: "validBefore", type: "uint256" },
140
- { name: "nonce", type: "bytes32" },
141
- ],
142
- };
143
-
144
- const now = Math.floor(Date.now() / 1000);
145
- const nonce = `0x${crypto.randomBytes(32).toString("hex")}` as `0x${string}`;
146
-
147
- const message = {
148
- from: this.account.address,
149
- to: payTo,
150
- value,
151
- validAfter: BigInt(0),
152
- validBefore: BigInt(now + 3600),
153
- nonce,
154
- };
155
-
156
- const signature = await this.account.signTypedData({
157
- domain,
158
- types,
159
- primaryType: "TransferWithAuthorization",
160
- message,
161
- });
162
-
163
- paymentPayload = {
164
- x402Version: 2,
165
- scheme: evmReq.scheme || "exact",
166
- network: evmReq.network || "eip155:8453",
167
- payload: {
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
- };
179
- } else {
180
- throw new Error("No matching private key configured for returned 402 networks.");
181
- }
182
-
183
- const encodedPayload = Buffer.from(JSON.stringify(paymentPayload)).toString("base64");
184
-
185
- // Resubmit request with signed x402 headers
186
- response = await fetch(url, {
187
- method: "POST",
188
- headers: {
189
- "Content-Type": "application/json",
190
- "X-PAYMENT": encodedPayload,
191
- "PAYMENT-SIGNATURE": encodedPayload,
192
- },
193
- body: JSON.stringify(payload),
194
- });
195
- }
196
-
197
- if (!response.ok) {
198
- const errText = await response.text();
199
- throw new Error(`WarpPay API Error (${response.status}): ${errText}`);
200
- }
201
-
202
- return (await response.json()) as T;
203
- }
204
-
205
- public async scrapeWeb(url: string): Promise<any> {
206
- return this.executePaidRequest("/api/v1/tools/web-scraper", { url });
207
- }
208
-
209
- public async getBaseAnalytics(address: string): Promise<any> {
210
- return this.executePaidRequest("/api/v1/tools/base-analytics", { address });
211
- }
212
-
213
- public async extractPdf(pdfUrl: string): Promise<any> {
214
- return this.executePaidRequest("/api/v1/tools/pdf-extractor", { pdfUrl });
215
- }
216
-
217
- public async browserScrape(url: string): Promise<any> {
218
- return this.executePaidRequest("/api/v1/tools/browser-scraper", { url });
219
- }
220
-
221
- public async renderScreenshot(url: string): Promise<any> {
222
- return this.executePaidRequest("/api/v1/tools/render-screenshot", { url });
223
- }
224
-
225
- public async extractJson(url: string, schema?: object): Promise<any> {
226
- return this.executePaidRequest("/api/v1/tools/extract-json", { url, schema });
227
- }
228
- }
package/src/langchain.ts DELETED
@@ -1,33 +0,0 @@
1
- import { WarpPayClient } from "./index.js";
2
-
3
- /**
4
- * Generates LangChain-compatible tool definitions initialized with WarpPay402
5
- */
6
- export function createWarpPayLangChainTools(client: WarpPayClient) {
7
- return [
8
- {
9
- name: "web_scraper",
10
- description: "Scrapes a web page URL and returns clean markdown content. Costs $0.01 USDC on Base.",
11
- func: async ({ url }: { url: string }) => {
12
- const result = await client.scrapeWeb(url);
13
- return result.markdown;
14
- },
15
- },
16
- {
17
- name: "base_analytics",
18
- description: "Fetches ETH balance and nonce for a Base 0x wallet address. Costs $0.02 USDC on Base.",
19
- func: async ({ address }: { address: string }) => {
20
- const result = await client.getBaseAnalytics(address);
21
- return JSON.stringify(result);
22
- },
23
- },
24
- {
25
- name: "pdf_extractor",
26
- description: "Extracts text preview from a public PDF URL. Costs $0.05 USDC on Base.",
27
- func: async ({ pdfUrl }: { pdfUrl: string }) => {
28
- const result = await client.extractPdf(pdfUrl);
29
- return result.textPreview;
30
- },
31
- },
32
- ];
33
- }
package/tsconfig.json DELETED
@@ -1,15 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "declaration": true,
7
- "outDir": "./dist",
8
- "rootDir": "./src",
9
- "strict": true,
10
- "esModuleInterop": true,
11
- "skipLibCheck": true,
12
- "types": ["node"]
13
- },
14
- "include": ["src/**/*"]
15
- }