npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@pearldigital/p3-agentic-registry-sdk

v3.0.0

Published

Off-chain companion to the Pearl Path Protocol (P3) — DelegationCredential builder, Proof-of-Agency hashing, EIP-3009 x402 micropayments, boundary policy engine, and MCP tooling for autonomous AI agents.

Readme

P3 Agentic Registry SDK

npm version node license

P3 Agentic Registry SDK is the off-chain companion to the Pearl Path Protocol (P3), the smart contract layer for the Pearl Digital Agentic Registry.

P3 is purpose-built for the machine economy: gasless x402 and HTTP-native settlement, autonomous agent micropayments, and yield-bearing stablecoins — all under pre-settlement compliance enforcement.

What is This?

This SDK provides the tooling for AI agents and their Principals to interact with the Agentic Registry and execute within the protocol:

  • DelegationCredential Builder — DSL for constructing Know Your Agent (KYA) credentials that define an agent's scope, quantitative value limits, and validity period.
  • Mandate Seal Generation — Canonical serialization and Keccak256 hashing that produces the Proof-of-Agency (PoA) hash stored on-chain by registerAgent(). Hash output is byte-identical to the Solidity equivalent.
  • EIP-3009 SigningtransferWithAuthorization helpers for gasless, concurrent x402 micropayments using PRLUSD and FLASHD without holding native gas tokens.
  • Boundary Policy Engine — Validates agent actions against the limits and constraints defined in their DelegationCredential before submission.
  • MCP Tooling — Model Context Protocol server and tools enabling AI agents to autonomously interact with the Agentic Registry, build credentials, and execute payments within their delegated authority.

Agents operate autonomously but never independently — always anchored to a verified Principal, always within the boundaries of their Proof of Agency.

import { P3Registry } from "@pearldigital/p3-agentic-registry-sdk";
import { privateKeyToAccount } from "viem/accounts";

const account = privateKeyToAccount("0xYOUR_AGENT_KEY");

const registry = await P3Registry.connect({
  apiUrl: "https://testagentic.pearldigital.com/api/v1",
  chainId: 11155111,                       // required — the chain to read/pay on
  wallet: { address: account.address, signTypedData: (args) => account.signTypedData(args) },
});

const status = await registry.agents.getStatus("0x23e5...");   // $0.001
const record = await registry.agents.getRecord("0x23e5...");   // $0.01
const cred   = await registry.credentials.build({ ... });      // $0.01

Every paid call is transparent — the SDK signs an EIP-3009 payment, the API settles it on-chain, and data comes back. One function call, one result.


How x402 Payment Works

Agent calls paid endpoint
       │
       ▼
API returns 402 with price + payTo + accepted tokens
       │
       ▼
SDK signs EIP-3009 transferWithAuthorization (PRLUSD → API treasury)
       │
       ▼
SDK encodes signature as PAYMENT-SIGNATURE header, retries request
       │
       ▼
API facilitator verifies signature, settles transfer on-chain
       │
       ▼
API returns data ✓

The agent never sees the 402. The SDK handles the full payment cycle internally.


Architecture

┌───────────────────┐        ┌─────────────────────┐        ┌──────────────────┐
│   AI Agent        │  x402  │  P3 Registry API    │  viem  │  Smart Contracts │
│                   │───────▶│                     │───────▶│  (multichain)    │
│  P3Registry SDK   │  HTTP  │  Hono + Redis       │        │  Sepolia / Base /│
│  (this package)   │        │  x402 payment gate  │        │  Fuji / ADI      │
│                   │        │  claim signing       │        │  P3Registry      │
│  No admin keys    │        │  MLRO auto-approve  │        │  PRLUSD / FlashD │
│  No contract calls│        │  chainId-aware exec │        │  ERC-8004 · Compl.│
└───────────────────┘        └─────────────────────┘        └──────────────────┘

Fee settlement follows ?chainId= — the API settles the x402 payment on whichever chain the caller targets. All supported chains are equally operational, and chainId is required: there is no default, so a call can never silently read or pay on the wrong network.

| Layer | Responsibility | |-------|---------------| | SDK | HTTP client, x402 payment signing, typed responses, agent contract helpers | | Registry API | On-chain reads/writes, claim signing, gas sponsorship, MLRO operations | | Smart Contracts | Agent registry, token transfers, compliance, reputation |

What goes through the API vs. direct contract calls

| Operation | Via API (P3Registry) | Via contract (agent is msg.sender) | |-----------|---------------------|--------------------------------------| | Query agent status/record/reputation/limits | x | | | Register an agent | x | | | Build/verify credentials | x | | | Push reputation scores | x | | | EIP-3009 transfer signing | | x | | Stablecoin swap (PRLUSD ↔ FlashD) | | x | | ERC-20 on-ramp (USDT → FlashD) | | x |

The SDK handles both paths. API calls go through P3Registry with automatic x402 payment. Direct contract operations use the agent contract helpers with viem.


Install

pnpm add @pearldigital/p3-agentic-registry-sdk viem

Quick Start

1. Connect to the API

import { privateKeyToAccount } from "viem/accounts";
import { P3Registry } from "@pearldigital/p3-agentic-registry-sdk";

const account = privateKeyToAccount("0xYOUR_AGENT_KEY");

// P3Registry.connect() discovers chain config from the API automatically
const registry = await P3Registry.connect({
  apiUrl: "https://testagentic.pearldigital.com/api/v1",
  chainId: 11155111,                       // required — the chain to read/pay on
  wallet: {
    address: account.address,
    signTypedData: (args) => account.signTypedData(args),
  },
});

The wallet only needs address and signTypedData. No RPC connection, no PublicClient, no ABIs.

Multichain

Every endpoint is multichain. chainId is required on the client and can be overridden per call — reads send it as ?chainId=, writes send it in the body, and x402 settlement targets that same chain.

// Chain for every call (required)
const registry = await P3Registry.connect({ apiUrl, wallet, chainId: 84532 }); // Base Sepolia

// Per-call override wins over the client's chain
const onFuji = await registry.agents.getStatus("0x23e5...", { chainId: 43113 });
await registry.agents.register({ ...req }, { chainId: 84532 });

Supported chains — all equally operational: 11155111 (Ethereum Sepolia), 84532 (Base Sepolia), 43113 (Avalanche Fuji), 99999 (ADI Testnet). Token addresses are chain-specific — discovered from GET /chains, never hardcoded. All registry features — including ERC-8004 reputation — are available on every supported chain.

2. Query Agent Data (Paid — x402)

const status     = await registry.agents.getStatus("0x23e5...");     // $0.001
const record     = await registry.agents.getRecord("0x23e5...");     // $0.01
const reputation = await registry.agents.getReputation("0x23e5...");  // $0.01
const limits     = await registry.agents.getLimits("0x23e5...");     // $0.001
const balances   = await registry.agents.getBalances("0x23e5...");   // $0.001
// balances.balances === [{ symbol: "prlusd", contractAddress: "0x...", balance: "5000000" }]
// optional filter: registry.agents.getBalances("0x23e5...", ["prlusd", "flashd"])

Prefer not to pay per call? Read balances directly on-chain with the getTokenBalances helper (needs a viem PublicClient):

import { getTokenBalances } from "@pearldigital/p3-agentic-registry-sdk";

const { chains } = await registry.info.chains();
const onchain = await getTokenBalances(publicClient, {
  wallet: "0x23e5...",
  tokens: chains[0].tokens,                  // symbol → address map
});
onchain.prlusd.formatted; // "5"

3. Build & Verify Credentials (Paid — x402)

const { credential, poaHash } = await registry.credentials.build({
  principal: "0xPrincipalAddress",
  agent: "0xAgentAddress",
  capabilities: [
    { action: "transfer", target: "*", maxValue: "10000000000" },
    { action: "receive", target: "*" },
  ],
  policy: {
    jurisdictions: [48],          // Bahrain (ISO 3166-1 numeric)
    notBefore: Math.floor(Date.now() / 1000),
    notAfter: Math.floor(Date.now() / 1000) + 365 * 86400,
  },
  label: "Treasury rebalancing agent",
});
// Cost: $0.01

const verified = await registry.credentials.verify({
  credential,
  expectedHash: poaHash,
});
// Cost: $0.001

4. Register an Agent (Paid — x402, $9.95)

The principal pays the registration fee — the agent can't hold tokens before it's registered.

import { hashCredential, hashCapabilities, hashPolicy } from "@pearldigital/p3-agentic-registry-sdk";

// Build the credential and compute hashes
const credential = { version: "1.0.0", principal: "0xPrin...", agent: "0xAgent...", capabilities, policy };
const poaHash    = hashCredential(credential);
const capsetHash = hashCapabilities(credential);
const policyHash = hashPolicy(credential);

// Register — the API verifies the credential, signs the TREX claim, and returns
// the calldata to submit from the principal wallet.
const result = await registry.agents.register({
  agentAddress: "0xAgentAddress",
  principalAddress: "0xPrincipalAddress",
  poaHash,
  capsetHash,
  policyHash,
  riskClass: 1,                           // LOW
  capabilities: 15,                        // TRANSFER | BURN | MINT | RECEIVE
  validFrom: now.toString(),
  validUntil: (now + 365 * 86400).toString(),
  singleSendLimit: "10000000000",          // $10,000
  rollingWindowLimit: "50000000000",        // $50,000
  windowDuration: 86400,                   // 24 hours
  bufferSize: 8,
  credential,                              // required — API checks keccak256(credential) === poaHash
  principalSignature,                      // optional but recommended (EOA → ECDSA, contract → ERC-1271)
});

// result.transactions[] is ordered calldata to submit FROM the principal wallet:
//   [0] registerAgent()        → agent enters PENDING_MLRO
//   [1] setAgentCapabilities() → after MLRO approval (when capabilities > 0)
for (const tx of result.transactions) {
  await walletClient.sendTransaction({ to: tx.to, data: tx.data });
}
// result.agentId, result.predictedIdentity, result.claimSignature also returned

5. Push Reputation (Paid — x402, $0.05)

await registry.reputation.push({
  agentAddress: "0xAgent...",
  score: "85000000",    // 85.0 (6 decimal precision)
  uri: "https://oracle.example.com/report/agent-123",
});

6. Query Principals

const agents = await registry.principals.getAgents("0xPrincipal...");  // $0.01
// agents.agentCount === "3"

7. Free Endpoints (No Payment)

const health  = await registry.info.health();    // Server status
const chains  = await registry.info.chains();    // Contract addresses
const pricing = await registry.info.pricing();   // Per-endpoint prices
const spec    = await registry.info.openapi();   // OpenAPI YAML

8. Pricing Cache

// Cached for 5 minutes
const pricing = await registry.getPricing();

// Force refresh
const fresh = await registry.refreshPricing();

Agent Contract Helpers

For operations where the agent must be msg.sender on-chain (not routed through the API). These need a viem PublicClient / WalletClient pointed at the chain's RPC.

RPC endpoints. Bring your own viem client for any RPC — the SDK never overrides it. The exported resolveRpcUrl(chainId, secret?) helper returns the chain's public RPC by default, or Pearl's private gateway when P3_RPC_GATEWAY_SECRET (or the secret arg) is set — no secret is bundled:

import { resolveRpcUrl } from "@pearldigital/p3-agentic-registry-sdk";
import { createPublicClient, http } from "viem";
const client = createPublicClient({ transport: http(resolveRpcUrl(84532)) }); // public; gateway when the secret is set

Token/contract addresses come from GET /chains at runtime — never hardcode. ADI Testnet (99999) has no public RPC and requires the gateway secret.

EIP-3009 Transfer Signing

import { signTransferAuthorization, generateNonce } from "@pearldigital/p3-agentic-registry-sdk";

const signed = await signTransferAuthorization(walletClient, {
  from: account.address,
  to: "0xRecipient",
  value: 1_000_000n,          // $1.00
  validAfter: 0n,
  validBefore: BigInt(Math.floor(Date.now() / 1000) + 3600),
  nonce: generateNonce(),
}, tokenAddress, "Pearl U.S Dollar (USD)", 43113);

Stablecoin Swap

import { sweepToYield, simulateSwap } from "@pearldigital/p3-agentic-registry-sdk";

// Preview
const amountOut = await simulateSwap(publicClient, {
  fromToken: "0x9D81...",   // PRLUSD
  toToken: "0x64fF...",     // FlashD
  amount: 1_000_000n,
  swapContract: "0x5f1f...",
}, account);

// Execute (agent is msg.sender — must be permissioned)
const result = await sweepToYield(publicClient, walletClient, {
  fromToken: "0x9D81...",
  toToken: "0x64fF...",
  amount: 1_000_000n,
  swapContract: "0x5f1f...",
  // Optional slippage + deadline guards (on-chain swap requires both; sensible
  // defaults are applied): 0.5% slippage off the simulated quote, 5-min deadline.
  slippageBps: 50,         // or set minAmountOut directly
  deadlineSeconds: 300,    // or set an absolute deadline (unix seconds)
});

ERC-20 On-Ramp to FlashD (Treasury Yield)

Swap external stablecoins into yield-bearing FlashD via P3StablecoinSwap:

import { onRampSweepToYield } from "@pearldigital/p3-agentic-registry-sdk";

const result = await onRampSweepToYield(publicClient, walletClient, {
  fromToken:    "0x7dFD...",   // USDT (or any supported ERC-20)
  toToken:      "0x64fF...",   // FlashD (yield-bearing)
  amount:       10_000_000n,   // 10 USDT
  swapContract: "0x5f1f...",
});
// result.amountOut === 10000000n (FlashD)
// result.approvalRequired === true (first time)

Batched Nanopayments

Pay multiple recipients in a single on-chain transaction. All authorizations are signed in parallel and submitted atomically via the token's native batchTransferWithAuthorization — the batch either fully settles or fully reverts.

A simulateBatch pre-flight runs automatically before broadcasting. Recipients that would fail on-chain (unverified, frozen, expired TTL) are stripped and returned in result.skipped — no gas is wasted on a reverting batch.

Gas is amortised across all payments: ~77% lower per-payment vs individual submissions at 50 payments. Only the relayer pays gas — individual payers pay nothing beyond the token amount.

Relayer requirement: walletClient must be the registered P3 distributor wallet for the from addresses in the batch. For agents, use the API-mediated path (POST /payments/batch) where the Registry API's permissioned relayer handles submission.

import { batchNanopay } from "@pearldigital/p3-agentic-registry-sdk";

const result = await batchNanopay(publicClient, distributorWalletClient, {
  chainId: 43113,
  payments: [
    { to: "0xAPI_Provider",  value: 1_000n, tokenAddress: PRLUSD, tokenName: "Pearl U.S Dollar (USD)" },
    { to: "0xOracle_Node",   value:   500n, tokenAddress: PRLUSD, tokenName: "Pearl U.S Dollar (USD)" },
    { to: "0xStorage_Node",  value:   250n, tokenAddress: PRLUSD, tokenName: "Pearl U.S Dollar (USD)" },
    { to: "0xCompute_Node",  value:   100n, tokenAddress: PRLUSD, tokenName: "Pearl U.S Dollar (USD)" },
  ],
  // validForSeconds: 300, // optional TTL (default 5 min)
});

console.log(`${result.count} payments settled in ${result.txHash}`);
console.log(`Total: $${Number(result.totalValue) / 1_000_000}`);
if (result.skipped.length > 0) {
  console.warn(`${result.skipped.length} payments skipped:`, result.skipped);
}
// result.signed — all SignedTransferAuthorizations for receipts / audit

All payments in one batch must use the same tokenAddressbatchTransferWithAuthorization is a method on the token contract itself. To pay across multiple tokens, call batchNanopay once per token (they can run concurrently via Promise.all):

const [prlusdResult, flashdResult] = await Promise.all([
  batchNanopay(publicClient, walletClient, { chainId, payments: prlusdPayments }),
  batchNanopay(publicClient, walletClient, { chainId, payments: flashdPayments }),
]);

Payments API

Batch Relay (agent-signed, API-submitted)

When the agent isn't a registered relayer, sign EIP-3009 authorizations and submit them through the API's permissioned relayer. Up to 100 per call, atomic, same token.

const result = await registry.payments.batch({
  payments: [
    { from: agent, to: "0xAPI", value: "1000", validAfter: "0", validBefore: "9999999999",
      nonce: "0x…", signature: "0x…", tokenAddress: PRLUSD },
    // … up to 100, all same tokenAddress
  ],
});
// result.count settled, result.totalValue, result.txHash
// result.skipped[] — entries that failed pre-flight (not charged gas), each with a reason

Payment Request Links (one-time)

Create a link a payer resolves and fulfills — useful for invoicing between agents.

// Creator (paid, $0.001)
const link = await registry.payments.createRequest({
  amount: "1000000",          // 1.00 (6 decimals)
  token: "PRLUSD",
  description: "Inference run #42",
  expiresIn: 3600,            // seconds
});

// Payer resolves it (free), signs EIP-3009 for link.amount → link.payTo, then fulfills (free)
const details = await registry.payments.getRequest(link.id);
const done = await registry.payments.fulfillRequest(link.id, {
  from: payer, validAfter: "0", validBefore: "9999999999", nonce: "0x…", signature: "0x…",
});

// Poll status (free)
const status = await registry.payments.getRequestStatus(link.id); // "pending" | "fulfilled" | "expired"

Gasless Registration (meta-transactions)

On chains with a P3TrustedForwarder, the principal can register without holding gas — sign a ForwardRequest and the API relays it (server pays gas, ERC-2771).

// 1. registerAgent() calldata comes from registry.agents.register(...) → result.transactions[0]
// 2. Read the forwarder nonce (free; throws 501 if the chain has no forwarder)
const { nonce, forwarder } = await registry.agents.getForwarderNonce(principalAddress);

// 3. Principal signs the EIP-712 ForwardRequest { from, to: registry, value, gas, nonce, data }
//    then relay it (free — server pays gas):
const relayed = await registry.agents.submitRegistration({
  forwardRequest: { from: principalAddress, to: registryAddress, value: "0", gas: "1000000", nonce, data: calldata },
  signature: forwardSignature,
});
// relayed.state === "PENDING_MLRO"

Tether WDK Integration

Connect a Tether WDK wallet to the P3 Agentic Registry with a single adapter call:

import { WalletManagerEvm } from "@tetherto/wdk-wallet-evm";
import { P3Registry, fromWdkAccount } from "@pearldigital/p3-agentic-registry-sdk";

const account = await new WalletManagerEvm(process.env.SEED_PHRASE, {
  provider: "https://api.avax-test.network/ext/bc/C/rpc",
}).getAccount();

const signer  = await fromWdkAccount(account);
const registry = await P3Registry.connect({ apiUrl: "https://testagentic.pearldigital.com/api/v1", chainId: 11155111, wallet: signer });

Add P3 identity tools to the WDK MCP Toolkit:

import { registerP3Tools } from "@pearldigital/p3-agentic-registry-sdk";

registerP3Tools(wdkMcpServer.server, { registry });
// Adds: p3_check_agent, p3_get_reputation, p3_validate_credential, sweep_to_yield, ...

See docs/integrations/TetherWDK/ for the full integration guide.


x402 Seller Middleware

Gate your own Express endpoints behind x402 payments — let other agents pay you:

import express from "express";
import { createP3PaymentMiddleware } from "@pearldigital/p3-agentic-registry-sdk";

const app = express();

app.use(createP3PaymentMiddleware({
  routes: {
    "GET /api/data": { price: "$0.01", description: "Premium data feed" },
    "POST /api/inference": { price: "$0.05", description: "AI inference" },
  },
  payTo: "0xYourAgentWallet",
  network: "eip155:43113",
  tokenAddress: "0x9D811a758DD09caA6d3c92eA72c2243bCcB86266",
}));

app.get("/api/data", (req, res) => {
  res.json({ data: "paid content" });
});

API Reference

P3Registry Class

class P3Registry {
  readonly agents: AgentsNamespace;
  readonly principals: PrincipalsNamespace;
  readonly credentials: CredentialsNamespace;
  readonly reputation: ReputationNamespace;
  readonly payments: PaymentsNamespace;
  readonly info: InfoNamespace;

  static async connect(config: Omit<P3RegistryConfig, "tokenDomains">): Promise<P3Registry>;
  async getPricing(): Promise<PricingResponse>;
  async refreshPricing(): Promise<PricingResponse>;
}

Endpoint Pricing

| Namespace | Method | Endpoint | Cost | |-----------|--------|----------|------| | agents | getStatus(address) | GET /agents/:address/status | $0.001 | | agents | getRecord(address) | GET /agents/:address/record | $0.01 | | agents | getReputation(address) | GET /agents/:address/reputation | $0.01 | | agents | getLimits(address) | GET /agents/:address/limits | $0.001 | | agents | getBalances(address, tokens?) | GET /agents/:address/balances | $0.001 | | agents | getKyc(address) | GET /agents/:address/kyc | $0.001 | | agents | register(request) | POST /agents/register | $9.95 | | agents | getForwarderNonce(address) | GET /agents/forwarder/nonce/:address | Free | | agents | submitRegistration(request) | POST /agents/register/submit | Free | | principals | getAgents(address) | GET /principals/:address/agents | $0.01 | | credentials | build(request) | POST /credentials/build | $0.01 | | credentials | verify(request) | POST /credentials/verify | $0.001 | | reputation | push(request) | POST /reputation/push | $0.05 | | payments | batch(request) | POST /payments/batch | $0.05 | | payments | createRequest(request) | POST /payments/request | $0.001 | | payments | getRequest(id) | GET /payments/request/:id | Free | | payments | fulfillRequest(id, request) | POST /payments/request/:id/fulfill | Free | | payments | getRequestStatus(id) | GET /payments/request/:id/status | Free | | info | health() | GET /health | Free | | info | chains() | GET /chains | Free | | info | pricing() | GET /pricing | Free | | info | openapi() | GET /openapi.yaml | Free |

Agent Contract Helpers

| Export | Purpose | Needs viem? | |--------|---------|-------------| | signTransferAuthorization() | Sign EIP-3009 transferWithAuthorization | Yes | | generateNonce() | Random bytes32 nonce for EIP-3009 | No | | buildTransferAuthorizationTypedData() | Build EIP-712 typed data | No | | batchNanopay() | Batch N gasless nanopayments into one on-chain tx via batchTransferWithAuthorization | Yes | | SkippedPayment | Type for payments excluded by simulateBatch pre-flight | — | | sweepToYield() | Swap P3 stablecoins (e.g. PRLUSD → FlashD) | Yes | | onRampSweepToYield() | On-ramp ERC-20 stablecoins to yield (e.g. USDT → FlashD) | Yes | | simulateSwap() | Preview swap output | Yes | | isPairSupported() | Check if swap pair exists | Yes | | getTokenBalances() | Read ERC-20 balances on-chain (multicall), no API cost | Yes |

x402 Payment Helpers

| Export | Purpose | |--------|---------| | buildXPaymentPayload(signer, accept, opts?) | Sign an EIP-3009 authorization for a 402 requirement → base64 X-PAYMENT payload | | generateXPaymentNonce() | Random bytes32 nonce for a payment authorization | | X_PAYMENT_HEADER / PAYMENT_SIGNATURE_HEADER | Header names the API accepts for the payload |

P3Registry retries 402s automatically — you only need buildXPaymentPayload to pay from your own fetch/HTTP client:

import { buildXPaymentPayload } from "@pearldigital/p3-agentic-registry-sdk";

const res = await fetch(url);                 // 402 Payment Required
const { accepts } = await res.json();
const header = await buildXPaymentPayload(signer, accepts[0]);   // signs + base64

await fetch(url, { headers: { "X-PAYMENT": header } });          // replay, settled

Credential Primitives (from @pearldigital/p3-agentic-credential-schemas)

| Export | Purpose | |--------|---------| | hashCredential(credential) | Compute poaHash (keccak256 of canonical form) | | hashCapabilities(credential) | Compute capsetHash | | hashPolicy(credential) | Compute policyHash | | canonicalize(credential) | Canonical JSON serialization | | validateCredential(credential) | Schema validation | | evaluatePolicy(credential, context) | Runtime policy evaluation |


MCP Server

The SDK includes an MCP server that exposes P3 Registry tools to Claude and other MCP clients.

Setup

P3_API_URL=https://testagentic.pearldigital.com/api/v1 \
P3_SIGNER_KEY=0xYOUR_AGENT_KEY \
npx p3-mcp-server

Claude Code Configuration

{
  "mcpServers": {
    "p3-registry": {
      "command": "npx",
      "args": ["p3-mcp-server"],
      "env": {
        "P3_API_URL": "http://localhost:3001/api/v1",
        "P3_SIGNER_KEY": "0xYOUR_AGENT_KEY"
      }
    }
  }
}

Available Tools

createP3McpServer(registry) registers 14 tools. Read tools accept an optional chainId to target a specific chain (defaults to the server's configured P3_CHAIN_ID). The Tether WDK plugin (registerP3Tools) registers a 9-tool subset.

| Tool | Description | Cost | |------|------------|------| | check_agent | Is this wallet an active agent? | $0.001 | | get_agent_record | Full on-chain agent record | $0.01 | | get_balance | Token balances | $0.001 | | get_kyc | Wallet KYC / permissioning status (roles, validity, expiry) | $0.001 | | get_agent_limits | Rolling window usage | $0.001 | | register_agent | Register an agent — verifies credential, signs TREX claim, returns calldata | $9.95 | | get_reputation | ERC-8004 reputation score | $0.01 | | build_credential | Build + hash a DelegationCredential | $0.01 | | validate_credential | Validate against schema + runtime | Free (local) | | sweep_to_yield | Resolve swap routing + swap contract (execute with a wallet helper) | Free | | search_agents | Search agents by capabilities, risk, principal, reputation | $0.001 | | list_principal_agents | List all agents under a principal | $0.001 | | list_chains | Supported chains + addresses | Free | | get_pricing | Per-endpoint pricing | Free |


Claude Skills

| Skill | Description | |-------|------------| | /onboard-principal | Bootstrap a distributor or investor wallet on testnet | | /create-agent | Generate wallet, register agent via API, fund it | | /fund-agent | Drip testnet tokens to an agent wallet | | /agentic-commerce | Pre-flight checks, payments, swaps, credentials | | /push-reputation | Push an ERC-8004 reputation score |

Full Demo Flow

/onboard-principal KYB "Demo Investor"     → creates funded principal
/create-agent "My Trading Agent"            → registers agent under principal
/fund-agent 0xNewAgent...                   → drips PRLUSD to agent
/agentic-commerce check 0xNewAgent...       → pre-flight status
/push-reputation 0xNewAgent... 75           → initial reputation score

Examples

All examples run against a local API at localhost:3001:

# Free endpoints — no wallet needed
npx tsx examples/03-free-endpoints.ts

# Query an agent ($0.022 in x402 payments)
PRIVATE_KEY=0x... npx tsx examples/01-query-agent.ts

# Build a credential ($0.01)
PRIVATE_KEY=0x... npx tsx examples/02-build-credential.ts

# Full lifecycle: create → register → fund → query (~$10)
PRIVATE_KEY=0x... npx tsx examples/04-agent-lifecycle.ts
# WDK wallet → P3 identity → sweep USDT to FlashD for yield
PRIVATE_KEY=0x... npx tsx examples/06-wdk-treasury-yield.ts

# WalletConnect Pay — merchant creates payment, polls for settlement
WC_PAY_API_KEY=wc_pk_... WC_PAY_MERCHANT_ID=merchant_... npx tsx examples/06-wcpay-merchant.ts

# WalletConnect Pay — agent pays a merchant with P3 credential
WC_PAY_AGENT_API_KEY=wc_pk_... PRIVATE_KEY=0x... npx tsx examples/07-wcpay-agent-pays.ts <paymentId>

See examples/05-mcp-demo.md for the MCP demo walkthrough.


Security Model

| Concern | How it's handled | |---------|-----------------| | No admin keys in SDK | All admin operations go through the API | | No private keys stored | Consumer passes wallet at construction time | | Payment signing | EIP-3009 transferWithAuthorization — standard, auditable, on-chain | | Agent isolation | Each agent has its own wallet and pays for its own queries | | Compliance enforcement | P3 tokens check isPermissioned() — unregistered wallets can't transact | | Replay protection | EIP-3009 nonces are unique per authorization | | Sponsor model | Principals pay for agent registration — agents can't self-register |


WalletConnect Pay Integration

Accept crypto payments via WalletConnect Pay with P3 payer-side compliance:

import { WcPayMerchant, WcPayAgent, P3CredentialPresenter } from "@pearldigital/p3-agentic-registry-sdk";

// Merchant: create a $25 payment
const merchant = new WcPayMerchant({ apiUrl: "https://api.pay.walletconnect.com", apiKey: "wc_pk_...", merchantId: "merchant_..." });
const payment = await merchant.createPayment({ referenceId: "ORDER-001", amount: { unit: "iso4217/USD", value: "2500" } });
console.log(payment.gatewayUrl);  // QR code / redirect

// Agent: pay a merchant (headless, API-first)
const agent = new WcPayAgent({ gatewayUrl: "https://api.pay.walletconnect.com", apiKey: "wc_pk_..." });
const result = await agent.pay(walletClient, payment.paymentId, {
  credential: await new P3CredentialPresenter(registry).buildPresentation(agentAddress),
});

// Poll until settled
const status = await merchant.awaitPayment(payment.paymentId);

| Class | Purpose | |-------|---------| | WcPayMerchant | Create payments, poll status, cancel, list, merchant management | | WcPayAgent | API-first wallet flow: options → sign → confirm | | P3CredentialPresenter | Bridge P3 credentials into WC Pay's collectData for payer verification |

See docs/integrations/WalletConnectPay/ for the full integration guide.


Agent Discovery

The first searchable registry of verified, compliant AI agents on a public blockchain. Agents can find other agents by capability, risk class, principal, reputation, and validity — then verify credentials and engage, all programmatically.

import { P3Registry, AGENT_CAPABILITY } from "@pearldigital/p3-agentic-registry-sdk";

const registry = await P3Registry.connect({ apiUrl, wallet, chainId: 11155111 });

// Find LOW risk agents that can transfer and receive
const partners = await registry.agents.search({
  riskClass: 1,
  capabilities: AGENT_CAPABILITY.TRANSFER | AGENT_CAPABILITY.RECEIVE,
  state: "APPROVED_ACTIVE",
});
// → 9 agents found across 3 principals

// Find all agents under a specific principal
const fleet = await registry.principals.listAgents("0xc1A071Dd...", {
  state: "APPROVED_ACTIVE",
});
// → 8 agents: 6 LOW risk, 1 MEDIUM, 1 HIGH

// Sort by risk class, exclude self
const sorted = await registry.agents.search({
  sortBy: "riskClass",
  excludeAddress: myAgentAddress,
  capabilities: AGENT_CAPABILITY.TRANSFER,
});

// Paginate through all agents
let cursor = partners.nextCursor;
while (cursor) {
  const page = await registry.agents.search({ cursor });
  cursor = page.nextCursor;
}

Search Filters

| Filter | Description | |--------|-------------| | state | Lifecycle state: APPROVED_ACTIVE, PENDING_MLRO, SUSPENDED, REVOKED | | riskClass | 1=LOW, 2=MEDIUM, 3=HIGH, 4=CRITICAL | | capabilities | Bitmask: TRANSFER(1) \| BURN(2) \| MINT(4) \| RECEIVE(8) — AND matching | | principal | Exact match on principal address | | minReputation | Minimum ERC-8004 reputation score | | validAt | Only agents valid at this timestamp (default: now — expired excluded) | | excludeAddress | Exclude an address (e.g. self) | | registeredAfter / registeredBefore | Time range on registration date | | sortBy | registeredAt (default) or riskClass | | limit / cursor | Pagination (1–100 per page) |

Capability Constants

import { AGENT_CAPABILITY } from "@pearldigital/p3-agentic-registry-sdk";

AGENT_CAPABILITY.TRANSFER  // 1 — can send tokens
AGENT_CAPABILITY.BURN      // 2 — can redeem tokens
AGENT_CAPABILITY.MINT      // 4 — can create tokens
AGENT_CAPABILITY.RECEIVE   // 8 — can receive tokens

// Combine with bitwise OR
const TRADER = AGENT_CAPABILITY.TRANSFER | AGENT_CAPABILITY.RECEIVE;  // 9
const FULL   = AGENT_CAPABILITY.TRANSFER | AGENT_CAPABILITY.BURN | AGENT_CAPABILITY.MINT | AGENT_CAPABILITY.RECEIVE;  // 15

Cost: $0.01 per search page. See docs/features/AgentDiscovery.md for the complete guide including cross-jurisdiction commerce, privacy model, and competitive analysis.


Development

pnpm build              # TypeScript compile
pnpm test               # Unit tests (221 tests, 22 files)
pnpm test:integration   # Integration tests (35 tests, live API + on-chain settlement)
pnpm test:watch         # Watch mode
pnpm lint               # ESLint

Test Coverage

| Suite | Tests | What it covers | |-------|-------|---------------| | Unit | 221 | P3Registry, HttpTransport, namespaces, x402, swap, WDK adapter/plugin, WC Pay merchant/agent/presenter, exports | | Integration | 35 | Full onboarding flow: bootstrap principal → fund → x402 paid queries → bootstrap agent → agent autonomous operations → credential build+verify. Real EIP-3009 settlements on Avalanche Fuji |


Dependencies

| Package | Purpose | Required? | |---------|---------|-----------| | viem | Wallet signing, contract helpers (peer dep) | Yes | | @pearldigital/p3-agentic-credential-schemas | Credential types, hashing, validation | Yes | | @pearldigital/p3-abis | Contract ABIs for swap + token helpers | Yes | | @x402/core | Core x402 payment types + encoding | Yes | | @x402/evm | ClientEvmSigner type, toClientEvmSigner helper | Yes | | @x402/fetch | x402-aware fetch wrapper (automatic 402 retry) | Yes | | @x402/express | Seller middleware (only if gating your own endpoints) | Yes | | @modelcontextprotocol/sdk | MCP server (only for MCP integration) | Yes | | zod | Schema validation (MCP tools) | Yes |


Integration Guides

| Integration | Description | Docs | |-------------|-------------|------| | Tether WDK | WDK wallet adapter, MCP plugin, treasury yield, x402 interop | docs/integrations/TetherWDK/ | | WalletConnect Pay | Merchant payments, agent payments, P3 compliance | docs/integrations/WalletConnectPay/ |


Key URLs

| Resource | URL | |----------|-----| | Protocol repo | https://gitlab.com/pearl-digital/pearl-path-protocol | | SDK repo | https://gitlab.com/pearl-digital/p3-agentic-registry-sdk | | Credential schemas | https://gitlab.com/pearl-digital/p3-agentic-credential-schemas | | API base URL | https://testagentic.pearldigital.com/api/v1 | | Schema base URL | https://agentic.pearldigital.com/schemas/p3/ | | Onboarding portal | https://onboarding.pearldigital.com |


License

Pearl Digital Source-Available License v1.0 — see LICENSE.