Put paid Sage turns inside any Ergo app.
The widget is the product surface for the live proof stack: chat, quote, testnet Note verification, receipt links, and full Accord receipt bundles without turning the host app into a payment backend.
The v0.5.0 source is pushed with wallet-policy handoff helpers, embed helpers, and a widget capability manifest. npm latest remains v0.3.0 until the release tag publishes through GitHub Actions Trusted Publishing. The canonical Sage host remains a testnet proof.
GitHub main now includes wallet-policy handoff helpers, embed config helpers, capability manifest, and generated React/vanilla snippets. npm release remains gated by tag publish.
npm latest is v0.3.0, published through GitHub Actions Trusted Publishing without local OTP prompts or long-lived npm tokens.
The canonical Sage host has a settled post-Blob receipt with Agreement, Verification, and Settlement JSON.
This is testnet live proof. Mainnet remains blocked by external review and audit-bound script identity.
Payment lifecycle
The widget shows the flow. The receipt API remains the truth.
The host app can own design and wallet UX, while Sage owns the protocol evidence: quote, payment verification, answer stream, public receipt page, and JSON bundle. No article, dashboard, or widget should duplicate receipt facts as a second database.
Ask
The host app embeds Sage and sends a normal question or a premium command.
Quote
Sage returns a task hash, receiver, reserve, price, expiry, and deadline for a testnet Note.
Verify
The user or host wallet creates the Note. The widget submits the Note box id to Sage for verification.
Receipt
Sage streams the answer and exposes both public receipt URL and machine-readable receipt bundle.
Try the exact embed flow without hiding the wallet step.
This demo calls the production Sage APIs directly. The host app asks for a quote, the user creates a testnet Note elsewhere, then the host verifies the Note and receives a receipt link. The widget never signs funds.
Run a premium-shaped prompt to request a quote.
Paste a Note box id after issuing the testnet Note.
Full receipt bundle appears after verification.
React paid widget
import { SagePaymentWidget } from "@ergoblockchain/sage-widget/react"
export function PaidSagePanel() {
return (
<SagePaymentWidget
tenant={{ id: "my-ergo-app", label: "My Ergo app" }}
paymentInstructions={{
helperText: "Issue the quoted testnet Note, then paste the Note box id.",
walletLauncherLabel: "Open my testnet wallet",
walletUrl: "https://www.ergoblockchain.org/build/agent-payments",
}}
onQuote={(quote) => console.log("quote", quote.quote)}
onPaymentIntent={(intent) => console.log("wallet intent", intent)}
onReceipt={(receipt) => console.log("receipt", receipt.receiptUrl)}
onReceiptBundle={(bundle) => console.log(bundle.completeness)}
walletLauncher={async (intent) => {
// Host-owned wallet flow. Return { ok: true, noteBoxId } when ready.
console.log(intent.amountErg, intent.receiverAddress, intent.taskHash)
return { ok: true }
}}
/>
)
}Vanilla mount
import { mountSagePaymentWidget } from "@ergoblockchain/sage-widget/vanilla"
const handle = mountSagePaymentWidget(
document.getElementById("sage-chat")!,
{
tenant: { id: "docs-footer", label: "Docs footer" },
},
)
await handle.send("/code show me a Fleet SDK example")
console.log(handle.status().receiptBundle?.completeness)Receipt-first apps
import {
createSagePaymentIntent,
fetchSageQuote,
fetchSageReceipt,
isFullSageReceiptBundle,
} from "@ergoblockchain/sage-widget"
const question = "/deep explain Accord receipts"
const quoteResponse = await fetchSageQuote({ question })
if (!quoteResponse.quote) throw new Error("No premium quote returned")
const intent = createSagePaymentIntent({
question,
quote: quoteResponse.quote,
})
const receipt = await fetchSageReceipt("f8752d10a2ece92fbc88065c3b92b94da621ec65943098f43c9e084deb763d81")
if (isFullSageReceiptBundle(receipt)) {
console.log(receipt.accord?.agreement_json)
}Wallet policy handoff
import {
checkSagePaymentIntentSafety,
createSageErgoConnectHandoff,
createSageWalletPolicyRequest,
} from "@ergoblockchain/sage-widget"
const safety = checkSagePaymentIntentSafety(intent, {
maxAmountErg: "0.050000000",
})
if (!safety.ok) throw new Error(safety.failed.join(", "))
const policyRequest = createSageWalletPolicyRequest(intent, {
agentId: "my-local-agent",
spentTodayErg: "0.000000000",
feeErg: "0.001000000",
})
const verdict = await fetch("/api/agent-economy/wallet-agent/policy-check", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify(policyRequest),
})
const handoff = createSageErgoConnectHandoff(intent)
console.log(handoff.widget_signs_transactions) // falseRelease gate
What changed now that this is the public install path.
Mainnet gate stays closed
The widget deliberately does not sign wallet transactions. It can verify a Note and show receipts for the canonical testnet proof flow, but production/mainnet language still requires external review and audited script identity.
Next product move
This page is now the canonical install doc and live host demo. The next upgrade is a wallet-specific ErgoPay or Fleet implementation that consumes the v0.5 policy handoff without weakening the receipt API as the source of truth.