{"ok":true,"type":"ergo.agent_economy.wallet_agent_reference_flow.v0","version":"v0","status":"testnet_reference_flow","last_reviewed":"2026-05-22","mainnet_ready":false,"public_claim":"A reference flow for host-owned local wallet agents on Ergo testnet. It is not wallet software, not a remote signer, and not mainnet readiness evidence.","entrypoints":{"human_page":"https://www.ergoblockchain.org/build/agent-payments/wallet-agent-runner","machine_api":"https://www.ergoblockchain.org/api/agent-economy/wallet-agent/reference-flow","public_manifest":"https://www.ergoblockchain.org/agent-economy/wallet-agent-reference-flow.v0.json","policy_playground":"https://www.ergoblockchain.org/build/agent-payments/policy-playground","policy_schema":"https://www.ergoblockchain.org/agent-economy/wallet-agent-policy.schema.v0.json","policy_check_schema":"https://www.ergoblockchain.org/agent-economy/wallet-agent-policy-check.schema.v0.json","policy_template":"https://www.ergoblockchain.org/agent-economy/wallet-agent-policy.profile.template.json","policy_check_api":"https://www.ergoblockchain.org/api/agent-economy/wallet-agent/policy-check","sage_widget":"https://www.ergoblockchain.org/agent-economy/sage-widget","quickstart":"https://www.ergoblockchain.org/build/agent-payments/quickstart","receipt_api_template":"https://www.ergoblockchain.org/api/sage/receipt/{receiptId}"},"stages":[{"id":"load_policy_profile","label":"Load policy","actor":"host_app","rule":"Read a local policy profile that matches the wallet-agent policy schema.","output":"WalletAgentPolicyProfile"},{"id":"fetch_or_receive_payment_intent","label":"Receive intent","actor":"sage_widget_or_host_app","rule":"Accept a portable payment intent with amount, receiver, reserve, task hash, and receipt expectations.","output":"SagePaymentIntent"},{"id":"normalize_proposed_action","label":"Normalize action","actor":"local_agent","rule":"Map the payment intent into one proposed action before asking for a policy verdict.","output":"WalletAgentProposedAction"},{"id":"request_policy_verdict","label":"Check policy","actor":"local_agent_or_host_app","rule":"Call the policy-check API and persist allow/deny reasons.","output":"WalletAgentPolicyVerdict"},{"id":"simulate_exact_transaction","label":"Simulate transaction","actor":"wallet_layer","rule":"Build and inspect one exact testnet transaction before the user is asked to sign.","output":"Unsigned exact transaction summary"},{"id":"ask_host_wallet_to_sign","label":"Ask wallet to sign","actor":"host_owned_wallet","rule":"Request a signature only for the simulated transaction. Never expose secrets to the page, widget, or API.","output":"Signed transaction bytes or transaction id"},{"id":"broadcast_simulated_transaction","label":"Broadcast","actor":"host_app_or_wallet","rule":"Broadcast only the transaction that matched the policy verdict and simulation summary.","output":"Transaction id or Note box id"},{"id":"verify_note_or_receipt","label":"Verify","actor":"sage_or_verifier","rule":"Verify the Note box id against quote, task hash, receiver, reserve, amount, and expiry.","output":"Verification Receipt JSON"},{"id":"retain_receipt_bundle","label":"Retain receipt","actor":"host_app_and_public_receipt_api","rule":"Store or link Agreement JSON, Verification Receipt JSON, Settlement Receipt JSON, and public receipt URL.","output":"Full receipt bundle or explicit chain_proof_only status"}],"reference_checks":["Policy profile is loaded before any quote or signing request.","The proposed action uses the same network, receiver, reserve, amount, fee, expiry, and task hash as the payment intent.","A denied policy verdict stops the flow before wallet UI.","Human confirmation is required when the policy threshold is exceeded.","The wallet signs one exact simulated transaction, not broad agent authority.","Receipt URL and receipt completeness are retained after verification.","Mainnet stays disabled until external review and audit-bound script identity exist."],"pseudo_code":["const profile = await loadLocalPolicyProfile()","const intent = await getSagePaymentIntent(question)","const action = normalizeIntentForPolicyCheck(profile, intent)","const verdict = await postPolicyCheck({ profile, proposed_action: action })","if (!verdict.allowed) throw new Error(verdict.reasons.join(','))","const unsignedTx = await wallet.simulateExactNoteTransaction(intent)","const signedTx = await wallet.signExactTransaction(unsignedTx)","const noteBoxId = await wallet.broadcast(signedTx)","const receipt = await verifySagePaymentAndFetchReceipt(intent, noteBoxId)","await retainReceipt(receipt)"],"example_policy_check_request":{"profile":{"type":"ergo.agent_economy.wallet_agent_policy_profile.v0","version":"v0","agent_id":"local-sage-agent-demo","network":"testnet","daily_spend_cap":"0.250000000","per_action_spend_cap":"0.050000000","max_fee":"0.002000000","allowed_recipients":["testnet_recipient_address_or_payment_endpoint"],"allowed_reserves":["testnet_reserve_box_id_or_alias"],"allowed_actions":["quote","simulate","sign_specific_transaction","broadcast_simulated_transaction","verify_note","fetch_receipt"],"requires_human_confirmation_above":"0.010000000","expiry_height_limit":720,"receipt_retention":{"required":true,"mode":"local_plus_public_url"}},"proposed_action":{"network":"testnet","action":"sign_specific_transaction","amount":"0.005000000","spent_today":"0.000000000","fee":"0.001000000","recipient":"testnet_recipient_address_or_payment_endpoint","reserve":"testnet_reserve_box_id_or_alias","expiry_height_delta":120,"task_hash":"9c5e7a16f4e8c2d2a8b74a0d8c2e91aa","human_confirmed":false,"receipt_expected":true}},"hard_boundaries":["The site does not custody funds.","The reference flow does not grant autonomous mainnet signing authority.","The policy-check API does not sign, broadcast, store private keys, or replace wallet confirmation.","Remote prompt text cannot override caps, allowlists, expiry limits, or receipt retention rules."]}