erc8004

package
v0.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 6, 2026 License: Apache-2.0 Imports: 21 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// IdentityRegistryBaseSepolia is the ERC-8004 Identity Registry on Base Sepolia.
	IdentityRegistryBaseSepolia = "0x8004A818BFB912233c491871b3d84c89A494BD9e"

	// IdentityRegistryMainnet is the ERC-8004 Identity Registry on Ethereum
	// mainnet and Base mainnet (deployed at the same address via CREATE2).
	IdentityRegistryMainnet = "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432"

	// ReputationRegistryBaseSepolia is the ERC-8004 Reputation Registry on Base Sepolia.
	ReputationRegistryBaseSepolia = "0x8004B663056A597Dffe9eCcC1965A193B7388713"

	// ValidationRegistryBaseSepolia is the ERC-8004 Validation Registry on Base Sepolia.
	ValidationRegistryBaseSepolia = "0x8004CB39f29c09145F24Ad9dDe2A108C1A2cdfC5"

	// DefaultRPCBase is the default JSON-RPC base URL the controller uses to
	// build per-chain ERC-8004 clients. It points at the in-cluster eRPC
	// service; per-chain endpoints are derived as
	//   <base>/<NetworkConfig.ERPCNetwork>
	// (see erc8004.NewClientForNetwork). Override with ERC8004_RPC_BASE.
	DefaultRPCBase = "http://erpc.erpc.svc.cluster.local/rpc"

	// BaseSepoliaChainID is the EIP-155 chain ID for Base Sepolia.
	BaseSepoliaChainID = 84532
)
View Source
const RegistrationType = "https://eips.ethereum.org/EIPS/eip-8004#registration-v1"

RegistrationType is the canonical type URI for ERC-8004 registration v1.

Variables

View Source
var (
	BaseSepolia = NetworkConfig{
		Name:            "base-sepolia",
		ChainID:         84532,
		RegistryAddress: IdentityRegistryBaseSepolia,
		ERPCNetwork:     "base-sepolia",
	}

	// Base mainnet and Ethereum mainnet share the same Identity Registry
	// address (deployed via CREATE2). Base Sepolia is a separate deployment.
	Base = NetworkConfig{
		Name:            "base",
		ChainID:         8453,
		RegistryAddress: IdentityRegistryMainnet,
		ERPCNetwork:     "base",
	}

	Ethereum = NetworkConfig{
		Name:            "ethereum",
		ChainID:         1,
		RegistryAddress: IdentityRegistryMainnet,
		ERPCNetwork:     "mainnet",
	}
)

Predefined network configurations.

Functions

This section is empty.

Types

type AgentRegistration

type AgentRegistration struct {
	Type           string            `json:"type"`                     // REQUIRED
	Name           string            `json:"name"`                     // REQUIRED
	Description    string            `json:"description,omitempty"`    // REQUIRED (omitempty for parsing)
	Image          string            `json:"image,omitempty"`          // REQUIRED (omitempty for parsing)
	Services       []ServiceDef      `json:"services"`                 // REQUIRED (>=1)
	X402Support    bool              `json:"x402Support"`              // REQUIRED
	Active         bool              `json:"active"`                   // REQUIRED
	Registrations  []OnChainReg      `json:"registrations,omitempty"`  // REQUIRED (>=1, omitempty for parsing)
	SupportedTrust []string          `json:"supportedTrust,omitempty"` // OPTIONAL
	Metadata       map[string]string `json:"metadata,omitempty"`       // OPTIONAL
	Provenance     map[string]string `json:"provenance,omitempty"`     // OPTIONAL
}

AgentRegistration is the JSON schema for the agent registration document served at agentURI (e.g., /.well-known/agent-registration.json). Conforms to ERC-8004 "Trustless Agents" registration format.

REQUIRED fields per spec: type, name, description, image, services (>=1), x402Support, active, registrations (>=1). OPTIONAL: supportedTrust.

Note: Description and Image use omitempty for parsing flexibility but MUST be populated when producing registration documents.

Spec: https://eips.ethereum.org/EIPS/eip-8004

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client interacts with the ERC-8004 Identity Registry.

func NewClient

func NewClient(ctx context.Context, rpcURL string) (*Client, error)

NewClient connects to rpcURL and binds to the Identity Registry on Base Sepolia. For multi-network support, use NewClientForNetwork instead.

func NewClientForNetwork

func NewClientForNetwork(ctx context.Context, rpcBaseURL string, net NetworkConfig) (*Client, error)

NewClientForNetwork connects to the eRPC base URL and binds to the Identity Registry on the given network. The RPC URL is constructed as rpcBaseURL + "/" + net.ERPCNetwork.

func (*Client) AgentWallet added in v0.9.0

func (c *Client) AgentWallet(ctx context.Context, agentID *big.Int) (common.Address, error)

AgentWallet returns the registered wallet for an agent id via the ERC-8004 `getAgentWallet` view, or an error if the READER reports a revert (the pre-mint case appears as ERC721NonexistentToken). Used by WaitForAgent to confirm the chain READER has caught up to a recent register tx before follow-up calls (setMetadata, setAgentURI) try to estimate gas against a state where the token id is still unknown.

func (*Client) ChainID

func (c *Client) ChainID() *big.Int

ChainID returns the chain ID for this client's connection.

func (*Client) Close

func (c *Client) Close()

Close releases the underlying RPC connection.

func (*Client) CurrentBlockNumber

func (c *Client) CurrentBlockNumber(ctx context.Context) (uint64, error)

CurrentBlockNumber returns the current tip height for the connected chain.

func (*Client) ETH

func (c *Client) ETH() *ethclient.Client

ETH returns the underlying ethclient for direct RPC calls.

func (*Client) FindRegistrationByOwnerAndURI

func (c *Client) FindRegistrationByOwnerAndURI(ctx context.Context, owner common.Address, agentURI string, fromBlock uint64) (*big.Int, string, bool, error)

FindRegistrationByOwnerAndURI recovers a registration by scanning recent Registered events for the controller wallet and published URI.

func (*Client) FindRegistrationByTxHash

func (c *Client) FindRegistrationByTxHash(ctx context.Context, txHash string) (*big.Int, string, bool, error)

FindRegistrationByTxHash resolves a previously submitted registration transaction once it has been mined.

func (*Client) GetMetadata

func (c *Client) GetMetadata(ctx context.Context, agentID *big.Int, k string) ([]byte, error)

GetMetadata reads metadata for the given key from the agent NFT.

func (*Client) Register

func (c *Client) Register(ctx context.Context, key *ecdsa.PrivateKey, agentURI string) (*big.Int, error)

Register mints a new agent NFT with the given agentURI using a raw private key. Returns the minted agentId (token ID).

func (*Client) RegisterDetailed

func (c *Client) RegisterDetailed(ctx context.Context, key *ecdsa.PrivateKey, agentURI string) (*big.Int, string, error)

RegisterDetailed mints a new agent NFT with the given agentURI and returns both the minted agentId and transaction hash.

func (*Client) RegisterWithOpts

func (c *Client) RegisterWithOpts(ctx context.Context, opts *bind.TransactOpts, agentURI string) (*big.Int, error)

RegisterWithOpts mints a new agent NFT using the provided TransactOpts. This allows callers to supply a custom Signer (e.g. remote-signer).

func (*Client) RegisterWithOptsDetailed

func (c *Client) RegisterWithOptsDetailed(ctx context.Context, opts *bind.TransactOpts, agentURI string) (*big.Int, string, error)

RegisterWithOptsDetailed mints a new agent NFT using the provided TransactOpts and returns both the minted agentId and transaction hash.

func (*Client) SetAgentURI

func (c *Client) SetAgentURI(ctx context.Context, key *ecdsa.PrivateKey, agentID *big.Int, uri string) error

SetAgentURI updates the agentURI for an existing agent NFT.

func (*Client) SetMetadata

func (c *Client) SetMetadata(ctx context.Context, key *ecdsa.PrivateKey, agentID *big.Int, k string, v []byte) error

SetMetadata stores arbitrary key-value metadata on the agent NFT. Read-before-write — see SetMetadataWithOpts for the rationale.

func (*Client) SetMetadataWithOpts

func (c *Client) SetMetadataWithOpts(ctx context.Context, opts *bind.TransactOpts, agentID *big.Int, k string, v []byte) error

SetMetadataWithOpts stores key-value metadata using the provided TransactOpts.

Read-before-write: registries we've integrated with (the canonical ERC-8004 reference impl among others) revert on `setMetadata` when the new value equals the current value — observed in the field as "execution reverted" on every subsequent ServiceOffer apply once the first one has set the `x402` key. The contract revert costs gas and looks scary in the CLI for what is logically a no-op, so we skip the write when the on-chain value already matches.

func (*Client) SubmitRegister

func (c *Client) SubmitRegister(ctx context.Context, key *ecdsa.PrivateKey, agentURI string) (string, error)

SubmitRegister submits a registration transaction and returns its hash without waiting for the receipt.

func (*Client) TokenURI

func (c *Client) TokenURI(ctx context.Context, agentID *big.Int) (string, error)

TokenURI returns the ERC-721 tokenURI for the agent NFT.

func (*Client) WaitForAgent added in v0.9.0

func (c *Client) WaitForAgent(ctx context.Context, agentID *big.Int, timeout time.Duration) (common.Address, error)

WaitForAgent polls AgentWallet until the chain READER reports the agent id as owned (any address). Returns when it does, or err on timeout. This closes the read-side staleness window after Register: the Register tx confirms via WaitMined on the WRITE upstream, but a subsequent setMetadata estimateGas goes through the READ upstream which may still be a block or two behind (we hit this in production when a stale eRPC route was pinned to a parallel Anvil fork — the simulation reverted with ERC721NonexistentToken).

type EIP712Field

type EIP712Field struct {
	Name string `json:"name"`
	Type string `json:"type"`
}

EIP712Field describes a single field in an EIP-712 type.

type EIP712TypedData

type EIP712TypedData struct {
	Types       map[string][]EIP712Field `json:"types"`
	PrimaryType string                   `json:"primaryType"`
	Domain      map[string]interface{}   `json:"domain"`
	Message     map[string]interface{}   `json:"message"`
}

EIP712TypedData represents a full EIP-712 typed data structure for signing.

type NetworkConfig

type NetworkConfig struct {
	// Name is the canonical network name (e.g. "base-sepolia", "base", "ethereum").
	Name string

	// ChainID is the EIP-155 chain identifier.
	ChainID int64

	// RegistryAddress is the ERC-8004 Identity Registry contract address on this chain.
	RegistryAddress string

	// ERPCNetwork is the path segment used by eRPC to route to this chain
	// (e.g. "base-sepolia", "base", "mainnet").
	ERPCNetwork string
}

NetworkConfig describes an ERC-8004 registration network.

func ResolveNetwork

func ResolveNetwork(name string) (NetworkConfig, error)

ResolveNetwork maps a network name to its configuration.

func ResolveNetworks

func ResolveNetworks(csv string) ([]NetworkConfig, error)

ResolveNetworks parses a comma-separated list of network names.

func SupportedNetworks

func SupportedNetworks() []NetworkConfig

SupportedNetworks returns all supported registration networks.

func (NetworkConfig) CAIP10Registry

func (n NetworkConfig) CAIP10Registry() string

CAIP10Registry returns the CAIP-10 formatted registry identifier.

type OnChainReg

type OnChainReg struct {
	AgentID       int64  `json:"agentId"`       // ERC-721 tokenId
	AgentRegistry string `json:"agentRegistry"` // CAIP-10 format: "eip155:84532:0x8004A818..."
}

OnChainReg links the registration to its on-chain record.

type RemoteSigner

type RemoteSigner struct {
	// contains filtered or unexported fields
}

RemoteSigner wraps the remote-signer REST API for signing operations. It communicates with the signer over HTTP (typically via a port-forward).

func NewRemoteSigner

func NewRemoteSigner(baseURL string) *RemoteSigner

NewRemoteSigner creates a client for the remote-signer API at the given base URL.

func (*RemoteSigner) GetAddress

func (s *RemoteSigner) GetAddress(ctx context.Context) (common.Address, error)

GetAddress returns the first loaded signing address from the remote-signer.

func (*RemoteSigner) RemoteTransactOpts

func (s *RemoteSigner) RemoteTransactOpts(ctx context.Context, addr common.Address, chainID *big.Int) *bind.TransactOpts

RemoteTransactOpts creates a bind.TransactOpts that delegates signing to the remote-signer. The returned opts can be used with Client.RegisterWithOpts and Client.SetMetadataWithOpts.

func (*RemoteSigner) SignTransaction

func (s *RemoteSigner) SignTransaction(ctx context.Context, addr common.Address, tx SignTxRequest) (string, error)

SignTransaction signs an EIP-1559 transaction via the remote-signer. Returns the RLP-encoded signed transaction bytes (hex-encoded with 0x prefix).

func (*RemoteSigner) SignTypedData

func (s *RemoteSigner) SignTypedData(ctx context.Context, addr common.Address, data EIP712TypedData) (string, error)

SignTypedData signs EIP-712 typed data via the remote-signer. Returns the 65-byte signature as a hex string with 0x prefix.

type ServiceDef

type ServiceDef struct {
	Name     string   `json:"name"`               // e.g., "web", "A2A", "MCP", "OASF"
	Endpoint string   `json:"endpoint,omitempty"` // full URL (omitempty for OASF entries)
	Version  string   `json:"version,omitempty"`  // protocol version (SHOULD per spec)
	Skills   []string `json:"skills,omitempty"`   // OASF skill taxonomy paths
	Domains  []string `json:"domains,omitempty"`  // OASF domain taxonomy paths
}

ServiceDef describes an endpoint the agent exposes. For OASF entries (name="OASF"), Skills and Domains provide machine-readable taxonomy for agent discovery. See https://schema.oasf.outshift.com/

type SignTxRequest

type SignTxRequest struct {
	ChainID              string `json:"chain_id"`
	To                   string `json:"to"`
	Nonce                string `json:"nonce"`
	GasLimit             string `json:"gas_limit"`
	MaxFeePerGas         string `json:"max_fee_per_gas"`
	MaxPriorityFeePerGas string `json:"max_priority_fee_per_gas"`
	Value                string `json:"value"`
	Data                 string `json:"data"`
}

SignTxRequest contains the canonical request body for remote-signer EIP-1559 transaction signing. The canonical wire contract is published in ObolNetwork/remote-signer at schema/sign-transaction-request.canonical.schema.json.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL