Feature summary
Add a backend endpoint that resets a buyer's operator to address(0), and add an operator-status check in the credit-deposit path so the service verifies it is still the operator before depositing credit.
Problem or opportunity
Operator status is granted on-chain via AntSeedFundingVault.acceptBuyerOperator (handled by POST /v1/accounts/:buyer/operator-consent in backend/src/worker.ts), but there is no way to revoke it — no reset endpoint exists, and no read call for current operator status exists in the backend's ABI/client (backend/src/antseed-funding-vault.ts). Separately, fundCredit in worker.ts (called from /v1/celo/events/record, the scheduled() cron, and /v1/accounts/:account/stream-credits) calls depositForWithId with no check that the service is still the current operator — if operator status was revoked, credit could still be deposited under a stale assumption.
Proposed solution
- Add a getter/read call for current operator status to the contract client (
AntSeedFundingVaultClient in antseed-funding-vault.ts) — needs plan-stage investigation into the actual AntSeedFundingVault contract ABI to confirm the correct view function.
- Add a new endpoint (e.g.
POST /v1/accounts/:buyer/operator-reset, following the existing /v1/accounts/:buyer/... convention) that resets the buyer's operator to address(0). Follow existing conventions: zod schema validation, logInfo/logWarn/logError with redactAddress/redactHash, errors bubbling to the global handler. Plan stage must confirm the exact on-chain call/authorization model (e.g. whether this requires a buyer-signed message like acceptBuyerOperator does, or can be self-initiated by the operator revoking its own status) against the actual contract.
- In
fundCredit (or the vault client method it calls), check current operator status before calling depositForWithId; if the service is no longer the operator, skip/reject the deposit and log accordingly rather than depositing under a stale assumption.
Required states, flows, and behaviors
- Operator reset endpoint called with a valid buyer → on-chain operator is set to
address(0); subsequent operator-status reads reflect this.
fundCredit invoked while service is still the current operator → deposit proceeds as today.
fundCredit invoked while service is no longer the operator (e.g. after a reset or revoke) → deposit is skipped/rejected, not silently attempted; failure is logged/surfaced consistent with existing error handling.
- No regression to the existing
/v1/accounts/:buyer/operator-consent grant flow.
Acceptance criteria
Additional context
Requested by Hadar Rottenberg (Bounty Lead) in #goodbounties-lead, 2026-08-10 — standalone from issue #150 on GoodWidget, per Hadar's confirmation. This is the backend counterpart the companion GoodWidget "Revoke Operator" button bounty will call — cross-reference once both issues are live. No local auth middleware currently exists on any POST endpoint in this backend; adding auth is out of scope here unless raised separately. Relevant files: backend/src/worker.ts, backend/src/antseed-funding-vault.ts, backend/src/kv-credit-store.ts, backend/src/types.ts.
Create the plan (keep this section in the issue body)
Based on the above description create an execution plan in a new sub-issue and preserve the original issue content unchanged.
Do not execute the plan until given instructions to do so.
Sub-issue requirements:
- Title format:
[DRAFT][PLAN] <what issue is being planned>
- Type:
Task
- Description must start with:
<sub-issue title>
- Link the sub-issue back to this parent issue.
Instructions when creating the plan:
- Map relevant files that are too be used as reference from all repos mentioned
- import existing @GoodDollar packages
- Map new components that should be created. Assess when a new component should be created in the new savings widget package or made part of the reusable packages/ui
Plan specification required sections:
- Required states, flows, and behaviors
- Execution plan
- acceptance criteria
- human-reviewer checklist
Feature summary
Add a backend endpoint that resets a buyer's operator to
address(0), and add an operator-status check in the credit-deposit path so the service verifies it is still the operator before depositing credit.Problem or opportunity
Operator status is granted on-chain via
AntSeedFundingVault.acceptBuyerOperator(handled byPOST /v1/accounts/:buyer/operator-consentinbackend/src/worker.ts), but there is no way to revoke it — no reset endpoint exists, and no read call for current operator status exists in the backend's ABI/client (backend/src/antseed-funding-vault.ts). Separately,fundCreditinworker.ts(called from/v1/celo/events/record, thescheduled()cron, and/v1/accounts/:account/stream-credits) callsdepositForWithIdwith no check that the service is still the current operator — if operator status was revoked, credit could still be deposited under a stale assumption.Proposed solution
AntSeedFundingVaultClientinantseed-funding-vault.ts) — needs plan-stage investigation into the actualAntSeedFundingVaultcontract ABI to confirm the correct view function.POST /v1/accounts/:buyer/operator-reset, following the existing/v1/accounts/:buyer/...convention) that resets the buyer's operator toaddress(0). Follow existing conventions: zod schema validation,logInfo/logWarn/logErrorwithredactAddress/redactHash, errors bubbling to the global handler. Plan stage must confirm the exact on-chain call/authorization model (e.g. whether this requires a buyer-signed message likeacceptBuyerOperatordoes, or can be self-initiated by the operator revoking its own status) against the actual contract.fundCredit(or the vault client method it calls), check current operator status before callingdepositForWithId; if the service is no longer the operator, skip/reject the deposit and log accordingly rather than depositing under a stale assumption.Required states, flows, and behaviors
address(0); subsequent operator-status reads reflect this.fundCreditinvoked while service is still the current operator → deposit proceeds as today.fundCreditinvoked while service is no longer the operator (e.g. after a reset or revoke) → deposit is skipped/rejected, not silently attempted; failure is logged/surfaced consistent with existing error handling./v1/accounts/:buyer/operator-consentgrant flow.Acceptance criteria
address(0)on-chain.fundCredit's deposit path checks current operator status before callingdepositForWithIdand does not deposit if the service is no longer the operator.worker.ts.fundCreditcall sites.Additional context
Requested by Hadar Rottenberg (Bounty Lead) in #goodbounties-lead, 2026-08-10 — standalone from issue #150 on GoodWidget, per Hadar's confirmation. This is the backend counterpart the companion GoodWidget "Revoke Operator" button bounty will call — cross-reference once both issues are live. No local auth middleware currently exists on any POST endpoint in this backend; adding auth is out of scope here unless raised separately. Relevant files:
backend/src/worker.ts,backend/src/antseed-funding-vault.ts,backend/src/kv-credit-store.ts,backend/src/types.ts.Create the plan (keep this section in the issue body)
Based on the above description create an execution plan in a new sub-issue and preserve the original issue content unchanged.
Do not execute the plan until given instructions to do so.
Sub-issue requirements:
[DRAFT][PLAN] <what issue is being planned>Task<sub-issue title>Instructions when creating the plan:
Plan specification required sections: