From e8ebcb17d75060733b04bad55e82c0e56033b89f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 17 Aug 2026 08:56:16 +0000 Subject: [PATCH 1/2] Initial plan From 53589fe9e6313d2d052dc881e2bbb3e2ef2c3e79 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 17 Aug 2026 09:06:18 +0000 Subject: [PATCH 2/2] revert proxy approach and restore deploy workflow paths Co-authored-by: sirpy <671095+sirpy@users.noreply.github.com> --- .github/workflows/deploy-ai-credits-web.yml | 5 ++ .../deploy-superfluid-campaign-web.yml | 6 ++ .../src/CitizenClaimWidget.tsx | 19 +------ packages/citizen-claim-widget/src/adapter.ts | 57 ++++--------------- .../src/widgetRuntimeContract.ts | 10 +--- packages/ui/src/components/Toast.tsx | 13 ++--- 6 files changed, 31 insertions(+), 79 deletions(-) diff --git a/.github/workflows/deploy-ai-credits-web.yml b/.github/workflows/deploy-ai-credits-web.yml index 3d8035d6..3e4e7c4d 100644 --- a/.github/workflows/deploy-ai-credits-web.yml +++ b/.github/workflows/deploy-ai-credits-web.yml @@ -8,6 +8,11 @@ on: paths: - 'apps/ai-credits-web/**' - 'packages/ai-credits-widget/**' + - 'packages/core/**' + - 'packages/ui/**' + - 'packages/embed/**' + - 'pnpm-lock.yaml' + - 'pnpm-workspace.yaml' pull_request_target: types: [opened, synchronize, edited, ready_for_review] branches: diff --git a/.github/workflows/deploy-superfluid-campaign-web.yml b/.github/workflows/deploy-superfluid-campaign-web.yml index 0a5dd7be..36316c01 100644 --- a/.github/workflows/deploy-superfluid-campaign-web.yml +++ b/.github/workflows/deploy-superfluid-campaign-web.yml @@ -8,6 +8,12 @@ on: paths: - 'apps/superfluid-campaign-web/**' - 'packages/superfluid-campaign-widget/**' + - 'packages/citizen-claim-widget/**' + - 'packages/core/**' + - 'packages/ui/**' + - 'packages/embed/**' + - 'pnpm-lock.yaml' + - 'pnpm-workspace.yaml' pull_request_target: types: [opened, synchronize, edited, ready_for_review] branches: diff --git a/packages/citizen-claim-widget/src/CitizenClaimWidget.tsx b/packages/citizen-claim-widget/src/CitizenClaimWidget.tsx index 596b2a99..b477aabf 100644 --- a/packages/citizen-claim-widget/src/CitizenClaimWidget.tsx +++ b/packages/citizen-claim-widget/src/CitizenClaimWidget.tsx @@ -252,13 +252,7 @@ function CitizenClaimInner({ }) try { - const receipt = await actions.claim(() => - updateToast(toastId, { - message: `Claiming on ${singleChainName} — waiting for blockchain confirmation`, - status: 'confirming', - duration: 0, - }), - ) + const receipt = await actions.claim() updateToast(toastId, { message: `Claim succeeded on ${singleChainName}`, status: 'success', @@ -302,17 +296,6 @@ function CitizenClaimInner({ const claimResults = await actions.claimAll( claimPlan.map((entry) => entry.chainId), - (submittedChainId) => { - const toastId = toastByChain.get(submittedChainId) - if (!toastId) return - const entryChainName = - chainNameById.get(submittedChainId) ?? getChainDisplayName(submittedChainId) - updateToast(toastId, { - message: `Claiming on ${entryChainName} — waiting for blockchain confirmation`, - status: 'confirming', - duration: 0, - }) - }, ) for (const claimResult of claimResults) { diff --git a/packages/citizen-claim-widget/src/adapter.ts b/packages/citizen-claim-widget/src/adapter.ts index 2027a118..9bf0c32a 100644 --- a/packages/citizen-claim-widget/src/adapter.ts +++ b/packages/citizen-claim-widget/src/adapter.ts @@ -60,35 +60,6 @@ const CHAIN_CONFIGS: Record = { } as Chain, } -/** - * Wraps an EIP-1193 provider so `onTransactionSubmitted` fires the instant a - * wallet finishes signing and broadcasting a transaction (its - * `eth_sendTransaction` call resolving), before viem's receipt polling even - * starts. citizen-sdk's public claim() has no equivalent mid-flight signal, - * but GoodWidget already owns this provider before handing it to viem's - * `custom()` transport, so it can observe that moment itself with no SDK - * change required. - */ -function wrapProviderWithSubmissionSignal( - provider: EIP1193Provider, - onTransactionSubmitted: () => void, -): EIP1193Provider { - return new Proxy(provider, { - get(target, property, receiver) { - if (property === 'request') { - return async (args: Parameters[0]) => { - const result = await target.request(args) - if (args.method === 'eth_sendTransaction') { - onTransactionSubmitted() - } - return result - } - } - return Reflect.get(target, property, receiver) - }, - }) -} - const SUPPORTED_CHAINS = citizenSdkCapabilities.chains const AVAILABLE_ENVIRONMENTS = citizenSdkCapabilities.environments @@ -285,14 +256,11 @@ export function useCitizenClaimAdapter( // available for integrations that prefer lazy per-chain client creation. // --------------------------------------------------------------------------- const createProviderClientsForChain = useCallback( - (targetChainId: number, onTransactionSubmitted?: () => void) => { + (targetChainId: number) => { if (!provider || !address) return null const chain = CHAIN_CONFIGS[targetChainId] if (!chain) return null - const effectiveProvider = onTransactionSubmitted - ? wrapProviderWithSubmissionSignal(provider, onTransactionSubmitted) - : provider - const transport = custom(effectiveProvider as Parameters[0]) + const transport = custom(provider as Parameters[0]) const publicClient = createPublicClient({ chain, transport }) const walletClient = createWalletClient({ account: address as `0x${string}`, @@ -346,7 +314,7 @@ export function useCitizenClaimAdapter( ) const resolveClientsForChain = useCallback( - async (targetChainId: number, onTransactionSubmitted?: () => void) => { + async (targetChainId: number) => { if (isCustodialExecution) { const configuredClients = claimExecution?.clientsByChain[targetChainId] if (configuredClients) return normalizeClientBundle(configuredClients) @@ -367,7 +335,7 @@ export function useCitizenClaimAdapter( return normalizeClientBundle(factoryClients) } - return normalizeClientBundle(createProviderClientsForChain(targetChainId, onTransactionSubmitted)) + return normalizeClientBundle(createProviderClientsForChain(targetChainId)) }, [ address, @@ -411,8 +379,8 @@ export function useCitizenClaimAdapter( ) const createSdkInstancesForChain = useCallback( - async (targetChainId: number, onTransactionSubmitted?: () => void) => { - const clients = await resolveClientsForChain(targetChainId, onTransactionSubmitted) + async (targetChainId: number) => { + const clients = await resolveClientsForChain(targetChainId) return createSdkInstances(clients) }, [createSdkInstances, resolveClientsForChain], @@ -684,7 +652,7 @@ export function useCitizenClaimAdapter( // Transitions: eligible → claiming → success | error // --------------------------------------------------------------------------- const claimOnChain = useCallback( - async (targetChainId: number, onTransactionSubmitted?: () => void): Promise => { + async (targetChainId: number): Promise => { if (!isCustodialExecution && !provider) { throw new CitizenClaimAdapterError('No wallet provider available') } @@ -719,7 +687,7 @@ export function useCitizenClaimAdapter( await switchChain(targetChainId) } - const sdk = await createSdkInstancesForChain(targetChainId, onTransactionSubmitted) + const sdk = await createSdkInstancesForChain(targetChainId) if (!sdk) { throw new CitizenClaimAdapterError( `Unable to initialize SDK clients for ${getChainDisplayName(targetChainId)}`, @@ -760,7 +728,6 @@ export function useCitizenClaimAdapter( const claimAll = useCallback( async ( targetChainIds: number[], - onTransactionSubmitted?: (chainId: number) => void, ): Promise => { const chainIdsToClaim = [...new Set(targetChainIds)] @@ -768,7 +735,7 @@ export function useCitizenClaimAdapter( const settled = await Promise.allSettled( chainIdsToClaim.map(async (targetChainId) => ({ chainId: targetChainId, - receipt: await claimOnChain(targetChainId, () => onTransactionSubmitted?.(targetChainId)), + receipt: await claimOnChain(targetChainId), })), ) @@ -793,7 +760,7 @@ export function useCitizenClaimAdapter( results.push({ chainId: targetChainId, status: 'fulfilled', - receipt: await claimOnChain(targetChainId, () => onTransactionSubmitted?.(targetChainId)), + receipt: await claimOnChain(targetChainId), }) } catch (claimError: unknown) { results.push({ @@ -808,14 +775,14 @@ export function useCitizenClaimAdapter( [claimOnChain, isCustodialExecution], ) - const handleClaim = useCallback(async (onTransactionSubmitted?: () => void): Promise => { + const handleClaim = useCallback(async (): Promise => { if (!chainId) throw new Error('No active chain selected') setStatus('claiming') setError(null) try { - const receipt = await claimOnChain(chainId, onTransactionSubmitted) + const receipt = await claimOnChain(chainId) if (!mountedRef.current) return receipt await loadClaimStatus() return receipt diff --git a/packages/citizen-claim-widget/src/widgetRuntimeContract.ts b/packages/citizen-claim-widget/src/widgetRuntimeContract.ts index a55316fd..63c3fae1 100644 --- a/packages/citizen-claim-widget/src/widgetRuntimeContract.ts +++ b/packages/citizen-claim-widget/src/widgetRuntimeContract.ts @@ -68,16 +68,10 @@ export interface CitizenClaimWidgetAdapterActions { connect: () => Promise refresh: () => Promise startVerification: () => Promise - /** - * `onTransactionSubmitted` fires once the wallet has signed and broadcast - * the transaction, ahead of on-chain confirmation — lets callers move a - * "sign in your wallet" toast to a "waiting for confirmation" state. - */ - claim: (onTransactionSubmitted?: () => void) => Promise - claimOnChain: (chainId: number, onTransactionSubmitted?: () => void) => Promise + claim: () => Promise + claimOnChain: (chainId: number) => Promise claimAll: ( chainIds: number[], - onTransactionSubmitted?: (chainId: number) => void, ) => Promise switchChain?: (chainId: number) => Promise } diff --git a/packages/ui/src/components/Toast.tsx b/packages/ui/src/components/Toast.tsx index 3c4366e4..0a9ce075 100644 --- a/packages/ui/src/components/Toast.tsx +++ b/packages/ui/src/components/Toast.tsx @@ -9,7 +9,7 @@ import { Spinner } from '../components-test/Spinner' // Multiple toasts can be visible at once; each is identified by a unique id. // --------------------------------------------------------------------------- -export type ToastStatus = 'pending' | 'confirming' | 'success' | 'error' | 'info' +export type ToastStatus = 'pending' | 'success' | 'error' | 'info' export interface ToastConfig { message: string @@ -83,11 +83,10 @@ export function useToast(): ToastItem[] { * Named 'Toast' so Tamagui resolves light_Toast / dark_Toast component themes. * * Status variant adjusts the border accent color to communicate the toast type: - * pending → primary (blue) — waiting on the wallet to sign - * confirming → primaryDark (deeper blue) — signed and broadcast, waiting on-chain - * success → success (green) - * error → error (red) - * info → primary (blue) + * pending → primary (blue) — waiting on the wallet to sign + * success → success (green) + * error → error (red) + * info → primary (blue) */ const ToastFrame = createComponent(Stack, { name: 'Toast', @@ -109,7 +108,6 @@ const ToastFrame = createComponent(Stack, { variants: { status: { pending: { borderColor: '$primary' }, - confirming: { borderColor: '$primaryDark' }, success: { borderColor: '$success' }, error: { borderColor: '$error' }, info: { borderColor: '$primary' }, @@ -163,7 +161,6 @@ function StatusIcon({ status }: { status?: ToastStatus }) { if (!status) return null switch (status) { case 'pending': - case 'confirming': return case 'success': return