Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
90b9b35
Initial plan
Copilot Jun 23, 2026
804b486
feat: add @goodwidget/ai-credits-widget package
Copilot Jun 23, 2026
d2ab65f
fix: icon color tokens + test selectors; add Playwright screenshots f…
Copilot Jun 24, 2026
d2c2801
fix: correct adapter per review — real buyer key, backend auth consen…
Copilot Jun 24, 2026
bad7032
test: re-capture Playwright screenshots after adapter corrections
Copilot Jun 24, 2026
9f8ba55
Refine buyer key panel UX interactions
Copilot Jun 24, 2026
55f4897
Update ai-credits widget smoke screenshots
Copilot Jun 24, 2026
3763558
Adjust Buyer Key action layout/colors and refresh widget screenshots
Copilot Jun 24, 2026
8e4e4f7
feat: improve Stepper visual hierarchy — active accent bar, completed…
Copilot Jun 24, 2026
c5c29e6
refactor: enhance BuyerKeyPanel messaging and button layout for clari…
blueogin Jun 24, 2026
0888118
feat: implement operator consent flow with EIP-712 signing and backen…
blueogin Jun 24, 2026
3f1e1f5
fix: update G$ token address and use constant for deposits address in…
blueogin Jun 24, 2026
8827a2c
fix: remove unused isVerified variable and handle goodId verification…
blueogin Jun 24, 2026
b8f1de4
feat: batch Celo payment via Multicall3 — stream (Superfluid CFA) + d…
Copilot Jun 24, 2026
d21f679
feat: refactor Celo payment logic into separate module for improved c…
blueogin Jun 24, 2026
3887a3c
test: refresh ai-credits-widget Playwright screenshots (13/13 pass)
Copilot Jun 24, 2026
7542d76
feat: enhance ai-credits-widget with improved credit handling and usa…
blueogin Jun 24, 2026
b2f3d0d
feat: implement account status loading and operator consent improveme…
blueogin Jun 25, 2026
3e7b9bf
feat: enhance mock backend client with improved account state managem…
blueogin Jun 25, 2026
8d60330
feat: update buyer key generation to derive from wallet signature and…
blueogin Jun 25, 2026
5437f8a
refactor: remove paste buyer key functionality from ai-credits-widget…
blueogin Jun 25, 2026
ae98eba
feat: implement buyer validation and refactor account status loading …
blueogin Jun 25, 2026
29e9e6a
feat: enhance ai-credits-widget with bought credits tracking and impr…
blueogin Jun 25, 2026
e8cd1d9
fix: correct has_credits test assertion + refresh Playwright screensh…
Copilot Jun 25, 2026
371451b
feat: enhance AmountPicker component to display credits alongside USD…
blueogin Jun 26, 2026
f42ce6f
refactor: remove disconnected state rendering from AiCreditsWidget an…
blueogin Jun 26, 2026
5dedbb1
fix: clarify EIP-712 SetOperator message description in OperatorConse…
blueogin Jun 26, 2026
e33e53f
feat: add purchase flow functionality to ai-credits-widget, including…
blueogin Jun 26, 2026
f8c5add
feat: implement clipboard functionality for copying text in ai-credit…
blueogin Jun 26, 2026
d8ee154
test: refresh Playwright screenshots + update lockfile (13/13 pass)
Copilot Jun 26, 2026
85c3211
refactor: update ai-credits-widget to streamline purchase flow and en…
blueogin Jul 2, 2026
65846d8
refactor: rename CreditsAccount to CreditsManagement and update relat…
blueogin Jul 2, 2026
1a74a2e
feat: enhance ai-credits-widget with improved quote handling, additio…
blueogin Jul 2, 2026
28cd525
chore: update test images for ai-credits-widget, including new scenar…
blueogin Jul 2, 2026
be6db18
feat: add InfoTooltip component and enhance AddressView in ai-credits…
blueogin Jul 2, 2026
d9ce4e6
feat: introduce mergeStatePreservingManagement function to streamline…
blueogin Jul 2, 2026
6a456f0
feat: update AiCreditsWidget showcase and enhance state management wi…
blueogin Jul 2, 2026
46a4fff
feat: integrate vault payment minimums into ai-credits-widget, enhanc…
blueogin Jul 2, 2026
ff291be
feat: enhance ai-credits-widget with buyer key management, improved c…
blueogin Jul 2, 2026
c430ba1
fix: update error messages and tooltips in ai-credits-widget for clea…
blueogin Jul 2, 2026
4313794
chore: update test images for ai-credits-widget to reflect new scenar…
blueogin Jul 2, 2026
3821765
feat: add payment validation messaging and tooltip support in ai-cred…
blueogin Jul 2, 2026
0da5705
feat: update AiCreditsWidget documentation and components to include …
blueogin Jul 2, 2026
68eddc1
feat: refactor operator consent handling in ai-credits-widget to impr…
blueogin Jul 3, 2026
92cbc61
feat: enhance AiCreditsWidget documentation and components with new o…
blueogin Jul 3, 2026
08b6e41
feat: add background color to AiCreditsHeroCard and OperatorConsentCa…
blueogin Jul 6, 2026
8968f12
feat: enhance AiCreditsWidget with new tab navigation for Buy and Man…
blueogin Jul 6, 2026
6e339c8
refactor: rename credits management to manage tab, update documentati…
blueogin Jul 6, 2026
715dd9d
feat: implement DisconnectedPanel in AiCreditsWidget for improved use…
blueogin Jul 6, 2026
4585d81
feat: integrate AiCreditsPurchaseFlow into AiCreditsWidget, enhancing…
blueogin Jul 6, 2026
6c75465
fix: add check for customElements availability in register function t…
blueogin Jul 6, 2026
99380af
feat: enhance AiCreditsWidget and related components with GoodID inte…
blueogin Jul 6, 2026
4e5198e
refactor: restructure ai-credits-widget components by moving and rena…
blueogin Jul 6, 2026
54aa0b5
fix: update bonusPercent to 0 across AiCreditsWidget components, ensu…
blueogin Jul 6, 2026
bfa545e
refactor: replace custom card components with standard Card component…
blueogin Jul 6, 2026
14458d2
refactor: update layout parameters and component styles in AiCreditsW…
blueogin Jul 6, 2026
0b80dfa
refactor: improve layout and styling in AiCreditsWidget and related c…
blueogin Jul 6, 2026
29b78e1
refactor: update layout parameters to 'padded' in AiCreditsWidget sto…
blueogin Jul 6, 2026
5590f87
refactor: introduce compactButtonProps for consistent button styling …
blueogin Jul 6, 2026
d9b60c5
refactor: enhance styling and layout in CreditsManagementCard for imp…
blueogin Jul 6, 2026
2bc83dc
refactor: streamline AiCreditsFlowStepper and AiCreditsPurchaseFlow c…
blueogin Jul 6, 2026
4ac316b
refactor: update ScrollArea component to use 'auto' overflow and add …
blueogin Jul 6, 2026
b74de8a
refactor: apply compactButtonProps for consistent button styling acro…
blueogin Jul 6, 2026
8f7d4f0
chore: update test result images for AiCreditsWidget to reflect recen…
blueogin Jul 6, 2026
bbeae58
refactor: update setupSnippet handling in AiCreditsWidget for improve…
blueogin Jul 6, 2026
2acd106
fix: address copilot reviewer comments (stepper failed weight, input …
Copilot Jul 6, 2026
31a3026
refactor: adjust width of YStack components in AiCreditsWidget storie…
blueogin Jul 7, 2026
7d2dfda
refactor: remove unused constants and allowance checks in celoPayment…
blueogin Jul 7, 2026
fa2e76e
feat: add ai-credits-web application with initial setup and deploymen…
blueogin Jul 7, 2026
88dbac6
disable git deployments, add gitignore
L03TJ3 Jul 7, 2026
d78d5bd
Update screenshots
L03TJ3 Jul 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions .github/workflows/deploy-ai-credits-web.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Deploy AI Credits Web

on:
push:
branches:
- main
paths:
- 'apps/ai-credits-web/**'
- 'packages/ai-credits-widget/**'
- 'packages/core/**'
- 'packages/ui/**'
- 'packages/embed/**'
- 'pnpm-lock.yaml'
- 'pnpm-workspace.yaml'

concurrency:
group: deploy-ai-credits-web-${{ github.ref }}
cancel-in-progress: true

env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_AI_CREDITS_WEB_PROJECT_ID }}

jobs:
production:
runs-on: ubuntu-latest
environment:
name: production
url: ${{ steps.deploy.outputs.url }}
defaults:
run:
working-directory: apps/ai-credits-web
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9.15.0

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm

- name: Install dependencies
run: pnpm install --frozen-lockfile
working-directory: ${{ github.workspace }}

- name: Pull Vercel project settings
run: pnpm exec vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}

- name: Build deployment
run: pnpm exec vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}

- name: Deploy production
id: deploy
run: |
url="$(pnpm exec vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }})"
echo "url=$url" >> "$GITHUB_OUTPUT"
9 changes: 9 additions & 0 deletions .github/workflows/deploy-storybook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ on:
push:
branches:
- main
paths:
- 'examples/storybook/**'
- 'packages/**'
- 'pnpm-lock.yaml'
- 'pnpm-workspace.yaml'

concurrency:
group: deploy-storybook-${{ github.ref }}
Expand All @@ -19,6 +24,9 @@ jobs:
environment:
name: production
url: ${{ steps.deploy.outputs.url }}
defaults:
run:
working-directory: examples/storybook
steps:
- name: Checkout
uses: actions/checkout@v4
Expand All @@ -36,6 +44,7 @@ jobs:

- name: Install dependencies
run: pnpm install --frozen-lockfile
working-directory: ${{ github.workspace }}

- name: Pull Vercel project settings
run: pnpm exec vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@ playwright-report/
local-reference-assets
.vercel
.env*


.agents
skills-lock.json
2 changes: 2 additions & 0 deletions apps/ai-credits-web/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.vercel
.env*
24 changes: 24 additions & 0 deletions apps/ai-credits-web/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>GoodDollar AI Credits</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body,
#root {
min-height: 100%;
}
</style>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
28 changes: 28 additions & 0 deletions apps/ai-credits-web/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "@goodwidget/ai-credits-web",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite --port 3001",
"build": "tsc && vite build",
"preview": "vite preview",
"lint": "eslint src/",
"clean": "rm -rf dist .turbo"
},
"dependencies": {
"@goodwidget/ai-credits-widget": "workspace:*",
"@goodwidget/core": "workspace:*",
"@goodwidget/ui": "workspace:*",
"react": "^18.3.0",
"react-dom": "^18.3.0",
"react-native-web": "^0.19.13"
},
"devDependencies": {
"@types/react": "^18.3.0",
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-react": "^4.3.0",
"typescript": "^5.7.0",
"vite": "^6.2.0"
}
}
44 changes: 44 additions & 0 deletions apps/ai-credits-web/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from 'react'
import { AiCreditsWidget } from '@goodwidget/ai-credits-widget'
import { Container, Text, YStack } from '@goodwidget/ui'

function getInjectedProvider(): unknown | null {
if (typeof window === 'undefined') return null
return window.ethereum ?? null
}

function envAddress(value: string | undefined): `0x${string}` | undefined {
return value ? (value as `0x${string}`) : undefined
}

export function App() {
const provider = getInjectedProvider()

if (!provider) {
return (
<Container>
<YStack gap="$3" paddingVertical="$6">
<Text fontWeight="700">No wallet found</Text>
<Text secondary>
Install or enable a browser wallet (e.g. Rabby, MetaMask), then refresh this page.
</Text>
</YStack>
</Container>
)
}

return (
<Container>
<AiCreditsWidget
provider={provider}
backendUrl={import.meta.env.VITE_AI_CREDITS_BACKEND_URL}
baseRpcUrl={import.meta.env.VITE_AI_CREDITS_BASE_RPC_URL}
celoRpcUrl={import.meta.env.VITE_AI_CREDITS_CELO_RPC_URL}
fundingVaultAddress={envAddress(import.meta.env.VITE_AI_CREDITS_FUNDING_VAULT_ADDRESS)}
vaultAddress={envAddress(import.meta.env.VITE_AI_CREDITS_VAULT_ADDRESS)}
goodIdAddress={envAddress(import.meta.env.VITE_AI_CREDITS_GOODID_ADDRESS)}
testId="AiCreditsWidget-web"
/>
</Container>
)
}
22 changes: 22 additions & 0 deletions apps/ai-credits-web/src/globals.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
declare const process: {
env: Record<string, string | undefined>
}

interface Window {
ethereum?: unknown
}

interface ImportMetaEnv {
readonly VITE_AI_CREDITS_BACKEND_URL?: string
readonly VITE_AI_CREDITS_BASE_RPC_URL?: string
readonly VITE_AI_CREDITS_CELO_RPC_URL?: string
readonly VITE_AI_CREDITS_FUNDING_VAULT_ADDRESS?: string
readonly VITE_AI_CREDITS_VAULT_ADDRESS?: string
readonly VITE_AI_CREDITS_GOODID_ADDRESS?: string
}

interface ImportMeta {
readonly env: ImportMetaEnv
}

declare function setImmediate(callback: (...args: unknown[]) => void, ...args: unknown[]): number
9 changes: 9 additions & 0 deletions apps/ai-credits-web/src/main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import { App } from './App'

ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>,
)
4 changes: 4 additions & 0 deletions apps/ai-credits-web/src/types/tamagui-shim.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
declare module 'tamagui' {
const tamagui: unknown
export = tamagui
}
13 changes: 13 additions & 0 deletions apps/ai-credits-web/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"noEmit": true,
"strict": false,
"baseUrl": ".",
"paths": {
"react-native": ["react-native-web"],
"tamagui": ["src/types/tamagui-shim.d.ts"]
}
},
"include": ["src"]
}
11 changes: 11 additions & 0 deletions apps/ai-credits-web/vercel.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$schema": "https://openapi.vercel.sh/vercel.json",
"framework": "vite",
"installCommand": "cd ../.. && pnpm install --frozen-lockfile",
"buildCommand": "cd ../.. && pnpm --filter @goodwidget/ai-credits-web build",
"outputDirectory": "dist",
"devCommand": "pnpm dev",
"git": {
"deploymentEnabled": false
}
}
36 changes: 36 additions & 0 deletions apps/ai-credits-web/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
plugins: [react()],
define: {
global: 'globalThis',
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
'process.env.TAMAGUI_TARGET': JSON.stringify('web'),
},
resolve: {
alias: {
'react-native': 'react-native-web',
},
},
optimizeDeps: {
esbuildOptions: {
resolveExtensions: [
'.web.js',
'.web.jsx',
'.web.ts',
'.web.tsx',
'.mjs',
'.js',
'.mts',
'.ts',
'.jsx',
'.tsx',
'.json',
],
loader: {
'.js': 'jsx',
},
},
},
})
1 change: 1 addition & 0 deletions examples/storybook/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"@goodwidget/governance-widget": "workspace:*",
"@goodwidget/streaming-widget": "workspace:*",
"@goodwidget/staking-migration-widget": "workspace:*",
"@goodwidget/ai-credits-widget": "workspace:*",
"react": "^18.3.0",
"react-dom": "^18.3.0",
"react-native-web": "^0.19.13",
Expand Down
Loading
Loading