Agent Quick Start
This guide is designed for AI agents and autonomous systems. It provides everything needed to programmatically interact with the Defactor protocol: authentication, asset tokenization, lending, governance, and error handling.
Prerequisites
Agent Manifest (JSON-LD)
Machine-readable capability manifest. AI agents can parse this to understand what operations are available and how to access them.
1{2 "@context": "https://schema.org",3 "@type": "APIReference",4 "name": "Defactor Protocol Agent Interface",5 "version": "2.0.0",6 "description": "Machine-readable interface for AI agents to tokenize, lend, govern, and manage real-world assets on-chain.",7 "provider": {8 "@type": "Organization",9 "name": "Defactor",10 "url": "https://defactor.com"11 },12 "capabilities": [13 {14 "name": "Asset Tokenization",15 "description": "Create ERC-20 and ERC-3643 tokens backed by real-world assets",16 "api": "GraphQL + REST",17 "endpoint": "https://api.defactor.com/graphql",18 "documentation": "https://defactor.ai/assets"19 },20 {21 "name": "Lending Pools",22 "description": "Create and interact with RWA-collateralized lending pools",23 "api": "Smart Contract (SDK)",24 "contract": "ERC20CollateralPool",25 "documentation": "https://defactor.ai/pools"26 },27 {28 "name": "Governance & Staking",29 "description": "Stake FACTR tokens and participate in protocol governance",30 "api": "Smart Contract (SDK)",31 "contract": "Engage",32 "documentation": "https://defactor.ai/engage"33 },34 {35 "name": "Counterparty Pools",36 "description": "Bilateral lending agreements between specific parties",37 "api": "Smart Contract (SDK)",38 "contract": "CounterpartyPool",39 "documentation": "https://defactor.ai/pools"40 }41 ],42 "authentication": {43 "type": "Wallet Signature (EIP-191)",44 "flow": ["generateNonce", "signMessage", "verifySignature"],45 "result": "JWT Bearer Token"46 },47 "supportedChains": [48 { "name": "Ethereum", "chainId": 1 },49 { "name": "Polygon", "chainId": 137 },50 { "name": "Base", "chainId": 8453 },51 { "name": "BSC", "chainId": 56 }52 ],53 "sdk": {54 "package": "@defactor/defactor-sdk",55 "version": "7.4.0",56 "runtime": "Node.js 18+",57 "language": "TypeScript",58 "repository": "https://github.com/defactor-com/sdk"59 }60}Agent Decision Tree
Use this decision tree to determine which API or contract to call based on the desired operation.
// Agent Decision Tree for Defactor Operations
//
// START
// ├── Need to tokenize a new asset?
// │ ├── Yes → Use Assets API (REST or GraphQL)
// │ │ ├── ERC-20 standard → Simple fungible token
// │ │ └── ERC-3643 standard → Compliant security token (needs KYC)
// │ └── No → Continue
// │
// ├── Need to interact with lending?
// │ ├── As Lender → pools.lend(poolId, amount)
// │ │ └── Requires: ERC-20 approval first
// │ ├── As Borrower → pools.borrow(poolId, amount)
// │ │ └── Requires: Sufficient collateral deposited
// │ └── As Liquidator → pools.liquidatePool(poolId)
// │ └── Requires: Pool health factor < 100%
// │
// ├── Need to participate in governance?
// │ ├── Stake FACTR → engage.stake(planId, amount)
// │ ├── Vote → engage.vote(proposalId, support)
// │ └── Claim rewards → engage.claimRewards(planId)
// │
// └── Need bilateral lending?
// └── Use Counterparty Pools
// ├── Create → createCounterpartyPool(params)
// └── Interact → same as standard poolsSafety Guidelines for Agents
Always check balances before transactions
Query token balances and allowances before attempting transfers, lending, or staking to avoid reverted transactions and wasted gas.
Verify pool status before interaction
Check pool deadline, status (ACTIVE/CLOSED/LIQUIDATED), and capacity (current vs hard cap) before lending or borrowing.
Handle gas estimation failures gracefully
If gas estimation fails, the transaction will likely revert. Catch the error and diagnose the root cause before retrying.
Use nonce management for concurrent transactions
When sending multiple transactions in parallel, manage nonces manually to prevent nonce conflicts.
Monitor for chain reorganizations
Wait for sufficient block confirmations (12+ on Ethereum, 128+ on Polygon) before considering transactions final.
Complete Agent Implementation
A full working example of an AI agent that authenticates, tokenizes an asset, lends to a pool, stakes FACTR, and votes on governance proposals.
1// ============================================2// DEFACTOR AI AGENT — Complete Implementation3// ============================================4// This agent tokenizes an asset, creates a lending pool,5// stakes FACTR, and participates in governance.67import { ethers } from 'ethers'8import {9 ERC20CollateralPool,10 Engage,11 SelfProvider12} from '@defactor/defactor-sdk'1314// ---- CONFIGURATION ----15const CONFIG = {16 rpc: 'https://polygon-rpc.com',17 privateKey: process.env.AGENT_PRIVATE_KEY!,18 contracts: {19 pool: '0x...ERC20CollateralPool',20 engage: '0x...Engage',21 factr: '0x...FACTR',22 usdc: '0x...USDC'23 },24 api: 'https://api.defactor.com'25}2627// ---- STEP 1: AUTHENTICATE ----28async function authenticate() {29 const wallet = new ethers.Wallet(CONFIG.privateKey)3031 // Get nonce32 const nonceRes = await fetch(`${CONFIG.api}/v1/generate-nonce`)33 const { res: nonce } = await nonceRes.json()3435 // Sign nonce36 const message = `Authenticate: ${nonce}`37 const signature = await wallet.signMessage(message)3839 // Verify and get JWT40 const authRes = await fetch(`${CONFIG.api}/v1/verify-signature`, {41 method: 'POST',42 headers: { 'Content-Type': 'application/json' },43 body: JSON.stringify({44 address: wallet.address,45 chainId: 137,46 message,47 signature48 })49 })5051 const { res: { token } } = await authRes.json()52 return { token, wallet }53}5455// ---- STEP 2: TOKENIZE AN ASSET ----56async function tokenizeAsset(token: string) {57 const res = await fetch(`${CONFIG.api}/v1/assets`, {58 method: 'POST',59 headers: {60 'Content-Type': 'application/json',61 'Authorization': `Bearer ${token}`62 },63 body: JSON.stringify({64 name: 'Commercial Real Estate Fund A',65 symbol: 'CREFA',66 totalSupply: ethers.parseEther('1000000').toString(),67 standard: 'ERC-20',68 chainId: 137,69 metadata: {70 assetType: 'Real Estate',71 jurisdiction: 'US',72 valuationDate: '2026-03-01',73 totalValue: '10000000' // $10M USD74 }75 })76 })77 return await res.json()78}7980// ---- STEP 3: INTERACT WITH POOLS ----81async function managePools() {82 const poolProvider = new SelfProvider.SelfProvider<ERC20CollateralPool>(83 ERC20CollateralPool,84 CONFIG.contracts.pool,85 CONFIG.rpc,86 CONFIG.privateKey87 )8889 // Discover pools90 const total = await poolProvider.contract.getTotalPools()91 const pools = await poolProvider.contract.getPools(0n, total)9293 // Find best lending opportunity94 const activePools = pools.filter(p => p.status === 'ACTIVE')95 const bestPool = activePools.reduce((best, pool, idx) => {96 const rate = Number(pool.interestRate)97 return rate > best.rate ? { idx, rate } : best98 }, { idx: 0, rate: 0 })99100 // Approve USDC spending101 const usdc = new ethers.Contract(102 CONFIG.contracts.usdc,103 ['function approve(address,uint256) returns (bool)'],104 new ethers.Wallet(CONFIG.privateKey, new ethers.JsonRpcProvider(CONFIG.rpc))105 )106 const lendAmount = ethers.parseUnits('10000', 6) // 10,000 USDC107 await usdc.approve(CONFIG.contracts.pool, lendAmount)108109 // Lend to pool110 await poolProvider.contract.lend(BigInt(bestPool.idx), lendAmount)111112 return { poolId: bestPool.idx, amount: lendAmount }113}114115// ---- STEP 4: STAKE & GOVERN ----116async function stakeAndGovern() {117 const engageProvider = new SelfProvider.SelfProvider<Engage>(118 Engage,119 CONFIG.contracts.engage,120 CONFIG.rpc,121 CONFIG.privateKey122 )123124 // Stake FACTR125 const plans = await engageProvider.contract.getStakingPlans()126 const bestPlan = plans[0] // Select optimal plan127 await engageProvider.contract.stake(bestPlan.planId, ethers.parseEther('1000'))128129 // Vote on active proposals130 const proposals = await engageProvider.contract.getProposals(0n, 10n)131 for (const p of proposals) {132 if (p.status === 'ACTIVE') {133 await engageProvider.contract.vote(p.proposalId, true)134 }135 }136}137138// ---- MAIN EXECUTION ----139async function main() {140 console.log('[Agent] Starting Defactor operations...')141142 const { token } = await authenticate()143 console.log('[Agent] Authenticated successfully')144145 const asset = await tokenizeAsset(token)146 console.log('[Agent] Asset tokenized:', asset)147148 const pool = await managePools()149 console.log('[Agent] Lent to pool:', pool)150151 await stakeAndGovern()152 console.log('[Agent] Staked and voted')153154 console.log('[Agent] All operations complete')155}156157main().catch(console.error)