Skip to content

[PLAN] AI Credits Widget: buy developer AI credits with G$ #34

@sirpy

Description

@sirpy

AI Credits Widget: buy developer AI credits with G$


This sub-issue defines the execution plan for the UI-only implementation of the AI Credits Widget described in parent issue #30.
The parent issue remains unchanged and is the product source of truth.

Parent issue: #30

Required states, flows, and behaviors

Required states

  • disconnected
  • connected_empty
  • quote_ready
  • payment_pending
  • payment_confirmed
  • has_credits
  • usage_empty
  • usage_active
  • insufficient_g_balance
  • insufficient_ai_credits
  • payment_failed
  • backend_unavailable
  • unsupported_chain

Required flows

  1. Connect wallet
  2. Show wallet address and G$ balance
  3. Choose purchase mode:
    • one-time purchase
    • streaming/top-up mode
  4. Enter G$ amount
  5. Show quote:
    • G$ amount
    • estimated AI credit value
    • highlighted top-up/bonus
    • monthly value if streaming mode is selected
    • plain-English note that backend handles Antseed settlement underneath
  6. Submit buy action
  7. Show pending confirmation state
  8. On success, show:
    • AI credit balance
    • masked API key
    • copyable setup instructions
  9. Show usage log after billed requests exist
  10. Support retry/degraded/unsupported states without implying payment success

Required UI behaviors

  • Linear compact card flow only; no marketplace/provider/team billing UI
  • API key masked by default with show/hide and copy
  • Copyable setup blocks for OpenAI-compatible tools
  • Usage rows must include model, status, estimated/captured cost, timestamp
  • Billing copy must consistently use hold/capture/release semantics
  • Main UX must not expose USDC/channel complexity
  • Integration must remain fixture/mock-backed until a real backend URL/config is provided

Relevant reference files

GoodWidget implementation references

  • packages/claim-widget/ — closest package and publishable widget reference
  • packages/ui/ — shared primitives, tokens, alerts, cards, buttons, input-like controls
  • packages/core/GoodWidgetProvider, wallet/runtime boundaries, EIP-1193 integration
  • packages/embed/ — embeddable export pattern if needed
  • examples/storybook/fixtures/custodialEip1193.ts
  • examples/storybook/fixtures/injectedEip1193.ts

antseed-integration architecture and API references

  • GoodDollar/antseed-integration/AGENTS.md
  • GoodDollar/antseed-integration/README.md
  • GoodDollar/antseed-integration/docs/ARCHITECTURE.md
  • GoodDollar/antseed-integration/docs/PAYMENT_FLOW.md
  • GoodDollar/antseed-integration/backend/README.md
  • GoodDollar/antseed-integration/backend/src/types.ts
  • GoodDollar/antseed-integration/backend/src/pricing.ts
  • GoodDollar/antseed-integration/contracts/src/AgentCreditVault.sol
  • GoodDollar/antseed-integration/contracts/src/CeloGdAntSeedVault.sol

Relevant code references from GoodDollar/antseed-integration

Architecture / boundary references

  • AGENTS.md
    • Confirms this repo is the backend + smart-contract integration layer and that UI work belongs in GoodDollar/GoodWidget
    • Source of truth for UI agents: auth/API key endpoints, credit quote/account balance endpoints, Celo deposit/stream ingestion flows, and OpenAI-compatible /v1/chat/completions
    • States that billing language should use hold/reserve before request, capture/settle after successful billable response, and release on failure/non-billable response
  • docs/PAYMENT_FLOW.md
    • Defines the two-layer model:
      • GoodDollar user/credit layer
      • AntSeed buyer payment layer
    • Confirms the widget must not imply native G$ settlement to sellers
    • Confirms the backend owns request reserve/release/settle lifecycle and forwards requests to the AntSeed buyer gateway
  • docs/ARCHITECTURE.md
    • Defines accounting model:
      • available = deposited - reserved
      • reserve(requestId, account, amount)
      • settle(requestId, actualCost)
      • release(requestId)
    • Confirms backend is Cloudflare Worker owned and frontend is out of scope for that repo

Backend API references for mocked UI contract

  • backend/README.md
    • Endpoints relevant to UI mocking and future integration:
      • POST /v1/auth/nonce
      • POST /v1/auth/api-keys
      • GET /v1/auth/api-keys
      • DELETE /v1/auth/api-keys/:id
      • GET /v1/accounts/:account/credit
      • GET /v1/requests/:requestId
      • POST /v1/credits/quote
      • POST /v1/chat/completions
    • Confirms production auth shape uses gd_live_... keys
    • Confirms credit rules:
      • non-streaming deposits receive 110% credits
      • active streamers receive 120% credits up to monthly stream-speed cap

Domain model references for UI state design

  • backend/src/types.ts
    • CreditReservation
      • useful for payment pending / confirmed / released / failed UI states
      • includes status, maxCostMicroUsd, actualCostMicroUsd, timestamps, and receipt/vault hashes
    • UserCreditProfile
      • useful for wallet balance, total credits, reserved credits, deposited amount, streaming-derived values
    • GdCreditEntry
      • useful for displaying source/type of issued credit and bonus breakdown
    • AntSeedChatCompletion
      • useful for usage/result fixture shape
  • backend/src/pricing.ts
    • estimateMaxCostMicroUsd(...)
    • actualCostMicroUsd(...)
    • useful reference for quote fixtures and for separating estimated reserve from captured final cost in UI copy

Contract references for UX wording and state modeling

  • contracts/src/AgentCreditVault.sol
    • availableBalance(address) supports the “available vs reserved” mental model
    • reserve(...) maps to pre-request hold/authorization language
    • settle(...) maps to post-success capture language
    • release(...) maps to refund/release-on-failure language
    • event names are useful as semantic references for state naming:
      • CreditReserved
      • CreditSettled
      • CreditReleased
  • contracts/src/CeloGdAntSeedVault.sol
    • shows supported G$ deposit sources:
      • ERC20 deposit
      • ERC677/ERC667 callback deposits
      • ERC777 callback deposits
      • Superfluid stream callbacks
    • confirms GoodID verification boundary
    • exposes stream state concepts that should inform streaming purchase mode copy:
      • streamFlowRate
      • streamMonthlyGdAmount
      • StreamUpdated
    • reinforces that backend converts G$ events into USDC-denominated credits under the hood, not the widget

Execution plan

1. Package and structure planning

  • Create a new package under packages/ai-credits-widget/
  • Follow packages/claim-widget structure for:
    • entrypoints
    • provider wiring
    • embeddable widget surface
    • story organization
    • package publishing shape
  • Add Playwright smoke coverage under tests/widgets/ai-credits-widget/

2. Dependency and shared package mapping

  • Import existing @goodwidget / GoodDollar shared packages instead of creating custom infrastructure:
    • packages/ui
    • packages/core
    • packages/embed
  • Reuse theme tokens, card/layout primitives, buttons, copyable controls, badges, alerts, and wallet-aware provider boundaries where available

3. New component mapping

Create widget-local components first, then evaluate promotion into packages/ui only if they are clearly generic and reusable.

Proposed widget-local components:

  • AiCreditsWidgetShell
  • AiCreditsHeaderCard
  • AiCreditsProgressStepper
  • AiCreditsPurchaseModeToggle
  • AiCreditsPurchaseForm
  • AiCreditsQuoteCard
  • AiCreditsPaymentStatusCard
  • AiCreditsApiKeyCard
  • AiCreditsSetupSnippetCard
  • AiCreditsBalanceCard
  • AiCreditsUsageCard
  • AiCreditsUsageTable
  • AiCreditsEmptyUsageState
  • AiCreditsErrorStateCard
  • AiCreditsUnsupportedChainCard

Candidates to promote to packages/ui only if existing equivalents do not exist:

  • generic compact progress stepper
  • generic masked secret display with show/hide/copy
  • generic copyable config/snippet block
  • generic usage/status table row pattern

4. Fixture and integration planning

  • Keep all backend interactions fixture-driven
  • Define adapter/interface boundaries for:
    • wallet connect state
    • quote fetch
    • payment submission
    • payment status polling
    • API key retrieval
    • usage retrieval
  • Mock contract/backend-driven values using reference semantics from:
    • backend/src/types.ts
    • backend/src/pricing.ts
    • docs/PAYMENT_FLOW.md

5. Storybook planning

Create stories for:

  • Disconnected initial state
  • Connected with zero credits
  • Quote ready
  • Payment pending
  • Payment confirmed with API key/setup visible
  • Has credits with empty usage
  • Has credits with recent usage rows
  • Insufficient G$ balance
  • Payment failed
  • Backend unavailable
  • Unsupported chain

Use wallet fixtures where relevant:

  • examples/storybook/fixtures/custodialEip1193.ts
  • examples/storybook/fixtures/injectedEip1193.ts

6. Playwright planning

  • Add smoke tests for the main states under tests/widgets/ai-credits-widget/
  • Capture screenshot evidence for:
    • disconnected
    • connected empty
    • quote ready
    • pending
    • confirmed
    • has credits
    • payment failed
    • backend unavailable
    • unsupported chain

7. UX/copy review planning

  • Ensure all copy reflects backend-first hosted OpenAI-compatible API MVP
  • Setup snippets must prioritize:
    • OPENAI_BASE_URL=https://<backend-domain>/v1
    • OPENAI_API_KEY=<developer_platform_key>
  • Any local proxy copy must be marked optional / coming later unless a real wrapper exists
  • Ensure copy consistently says:
    • user pays with G$
    • backend handles AntSeed settlement underneath

Acceptance criteria

  • A draft implementation plan exists for the new packages/ai-credits-widget/ package
  • The plan maps all required widget states, flows, and behaviors from the parent issue
  • The plan references GoodDollar/antseed-integration architecture, API, pricing, and contract files as integration/source-of-truth inputs
  • The plan identifies which components belong in the widget package vs possible reusable packages/ui promotion candidates
  • The plan specifies Storybook scenarios and Playwright smoke coverage
  • The plan preserves the MVP boundary:
    • UI only
    • fixture-backed integrations
    • no direct AntSeed settlement implementation
    • no subscriptions/org billing/marketplace scope creep

human-reviewer checklist

  • Parent issue content remains unchanged
  • Sub-issue title follows [DRAFT][PLAN] ...
  • Description begins with [DRAFT] ...
  • Sub-issue is typed as Task
  • Sub-issue is linked back to parent issue AI Credits Widget: buy developer AI credits with G$ #30
  • Relevant GoodDollar/antseed-integration files are explicitly mapped
  • Backend/API/payment-boundary wording is accurate
  • Required UI states and stories are fully covered
  • New component mapping is specific enough to implement later
  • Acceptance criteria are implementation-ready without executing the work yet
    parent:
    repository: "GoodDollar/GoodWidget"
    number: 30
    url: "AI Credits Widget: buy developer AI credits with G$ #30"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No fields configured for Task.

    Projects

    Status

    In Progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions