OpenPermit Docs
SDK

Buyer SDK

Prepare smart-account mandates, create agent continuations, and pay direct x402 resources.

For autonomous agent commerce, the buyer path is permission-first:

  1. Approve a MetaMask ERC-7715 permission for the seller payee and token.
  2. Check readiness for a seller/resource/payment scope.
  3. Create a continuation only when readiness is ready.
  4. Open or redirect to the seller-hosted continuation URL with the scoped continuation token appended. The seller server calls OpenPermit internally to issue the x402 ERC-7710 credential and finish checkout.
import { createOpenPermitClient } from '@openpermit/sdk/client';

const openpermit = createOpenPermitClient({
	baseUrl: 'https://api.openpermit.ai',
	apiKey: process.env.OPENPERMIT_API_KEY,
});

const scope = {
	mandateId: 'mandate_...',
	storefrontUrl: 'https://storefront.example',
	sellerId: 'seller_...',
	resourceId: 'storefront:checkout',
	paymentChallenge: 'x402' as const,
	paymentMode: 'metamaskErc7715' as const,
	chain: 'eip155:11155111',
	asset: 'USDC',
	payTo: '0xSellerPayTo...',
	tokenAddress: '0xUsdcToken...',
	tokenDecimals: 6,
	tokenName: 'USDC',
	tokenVersion: '2',
	metadata: {
		merchantContinuationUrl: 'https://storefront.example/agent-payments/continue/session_123?checkoutSession=checkout_session_123',
	},
};

const readiness = await openpermit.checkAgentCommerceReadiness(scope);
if (readiness.status !== 'ready') {
	throw new Error(readiness.requiredActions.join('\\n'));
}

const continuation = await openpermit.createAgentCommerceContinuation(scope);

The continuation response includes link-first agentInstructions; show or copy those only after readiness is ready. For browser-first checkout, append the continuation token to the seller merchantContinuationUrl and let the seller page complete checkout.

OpenPermit's dashboard requests the MetaMask ERC-7715 permission from the connected payer wallet. Viem signAuthorization and the EIP-7702 helpers below are future/advanced mode; production MetaMask extension accounts should use paymentMode: 'metamaskErc7715' instead of the 7702 helper path.

import {
	registerSmartAccountX402Mandate,
	revokeSmartAccountX402Mandate,
} from '@openpermit/sdk/experimental/openpermit7702';

await registerSmartAccountX402Mandate({
	client: openpermit,
	mandateId: 'mandate_...',
	walletClient,
	publicClient, // must support getCode for already-delegated browser-wallet accounts
	chain: 'eip155:10143',
	payeeAddress: '0xSellerPayTo...',
	tokenAddress: '0xUsdcToken...',
	tokenDecimals: 6,
	tokenName: 'USDC',
	tokenVersion: '2',
});

await revokeSmartAccountX402Mandate({
	client: openpermit,
	mandateId: 'mandate_...',
	walletClient,
	publicClient,
	chain: 'eip155:10143',
});

wrapFetch is still useful for developer-controlled agents that can run SDK code directly. For x402, it can also run in manual wallet-signed mode when you supply an x402.walletClient capable of signing the EIP-3009 payload. Manual x402 helpers are also available under @openpermit/sdk/x402/manual so they are not confused with autonomous generic-agent checkout.

import { wrapFetch } from '@openpermit/sdk/buyer';
import { createOpenPermitClient } from '@openpermit/sdk/client';

const openpermit = createOpenPermitClient({
	baseUrl: 'https://api.openpermit.ai',
	apiKey: process.env.OPENPERMIT_API_KEY,
});

const paidFetch = wrapFetch(fetch, {
	client: openpermit,
	mandateId: 'mandate_...',
	x402: { walletClient },
	idempotencyKey: (intent) => `agent-run-${intent.intentId}`,
	onPaymentExecuted: (execution, intent) => {
		console.log('paid', intent.intentId, execution.executionId);
	},
});

const response = await paidFetch('https://seller.example/paid/data');

Policy denials throw OpenPermitPolicyError. Malformed or unsupported payment challenges throw OpenPermitPaymentRequiredError.

Manual wallet-signed x402 requires a fresh real PAYMENT-SIGNATURE. Generic agents should use MetaMask ERC-7715 readiness and continuations instead of pretending they can sign from the user's wallet.