import { privateKeyToAccount } from "viem/accounts";
import { createWalletClient, http, publicActions } from "viem";
import { base } from "viem/chains";
import { createKeyPairSignerFromBytes } from "@solana/kit";
import { base58 } from "@scure/base";
import { x402Client } from "@x402/core/client";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { ExactSvmScheme } from "@x402/svm/exact/client";
import { wrapFetchWithPayment } from "@x402/fetch";
const account = privateKeyToAccount("0xYOUR_PRIVATE_KEY");
const walletClient = createWalletClient({
account,
chain: base, // Use baseSepolia for testnet
transport: http(),
}).extend(publicActions);
// 64-byte base58 secret key (private + public)
const svmSigner = await createKeyPairSignerFromBytes(
base58.decode("YOUR_SOLANA_BASE58_SECRET_KEY"),
);
const client = new x402Client();
const evmScheme = new ExactEvmScheme(walletClient);
client.register("eip155:8453", evmScheme); // 84532 for testnet
client.register(
"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", // EtWTRABZaYq6iMfeYKouRu166VU2xqa1 for testnet
new ExactSvmScheme(svmSigner),
);
const payFetch = wrapFetchWithPayment(fetch, client);
const baseUrl = "https://dripstack.com";
const searchResponse = await fetch(
`${baseUrl}/api/v1/search?q=Michael%20Burry&limit=5`,
);
const search = await searchResponse.json();
const firstPost = search.items[0];
if (!firstPost) {
throw new Error("No Michael Burry posts found.");
}
const articleUrl = `${baseUrl}/api/v1/publications/${firstPost.publicationSlug}/${firstPost.slug}`;
// Check the discovery price before requesting payment.
const publicationResponse = await fetch(
`${baseUrl}/api/v1/publications/${firstPost.publicationSlug}?limit=100`,
);
const publication = await publicationResponse.json();
const selectedPost = publication.posts.find(
(post: { slug: string }) => post.slug === firstPost.slug,
);
console.log("Selected:", firstPost.title);
console.log("Listed price (cents):", selectedPost?.priceCents);
// A plain request exposes the authoritative x402 price before payment.
const challengeResponse = await fetch(articleUrl);
if (challengeResponse.status !== 402) {
throw new Error(`Expected 402 challenge, got ${challengeResponse.status}`);
}
console.log(
"x402 challenge:",
challengeResponse.headers.get("PAYMENT-REQUIRED"),
);
// The wallet-aware client handles the challenge, pays, and retries.
const articleResponse = await payFetch(articleUrl);
if (!articleResponse.ok) {
throw new Error(`Paid request failed: ${articleResponse.status}`);
}
const article = await articleResponse.json();
console.log(article.title);
console.log(article.synthesizedSummary);