Skip to content

[DRAFT][PLAN] Reset buyer operator and guard credit deposits #23

Description

@Dark7978

[DRAFT][PLAN] Reset buyer operator and guard credit deposits

Parent: #22

This plan keeps the parent issue unchanged and maps the implementation to the current repository state.

Relevant code and existing behavior

  • backend/src/worker.ts
    • Routes POST /v1/accounts/:buyer/operator-consent through OperatorConsentSchema to AntSeedFundingVaultClient.acceptBuyerOperator.
    • All event, manual stream-credit, and scheduled stream-credit paths converge on fundCredit, so the operator check belongs in that shared path or in the client method it calls.
    • Existing routes use zod validation plus logInfo, logWarn, logError, redactAddress, and the global error handler.
  • backend/src/antseed-funding-vault.ts
    • FUNDING_VAULT_ABI currently exposes accept/deposit methods but omits the already-implemented transferBuyerOperator operation and operator-status read.
    • depositForBuyerWithId performs the duplicate-ID check before submitting depositForWithId.
  • contracts/src/AntseedBuyerOperator.sol
    • transferBuyerOperator(address buyer, address newOperator) is onlyOwner and forwards to the deposits contract.
    • _requireDepositsOperator already verifies IAntseedDeposits.getOperator(buyer) == address(this) for on-chain deposits.
  • contracts/src/interfaces/IAntseedDeposits.sol
    • Already declares transferOperator and getOperator.
  • contracts/test/AntseedBuyerOperator.t.sol
    • Already covers successful transfer and rejects an outsider, but not specifically transfer to address(0).
  • backend/test/worker.test.ts
    • Contains route-level tests for operator consent and the disabled bridge; extend the same test style for reset validation/disabled behavior and guarded funding.

No new shared package or UI component is needed in this backend repository. The companion GoodWidget issue can consume the new endpoint through its existing backend client/runtime abstractions.

Required states, flows, and behaviors

  1. When the bridge is configured and the service wrapper is the buyer's current operator, a valid reset request transfers the operator to address(0) and returns the confirmed transaction hash.
  2. When the bridge is disabled, reset follows the existing client convention and returns enabled: false without attempting a transaction.
  3. Before a credit deposit is submitted, the backend reads the buyer's current operator. A match with the configured wrapper address permits the existing deposit flow.
  4. A missing or different operator prevents depositForWithId from being submitted. The result is logged with redacted addresses and surfaced through the existing failed-funding flow rather than silently marked funded.
  5. Duplicate-ID behavior remains intact. The operator check should occur before any irreversible local success state; the contract remains the final authority.
  6. Existing consent, event ingestion, manual stream-credit, and scheduled credit paths keep their current behavior when operator status is valid.

Execution plan

  1. Extend FUNDING_VAULT_ABI and AntSeedFundingVaultClient with:
    • transferBuyerOperator(address,address) for the existing wrapper call.
    • An operator-status read. Prefer adding a small getBuyerOperator(address) view to AntseedBuyerOperator that delegates to IAntseedDeposits.getOperator, because the backend is configured with the wrapper address rather than the registry/deposits address. Add the matching ABI entry and client method.
    • A client accessor for the wrapper address used in equality checks, normalized with ethers.getAddress or consistently lowercased.
  2. Add a buyer-address zod schema and a POST /v1/accounts/:buyer/operator-reset route in worker.ts following the consent route's validation, response, and logging conventions. Call transferBuyerOperator(buyer, ethers.ZeroAddress) through the client. No buyer signature is required by the current wrapper contract because the configured owner/admin initiates the transfer; call this out in endpoint documentation.
  3. Add the current-operator check at the shared funding boundary before depositForBuyerWithId. On mismatch, throw or return a typed failure that fundCredit records via KVCreditStore.markFundingResult, with a specific non-secret error such as buyer operator is not configured for funding.
  4. Add Solidity tests for getBuyerOperator, reset to address(0), and deposit rejection after reset. Preserve the existing only-owner/only-admin authorization coverage.
  5. Add backend unit tests using a mocked JSON-RPC/provider boundary for:
    • invalid buyer address -> 400;
    • disabled bridge -> enabled: false;
    • configured reset submits zero-address transfer and returns a transaction hash;
    • matching operator permits funding;
    • zero/different operator prevents depositForWithId and records/logs a failed funding result;
    • existing operator-consent tests remain green.
  6. Update backend/API documentation with the endpoint request/response, authorization assumption, and the fact that all credit sources are protected by the shared pre-deposit check.
  7. Run forge test under contracts, then npm run typecheck, npm test, and npm run build under backend.

Acceptance criteria

  • POST /v1/accounts/:buyer/operator-reset validates the buyer address and transfers the configured buyer operator to address(0) on-chain.
  • The wrapper exposes a read-only current-operator query backed by IAntseedDeposits.getOperator.
  • Every fundCredit call path checks that the configured wrapper is still the buyer's operator before calling depositForWithId.
  • A stale, zero, or different operator never causes a deposit submission and produces an observable failed/skipped result using existing logging and persistence conventions.
  • Existing operator-consent and valid funding flows continue to work.
  • Contract and backend regression tests cover reset, authorization, matching, and mismatch states.
  • API documentation explains the new route and owner/admin authorization model.

Human-reviewer checklist

  • Confirm that owner/admin-initiated transferBuyerOperator(buyer, address(0)) is the intended authorization model; no new buyer signature is necessary under the current contract.
  • Confirm whether a stale-operator credit should be persisted as failed (retryable after renewed consent) or receive a distinct skipped status in a follow-up schema change.
  • Confirm the operator read is exposed through the wrapper rather than coupling the Worker to the registry/deposits contract address.
  • Verify the operator check occurs for event, manual stream-credit, and scheduled paths through their shared funding boundary.
  • Verify logs contain only redacted addresses/hashes and no private configuration.
  • Verify reset-to-zero and post-reset deposit-rejection tests pass on the contract side, and backend typecheck/tests/build pass.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions