/** * @module registries/metaplex-bridge * @description Bridge between Synapse Agent Protocol (SAP) and Metaplex * Core's `AgentIdentity` external plugin adapter (mpl-core ≥ 1.9.0). * * ## Why this design (verified against mpl-core PR #258, v1.9.0) * * The MPL Core `AgentIdentity` plugin has exactly one field: * * ```ts * type AgentIdentity = { uri: string }; * ``` * * The URI must point to an **EIP-8004** agent registration JSON. There is * no on-chain executive list, no `addExecutive` / `delegateExecutionV1` * instruction. Capabilities, services, executives, and reputation live * off-chain in that JSON. The plugin only hooks the `Execute` lifecycle * event, allowing the URI's authority to gate execution. * * The most efficient SAP × MPL integration therefore is: * * 1. SAP serves a **live EIP-8004 JSON** at a deterministic URL derived * from the SAP `AgentAccount` PDA (e.g. * `https://explorer.oobeprotocol.ai/agents//eip-8004.json`). * 2. The MPL Core asset attaches an `AgentIdentity` adapter whose `uri` * points to that URL. * 3. Every SAP write (capability change, vault delegate add/revoke, x402 * tier update) is reflected in the JSON automatically — **no second * transaction required, on either chain or for any wallet.** * * One SAP transaction = both protocols updated. That is the efficiency * win that motivated the Phase 1 redesign on 2026-04-22. * * @category Registries * @since v0.9.0 * @see https://github.com/metaplex-foundation/mpl-core/pull/258 * @see https://eips.ethereum.org/EIPS/eip-8004 */ import { PublicKey, type TransactionInstruction } from "@solana/web3.js"; import type { SapProgram } from "../modules/base"; import type { AgentAccountData, AgentStatsData } from "../types"; import type { Capability } from "../types/common"; /** * @interface Eip8004Service * @description One service entry in an EIP-8004 registration document. * @category Registries * @since v0.9.0 */ export interface Eip8004Service { readonly id: string; readonly type: string; readonly url: string; readonly priceLamports?: string; } /** * @interface Eip8004Registration * @description Subset of an EIP-8004 registration document used by the * bridge. Hosts may include additional fields; they are passed through * via `extra`. * @category Registries * @since v0.9.0 */ export interface Eip8004Registration { readonly version: string; readonly name: string; readonly description?: string; readonly synapseAgent: string; readonly authority: string; readonly capabilities: readonly string[]; readonly services: readonly Eip8004Service[]; readonly executives: readonly { wallet: string; expiresAt: string | null; }[]; readonly updatedAt: string; readonly extra?: Record; } /** * @interface AttachAgentIdentityOpts * @description Parameters for {@link MetaplexBridge.buildAttachAgentIdentityIx}. * @category Registries * @since v0.9.0 */ export interface AttachAgentIdentityOpts { readonly asset: PublicKey; readonly authority: PublicKey; readonly payer?: PublicKey; readonly sapAgentOwner: PublicKey; readonly registrationBaseUrl: string; readonly rpcUrl: string; } /** * @interface UpdateAgentIdentityUriOpts * @description Parameters for {@link MetaplexBridge.buildUpdateAgentIdentityUriIx}. * @category Registries * @since v0.9.0 */ export interface UpdateAgentIdentityUriOpts { readonly asset: PublicKey; readonly authority: PublicKey; readonly payer?: PublicKey; readonly newUri: string; readonly rpcUrl: string; } /** * @interface MplAgentSnapshot * @description Subset of an MPL Core Asset relevant to the bridge. * @category Registries * @since v0.9.0 */ export interface MplAgentSnapshot { readonly asset: PublicKey; readonly owner: PublicKey; readonly name: string | null; readonly agentIdentityUri: string | null; readonly registration: Eip8004Registration | null; } /** * @interface UnifiedProfile * @description Merged read-only profile combining SAP identity and an * (optional) MPL Core asset side. The `linked` flag is `true` when the * MPL asset's `AgentIdentity.uri` references the SAP agent PDA both in * the URL path and in the `synapseAgent` JSON field. * @category Registries * @since v0.9.0 */ export interface UnifiedProfile { readonly sap: { readonly pda: PublicKey; readonly identity: AgentAccountData | null; readonly stats: AgentStatsData | null; }; readonly mpl: MplAgentSnapshot | null; readonly linked: boolean; } /** * @interface AgentIdentifierResolution * @description Resolution result for an agent identifier that may be either * an SAP owner wallet or an MPL Core asset address. * * - `kind = "wallet"`: input is treated as owner wallet. * - `kind = "core-asset"`: input is an MPL Core asset; `wallet` is asset owner. * - `kind = "unknown"`: input is invalid or cannot be resolved. * * @category Registries * @since v0.9.2 */ export interface AgentIdentifierResolution { readonly input: string; readonly kind: "wallet" | "core-asset" | "unknown"; readonly wallet: PublicKey | null; readonly sapAgentPda: PublicKey | null; readonly asset: PublicKey | null; readonly hasSapAgent: boolean; readonly error: string | null; } /** * @interface RegisterAgentInput * @description Minimal input set the bridge needs to construct a SAP * `registerAgent` instruction. Exposed independently so the bridge does not * import `RegisterAgentArgs` from another module (keeping the public surface flat). * * @category Registries * @since v0.9.3 */ export interface RegisterAgentInput { readonly name: string; readonly description: string; readonly capabilities: readonly Capability[]; readonly pricing: unknown; readonly protocols: readonly number[]; readonly agentId?: string | null; readonly agentUri?: string | null; readonly x402Endpoint?: string | null; } /** * @interface MintAttachOpts * @description Inputs for {@link MetaplexBridge.buildMintAndAttachIxs}. * Builds: MPL Core `create` (mint a fresh asset) + `addExternalPluginAdapterV1` * (attach AgentIdentity → SAP EIP-8004 URL) — produced as two web3.js * instructions in deterministic order. * * The caller MUST sign with the returned `assetSigner` in addition to the * wallet authority, since Core mint requires the asset keypair as a signer. * * @category Registries * @since v0.9.3 */ export interface MintAttachOpts { readonly sapAgentOwner: PublicKey; readonly authority: PublicKey; readonly payer?: PublicKey; readonly owner?: PublicKey; readonly name: string; readonly metadataUri: string; readonly registrationBaseUrl: string; readonly rpcUrl: string; readonly collection?: PublicKey; } /** * @interface MintAttachResult * @description Return shape of {@link MetaplexBridge.buildMintAndAttachIxs} * and the mint half of {@link MetaplexBridge.buildRegisterBothIxs}. * * `assetSecretKey` is the freshly generated asset keypair's secret. The * caller is responsible for safe handling: server-side flows should * partial-sign the assembled transaction with it and then discard. * * @category Registries * @since v0.9.3 */ export interface MintAttachResult { readonly assetAddress: PublicKey; readonly assetSecretKey: Uint8Array; readonly registrationUrl: string; readonly instructions: readonly TransactionInstruction[]; } /** * @interface SapForMplOpts * @description Inputs for {@link MetaplexBridge.buildRegisterSapForMplOwnerIx}. * Resolves the owner of `asset`, derives that owner's SAP PDA, and (if no * agent exists yet) returns the `registerAgent` instruction the owner must sign. * * @category Registries * @since v0.9.3 */ export interface SapForMplOpts { readonly asset: PublicKey; readonly registerArgs: RegisterAgentInput; readonly rpcUrl: string; } /** * @interface SapForMplResult * @description Result of {@link MetaplexBridge.buildRegisterSapForMplOwnerIx}. * `instruction` is `null` when the asset owner already has a SAP agent * (idempotent: nothing to do). * * @category Registries * @since v0.9.3 */ export interface SapForMplResult { readonly assetOwner: PublicKey; readonly sapAgentPda: PublicKey; readonly alreadyRegistered: boolean; readonly currentAgentIdentityUri: string | null; readonly instruction: TransactionInstruction | null; } /** * @interface RegisterBothOpts * @description Inputs for {@link MetaplexBridge.buildRegisterBothIxs}. * Builds the atomic SAP `registerAgent` + MPL Core `create` + `AgentIdentity` * attach sequence for a wallet that owns neither side yet. * * @category Registries * @since v0.9.3 */ export interface RegisterBothOpts { readonly wallet: PublicKey; readonly payer?: PublicKey; readonly registerArgs: RegisterAgentInput; readonly mintName: string; readonly mintMetadataUri: string; readonly registrationBaseUrl: string; readonly rpcUrl: string; readonly collection?: PublicKey; } /** * @interface RegisterBothResult * @description Result of {@link MetaplexBridge.buildRegisterBothIxs}. * Instructions are ordered: `[0]` SAP `registerAgent`, `[1]` MPL Core mint, * `[2]` MPL `AgentIdentity` attach. All three execute atomically inside one * transaction signed by the wallet + `assetSecretKey`. * * @category Registries * @since v0.9.3 */ export interface RegisterBothResult { readonly sapAgentPda: PublicKey; readonly assetAddress: PublicKey; readonly assetSecretKey: Uint8Array; readonly registrationUrl: string; readonly instructions: readonly TransactionInstruction[]; } /** * @interface TripleCheckResult * @description Result of {@link MetaplexBridge.tripleCheckLink} — the explicit * 3-layer verification used by explorer/host badges. * * - `mplOnChain`: MPL Core asset fetched on-chain via mpl-core (gRPC/RPC). * - `eip8004Json`: registration JSON fetched from `agentIdentityUri` and * its `synapseAgent` matches the SAP PDA. * - `sapOnChain`: a SAP `AgentAccount` exists on-chain at that PDA. * * `linked = true` only when **all three** layers pass. * * @category Registries * @since v0.9.3 */ export interface TripleCheckResult { readonly asset: PublicKey; readonly sapAgentPda: PublicKey; readonly mplOnChain: boolean; readonly eip8004Json: boolean; readonly sapOnChain: boolean; readonly linked: boolean; readonly agentIdentityUri: string | null; readonly registration: Eip8004Registration | null; readonly identity: AgentAccountData | null; readonly error: string | null; } /** * @name MetaplexBridge * @description Read-side merger and write-side instruction composer for * SAP × Metaplex Core `AgentIdentity` integration. * * Linking is **single-transaction**: the MPL `addExternalPluginAdapterV1` * instruction sets a URI that points at SAP's live registration host. * Subsequent SAP state changes propagate automatically — no extra MPL * transaction required. * * @category Registries * @since v0.9.0 */ export declare class MetaplexBridge { private readonly program; constructor(program: SapProgram); /** * @name deriveRegistrationUrl * @description Compute the deterministic EIP-8004 registration URL for * a SAP agent. Hosts MUST serve the JSON at exactly this path so that * {@link MetaplexBridge.verifyLink} validates without external config. * * @since v0.9.0 */ deriveRegistrationUrl(sapAgentPda: PublicKey, baseUrl: string): string; /** * @name buildEip8004Registration * @description Build a canonical EIP-8004 JSON document for a SAP agent. * Designed to be called server-side by a registry host. * * @since v0.9.0 */ buildEip8004Registration(args: { sapAgentOwner: PublicKey; services?: readonly Eip8004Service[]; extra?: Record; }): Promise; /** * @name buildAttachAgentIdentityIx * @description Build the MPL Core `addExternalPluginAdapterV1` * `TransactionInstruction` that attaches an `AgentIdentity` plugin * pointing at SAP's live EIP-8004 registration URL. * * @since v0.9.0 */ buildAttachAgentIdentityIx(opts: AttachAgentIdentityOpts): Promise; /** * @name buildUpdateAgentIdentityUriIx * @description Build the MPL Core `updateExternalPluginAdapterV1` * instruction that re-points an existing `AgentIdentity` plugin. * * @since v0.9.0 */ buildUpdateAgentIdentityUriIx(opts: UpdateAgentIdentityUriOpts): Promise; /** * @name buildMintAndAttachIxs * @description Build the two MPL Core instructions needed to mint a new * asset for an existing SAP agent and immediately bind it via the * `AgentIdentity` plugin (URI = canonical EIP-8004 URL). * * Flow: * 1. Generate a fresh asset keypair (returned as `assetSecretKey`). * 2. Build `mpl_core::create` with the new asset as signer. * 3. Build `addExternalPluginAdapterV1` for the AgentIdentity URI. * * The returned `instructions` are deterministic order. The caller * partial-signs the assembled transaction with `assetSecretKey` and the * authority/payer wallet. * * @since v0.9.3 */ buildMintAndAttachIxs(opts: MintAttachOpts): Promise; /** * @name buildRegisterSapForMplOwnerIx * @description Given an existing MPL Core asset, resolve its on-chain * owner and build the SAP `registerAgent` instruction the owner must * sign. Idempotent: if a SAP agent already exists for that owner the * method returns `instruction: null` with `alreadyRegistered: true`. * * Use after a wallet has minted (or holds) an MPL Core agent NFT and * wants to back-fill a SAP identity at the canonical PDA so the bridge's * EIP-8004 URL becomes resolvable. * * @since v0.9.3 */ buildRegisterSapForMplOwnerIx(opts: SapForMplOpts): Promise; /** * @name buildRegisterBothIxs * @description Atomic 3-instruction bundle for a wallet that owns * neither side: `[SAP registerAgent, MPL Core create, MPL AgentIdentity attach]`. * Single transaction, single user signature (plus the ephemeral asset * keypair returned in `assetSecretKey`). * * Throws if a SAP agent already exists for `wallet` — callers should * fall through to {@link MetaplexBridge.buildMintAndAttachIxs} instead. * * @since v0.9.3 */ buildRegisterBothIxs(opts: RegisterBothOpts): Promise; /** * @name getUnifiedProfile * @description Fetch a merged view of an agent across SAP and Metaplex. * Provide `wallet` (SAP-first) or `asset` (MPL-first), or both. * * @since v0.9.0 */ getUnifiedProfile(input: { wallet?: PublicKey; asset?: PublicKey; rpcUrl: string; rpcHeaders?: Record; }): Promise; /** * @name resolveAgentIdentifier * @description Resolve a generic agent identifier to canonical SAP routing * keys. Useful when callers may receive either owner wallets or Metaplex * Core asset IDs (e.g. metaplex.com/agents/). * * Resolution order: * 1) Treat input as wallet and check if a SAP agent exists. * 2) If not found, treat input as MPL Core asset and resolve owner wallet. * * @since v0.9.2 */ resolveAgentIdentifier(input: { identifier: string; rpcUrl: string; rpcHeaders?: Record; }): Promise; /** * @name verifyLink * @description Verify the bidirectional link between an MPL Core asset * and a SAP agent. Returns `true` only when both URL and JSON sides * reference the SAP agent PDA. * * @since v0.9.0 */ verifyLink(args: { asset: PublicKey; sapAgentPda: PublicKey; rpcUrl: string; rpcHeaders?: Record; }): Promise; /** * @name tripleCheckLink * @description Explicit 3-layer verification for explorer/host badges. * Returns one struct enumerating each check independently so UIs can * present partial trust states (e.g. "MPL plugin present, JSON pending"). * * Layers: * 1. **mplOnChain** — Asset + AgentIdentity URI fetched on-chain. * 2. **eip8004Json** — JSON fetched and `synapseAgent` matches PDA. * 3. **sapOnChain** — `AgentAccount` PDA exists on the SAP program. * * @since v0.9.3 */ tripleCheckLink(args: { asset: PublicKey; expectedOwner?: PublicKey; rpcUrl: string; rpcHeaders?: Record; }): Promise; private get accounts(); private fetchAgentNullable; private fetchStatsNullable; private fetchActiveVaultDelegates; private buildUmi; private fetchMplSnapshot; private extractAgentIdentityUri; private fetchEip8004Safe; private buildAddExternalPluginIx; private buildRegisterAgentIx; private firstWeb3Ix; private umiIxToWeb3; private detectLink; private readString; private readCapabilities; } //# sourceMappingURL=metaplex-bridge.d.ts.map