Skip to content

Latest commit

 

History

History
 
 

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

README.md

@microai/paygate-sdk

Local TypeScript SDK for the current MicroAI Paygate x402-style protocol.

The SDK handles the existing gateway flow:

  1. Send an unsigned request.
  2. Read the 402 Payment Required paymentContext.
  3. Sign the payment context with EIP-712.
  4. Retry with X-402-Signature, X-402-Nonce, and X-402-Timestamp.
  5. Decode the X-402-Receipt response header.
  6. Verify the signed receipt locally.

This package is private and local for now. It is not published to npm.

Protocol Status

MicroAI Paygate currently uses a custom x402-style wire contract. It is not official x402-compatible yet because it uses custom X-402-* headers and does not perform facilitator-backed or on-chain USDC settlement.

A valid EIP-712 signature proves wallet authorization for the payment context. It does not prove that USDC moved on-chain.

Install And Test

cd sdk/typescript
bun install
bun run test

Run the type checker:

bun run typecheck

Usage

import { ethers } from "ethers";
import { PaygateClient } from "@microai/paygate-sdk";

const client = new PaygateClient({
  gatewayUrl: "http://localhost:3000",
  signer: new ethers.Wallet(process.env.EVM_PRIVATE_KEY!),
  trustedServerPublicKey: process.env.PAYGATE_SERVER_PUBLIC_KEY,
});

const response = await client.summarize("Text to summarize");

console.log(response.data.result);
console.log(response.receipt?.receipt.id);
console.log(response.receiptVerified);

Generic endpoint usage:

const response = await client.request<{ text: string }, { result: string }>({
  method: "POST",
  path: "/api/ai/summarize",
  body: { text: "..." },
});

Example

Set environment variables:

PAYGATE_GATEWAY_URL=http://localhost:3000
EVM_PRIVATE_KEY=0x...
PAYGATE_SERVER_PUBLIC_KEY=0x...

Use only unfunded local or test wallets. Never use a funded wallet, seed phrase, production key, or real customer wallet in examples.

PAYGATE_SERVER_PUBLIC_KEY should be the gateway receipt signing public key distributed out of band. Without it, the SDK can decode receipts and verify request/response hash binding, but it returns receiptVerified: false instead of trusting the self-declared key inside the receipt.

Run:

cd sdk/typescript
bun run examples/summarize.ts "Text to summarize"

Receipt Verification Example

Receipt verification with a trusted public key (replace the placeholder with the gateway's real public key):

import { ethers } from "ethers";
import { PaygateClient, PaygateSdkError } from "@microai/paygate-sdk";

async function main(): Promise<void> {
  const client = new PaygateClient({
    gatewayUrl: process.env.PAYGATE_GATEWAY_URL ?? "http://localhost:3000",
    signer: new ethers.Wallet(process.env.EVM_PRIVATE_KEY!),
    trustedServerPublicKey: process.env.PAYGATE_SERVER_PUBLIC_KEY ?? "0xYOUR_GATEWAY_PUBLIC_KEY",
  });

  try {
    const response = await client.summarize("Text to summarize");

    if (!response.receipt) {
      console.warn("No receipt returned; treat the response as untrusted.");
      return;
    }

    if (!response.receiptVerified) {
      console.warn("Receipt was present but did not verify; discard the response.");
      return;
    }

    console.log("Verified receipt ID:", response.receipt.receipt.id);
    console.log("Summary:", response.data.result);
  } catch (error) {
    if (
      error instanceof PaygateSdkError &&
      (error.code === "receipt_verification_failed" || error.code === "receipt_decode_failed")
    ) {
      console.error("Receipt verification failed; treat the response as untrusted.");
      return;
    }
    throw error;
  }
}

await main();

Run the receipt verification example:

cd sdk/typescript
bun run examples/verify-receipt.ts "Text to summarize"

Optional Live Test

The live SDK test is skipped by default. Start the local stack first:

bun run stack

Then run:

PAYGATE_SDK_LIVE_TEST=1 EVM_PRIVATE_KEY=0x... PAYGATE_SERVER_PUBLIC_KEY=0x... PAYGATE_GATEWAY_URL=http://localhost:3000 bun test src/__tests__/live-gateway.test.ts

The live path depends on the gateway's configured AI provider. With the default OpenRouter provider, the gateway still needs OPENROUTER_API_KEY.