GOAT Network
AgentKit

GOAT Flow for AgentKit

AgentKit integrates GOAT Flow through two complementary plugin sets. Both use the x402 protocol and retain their published package and action identifiers:

  • x402 plugin (payer side) -- 5 actions enabling your agent to create payments, sign EIP-712 authorization data, transfer tokens, check status, and cancel orders
  • x402-merchant plugin (merchant side) -- 30 actions for managing a full merchant portal: auth, orders, balance, webhooks, API keys, and more

Before wiring the plugins, read the GOAT Flow overview, Flow Quick Start, and integration guide. This page stays focused on AgentKit-specific usage.

GOAT Flow Payer Plugin

The payer-side flow uses two adapter interfaces:

  • MerchantGatewayAdapter -- communicates with the merchant's payment API
  • PayerWalletAdapter -- signs EIP-712 typed data and transfers tokens

Payment Flow

GOAT Flow Payment Flow
Agent                    Merchant Gateway           Blockchain
  │                           │                        │
  │ 1. createPayment -------->│                        │
  │ <--- paymentId + EIP-712  │                        │
  │                           │                        │
  │ 2. signTypedData -------->│ (local EIP-712 sign)   │
  │ 3. submitSignature ------>│                        │
  │ <--- authorized           │                        │
  │                           │                        │
  │ 4. transferToken ---------│----------------------->│
  │                           │                        │
  │ 5. status/cancel -------->│                        │

Setup

src/goat-flow-setup.ts
import { ActionProvider } from '@goatnetwork/agentkit/providers';
import {
  createPaymentAction,
  submitSignatureAction,
  transferPaymentAction,
  paymentStatusAction,
  cancelPaymentAction,
  HttpMerchantGatewayAdapter,
  EvmPayerWalletAdapter,
} from '@goatnetwork/agentkit/plugins';
import { Wallet } from 'ethers';

// 1. Create the merchant gateway adapter (HTTP client to your merchant)
const merchant = new HttpMerchantGatewayAdapter(
  process.env.MERCHANT_API_BASE_URL!,
  {
    headers: {
      Authorization: `Bearer ${process.env.MERCHANT_API_KEY}`,
    },
    routes: {
      createOrderPath: '/x402/create-order',
      orderStatusPath: '/x402/order-status/:paymentId',
      submitSignaturePath: '/x402/submit-signature',
      cancelOrderPath: '/x402/cancel-order',
    },
  }
);

// 2. Create the payer wallet adapter (signs EIP-712 data)
const signer = new Wallet(process.env.PRIVATE_KEY!);
const payer = new EvmPayerWalletAdapter(signer);

// 3. Register all x402 actions
const provider = new ActionProvider();
provider.register(createPaymentAction(merchant));
provider.register(submitSignatureAction(merchant, payer));
provider.register(transferPaymentAction(payer));
provider.register(paymentStatusAction(merchant));
provider.register(cancelPaymentAction(merchant));

Complete Payment Flow Example

This example is based on the repo's examples/x402-payment-flow/eip712-full-flow.ts:

src/goat-flow.ts
import { Wallet } from 'ethers';
import { EvmPayerWalletAdapter } from '@goatnetwork/agentkit/plugins';

// 1. Create a signer
const signer = Wallet.createRandom();
const payer = new EvmPayerWalletAdapter(signer);

// 2. Merchant creates a payment intent (returns EIP-712 data to sign)
const created = await merchant.createPaymentIntent({
  to: '0xabc...',
  asset: 'USDC',
  amount: '1000000',
});

// 3. Agent signs the EIP-712 calldata
const signature = await payer.signCalldataTypedData(
  created.calldataSignRequest!
);

// 4. Submit the signature to the merchant
const authorized = await merchant.submitPaymentAuthorization(
  created.paymentId,
  signature
);

// 5. Check status
const status = await merchant.getPaymentStatus(created.paymentId);
console.log({ paymentId: created.paymentId, authorized, status });

Using the Runtime

When executing x402 actions through the runtime, pass confirmed: true since payment actions require confirmation:

src/goat-flow-runtime.ts
const context = {
  traceId: 'trace_pay_001',
  network: 'goat-testnet',
  now: Date.now(),
  caller: 'payment-agent',
};

// Create payment
const create = await runtime.run(
  provider.get('goat.x402.payment.create'),
  context,
  { to: '0xabc...', asset: 'USDC', amount: '10' },
  { confirmed: true, idempotencyKey: 'pay-001' }
);

if (!create.ok) {
  console.error('Payment failed:', create.error);
  return;
}

// Submit signature
const sign = await runtime.run(
  provider.get('goat.x402.payment.submitSignature'),
  context,
  {
    paymentId: create.output.paymentId,
    calldataSignRequest: create.output.calldataSignRequest,
  },
  { confirmed: true }
);

// Transfer tokens
const transfer = await runtime.run(
  provider.get('goat.x402.payment.transfer'),
  context,
  {
    tokenAddress: create.output.tokenAddress,
    to: create.output.payToAddress,
    amount: '10',
  },
  { confirmed: true }
);

// Check status
const status = await runtime.run(
  provider.get('goat.x402.payment.status'),
  context,
  { paymentId: create.output.paymentId }
);

MerchantGatewayAdapter Interface

If you need to integrate with a non-standard merchant API, implement the MerchantGatewayAdapter interface:

Interface
interface MerchantGatewayAdapter {
  createPaymentIntent(
    input: CreatePaymentIntentInput,
    signal?: AbortSignal
  ): Promise<CreatePaymentIntentResult>;

  getPaymentStatus(
    paymentId: string,
    signal?: AbortSignal
  ): Promise<{ paymentId: string; status: PaymentStatus }>;

  submitPaymentAuthorization(
    paymentId: string,
    signature: string,
    signal?: AbortSignal
  ): Promise<{ paymentId: string; status: 'authorized' | 'failed' }>;

  cancelPayment(
    paymentId: string,
    signal?: AbortSignal
  ): Promise<{ paymentId: string; status: 'cancelled' | 'failed' }>;
}

Payment Statuses

StatusDescription
createdPayment intent created, awaiting authorization
authorizedSignature submitted and verified
settledOn-chain transfer confirmed
failedPayment failed at any stage
expiredPayment intent timed out

GOAT Flow Merchant Plugin

The merchant plugin provides 30 actions for managing the GOAT Flow merchant portal. It uses the HttpMerchantPortalClient HTTP adapter.

Setup

src/merchant-setup.ts
import { HttpMerchantPortalClient } from '@goatnetwork/agentkit/plugins';
import {
  merchantAuthLoginAction,
  merchantAuthRegisterAction,
  merchantDashboardStatsAction,
  merchantOrdersListAction,
  merchantBalanceGetAction,
  // ... (30 actions total)
} from '@goatnetwork/agentkit/plugins';

const merchantClient = new HttpMerchantPortalClient(
  process.env.MERCHANT_PORTAL_BASE_URL ?? 'http://localhost:8080'
);

const provider = new ActionProvider();
provider.register(merchantAuthLoginAction(merchantClient));
provider.register(merchantAuthRegisterAction(merchantClient));
provider.register(merchantDashboardStatsAction(merchantClient));
provider.register(merchantOrdersListAction(merchantClient));
provider.register(merchantBalanceGetAction(merchantClient));
// ... register additional actions as needed

Authentication Flow

Merchant portal actions use bearer token authentication. The auth actions (login, register) return an access_token. Pass it via ActionContext.accessToken in subsequent calls:

Authentication example
// 1. Login
const loginResult = await runtime.run(
  provider.get('x402_merchant.auth.login'),
  context,
  { email: 'merchant@example.com', password: 'secret' },
  { confirmed: true }
);

// 2. Use the token in subsequent calls
const authedContext = {
  ...context,
  accessToken: loginResult.output.access_token,
};

const stats = await runtime.run(
  provider.get('x402_merchant.dashboard.stats'),
  authedContext,
  {}
);

The accessToken field on ActionContext is never included in hook events or logs for security. Auth action outputs containing tokens are automatically marked with sensitiveOutputFields.

Session-Scoped Clients

For multi-tenant deployments, use withAccessToken() to create session-scoped client clones that avoid cross-session token leakage:

Multi-tenant usage
const sessionClient = merchantClient.withAccessToken(userToken);
// sessionClient has independent token state

Environment Variables

.env
# GOAT Flow payer (merchant gateway)
MERCHANT_API_BASE_URL=https://merchant.example.com
MERCHANT_API_KEY=your-api-key

# Custom route paths (optional — defaults shown)
MERCHANT_CREATE_ORDER_PATH=/x402/create-order
MERCHANT_ORDER_STATUS_PATH=/x402/order-status/:paymentId
MERCHANT_SUBMIT_SIGNATURE_PATH=/x402/submit-signature
MERCHANT_CANCEL_ORDER_PATH=/x402/cancel-order

# GOAT Flow merchant portal
MERCHANT_PORTAL_BASE_URL=http://localhost:8080

# GoatAdapter credentials (published variable names below)
GOAT_X402_BASE_URL=https://x402-api.goat.network
GOAT_X402_API_KEY=your-key
GOAT_X402_API_SECRET=your-secret

On this page