x402-payguard / tree / src/stellar-testnet.js ยท raw (this view has old GitHub links rewritten for the mirror; raw is byte-exact)
// Stellar testnet x402 route (testnet demo / integration target; Base mainnet routes are untouched).
//   GET|POST /stellar-testnet/v1/address?address=   PAID 0.01 XLM on Stellar testnet (x402 v2, exact, stellar:testnet)
// Same OFAC SDN screen as the Base route /v1/address. Uses the official @x402/stellar server scheme and the public
// x402.org facilitator (free, no API key, sponsors the network fee: areFeesSponsored). The asset is the native XLM
// Stellar Asset Contract (SEP-41), so a Friendbot-funded testnet account can pay with no trustline or USDC faucet.
// Separate x402ResourceServer + paymentMiddleware scoped to /stellar-testnet/*; /supported is answered statically.
import { paymentMiddleware, x402ResourceServer } from '@x402/hono';
import { ExactStellarScheme } from '@x402/stellar/exact/server';
import { ResilientFacilitatorClient } from './facilitator.js';

export const STELLAR_TESTNET = 'stellar:testnet'; // CAIP-2
export const STELLAR_TESTNET_XLM_SAC = 'CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC'; // native XLM SAC (testnet), 7 decimals
export const STELLAR_TESTNET_PREFIX = '/stellar-testnet';
export const STELLAR_TESTNET_ADDRESS_PATH = `${STELLAR_TESTNET_PREFIX}/v1/address`;
export const STELLAR_TESTNET_DEFAULTS = {
  stellarTestnetPayTo: 'GD2I22CZ7K6BJR2JLN54LDM7TSXFSMTDWYFPJECWXZOHK3TFM6PEX44I', // swarm-owned testnet receiver (key in the vault)
  stellarTestnetFacilitatorUrl: 'https://x402.org/facilitator',
  stellarTestnetAmount: '100000', // 0.01 XLM (stroops)
};

class StaticStellarFacilitatorClient extends ResilientFacilitatorClient {
  staticKinds() {
    return { kinds: [{ x402Version: 2, scheme: 'exact', network: this.network, extra: { areFeesSponsored: true } }], extensions: [], signers: {} };
  }
}

export function stellarTestnetInfo(cfg, origin) {
  const c = { ...STELLAR_TESTNET_DEFAULTS, ...cfg };
  return {
    methods: ['GET', 'POST'], path: STELLAR_TESTNET_ADDRESS_PATH, url: `${origin}${STELLAR_TESTNET_ADDRESS_PATH}`, param: 'address',
    price: `${Number(c.stellarTestnetAmount) / 1e7} XLM (testnet)`, amount: c.stellarTestnetAmount, network: STELLAR_TESTNET, asset: 'XLM (native Stellar Asset Contract, testnet)', assetAddress: STELLAR_TESTNET_XLM_SAC,
    payTo: c.stellarTestnetPayTo, facilitator: c.stellarTestnetFacilitatorUrl, x402: ['v2'], testnet: true,
    note: 'Stellar testnet test route (no real money). Same result as /v1/address. Fund a testnet account free with Friendbot (https://friendbot.stellar.org/?addr=G...); fees are sponsored by the facilitator.',
  };
}

export function mountStellarTestnet(app, cfg, o) {
  const c = { ...STELLAR_TESTNET_DEFAULTS, ...Object.fromEntries(Object.entries(cfg).filter(([k, v]) => k.startsWith('stellarTestnet') && v !== undefined)) };
  // Stellar settle waits for ledger close (often 10-20 s), so it gets 30 s (verify 8 s + settle 30 s < 45 s watchdog).
  const facilitatorClient = o.facilitatorClient || new StaticStellarFacilitatorClient({ url: c.stellarTestnetFacilitatorUrl, name: 'x402.org', network: STELLAR_TESTNET, staticSupported: true, settleTimeoutMs: 30000 });
  const server = new x402ResourceServer(facilitatorClient).register(STELLAR_TESTNET, new ExactStellarScheme());
  const resource = cfg.publicUrl ? { resource: `${cfg.publicUrl.replace(/\/$/, '')}${STELLAR_TESTNET_ADDRESS_PATH}` } : {};
  const route = {
    ...resource,
    accepts: { scheme: 'exact', price: { amount: String(c.stellarTestnetAmount), asset: STELLAR_TESTNET_XLM_SAC }, network: STELLAR_TESTNET, payTo: c.stellarTestnetPayTo, maxTimeoutSeconds: 120 },
    description: 'PayGuard OFAC SDN sanctions screen for one crypto address, paid in Stellar testnet XLM (test route). Same output as the Base mainnet /v1/address.',
    mimeType: 'application/json',
  };
  const routes = { [`GET ${STELLAR_TESTNET_ADDRESS_PATH}`]: route, [`POST ${STELLAR_TESTNET_ADDRESS_PATH}`]: route };
  app.use(STELLAR_TESTNET_ADDRESS_PATH, o.validate);
  app.use(STELLAR_TESTNET_ADDRESS_PATH, paymentMiddleware(routes, server, undefined, undefined, o.syncFacilitatorOnStart ?? true));
  app.on(['GET', 'POST'], STELLAR_TESTNET_ADDRESS_PATH, o.handler);
  return c;
}

agentgate-source: code mirror on Cloudflare Pages. All repos