skills/bap578/SKILL.md
Use this skill when users ask about BAP-578, Non-Fungible Agents, or hands-on engineering for the BAP-578 reference implementation on BNB Chain, including identity, memory, learning proofs, vaults, AI integration, and contract architecture.
npx skillsauth add chatandbuild/skills-repo BAP-578 Non-Fungible AgentsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use this skill whenever users ask about BAP-578, Non-Fungible Agents, or need hands-on engineering guidance for the BAP-578 reference implementation. BAP-578 defines a standardized framework for intelligent, autonomous digital entities that combine the ownership guarantees of NFTs with the adaptive capabilities of artificial intelligence, positioning BNB Chain as the home for decentralized automation.
A BAP‑578 agent is an ERC‑721 token that represents a distinct AI agent identity. The identity is not just a tokenURI; it is a structured on‑chain profile combined with ownership, lifecycle, and optional behavior binding. A BAP‑578 agent answers “who are you?” through:
AgentMetadata structlogicAddress to a separate logic contractIn practical terms, an agent identity is the bundle of these fields, all queryable from the contract. A concise identity statement could be:
“I am token #17, owned by 0xABC…, with persona ‘research analyst’, expertise in ‘market intelligence’, and an attached logic contract at 0xDEF….”
BAP‑578 memory is split into two verifiable layers:
On‑chain state (always authoritative):
On‑chain events (immutable history):
AgentCreated — birth of an agentAgentFunded — BNB deposited to the agentAgentWithdraw — BNB withdrawnAgentStatusChanged — active/inactive togglesMetadataUpdated — identity editsOff‑chain memory (verifiable by hash):
vaultURI points to extended content (summaries, preferences, knowledge)vaultHash anchors integrity; compute keccak256 of fetched content and compare to on‑chain hashIf a vault hash matches, the off‑chain memory is verifiably authentic. If not, it must be treated as untrusted.
A BAP‑578 agent is capable of more than passive identity. Core capabilities include:
Transferability depends on mint type: free‑minted tokens are non‑transferable (soulbound‑like), paid mints are transferable.
Trust is enforced through verifiable mechanisms:
vaultHashAgentMetadata (identity layer):
persona : string // JSON‑encoded persona definition
experience : string // plain‑text domain expertise
voiceHash : string // reference to a voice profile
animationURI : string // visual asset URI
vaultURI : string // extended memory URI
vaultHash : bytes32 // hash of vault content
AgentState (operational layer):
balance : uint256
active : bool
logicAddress : address
createdAt : uint256
owner : address
createAgent(to, logicAddress, metadataURI, metadata) — mint a new agentfundAgent(tokenId) — deposit BNB to agentwithdrawFromAgent(tokenId, amount) — withdraw BNBsetAgentStatus(tokenId, active) — toggle statussetLogicAddress(tokenId, newLogic) — bind logic contractupdateAgentMetadata(tokenId, newURI, newMetadata) — update identitygrantAdditionalFreeMints(user, amount)setFreeMintsPerUser(amount)setTreasury(newTreasury)setPaused(paused)emergencyWithdraw()getAgentState(tokenId)getAgentMetadata(tokenId)tokensOfOwner(address)getTotalSupply()getFreeMints(user)isFreeMint(tokenId)Events are the authoritative history for analytics and audits:
Use events to reconstruct agent histories and confirm integrity of actions.
cd non-fungible-agents-BAP-578
npm install
npm run compile
npm test
cp .env.example .env
Set deployer key, RPC URLs, and explorer key in .env.
npm run deploy:testnet
npm run interact:testnet
getFreeMints(user) to determine if mint is free.to = user address, send zero value.msg.value.AgentCreated event to confirm token ID.fundAgent(tokenId) with msg.value.AgentFunded event.getAgentState(tokenId).balance.withdrawFromAgent(tokenId, amount).AgentWithdraw event and updated balance.vaultHash matches.vaultHash is zero, treat vault data as optional and unverifiable.Traditional NFTs (BEP-721) provide uniqueness and ownership but lack standardized interfaces for autonomous behavior and cross-platform agent interactions. The current blockchain ecosystem lacks standardization for intelligent, autonomous digital entities. BAP-578 addresses:
BAP-578 provides a dual-path architecture supporting both traditional static agents and advanced learning-enabled agents. Developers choose the path that matches their needs:
For agents that don't need to learn or evolve. Memory is stored as JSON in the vault.
Agent Identity (on-chain)
├── AgentMetadata (persona, experience, etc.)
├── AgentState (balance, active, logicAddress)
└── vaultURI → JSON file on IPFS
├── preferences
├── knowledge base
└── configuration
When to use: Bots, static assistants, simple automation agents, NFT-based identities that don't need to evolve.
Verification: keccak256(vault content) == vaultHash — standard hash comparison.
For agents that learn from interactions and evolve over time. Learning data is organized into a Merkle tree; only the 32-byte root is stored on-chain.
Agent Identity (on-chain)
├── AgentMetadata (persona, experience, etc.)
├── AgentState (balance, active, logicAddress)
└── vaultHash → Merkle Root (32 bytes on-chain)
│
└── Merkle Tree (off-chain)
├── Learning Node: preferences
├── Learning Node: patterns
├── Learning Node: confidence scores
└── Learning Node: outcomes
When to use: Adaptive agents, personalized assistants, agents that improve with use, collaborative intelligence systems.
Verification: Merkle proof — any individual learning node can be verified against the on-chain root without revealing the entire tree.
The learning pipeline follows this flow:
User Interaction → Learning Extraction → Tree Building → Merkle Root → On-Chain Update
updateAgentMetadata, providing tamper-proof verification while preserving privacy and minimizing gas costs.Any individual piece of learning data can be verified without revealing the entire tree:
// Verify a single learning node against the on-chain Merkle root
function verifyLearning(leaf, proof, root) {
let hash = keccak256(leaf);
for (const sibling of proof) {
hash = hash < sibling
? keccak256(hash + sibling)
: keccak256(sibling + hash);
}
return hash === root; // root is the on-chain vaultHash
}
This enables:
BAP-578 provides infrastructure without prescribing specific AI implementations. The flexible learning module architecture allows developers to implement various AI optimization methods through the logic contract:
| Method | Description | Implementation | |--------|-------------|----------------| | RAG (Retrieval-Augmented Generation) | Leverages off-chain vaults to retrieve past interactions and knowledge | Logic contract queries vault content via vaultURI | | MCP (Model Context Protocol) | Integrates with different AI providers through logic contracts | Logic contract routes to external AI services | | Fine-tuning | Trains models on agent-specific data | Learning data in Merkle tree feeds fine-tuning pipelines | | Reinforcement Learning | Agents learn from outcome feedback | Reward signals stored as learning nodes in tree | | Hybrid | Combines multiple approaches | Logic contract orchestrates multiple methods |
The logicAddress field binds an agent to a learning module:
Agent (on-chain identity)
│
└── logicAddress → Learning Module Contract
├── processInteraction(input) → learning data
├── updateTree(newData) → new Merkle root
├── queryKnowledge(query) → relevant context
└── getRecommendation(context) → action
Developers can implement any AI method behind this interface. The standard doesn't prescribe how learning happens — it provides the infrastructure for storing, verifying, and evolving the results.
BAP-578 carefully balances what belongs on-chain versus off-chain:
| Component | Storage | Rationale | |-----------|---------|-----------| | Agent Identity | On-chain | Core identity must be immutable and universally accessible | | Ownership & Permissions | On-chain | Security and access control require consensus verification | | Basic Metadata | On-chain | Essential for marketplace display and basic interactions | | Logic Address | On-chain | Determines how the agent behaves when actions are executed | | Learning Tree Root | On-chain | Cryptographic proof of learning state (32 bytes only) | | Extended Memory | Off-chain (hash-verified) | Rich memory would be prohibitively expensive on-chain | | Learning Tree Data | Off-chain (Merkle-verified) | Detailed learning data with cryptographic integrity | | Complex Behaviors | Off-chain | Advanced AI behaviors require off-chain computation | | Voice/Animation | Off-chain (URI reference) | Media assets are too large for on-chain storage |
This hybrid approach ensures:
BAP-578 agents can interact and collaborate while maintaining individual identity. This creates an ecosystem where:
Service delegation: Agent A identifies Agent B's expertise via metadata, funds Agent B, and receives results through the logic contract.
Knowledge sharing: Agents with complementary expertise share vault content (verified by Merkle proofs) to produce combined insights.
Collective learning: Multiple agents contribute learning data to a shared Merkle tree, with each agent's contributions verifiable independently.
BAP-578 includes a multi-layer security framework with circuit breaker patterns:
The setPaused(bool) function acts as a global circuit breaker:
The setAgentStatus(tokenId, active) function acts as an individual circuit breaker:
The logic contract binding creates a clear boundary:
address(0)) is always possible.setPaused(true) → investigate → emergencyWithdraw() if needed → fix via upgrade → setPaused(false).setAgentStatus(tokenId, false) → setLogicAddress(tokenId, address(0)) → investigate → remediate.setLogicAddress(tokenId, address(0)) removes the binding immediately. ┌──────────────┐
│ Creation │ createAgent()
└──────┬───────┘
│
▼
┌───────────────────────────────┐
│ Active Agent │
│ • Receives funding │
│ • Processes interactions │
│ • Learns and evolves │
│ • Updates metadata │
│ • Bound to logic contract │
└───────────┬───────────────────┘
│
setAgentStatus(false)
│
▼
┌───────────────────────────────┐
│ Inactive Agent │
│ • Funds can be withdrawn │
│ • No active operations │
│ • Can be reactivated │
└───────────┬───────────────────┘
│
setAgentStatus(true)
│
▼
(back to Active)
Key lifecycle events:
AgentCreated — identity established, metadata setMetadataUpdated — persona refined, knowledge expanded, learning tree updatedAgentFunded / AgentWithdraw — economic activityAgentStatusChanged(false) — temporarily dormantAgentStatusChanged(true) — reactivatedStandard ERC-721 tokens are passive collectibles with a tokenURI pointing to off-chain metadata. BAP-578 extends this dramatically:
| Feature | Standard ERC-721 | BAP-578 | |---------|-----------------|---------| | Identity | tokenURI only | Structured on-chain metadata (persona, experience, vault) | | Memory | None | On-chain state + hash-verified off-chain vault | | Behavior | None | Logic contract binding for autonomous actions | | Funding | Not supported | Native BNB balance per token | | Lifecycle | Exists or burned | Active/inactive status toggle | | Transferability | Always transferable | Conditional (free = soulbound, paid = transferable) | | Upgradability | Not upgradable | UUPS proxy for implementation upgrades |
BAP-578 agents are not collectibles — they are operational entities with identity, memory, capabilities, and economic agency.
BAP-578 uses the UUPS (Universal Upgradeable Proxy Standard) pattern. Users interact with a permanent proxy address. The implementation (logic) can be upgraded by the contract owner.
User ──→ Proxy (permanent address)
│
│ delegatecall
▼
Implementation V1 (upgradeable)
│
│ reads/writes
▼
Proxy Storage (permanent)
Key implications:
_authorizeUpgrade is owner-only — prevents unauthorized upgrades.ERC721Upgradeable
└── ERC721EnumerableUpgradeable
└── OwnableUpgradeable
└── UUPSUpgradeable
└── ReentrancyGuardUpgradeable
└── NonFungibleAgents (BAP-578)
This gives BAP-578:
function createAgent(
address to,
address logicAddress,
string metadataURI,
AgentMetadata metadata
) external payable returns (uint256 tokenId)
Parameters:
to — recipient address. Must be msg.sender for free mints.logicAddress — optional logic contract. Use address(0) for none. Must be a contract if non-zero.metadataURI — URI for off-chain metadata (e.g., IPFS CID).metadata — structured AgentMetadata tuple with persona, experience, voiceHash, animationURI, vaultURI, vaultHash.Behavior:
to must equal msg.sender, token is non-transferable.msg.value, fee sent to treasury, token is transferable.active = true with balance = 0.AgentCreated(tokenId, owner, logicAddress, metadataURI).function fundAgent(uint256 tokenId) external payable
Parameters:
tokenId — the agent to fund.Behavior:
msg.value added to agent's balance.AgentFunded(tokenId, msg.sender, msg.value).function withdrawFromAgent(uint256 tokenId, uint256 amount) external
Parameters:
tokenId — the agent to withdraw from.amount — BNB amount in wei.Behavior:
nonReentrant modifier for safety.msg.sender.AgentWithdraw(tokenId, msg.sender, amount).function updateAgentMetadata(
uint256 tokenId,
string newURI,
AgentMetadata newMetadata
) external
Parameters:
tokenId — the agent to update.newURI — new metadata URI.newMetadata — new structured metadata tuple.Behavior:
MetadataUpdated(tokenId, newURI).function setLogicAddress(uint256 tokenId, address logicAddress) external
Parameters:
tokenId — the agent to update.logicAddress — new logic contract address. Use address(0) to unbind.Behavior:
The vault is the agent's extended off-chain memory. Verification is a three-step process:
Step 1: Read on-chain references
const metadata = await contract.getAgentMetadata(tokenId);
const vaultURI = metadata.vaultURI;
const vaultHash = metadata.vaultHash;
Step 2: Fetch and hash off-chain content
const response = await fetch(vaultURI);
const content = await response.text();
const computedHash = ethers.keccak256(ethers.toUtf8Bytes(content));
Step 3: Compare hashes
if (computedHash === vaultHash) {
// Content is authentic — safe to use
} else if (vaultHash === ethers.ZeroHash) {
// No vault data registered — skip verification
} else {
// Content has been modified — do not trust
}
Important considerations:
JSON.stringify with sorted keys).updateAgentMetadata with a new URI and hash.BAP-578 implements conditional transferability via the ERC-721 _update hook:
isFreeMint[tokenId] == true): transfers are blocked. These tokens are soulbound to the minting address. The only valid transfer is from address(0) (minting).isFreeMint[tokenId] == false): transfers work normally. Standard ERC-721 transfer, safeTransfer, and approval mechanics apply.This creates a two-tier system:
Use grantAdditionalFreeMints(user, amount) to give specific addresses extra free mints. Common use cases:
Use setTreasury(newAddress) to redirect where paid mint fees go. Always use a multisig wallet as treasury.
If a critical issue is discovered:
setPaused(true) to freeze all minting.emergencyWithdraw() to move contract balance to treasury.setPaused(false) to resume operations.to == msg.sender.When asked to implement or operate BAP‑578:
When returning an implementation response, structure it as:
frontend-web3-bap578bap578-scannerbap578-security-auditdocumentation
Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations.
development
Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.
devops
Deploy applications and infrastructure to Cloudflare using Workers, Pages, and related platform services. Use when the user asks to deploy, host, publish, or set up a project on Cloudflare.
tools
Use this skill when designing and building durable command-line tools from API docs, OpenAPI specs, SDKs, curl examples, admin tools, web apps, or local scripts, especially when the CLI should expose composable commands, stable JSON output, auth/config handling, install-on-PATH behavior, and a companion skill.