Spaces:
Running
Running
| import "dotenv/config"; | |
| import { writeFileSync } from "fs"; | |
| import { Transaction, TransactionBuilder } from "@stellar/stellar-sdk"; | |
| import { x402Client, x402HTTPClient } from "@x402/fetch"; | |
| import { createEd25519Signer, getNetworkPassphrase } from "@x402/stellar"; | |
| import { ExactStellarScheme } from "@x402/stellar/exact/client"; | |
| const SERVER_URL = process.env.SERVER_URL || "https://tantk-rendergate.hf.space"; | |
| const NETWORK = "stellar:testnet"; | |
| const signer = createEd25519Signer(process.env.STELLAR_PRIVATE_KEY, NETWORK); | |
| const client = new x402Client().register( | |
| "stellar:*", | |
| new ExactStellarScheme(signer, { url: "https://soroban-testnet.stellar.org" }), | |
| ); | |
| const httpClient = new x402HTTPClient(client); | |
| async function paidRender(targetUrl) { | |
| const endpoint = `${SERVER_URL}/render?url=${encodeURIComponent(targetUrl)}`; | |
| const r1 = await fetch(endpoint); | |
| if (r1.status !== 402) return await r1.json(); | |
| const pr = httpClient.getPaymentRequiredResponse((n) => r1.headers.get(n)); | |
| let pp = await client.createPaymentPayload(pr); | |
| const np = getNetworkPassphrase(NETWORK); | |
| const tx = new Transaction(pp.payload.transaction, np); | |
| const sd = tx.toEnvelope().v1()?.tx()?.ext()?.sorobanData(); | |
| if (sd) { | |
| pp = { | |
| ...pp, | |
| payload: { | |
| ...pp.payload, | |
| transaction: TransactionBuilder.cloneFrom(tx, { | |
| fee: "1", sorobanData: sd, networkPassphrase: np, | |
| }).build().toXDR(), | |
| }, | |
| }; | |
| } | |
| const headers = httpClient.encodePaymentSignatureHeader(pp); | |
| const r2 = await fetch(endpoint, { headers }); | |
| return await r2.json(); | |
| } | |
| function formatOutput(data, targetUrl) { | |
| let out = `=== RenderGate: ${targetUrl} ===\n`; | |
| out += `Payment: ${data.payment?.price} USDC on ${data.payment?.network}\n`; | |
| out += `Render time: ${data.renderTimeMs}ms\n\n`; | |
| out += `Title: ${data.title}\n`; | |
| if (data.description) out += `Description: ${data.description}\n`; | |
| out += `\n`; | |
| if (data.headings?.length > 0) { | |
| out += `Headings (${data.headings.length}):\n`; | |
| data.headings.slice(0, 15).forEach((h) => { | |
| out += ` ${h.level}: ${h.text}\n`; | |
| }); | |
| out += `\n`; | |
| } | |
| if (data.links?.length > 0) { | |
| out += `Links (${data.links.length}):\n`; | |
| data.links.slice(0, 15).forEach((l) => { | |
| out += ` ${l.text.substring(0, 50)} → ${l.href}\n`; | |
| }); | |
| out += `\n`; | |
| } | |
| if (data.refund) { | |
| out += `*** AUTO-REFUND ***\n`; | |
| out += `Reason: ${data.refund.reason}\n`; | |
| out += `Refund amount: ${data.refund.amount}\n`; | |
| out += `Refund transaction: ${data.refund.transaction}\n`; | |
| out += `Verify: https://stellar.expert/explorer/testnet/tx/${data.refund.transaction}\n\n`; | |
| } | |
| out += `Content (${data.content?.length} chars):\n`; | |
| out += data.content || "(empty)"; | |
| return out; | |
| } | |
| const sites = [ | |
| { name: "1-twitter", url: "https://x.com/stellarorg" }, | |
| { name: "2-linkedin", url: "https://www.linkedin.com/company/stellar-development-foundation" }, | |
| { name: "3-soroswap", url: "https://soroswap.finance" }, | |
| { name: "4-producthunt", url: "https://www.producthunt.com" }, | |
| ]; | |
| for (const site of sites) { | |
| console.log(`Rendering ${site.name}...`); | |
| try { | |
| const data = await paidRender(site.url); | |
| const output = formatOutput(data, site.url); | |
| const path = `demo-output/${site.name}-with.txt`; | |
| writeFileSync(path, output); | |
| console.log(` Saved: ${path} (${data.content?.length} chars, refund: ${!!data.refund})`); | |
| } catch (err) { | |
| console.error(` Failed: ${err.message}`); | |
| } | |
| } | |
| console.log("Done!"); | |