快速入门
铸造 Agent
Last updated March 27, 2026
使用 Metaplex API 和 mpl-agent-registry SDK,通过单次调用在链上注册 AI Agent。
Summary
Metaplex API 提供托管端点,存储 Agent 元数据并返回未签名的 Solana 交易。对该交易签名并提交后,将创建代表 Agent 的 MPL Core 资产,并在单个原子操作中注册 Agent Identity PDA。
- 创建 — 在一笔交易中同时创建 MPL Core 资产和 Agent Identity PDA,无需预先存在的资产
- 托管 API —
https://api.metaplex.com负责元数据存储,铸造前无需单独上传 - 两个 SDK 函数 — 一键流程使用
mintAndSubmitAgent,手动签名控制使用mintAgent - 多网络支持 — 支持 Solana 主网·devnet、Eclipse、Sonic 和 Fogo
- 要求 —
@metaplex-foundation/mpl-agent-registryv0.2.0+
您将构建的内容
一个已注册的链上 AI Agent:通过 Metaplex API 和 mpl-agent-registry SDK 创建的、连接了 Agent Identity PDA 的 MPL Core 资产。
快速开始
How It Works
通过 Metaplex API 铸造 Agent 是一个由 SDK 协调的三步流程:
- API 调用 — SDK 将 Agent 详情发送至
https://api.metaplex.com的POST /v1/agents/mint。API 将agentMetadata存储在链下并构建未签名的 Solana 交易。 - 返回未签名交易 — API 返回未签名的交易。您的私钥不会离开您的环境,API 只负责构建指令集。
- 签名并提交 — 您(或
mintAndSubmitAgent自动)用密钥对为交易签名并提交到网络。链上通过单个原子操作创建 Core 资产并注册 Agent Identity PDA。
两个字段,两个存储位置
调用 mintAndSubmitAgent 或 mintAgent 时,您提供两段不同的元数据:
| 字段 | 存储位置 | 用途 |
|---|---|---|
uri | 链上(Core 资产元数据中) | 指向公开托管的 JSON 文件,与标准 Core 资产 URI 相同。 |
agentMetadata | 链下(Metaplex API 存储) | 描述 Agent 的功能、服务和信任模型,由注册表索引以供发现。 |
两者均在铸造时设置,不更新 Agent 就无法独立修改。
本指南在一笔交易中同时创建新的 Core 资产并注册 Agent 身份。如果您已拥有 Core 资产且只需附加身份,请改用 registerIdentityV1。
Prerequisites
铸造前需要满足以下条件:
- Node.js 18 或更高版本
- 有余额的 Solana 钱包密钥对(该钱包支付交易费用并成为 Agent 所有者)
- Core 资产 NFT 元数据 JSON 的公开可访问
uri
Installation
安装三个必需的软件包:Agent Registry SDK、核心 Umi 框架,以及提供 RPC 客户端和交易发送器的默认 Umi 包。
npm install @metaplex-foundation/mpl-agent-registry @metaplex-foundation/umi @metaplex-foundation/umi-bundle-defaults
Umi Setup
Umi 是用于与 Solana 程序交互的 Metaplex JavaScript 框架。调用任何 SDK 函数前,需先配置 RPC 端点和密钥对。
mplAgentIdentity() 插件将 Agent Identity 程序的指令构建器和账户反序列化器注册到您的 Umi 实例。没有它,Umi 无法构建或读取 Agent Identity 程序指令。
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import { keypairIdentity } from '@metaplex-foundation/umi';
import { mplAgentIdentity } from '@metaplex-foundation/mpl-agent-registry';
// 将 Umi 指向您首选的 RPC
const umi = createUmi('https://api.mainnet-beta.solana.com')
.use(mplAgentIdentity());
// 加载密钥对 — 该钱包支付交易费用并成为 Agent 所有者
const keypair = umi.eddsa.createKeypairFromSecretKey(mySecretKeyBytes);
umi.use(keypairIdentity(keypair));
上述示例使用 keypairIdentity,即将原始私钥直接加载到 Umi 中。这是服务端脚本和后端集成的标准方式。Umi 还根据环境支持另外两种身份模式:
| 方式 | 方法 | 适用场景 |
|---|---|---|
| 原始密钥对(本示例) | keypairIdentity + createKeypairFromSecretKey | 服务端脚本、后端 |
| 文件系统钱包 | createSignerFromKeypair + signerIdentity(JSON 密钥文件) | 本地开发和 CLI 工具 |
| 浏览器钱包适配器 | umi-signer-wallet-adapters 中的 walletAdapterIdentity | Phantom、Backpack 等 Web dApp |
各种方式的完整代码示例,包括如何从 .json 文件加载文件系统密钥对以及如何接入钱包适配器,请参阅 Umi 文档中的连接钱包。
Mint and Submit an Agent
mintAndSubmitAgent 调用 Metaplex API,对返回的交易签名,并一步提交到网络。大多数集成场景使用此方式。
1import { mintAndSubmitAgent, mplAgentIdentity } from '@metaplex-foundation/mpl-agent-registry'
2import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
3import { keypairIdentity } from '@metaplex-foundation/umi'
4
5const umi = createUmi('https://api.mainnet-beta.solana.com')
6 .use(mplAgentIdentity())
7
8const keypair = umi.eddsa.createKeypairFromSecretKey(mySecretKeyBytes)
9umi.use(keypairIdentity(keypair))
10
11const result = await mintAndSubmitAgent(umi, {}, {
12 wallet: umi.identity.publicKey,
13 name: 'My AI Agent',
14 uri: 'https://example.com/agent-metadata.json', // Core asset NFT metadata URI
15 agentMetadata: { // Stored off-chain by the Metaplex API
16 type: 'agent',
17 name: 'My AI Agent',
18 description: 'An autonomous trading agent',
19 services: [
20 { name: 'trading', endpoint: 'https://myagent.ai/trade' },
21 ],
22 registrations: [],
23 supportedTrust: [],
24 },
25})
26
27console.log('Asset address:', result.assetAddress)
28console.log('Transaction signature:', result.signature)
29
30// Asset address: <base58 address>
31// Transaction signature: <base58 signature>
Mint an Agent with Manual Signing
mintAgent 返回未签名的交易而不提交。需要添加优先费用、使用硬件钱包或集成自定义重试逻辑时使用。
1import {
2 mintAgent,
3 signAndSendAgentTransaction,
4 mplAgentIdentity,
5} from '@metaplex-foundation/mpl-agent-registry'
6import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
7import { keypairIdentity } from '@metaplex-foundation/umi'
8
9const umi = createUmi('https://api.mainnet-beta.solana.com')
10 .use(mplAgentIdentity())
11
12const keypair = umi.eddsa.createKeypairFromSecretKey(mySecretKeyBytes)
13umi.use(keypairIdentity(keypair))
14
15// Step 1: Call the API — returns the unsigned transaction and the pre-computed asset address
16const mintResult = await mintAgent(umi, {}, {
17 wallet: umi.identity.publicKey,
18 name: 'My AI Agent',
19 uri: 'https://example.com/agent-metadata.json',
20 agentMetadata: {
21 type: 'agent',
22 name: 'My AI Agent',
23 description: 'An autonomous trading agent',
24 services: [
25 { name: 'trading', endpoint: 'https://myagent.ai/trade' },
26 { name: 'analysis', endpoint: 'https://myagent.ai/analyze' },
27 ],
28 registrations: [
29 { agentId: 'agent-123', agentRegistry: 'my-registry' },
30 ],
31 supportedTrust: ['tee'],
32 },
33})
34
35console.log('Asset address:', mintResult.assetAddress)
36
37// Step 2: Sign and send using the SDK helper
38const signature = await signAndSendAgentTransaction(umi, mintResult)
39console.log('Confirmed signature:', signature)
40
41// Asset address: <base58 address>
42// Confirmed signature: <base58 signature>
Verify the Result
铸造后,获取 Core 资产并检查 AgentIdentity 插件以确认 Agent 身份已注册。注册成功会附加 Transfer、Update 和 Execute 的生命周期钩子,这些是需要检查的信号。
1import { fetchAsset } from '@metaplex-foundation/mpl-core'
2import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
3import { publicKey } from '@metaplex-foundation/umi'
4import { mplAgentIdentity } from '@metaplex-foundation/mpl-agent-registry'
5
6const umi = createUmi('https://api.mainnet-beta.solana.com')
7 .use(mplAgentIdentity())
8
9// Replace with the assetAddress returned by mintAndSubmitAgent or mintAgent
10const assetAddress = publicKey('YOUR_ASSET_ADDRESS')
11const assetData = await fetchAsset(umi, assetAddress)
12const agentIdentity = assetData.agentIdentities?.[0]
13
14console.log('Registration URI:', agentIdentity?.uri)
15console.log('Transfer hook active:', agentIdentity?.lifecycleChecks?.transfer)
16console.log('Update hook active:', agentIdentity?.lifecycleChecks?.update)
17console.log('Execute hook active:', agentIdentity?.lifecycleChecks?.execute)
18
19// Registration URI: https://example.com/agent-metadata.json
20// Transfer hook active: { __kind: 'Listen' }
21// Update hook active: { __kind: 'Listen' }
22// Execute hook active: { __kind: 'Listen' }
如果 agentIdentities 为 undefined 或为空,则身份未注册——交易可能静默失败或未确认。重试前请先在链上检查交易签名。
Agent Metadata Fields
agentMetadata 对象发送给 Metaplex API,与 Agent 记录一起存储在链下。它与 Core 资产的 uri(NFT 元数据文件)不同,详情请参阅 How It Works。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
type | string | 是 | 模式标识符,使用 'agent'。 |
name | string | 是 | Agent 显示名称 |
description | string | 是 | Agent 的功能及交互方式 |
services | AgentService[] | 否 | Agent 提供的服务端点 |
registrations | AgentRegistration[] | 否 | 外部注册表条目链接 |
supportedTrust | string[] | 否 | 支持的信任机制,如 'tee'、'reputation' |
Agent Service 字段
services 中的每个条目描述与 Agent 交互的一种方式。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
name | string | 是 | 服务类型,如 'trading'、'chat'、'MCP'、'A2A' |
endpoint | string | 是 | 访问服务的 URL |
Supported Networks
在输入对象中传入 network 值。省略时默认为 'solana-mainnet'。请确保 Umi RPC 端点与所选网络匹配。
| 网络 | network 值 |
|---|---|
| Solana 主网 | solana-mainnet(默认) |
| Solana Devnet | solana-devnet |
| Localnet | localnet |
| Eclipse 主网 | eclipse-mainnet |
| Sonic 主网 | sonic-mainnet |
| Sonic Devnet | sonic-devnet |
| Fogo 主网 | fogo-mainnet |
| Fogo 测试网 | fogo-testnet |
Devnet Testing
在上线主网前,先在 Solana devnet 上测试集成。将 Umi 实例指向 devnet RPC 并传入 network: 'solana-devnet',API 将在 devnet 集群上注册 Agent。在 devnet 上铸造的 Agent 与主网拥有独立的资产地址,不会出现在主网浏览器中。
1import { mintAndSubmitAgent, mplAgentIdentity } from '@metaplex-foundation/mpl-agent-registry'
2import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
3import { keypairIdentity } from '@metaplex-foundation/umi'
4
5const umi = createUmi('https://api.devnet.solana.com')
6 .use(mplAgentIdentity())
7
8const keypair = umi.eddsa.createKeypairFromSecretKey(mySecretKeyBytes)
9umi.use(keypairIdentity(keypair))
10
11const result = await mintAndSubmitAgent(umi, {}, {
12 wallet: umi.identity.publicKey,
13 network: 'solana-devnet',
14 name: 'Test Agent',
15 uri: 'https://example.com/test-metadata.json',
16 agentMetadata: {
17 type: 'agent',
18 name: 'Test Agent',
19 description: 'A test agent on devnet',
20 services: [],
21 registrations: [],
22 supportedTrust: [],
23 },
24})
25
26console.log('Asset address:', result.assetAddress)
27console.log('Transaction signature:', result.signature)
28
29// Asset address: <base58 address>
30// Transaction signature: <base58 signature>
Custom API Base URL
在配置参数(mintAgent 或 mintAndSubmitAgent 的第二个参数)中传入 baseUrl,可以指向 staging 或自托管 API。用于对接非生产环境时使用。
1import { mintAgent, mplAgentIdentity } from '@metaplex-foundation/mpl-agent-registry'
2import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
3import { keypairIdentity } from '@metaplex-foundation/umi'
4
5const umi = createUmi('https://api.mainnet-beta.solana.com')
6 .use(mplAgentIdentity())
7
8const keypair = umi.eddsa.createKeypairFromSecretKey(mySecretKeyBytes)
9umi.use(keypairIdentity(keypair))
10
11const result = await mintAgent(
12 umi,
13 { baseUrl: 'https://staging-api.metaplex.com' },
14 {
15 wallet: umi.identity.publicKey,
16 name: 'My Agent',
17 uri: 'https://example.com/metadata.json',
18 agentMetadata: {
19 type: 'agent',
20 name: 'My Agent',
21 description: 'Agent targeting staging API',
22 services: [],
23 registrations: [],
24 supportedTrust: [],
25 },
26 }
27)
28
29console.log('Asset address:', result.assetAddress)
30
31// Asset address: <base58 address>
Custom Transaction Sender
将 txSender 函数作为 mintAndSubmitAgent 的第四个参数传入,使用自己的签名和提交基础设施。适用于添加 Jito 包小费、优先费用或自定义确认轮询。
1import { mintAndSubmitAgent, mplAgentIdentity } from '@metaplex-foundation/mpl-agent-registry'
2import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
3import { keypairIdentity } from '@metaplex-foundation/umi'
4
5const umi = createUmi('https://api.mainnet-beta.solana.com')
6 .use(mplAgentIdentity())
7
8const keypair = umi.eddsa.createKeypairFromSecretKey(mySecretKeyBytes)
9umi.use(keypairIdentity(keypair))
10
11const result = await mintAndSubmitAgent(
12 umi,
13 {},
14 {
15 wallet: umi.identity.publicKey,
16 name: 'My Agent',
17 uri: 'https://example.com/metadata.json',
18 agentMetadata: {
19 type: 'agent',
20 name: 'My Agent',
21 description: 'Agent with custom transaction sender',
22 services: [],
23 registrations: [],
24 supportedTrust: [],
25 },
26 },
27 {
28 txSender: async (tx) => {
29 const signed = await umi.identity.signTransaction(tx)
30 return myCustomSend(signed)
31 },
32 }
33)
34
35console.log('Asset address:', result.assetAddress)
36console.log('Transaction signature:', result.signature)
37
38// Asset address: <base58 address>
39// Transaction signature: <base58 signature>
Error Handling
SDK 导出了带类型的错误守卫,可以明确处理各种失败模式,而不是捕获通用错误。
1import {
2 mintAgent,
3 isAgentApiError,
4 isAgentApiNetworkError,
5 isAgentValidationError,
6 mplAgentIdentity,
7} from '@metaplex-foundation/mpl-agent-registry'
8import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
9import { keypairIdentity } from '@metaplex-foundation/umi'
10
11const umi = createUmi('https://api.mainnet-beta.solana.com')
12 .use(mplAgentIdentity())
13
14const keypair = umi.eddsa.createKeypairFromSecretKey(mySecretKeyBytes)
15umi.use(keypairIdentity(keypair))
16
17const input = {
18 wallet: umi.identity.publicKey,
19 name: 'My Agent',
20 uri: 'https://example.com/metadata.json',
21 agentMetadata: {
22 type: 'agent',
23 name: 'My Agent',
24 description: 'An autonomous agent',
25 services: [],
26 registrations: [],
27 supportedTrust: [],
28 },
29}
30
31try {
32 const result = await mintAgent(umi, {}, input)
33} catch (err) {
34 if (isAgentValidationError(err)) {
35 // Client-side validation failed before the API was called
36 console.error(`Validation error on field "${err.field}": ${err.message}`)
37 } else if (isAgentApiNetworkError(err)) {
38 // Could not reach the API endpoint
39 console.error('Network error:', err.message, err.cause)
40 } else if (isAgentApiError(err)) {
41 // API responded with a non-2xx status
42 console.error(`API error (${err.statusCode}): ${err.message}`)
43 console.error('Response body:', err.responseBody)
44 } else {
45 throw err
46 }
47}
Common Errors
最常见的失败模式及解决方法。
| 错误 | 原因 | 解决方法 |
|---|---|---|
isAgentValidationError | 必填输入字段缺失或格式错误 | 检查 err.field,确保提供了所有必填的 agentMetadata 字段 |
isAgentApiNetworkError | 无法访问 API 端点 | 检查网络连接;查看 err.cause 了解底层错误 |
isAgentApiError | API 返回非 2xx 状态码 | 检查 err.statusCode 和 err.responseBody;确认 uri 可公开访问 |
| Blockhash 过期 | 交易在 blockhash 过期前未提交 | 再次调用 mintAgent 获取新交易,然后重试提交 |
铸造后 agentIdentities 为空 | 交易已确认但身份插件未附加 | 获取交易回执确认成功;若静默失败,重试完整铸造流程 |
Full Example
完整的端到端代码片段——配置、铸造、验证,可直接复制运行。
1import {
2 mintAndSubmitAgent,
3 mplAgentIdentity,
4} from '@metaplex-foundation/mpl-agent-registry'
5import { fetchAsset } from '@metaplex-foundation/mpl-core'
6import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
7import { keypairIdentity } from '@metaplex-foundation/umi'
8
9const umi = createUmi('https://api.mainnet-beta.solana.com')
10 .use(mplAgentIdentity())
11
12const keypair = umi.eddsa.createKeypairFromSecretKey(mySecretKeyBytes)
13umi.use(keypairIdentity(keypair))
14
15// 1. Mint the agent
16const result = await mintAndSubmitAgent(umi, {}, {
17 wallet: umi.identity.publicKey,
18 name: 'My AI Agent',
19 uri: 'https://example.com/agent-metadata.json',
20 agentMetadata: {
21 type: 'agent',
22 name: 'My AI Agent',
23 description: 'An autonomous trading agent',
24 services: [
25 { name: 'trading', endpoint: 'https://myagent.ai/trade' },
26 ],
27 registrations: [],
28 supportedTrust: [],
29 },
30})
31
32console.log('Asset address:', result.assetAddress)
33console.log('Tx signature:', result.signature)
34
35// 2. Verify the agent identity was registered
36const assetData = await fetchAsset(umi, result.assetAddress)
37const agentIdentity = assetData.agentIdentities?.[0]
38
39console.log('Registered:', agentIdentity !== undefined)
40console.log('Registration URI:', agentIdentity?.uri)
41
42// Asset address: <base58 address>
43// Tx signature: <base58 signature>
44// Registered: true
45// Registration URI: https://example.com/agent-metadata.json
Notes
mintAndSubmitAgent每次调用都会创建新的 Core 资产,没有去重机制。用相同输入调用两次会在两个不同地址创建两个独立的 Agent。uri字段存储在 Core 资产的链上元数据中,必须指向可公开访问的 JSON 文档。如果还没有托管的元数据 URI,请先将文件上传到 Arweave 或其他永久存储提供商。- 如需在不创建新 Core 资产的情况下为现有资产附加 Agent 身份,请改用
registerIdentityV1。 - Metaplex API 基础 URL 默认为
https://api.metaplex.com,无需 API 密钥。 - 铸造费用包括标准 Solana 交易费用以及 Core 资产账户和 Agent Identity PDA 的租金。
- 需要
@metaplex-foundation/mpl-agent-registryv0.2.0+。
FAQ
mintAndSubmitAgent 和 mintAgent 有什么区别?
mintAndSubmitAgent 是调用 mintAgent 后一步完成交易签名和提交的便利封装。需要手动签名控制、自定义交易发送器或在提交前检查交易时,请直接使用 mintAgent。
通过 Metaplex API 铸造与直接使用 registerIdentityV1 有什么区别?
Metaplex API 流程(mintAgent / mintAndSubmitAgent)在单笔交易中同时创建 Core 资产和 Agent 身份,无需预先存在的 Core 资产。registerIdentityV1 方式则是将身份插件附加到您已拥有的 MPL Core 资产上。
uri 字段和 agentMetadata 有什么区别?
uri 直接存储在 Core 资产的链上元数据中,应指向公开托管的 JSON 文件,与标准 NFT 相同。agentMetadata 对象发送给 Metaplex API,与 Agent 记录一起存储在链下。两者都在铸造时设置。详情请参阅 How It Works。
调用 mintAndSubmitAgent 之前需要创建 Core 资产吗?
不需要。API 同时处理 Core 资产创建和 Agent 身份注册。您只需提供钱包地址、Agent 名称、元数据 URI 和 agentMetadata 对象。
上线主网前可以在 devnet 上测试吗?
可以。在输入中传入 network: 'solana-devnet',并将 Umi 实例指向 https://api.devnet.solana.com。
API 返回了交易但链上提交失败会怎样?
链上交易失败意味着 Core 资产未创建且 Agent 身份未注册。再次调用 mintAgent 获取带有新 blockhash 的新交易,然后重试。
Metaplex API 支持哪些网络?
Solana 主网、Solana Devnet、Localnet、Eclipse 主网、Sonic 主网、Sonic Devnet、Fogo 主网和 Fogo 测试网。传入的准确值请参阅 Supported Networks。
铸造 Agent 需要多少费用?
铸造费用包括标准 Solana 交易费用以及 Core 资产账户和 Agent Identity PDA 的租金。Metaplex API 的铸造不收取额外协议费用。
