Skip to content

AI Credits widget: explicit operator consent, updated consent copy, antseed-only view - #153

Open
goodbounties-nanoclaw-agent[bot] wants to merge 1 commit into
mainfrom
plan/ai-credits-consent-flow
Open

AI Credits widget: explicit operator consent, updated consent copy, antseed-only view#153
goodbounties-nanoclaw-agent[bot] wants to merge 1 commit into
mainfrom
plan/ai-credits-consent-flow

Conversation

@goodbounties-nanoclaw-agent

Copy link
Copy Markdown
Contributor

Summary

Implements the plan in #152, closing out #150:

  • Explicit consent gate: a URL-supplied operatorSignature (deep-link flow) now only pre-fills the buyer's identity/signature — it no longer auto-submits operator consent. OperatorConsentStep always renders and requires an explicit click before consent is granted.
  • Updated consent copy: OperatorConsentStep now explains, in generic operator wording, that granting consent gives the operator control of the buyer's signer funds specifically to prevent fraud in bonus distribution, and that revoking consent later makes the buyer ineligible for future bonuses and removes any existing bonuses from their account.
  • source=antseed view: apps/ai-credits-web's App.tsx now supports a source=antseed URL flag that renders only the purchase widget, skipping LandingPage's marketing wrapper, while still composing correctly with buyerAddress/operatorSignature.

Test plan

  • New Storybook QA fixture (DeepLinkConsentPending) + Playwright test in tests/widgets/ai-credits-widget/states.spec.ts verifying the consent step requires an explicit click even when operatorSignature is pre-filled, and that the updated copy renders. Baseline screenshot committed.
  • New apps/ai-credits-web/tests/purchase-only.spec.ts covering widget-only rendering under source=antseed, default landing-page behavior otherwise, and composition with buyerAddress/operatorSignature.
  • pnpm turbo run build --filter=@goodwidget/ai-credits-widget --filter=@goodwidget/ai-credits-web — all tasks pass.
  • pnpm turbo run lint on both touched packages — clean, aside from one pre-existing unrelated lint error in backendClient.ts (untouched by this change).
  • Full states.spec.ts suite run against a clean baseline confirms 6 other failing tests are pre-existing/unrelated to this change.

Closes #150

🤖 Generated with Claude Code

…nly view

- adapter.ts: a URL-supplied operatorSignature now only pre-fills the
  deep-link buyer state; it no longer auto-submits consent, so
  OperatorConsentStep always renders and requires an explicit user action.
- OperatorConsentStep.tsx: rewrite consent copy in generic operator wording
  to explain that granting consent gives the operator control of the
  buyer's signer funds to prevent fraud in bonus distribution, and that
  revoking consent later makes the buyer ineligible for future bonuses and
  removes any existing bonuses.
- App.tsx (ai-credits-web): add a source=antseed URL flag that renders the
  purchase widget alone, skipping LandingPage's marketing wrapper, while
  still composing with buyerAddress/operatorSignature.
- Add a QA story fixture (DeepLinkConsentPending) and Playwright coverage
  in states.spec.ts exercising the consent gate when a signature is
  pre-filled via deep link, plus a purchase-only.spec.ts suite for the
  new antseed view.

Co-Authored-By: Claude <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot could not run the full agentic suite for this review because it was automatically requested on a bot-authored pull request. Request a review from Copilot under Reviewers to retry with the full agentic suite. Improved support for bot-authored pull requests is coming soon.

Adds new deep-link QA coverage and partner “widget-only” entrypoint behavior, while preventing deep-linked operator signatures from implicitly granting consent.

Changes:

  • Added Storybook QA fixture + Playwright spec to verify “consent requires explicit click” when a deep-linked operator signature is prefilled.
  • Updated adapter deep-link handling to stop auto-submitting operator consent and to clear deep-link artifacts in more flows.
  • Added source=antseed widget-only rendering mode for the web app, with Playwright coverage.

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/widgets/ai-credits-widget/states.spec.ts Adds a UI regression test ensuring consent doesn’t auto-advance with a prefilled signature.
packages/ai-credits-widget/src/components/buy/OperatorConsentStep.tsx Updates consent step copy to reflect explicit consent implications.
packages/ai-credits-widget/src/adapter.ts Removes auto-consent submission on deep link; adjusts state + clearing behavior.
examples/storybook/src/stories/helpers/aiCreditsWidgetStories.tsx Adds a Storybook fixture for “deep-link consent pending” state.
examples/storybook/src/stories/ai-credits-widget/AiCreditsWidgetQA.stories.tsx Exposes the new QA story in the Storybook QA suite.
apps/ai-credits-web/tests/purchase-only.spec.ts Adds Playwright tests for the new widget-only source mode.
apps/ai-credits-web/src/App.tsx Conditionally renders a purchase-only view when source=antseed.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +296 to +311
const openConsentStepButton = root.getByRole('button', { name: 'Sign Operator Consent' })
await expect(openConsentStepButton).toBeVisible()
await openConsentStepButton.click()

// The Drawer renders via a Tamagui Sheet portal outside the widget's root DOM
// subtree, so its content must be queried at the page level, not scoped to `root`.
await expect(
page.getByText(/Granting consent gives the operator control of your signer funds/i),
).toBeVisible()
await expect(
page.getByText(/ineligible for future bonuses and removes any existing bonuses/i),
).toBeVisible()
await expect(page.getByText('Operator consent accepted')).not.toBeVisible()

const signConsentButton = page.getByRole('button', { name: 'Sign Operator Consent' })
await expect(signConsentButton).toBeEnabled()
Comment on lines +313 to +316
await page.screenshot({
path: 'tests/widgets/ai-credits-widget/test-results/acw-19-deep-link-consent-pending.png',
fullPage: true,
})
Comment on lines 950 to 952
},
[address, backendClient, chainClient, resolveBuyerList],
[address],
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] AI Credits widget: explicit operator consent, updated consent copy, antseed widget-only view

1 participant