Skip to content

fix(shared,client,agent): harden vault crowdfunding flow#543

Open
Oba-One wants to merge 61 commits into
developfrom
feature/nyc-vault-crowdfunding
Open

fix(shared,client,agent): harden vault crowdfunding flow#543
Oba-One wants to merge 61 commits into
developfrom
feature/nyc-vault-crowdfunding

Conversation

@Oba-One

@Oba-One Oba-One commented Jun 4, 2026

Copy link
Copy Markdown
Member

Summary

  • Tighten the NYC vault crowdfunding state machine so /vaults stays amount-first, locks unsafe transitions during live payment steps, and only records Card Endow proof after recovered-wallet share confirmation.
  • Keep Card Endow gated to the complete Greenpill NYC campaign while preserving Wallet Endow and existing /fund behavior.
  • Update the agent funding-intent endpoints and shared contracts/hooks so public proof submission and validation stay structured and CORS-safe.

Validation

  • bun run test passes
  • bun format && bun lint passes

Oba-One added 28 commits May 30, 2026 22:36
Oba-One added 2 commits June 8, 2026 15:57
## Summary
- Implement Octant QA quick fixes PRD-583, PRD-584, PRD-585, PRD-586,
and PRD-588 for `/vaults`.
- Add Ethereum Mainnet/Etherscan technical details, ETH/WETH balance +
wrap step, leading-decimal normalization, and source-backed strategy
copy.
- Keep PRD-587 shares-first redeem and PRD-589 aggregate support metric
out of scope.

## Validation
- [x] `bun run --filter @green-goods/shared test --
src/__tests__/utils/vaults.test.ts
src/__tests__/hooks/vault/useVaultOperations.test.ts`
- [x] `bun run --filter @green-goods/client test -- PublicVaults
VaultManagePositions`
- [x] `bun run lint:vocab`
- [x] `node -e
"JSON.parse(require('fs').readFileSync('.plans/active/nyc-vault-crowdfunding/status.json','utf8'));
console.log('status.json parses')"`
- [x] `node scripts/harness/plan-hub.mjs linear-sync --feature
nyc-vault-crowdfunding --json`
- [x] `git diff --check`
- [x] Browser proof:
`/private/tmp/green-goods-octant-qa-quick-fixes/vaults-strategy-explainer.png`,
`/private/tmp/green-goods-octant-qa-quick-fixes/wallet-technical-details.png`

Linear: PRD-583 PRD-584 PRD-585 PRD-586 PRD-588
QA gate: PRD-441 comment `fb9f9a9a-368e-4753-8ef0-8f780683ef48`

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
.github/workflows/shared.yml (1)

72-72: ⚠️ Potential issue | 🟡 Minor

Align Bun version pinning and docs (CI reproducibility)

  • Bun v1.3.10 is an official release; latest stable as of 2026-06-08 is v1.3.14—confirm whether CI should stay on 1.3.10 or bump.
  • No .tool-versions/.bun-version files found; package.json only has "bun": ">=1.x", so it won’t enforce the pinned minor.
  • Update docs/docs/builders/quality/gh-actions.mdx (currently bun-version: latest) to match the workflow’s pinned Bun version (1.3.10 or 1.3.14).
  • .mise.toml also references bun-version: latest; align it with the intended CI pin.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/shared.yml at line 72, Decide whether to keep Bun pinned
at 1.3.10 or bump to 1.3.14 (recommend bump to 1.3.14), then make the pin
consistent: update the workflow Bun pin in the CI YAML (the action reference
that pins Bun), change the bun-version front-matter/metadata in
docs/docs/builders/quality/gh-actions.mdx (the "bun-version" key), update
.mise.toml's "bun-version" entry to the same value, add a repository-level
version file (.bun-version or .tool-versions) containing the chosen version, and
tighten package.json's "bun" field from ">=1.x" to the chosen pinned version so
all references match.
.plans/active/nyc-vault-crowdfunding/status.json (1)

1147-1149: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Refresh linear.lastSyncedAt to the latest recorded sync.

This file now records Linear activity through 2026-06-08T19:24:57Z, but linear.lastSyncedAt still says 2026-06-02T07:44:23Z. Any automation that trusts this field will treat the Linear mirror as much older than the rest of the document.

Suggested fix
-    "lastSyncedAt": "2026-06-02T07:44:23Z",
+    "lastSyncedAt": "2026-06-08T19:24:57Z",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.plans/active/nyc-vault-crowdfunding/status.json around lines 1147 - 1149,
Update the linear.lastSyncedAt field in the JSON object named "linear" to
reflect the latest recorded Linear sync timestamp (set lastSyncedAt to
"2026-06-08T19:24:57Z") so the document's Linear mirror timestamp is consistent
with recorded activity; locate the "linear" object and adjust the "lastSyncedAt"
value accordingly.
🧹 Nitpick comments (1)
packages/client/src/views/Public/Fund.tsx (1)

300-309: ⚡ Quick win

Update the behavior-contract comment to match the current page.

FundPageContent now routes both Donate and Endow through handleSupport, and the updated tests assert both CTAs. This block still says Donate is deferred and hidden, which will mislead the next change in this area.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/client/src/views/Public/Fund.tsx` around lines 300 - 309, Update the
top behavior-contract comment to reflect that FundPageContent now routes both
Donate and Endow through handleSupport and that tests assert both CTAs are
present; specifically edit the comment block describing FundPage behavior (the
paragraph listing intent, garden, Endow CTA, Donate status, and
manage=endowments) to remove the line saying "Donate remains deferred and is not
exposed from this page" and instead state that both Donate and Endow use
handleSupport and appear as CTAs (which open PublicFundingCard / wallet flow as
appropriate); reference FundPageContent and handleSupport in the updated
comment.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/shared/src/hooks/vault/useWrapEthToWeth.ts`:
- Around line 27-52: The mutation currently returns as soon as
sender.sendContractCall resolves with result.hash, causing the UI to refetch
balances before the wrap is confirmed; update the mutationFn in
useWrapEthToWeth.ts to wait for the transaction confirmation after
sendContractCall (use the sender.waitForTransaction or the
provider.waitForTransaction/ethers provider with the returned result.hash) and
only resolve/return after the receipt/confirmation is obtained (return the
receipt or confirmed status instead of the immediate hash) so onSuccess fires
after the wrap is mined.
- Around line 12-15: The hook useWrapEthToWeth currently trusts caller-supplied
wethAddress (from WrapEthToWethParams) and can send ETH to arbitrary contracts;
update the hook to validate and reject any non-canonical WETH target: ensure
chainId === 1 (already assumed) and enforce wethAddress ===
CANONICAL_WETH_ADDRESS (compare checksummed addresses, e.g. via
ethers.utils.getAddress) before performing the deposit/send; if the address does
not match, throw or return a clear error and do not perform the transaction
(apply the same validation wherever wethAddress is used in the hook, including
the logic referenced around lines 28-49).

---

Outside diff comments:
In @.github/workflows/shared.yml:
- Line 72: Decide whether to keep Bun pinned at 1.3.10 or bump to 1.3.14
(recommend bump to 1.3.14), then make the pin consistent: update the workflow
Bun pin in the CI YAML (the action reference that pins Bun), change the
bun-version front-matter/metadata in docs/docs/builders/quality/gh-actions.mdx
(the "bun-version" key), update .mise.toml's "bun-version" entry to the same
value, add a repository-level version file (.bun-version or .tool-versions)
containing the chosen version, and tighten package.json's "bun" field from
">=1.x" to the chosen pinned version so all references match.

In @.plans/active/nyc-vault-crowdfunding/status.json:
- Around line 1147-1149: Update the linear.lastSyncedAt field in the JSON object
named "linear" to reflect the latest recorded Linear sync timestamp (set
lastSyncedAt to "2026-06-08T19:24:57Z") so the document's Linear mirror
timestamp is consistent with recorded activity; locate the "linear" object and
adjust the "lastSyncedAt" value accordingly.

---

Nitpick comments:
In `@packages/client/src/views/Public/Fund.tsx`:
- Around line 300-309: Update the top behavior-contract comment to reflect that
FundPageContent now routes both Donate and Endow through handleSupport and that
tests assert both CTAs are present; specifically edit the comment block
describing FundPage behavior (the paragraph listing intent, garden, Endow CTA,
Donate status, and manage=endowments) to remove the line saying "Donate remains
deferred and is not exposed from this page" and instead state that both Donate
and Endow use handleSupport and appear as CTAs (which open PublicFundingCard /
wallet flow as appropriate); reference FundPageContent and handleSupport in the
updated comment.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 77063cd1-a16d-4028-989f-f506ec3ea695

📥 Commits

Reviewing files that changed from the base of the PR and between 3fae97b and 700d035.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (41)
  • .github/workflows/admin.yml
  • .github/workflows/agent.yml
  • .github/workflows/client.yml
  • .github/workflows/contracts.yml
  • .github/workflows/design.yml
  • .github/workflows/docs.yml
  • .github/workflows/indexer.yml
  • .github/workflows/shared.yml
  • .plans/active/nyc-vault-crowdfunding/plan.todo.md
  • .plans/active/nyc-vault-crowdfunding/status.json
  • docs/docs/builders/packages/client-pwa-token-audit.generated.md
  • packages/client/package.json
  • packages/client/src/__tests__/routes/PublicShell.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/client/src/components/Public/PublicGardenRow.tsx
  • packages/client/src/components/Public/VaultCardEndowFlow.tsx
  • packages/client/src/components/Public/VaultCheckoutDialog.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/client/src/components/Public/vaultCheckoutShell.tsx
  • packages/client/src/views/Public/Fund.tsx
  • packages/client/src/views/Public/Vaults.tsx
  • packages/shared/src/__tests__/hooks/vault/useVaultOperations.test.ts
  • packages/shared/src/__tests__/utils/vaults.test.ts
  • packages/shared/src/config/query-keys/vault.ts
  • packages/shared/src/hooks/index.ts
  • packages/shared/src/hooks/vault/useOctantVaultWalletBalances.ts
  • packages/shared/src/hooks/vault/useVaultOperations.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/i18n/en.json
  • packages/shared/src/i18n/es.json
  • packages/shared/src/i18n/pt.json
  • packages/shared/src/index.ts
  • packages/shared/src/modules/index.ts
  • packages/shared/src/utils/blockchain/abis.ts
  • packages/shared/src/utils/blockchain/abis/erc20.ts
  • packages/shared/src/utils/blockchain/abis/index.ts
  • packages/shared/src/utils/blockchain/price-feeds.ts
  • packages/shared/src/utils/blockchain/vaults.ts
  • packages/shared/src/utils/index.ts
✅ Files skipped from review due to trivial changes (4)
  • packages/shared/src/hooks/vault/useVaultOperations.ts
  • docs/docs/builders/packages/client-pwa-token-audit.generated.md
  • packages/client/src/components/Public/PublicGardenRow.tsx
  • .plans/active/nyc-vault-crowdfunding/plan.todo.md
🚧 Files skipped from review as they are similar to previous changes (14)
  • packages/shared/src/utils/blockchain/abis.ts
  • packages/shared/src/config/query-keys/vault.ts
  • packages/shared/src/hooks/index.ts
  • packages/shared/src/modules/index.ts
  • packages/shared/src/utils/blockchain/abis/index.ts
  • packages/client/src/tests/routes/PublicShell.test.tsx
  • packages/shared/src/i18n/es.json
  • packages/client/src/views/Public/Vaults.tsx
  • packages/client/src/components/Public/vaultCheckoutShell.tsx
  • packages/client/src/components/Public/VaultCardEndowFlow.tsx
  • packages/client/src/tests/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultCheckoutDialog.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/shared/src/index.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: Test
  • GitHub Check: Storybook
  • GitHub Check: Lint And Build
  • GitHub Check: Unit Tests
  • GitHub Check: Playwright Client CI
  • GitHub Check: Lint And Build
  • GitHub Check: Test
  • GitHub Check: CI Gate
  • GitHub Check: Test
  • GitHub Check: Build Docs
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (javascript-typescript)
🧰 Additional context used
📓 Path-based instructions (36)
.github/workflows/**/*.{yml,yaml}

📄 CodeRabbit inference engine (.github/instructions/root.instructions.md)

.github/workflows/**/*.{yml,yaml}: Keep GitHub automation aligned with this repo's existing branch strategy: most CI targets main and develop, with narrower scopes only when a workflow is intentionally release-only
Minimize workflow permissions and runners. Start from contents: read, add only the scopes a job needs, and keep path filters narrow to control CI noise and Copilot spend

Files:

  • .github/workflows/shared.yml
  • .github/workflows/design.yml
  • .github/workflows/indexer.yml
  • .github/workflows/agent.yml
  • .github/workflows/docs.yml
  • .github/workflows/contracts.yml
  • .github/workflows/client.yml
  • .github/workflows/admin.yml
{package.json,.github/workflows/**/*.{yml,yaml},scripts/**}

📄 CodeRabbit inference engine (.github/instructions/root.instructions.md)

Use Bun and Node 22 conventions already established in this repo's workflows. The only npm exception is npm run setup on a fresh machine before Bun is available; do not introduce yarn or raw forge

Files:

  • .github/workflows/shared.yml
  • .github/workflows/design.yml
  • .github/workflows/indexer.yml
  • .github/workflows/agent.yml
  • .github/workflows/docs.yml
  • .github/workflows/contracts.yml
  • .github/workflows/client.yml
  • .github/workflows/admin.yml
{.github/workflows/**,**/*.test.{js,ts,jsx,tsx},**/*.spec.{js,ts,jsx,tsx}}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use bun run test, never bun test

Files:

  • .github/workflows/shared.yml
  • .github/workflows/design.yml
  • .github/workflows/indexer.yml
  • .github/workflows/agent.yml
  • .github/workflows/docs.yml
  • .github/workflows/contracts.yml
  • packages/shared/src/__tests__/utils/vaults.test.ts
  • .github/workflows/client.yml
  • .github/workflows/admin.yml
  • packages/shared/src/__tests__/hooks/vault/useVaultOperations.test.ts
  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
.github/workflows/**

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Keep .github/workflows/**, Copilot instruction files, and dependency/security config human-governed even when Copilot review runs automatically

Files:

  • .github/workflows/shared.yml
  • .github/workflows/design.yml
  • .github/workflows/indexer.yml
  • .github/workflows/agent.yml
  • .github/workflows/docs.yml
  • .github/workflows/contracts.yml
  • .github/workflows/client.yml
  • .github/workflows/admin.yml
packages/shared/**

📄 CodeRabbit inference engine (.github/instructions/shared.instructions.md)

@green-goods/shared is the only home for reusable hooks, providers, stores, modules, types, i18n, and shared UI primitives

Files:

  • packages/shared/src/utils/index.ts
  • packages/shared/src/utils/blockchain/vaults.ts
  • packages/shared/src/utils/blockchain/price-feeds.ts
  • packages/shared/src/__tests__/utils/vaults.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWalletBalances.ts
  • packages/shared/src/utils/blockchain/abis/erc20.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useVaultOperations.test.ts
  • packages/shared/src/i18n/en.json
  • packages/shared/src/i18n/pt.json
packages/shared/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/instructions/shared.instructions.md)

Use centralized queryKeys, event-driven invalidation, useCurrentChain() or DEFAULT_CHAIN_ID, logger, and typed domain models such as Address in @green-goods/shared

Keep reusable hooks, providers, stores, modules, and shared UI primitives in @green-goods/shared

Files:

  • packages/shared/src/utils/index.ts
  • packages/shared/src/utils/blockchain/vaults.ts
  • packages/shared/src/utils/blockchain/price-feeds.ts
  • packages/shared/src/__tests__/utils/vaults.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWalletBalances.ts
  • packages/shared/src/utils/blockchain/abis/erc20.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useVaultOperations.test.ts
packages/shared/src/**/*.{tsx,ts}

📄 CodeRabbit inference engine (.github/instructions/shared.instructions.md)

Shared UI primitive changes should ship with tests, barrel updates, and Storybook coverage in the same change when applicable

Files:

  • packages/shared/src/utils/index.ts
  • packages/shared/src/utils/blockchain/vaults.ts
  • packages/shared/src/utils/blockchain/price-feeds.ts
  • packages/shared/src/__tests__/utils/vaults.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWalletBalances.ts
  • packages/shared/src/utils/blockchain/abis/erc20.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useVaultOperations.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx}: Default to single-chain behavior through getDefaultChain() or DEFAULT_CHAIN_ID
Use logger from shared instead of console.log
Use bun run format:check && bun lint for code quality checks

Files:

  • packages/shared/src/utils/index.ts
  • packages/shared/src/utils/blockchain/vaults.ts
  • packages/shared/src/utils/blockchain/price-feeds.ts
  • packages/shared/src/__tests__/utils/vaults.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWalletBalances.ts
  • packages/shared/src/utils/blockchain/abis/erc20.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useVaultOperations.test.ts
  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/views/Public/Fund.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use the Address type for Ethereum addresses instead of raw string types

Files:

  • packages/shared/src/utils/index.ts
  • packages/shared/src/utils/blockchain/vaults.ts
  • packages/shared/src/utils/blockchain/price-feeds.ts
  • packages/shared/src/__tests__/utils/vaults.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWalletBalances.ts
  • packages/shared/src/utils/blockchain/abis/erc20.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useVaultOperations.test.ts
  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/views/Public/Fund.tsx
**/*.{json,ts,tsx}?(locales|i18n|translations|lang)

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Add every new user-facing string to en, es, and pt language files

Files:

  • packages/shared/src/utils/index.ts
  • packages/shared/src/utils/blockchain/vaults.ts
  • packages/shared/src/utils/blockchain/price-feeds.ts
  • packages/shared/src/__tests__/utils/vaults.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWalletBalances.ts
  • packages/shared/src/utils/blockchain/abis/erc20.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useVaultOperations.test.ts
  • packages/client/package.json
  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/shared/src/i18n/en.json
  • packages/shared/src/i18n/pt.json
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/views/Public/Fund.tsx
packages/shared/**/*.{ts,tsx}

📄 CodeRabbit inference engine (packages/shared/AGENTS.md)

packages/shared/**/*.{ts,tsx}: Use centralized query keys from queryKeys in packages/shared. Do not invent ad-hoc query arrays.
Use useCurrentChain() or DEFAULT_CHAIN_ID for application defaults in packages/shared, not wallet chain state.
Prefer event-driven invalidation over polling in packages/shared hooks and queries.
Use logger and typed domain models (Address, discriminated unions, unknown for untrusted data) in packages/shared code.

Files:

  • packages/shared/src/utils/index.ts
  • packages/shared/src/utils/blockchain/vaults.ts
  • packages/shared/src/utils/blockchain/price-feeds.ts
  • packages/shared/src/__tests__/utils/vaults.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWalletBalances.ts
  • packages/shared/src/utils/blockchain/abis/erc20.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useVaultOperations.test.ts
packages/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use Address type (not string) for Ethereum addresses in TypeScript across all packages

Files:

  • packages/shared/src/utils/index.ts
  • packages/shared/src/utils/blockchain/vaults.ts
  • packages/shared/src/utils/blockchain/price-feeds.ts
  • packages/shared/src/__tests__/utils/vaults.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWalletBalances.ts
  • packages/shared/src/utils/blockchain/abis/erc20.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useVaultOperations.test.ts
packages/{shared,client,admin}/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Never swallow errors — use parseContractError() + USER_FRIENDLY_ERRORS for contract errors, use createMutationErrorHandler() in shared mutation hooks, use logger from shared (not console.log)

Files:

  • packages/shared/src/utils/index.ts
  • packages/shared/src/utils/blockchain/vaults.ts
  • packages/shared/src/utils/blockchain/price-feeds.ts
  • packages/shared/src/__tests__/utils/vaults.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWalletBalances.ts
  • packages/shared/src/utils/blockchain/abis/erc20.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useVaultOperations.test.ts
  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/views/Public/Fund.tsx
packages/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

packages/**/*.{ts,tsx}: Use queryKeys.* helpers from shared for React Query key serialization — serialize objects in query keys
Do not use banned vocabulary in i18n strings (enforced by bun run lint:vocab): never use streak, countdown, leaderboard, FOMO, or growth-hacking language (urgent, limited time, re-engagement, retention hook)

Files:

  • packages/shared/src/utils/index.ts
  • packages/shared/src/utils/blockchain/vaults.ts
  • packages/shared/src/utils/blockchain/price-feeds.ts
  • packages/shared/src/__tests__/utils/vaults.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWalletBalances.ts
  • packages/shared/src/utils/blockchain/abis/erc20.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useVaultOperations.test.ts
  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/views/Public/Fund.tsx
packages/{contracts,agent,admin,shared}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use the Address type for Ethereum addresses.

Files:

  • packages/shared/src/utils/index.ts
  • packages/shared/src/utils/blockchain/vaults.ts
  • packages/shared/src/utils/blockchain/price-feeds.ts
  • packages/shared/src/__tests__/utils/vaults.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWalletBalances.ts
  • packages/shared/src/utils/blockchain/abis/erc20.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useVaultOperations.test.ts
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

Use logger from shared, never console.log.

Files:

  • packages/shared/src/utils/index.ts
  • packages/shared/src/utils/blockchain/vaults.ts
  • packages/shared/src/utils/blockchain/price-feeds.ts
  • packages/shared/src/__tests__/utils/vaults.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWalletBalances.ts
  • packages/shared/src/utils/blockchain/abis/erc20.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useVaultOperations.test.ts
  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/views/Public/Fund.tsx
packages/{client,admin,shared}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use Remixicon (Ri*Line), never lucide.

Files:

  • packages/shared/src/utils/index.ts
  • packages/shared/src/utils/blockchain/vaults.ts
  • packages/shared/src/utils/blockchain/price-feeds.ts
  • packages/shared/src/__tests__/utils/vaults.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWalletBalances.ts
  • packages/shared/src/utils/blockchain/abis/erc20.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useVaultOperations.test.ts
  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/views/Public/Fund.tsx
packages/{client,admin,shared}/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Any new user-facing string must be added to en, es, and pt.

Files:

  • packages/shared/src/utils/index.ts
  • packages/shared/src/utils/blockchain/vaults.ts
  • packages/shared/src/utils/blockchain/price-feeds.ts
  • packages/shared/src/__tests__/utils/vaults.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWalletBalances.ts
  • packages/shared/src/utils/blockchain/abis/erc20.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useVaultOperations.test.ts
  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/views/Public/Fund.tsx
packages/{client,admin,shared}/src/**/*.{ts,tsx,css}

📄 CodeRabbit inference engine (AGENTS.md)

packages/{client,admin,shared}/src/**/*.{ts,tsx,css}: Treat Baseline Widely Available as the baseline target for frontend changes. Use repo-installed Modern Web Guidance through bun run agentic:guidance before frontend, UI, CSS, accessibility, browser proof, or web-design changes.
Prefer semantic HTML, native controls, platform CSS, and browser primitives before custom JavaScript.

Files:

  • packages/shared/src/utils/index.ts
  • packages/shared/src/utils/blockchain/vaults.ts
  • packages/shared/src/utils/blockchain/price-feeds.ts
  • packages/shared/src/__tests__/utils/vaults.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWalletBalances.ts
  • packages/shared/src/utils/blockchain/abis/erc20.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useVaultOperations.test.ts
  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/views/Public/Fund.tsx
packages/{client,admin,shared}/src/**/*.{ts,tsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Banned vocabulary for any surface: streak, countdown, leaderboard, FOMO.

Files:

  • packages/shared/src/utils/index.ts
  • packages/shared/src/utils/blockchain/vaults.ts
  • packages/shared/src/utils/blockchain/price-feeds.ts
  • packages/shared/src/__tests__/utils/vaults.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWalletBalances.ts
  • packages/shared/src/utils/blockchain/abis/erc20.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useVaultOperations.test.ts
  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/shared/src/i18n/en.json
  • packages/shared/src/i18n/pt.json
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/views/Public/Fund.tsx
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use bun run test for running tests

Files:

  • packages/shared/src/__tests__/utils/vaults.test.ts
  • packages/shared/src/__tests__/hooks/vault/useVaultOperations.test.ts
  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
**/*.test.{ts,tsx,js}

📄 CodeRabbit inference engine (CLAUDE.md)

Use bun run test instead of bun test for running tests — bun test uses bun's built-in runner (ignores vitest config), while bun run test runs the package.json script with proper vitest environment

Files:

  • packages/shared/src/__tests__/utils/vaults.test.ts
  • packages/shared/src/__tests__/hooks/vault/useVaultOperations.test.ts
  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
**/package.json

📄 CodeRabbit inference engine (AGENTS.md)

Use bun for repo scripts and package operations. The only npm exception is npm run setup on a fresh machine before Bun is available.

Files:

  • packages/client/package.json
packages/client/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/instructions/client.instructions.md)

packages/client/**/*.{ts,tsx,js,jsx}: Hooks, providers, and most business logic should come from @green-goods/shared in packages/client
Do not add local hooks or providers when the logic belongs in shared
Preserve the offline-first queue flow for work submission; do not bypass the queue for passkey users
Keep authentication branches on shared auth APIs and shared default-chain helpers instead of wallet chain state
Manage blob URLs through shared utilities such as mediaResourceManager; do not leave orphaned URL.createObjectURL values behind
Prefer event-driven invalidation over polling

Files:

  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/views/Public/Fund.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use Remixicon (Ri*Line), never lucide for UI icons

Files:

  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/views/Public/Fund.tsx
packages/client/**/*.{ts,tsx}

📄 CodeRabbit inference engine (packages/client/AGENTS.md)

packages/client/**/*.{ts,tsx}: Do not create local hooks or providers in the client package when the logic belongs in @green-goods/shared
Work submission must preserve the offline-first queue flow; do not bypass the queue for passkey users
Prefer event-driven invalidation over polling
Manage blob URLs through shared utilities such as mediaResourceManager; do not leave orphaned URL.createObjectURL values behind
Authentication branches must go through shared auth APIs; do not treat wallet chain state as the source of truth for app defaults

Files:

  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/views/Public/Fund.tsx
packages/client/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (packages/client/AGENTS.md)

New user-facing strings must be translated in all three locale files

Client-only banned vocabulary (never use in client PWA): operator cockpit, utility copy, KPI tile, dashboard, Plus Jakarta Sans

Client only: do not use operator cockpit, utility copy, Plus Jakarta Sans, KPI tile, dashboard.

Files:

  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/views/Public/Fund.tsx
packages/{client,admin}/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

packages/{client,admin}/src/**/*.{ts,tsx}: ALL React hooks MUST live in @green-goods/shared — client and admin packages must not define their own hooks and should import hooks from the shared package
Import hooks from @green-goods/shared using barrel imports: import { useAuth, useGardens } from '@green-goods/shared' — never use deep paths like @green-goods/shared/src/hooks/useAuth
Contract integration: Import deployment artifacts from ../../../contracts/deployments/11155111-latest.json (or appropriate chain ID), never hardcode Ethereum addresses in code
Use isGreenWillDeployed(chainId?) from @green-goods/shared to detect when a feature contract is undeployed (zero-address) on the active chain — render a 'not available on this network' branch instead of a generic empty state
When a useMemo depends on a value written to localStorage in the same tab (e.g., pending-join membership), include usePendingJoinsVersion() from @green-goods/shared in its useMemo deps — this returns an incrementing counter that ticks on every in-tab pending-join change

Files:

  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/views/Public/Fund.tsx
packages/{client,admin}/src/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

When debugging user-observed UI regressions, start from the rendered surface before tracing data flow — inspect DOM geometry, computed styles (bounding rect, width/height, opacity, display, pointer-events, z-index, overflow, disabled state, selected classes, border/ring), verify click/tap changes state, then trace visible element → component → state setter

Files:

  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/views/Public/Fund.tsx
packages/{client,admin,shared}/src/**/*.{tsx,css}

📄 CodeRabbit inference engine (CLAUDE.md)

Design System: Load design skill (direction) + ui skill (implementation) explicitly when paradigm, layout composition, new view, tokens, or PR review is at stake — for trivial edits (padding, copy, single component touch), use the rules in CLAUDE.md

Files:

  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/views/Public/Fund.tsx
packages/client/src/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Client PWA uses @green-goods/shared primitives + presentation-mode loaders/PublicShell/PwaRuntime/AppShell/SiteHeader/AppBar — do not invent component names; flag missing primitives instead

Files:

  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/views/Public/Fund.tsx
packages/{client,admin,shared}/src/**/*.{css,scss,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Design tokens: never hardcode cubic-bezier, duration, or raw color/radius values — use --spring-* (6 motion tokens), --color-*, --radius-*, --color-material-* + --blur-material-* from theme.css

Files:

  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/views/Public/Fund.tsx
packages/{client,admin}/src/**/*.{tsx,css}

📄 CodeRabbit inference engine (CLAUDE.md)

Volume hierarchy: canvas 80–90% / ink 8–15% / stone 3–5% / accent green 1–3% — flooding the screen with green is the #1 design failure mode

Files:

  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/views/Public/Fund.tsx
packages/{contracts,agent,client,admin}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Default to single-chain behavior through getDefaultChain() or DEFAULT_CHAIN_ID.

Files:

  • packages/client/src/__tests__/views/fund.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/views/Public/Fund.tsx
packages/shared/src/i18n/{en,es,pt}.json

📄 CodeRabbit inference engine (.github/instructions/shared.instructions.md)

New user-facing strings must be added to src/i18n/en.json, src/i18n/es.json, and src/i18n/pt.json

Files:

  • packages/shared/src/i18n/en.json
  • packages/shared/src/i18n/pt.json
packages/shared/src/i18n/*.json

📄 CodeRabbit inference engine (packages/shared/AGENTS.md)

Add every new user-facing string to src/i18n/en.json, src/i18n/es.json, and src/i18n/pt.json in the shared package. Do not hardcode user-facing strings.

Files:

  • packages/shared/src/i18n/en.json
  • packages/shared/src/i18n/pt.json
🔇 Additional comments (16)
.github/workflows/agent.yml (1)

48-48: LGTM!

Also applies to: 77-77

.github/workflows/client.yml (1)

72-72: LGTM!

Also applies to: 99-99, 140-140, 176-176, 241-241

.github/workflows/contracts.yml (1)

65-65: LGTM!

Also applies to: 99-99, 137-137, 233-233

.github/workflows/design.yml (1)

97-97: LGTM!

Also applies to: 133-133

.github/workflows/docs.yml (1)

48-48: LGTM!

.github/workflows/indexer.yml (1)

50-50: LGTM!

Also applies to: 100-100

.github/workflows/shared.yml (2)

72-72: LGTM!

Also applies to: 99-99, 139-139, 174-174, 239-239


132-132: LGTM!

Also applies to: 160-160

packages/shared/src/__tests__/utils/vaults.test.ts (1)

11-12: LGTM!

Also applies to: 119-121, 152-161

packages/shared/src/hooks/vault/useOctantVaultWalletBalances.ts (1)

1-69: LGTM!

packages/shared/src/i18n/en.json (1)

1385-1387: LGTM!

Also applies to: 1413-1413, 1436-1436, 1440-1442, 1447-1448, 1451-1451, 1457-1458, 2965-2965, 2968-2968, 3005-3007, 3057-3057, 3061-3063, 3065-3065, 3067-3070, 3122-3122, 3420-3642

packages/shared/src/i18n/pt.json (1)

1385-1387: LGTM!

Also applies to: 1413-1413, 1436-1436, 1440-1442, 1447-1448, 1451-1451, 1457-1458, 2965-2965, 2968-2968, 3005-3007, 3057-3057, 3061-3063, 3065-3065, 3067-3069, 3122-3122, 3587-3588, 3594-3600, 3608-3614, 3640-3641

packages/shared/src/utils/blockchain/abis/erc20.ts (1)

7-15: LGTM!

Also applies to: 60-68

packages/shared/src/utils/blockchain/price-feeds.ts (1)

19-28: LGTM!

Also applies to: 94-96

packages/shared/src/utils/blockchain/vaults.ts (1)

97-113: LGTM!

packages/shared/src/utils/index.ts (1)

242-243: LGTM!

Also applies to: 331-331

Comment thread packages/shared/src/hooks/vault/useWrapEthToWeth.ts
Comment thread packages/shared/src/hooks/vault/useWrapEthToWeth.ts
Implement shares-first Octant redeem handling for vault positions, including maxRedeem-based limits, redeem argument construction, WETH proceeds previews, and visible unavailable states. Add the conservative aggregate project-supporting value metric with unavailable/zero/positive coverage.

Refs PRD-441

Refs PRD-587

Refs PRD-589
Oba-One and others added 2 commits June 8, 2026 18:37
…into codex/octant-qa-quick-fixes

# Conflicts:
#	packages/shared/src/i18n/pt.json
## Summary
- Implements shares-first `/vaults?manage=positions` redeem semantics
for Octant vault positions, including `maxRedeem` limits, share-first
Max, explicit owner/receiver handling, and `redeem(shares, receiver,
owner)` submission.
- Adds conservative aggregate project-supporting vault value states for
PRD-589 without APY, payout cadence, guaranteed-yield, or per-user
accrued-profit claims.
- Records plan evidence and QA status for the NYC Vault Crowdfunding
lane.

## Validation
- [x] `node scripts/dev/ci-local.js --quick` passed after commit.
- [x] `bun run --filter @green-goods/client test` passed.
- [x] `bun run --filter @green-goods/shared test` passed.
- [x] `bun run --filter @green-goods/client build` passed.
- [x] `bun run --filter @green-goods/shared typecheck` passed.
- [x] `bun run lint:vocab` passed.
- [x] `git diff --check` passed.
- [x] `node scripts/harness/plan-hub.mjs linear-sync --feature
nyc-vault-crowdfunding --json` passed.
- [x] Browser proof captured for `/vaults?manage=positions`:
`/private/tmp/green-goods-vaults-production-proof.png`.

## Notes
- No live mainnet value movement was performed; wallet-confirmed
redemption remains human-gated.
- The requested `automated/codex` GitHub label was not present in the
repository, and creating a repository-wide label was blocked by the
approval policy.

Linear: PRD-441
Linear: PRD-587
Linear: PRD-589

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
packages/shared/src/hooks/vault/useOctantVaultProjectSupportMetric.ts (1)

67-75: 💤 Low value

Unreachable code in queryFn when enabled is false.

The early return at lines 68-75 inside queryFn is unreachable when enabled: false since React Query won't execute the queryFn. This defensive guard is harmless but unnecessary since the hook already returns early at lines 126-136 when !enabled.

Consider removing this block to simplify the code, or keep it as a defensive measure if the enabled logic could change in the future.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/shared/src/hooks/vault/useOctantVaultProjectSupportMetric.ts` around
lines 67 - 75, Inside the useOctantVaultProjectSupportMetric hook remove the
unreachable defensive early-return inside the queryFn (the if (!vaultAddress ||
!chainId) { return { sourceAddress: null, shareBalance: 0n, assetValue: 0n,
unavailableReason: "missing_vault" } } block) because React Query's enabled flag
already prevents queryFn execution when !enabled; update queryFn to assume
vaultAddress and chainId are present (or keep a very small assertion) and ensure
the hook's existing enabled logic and external fallback handling remain intact
so TypeScript types still match the expected query result shape.
packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts (1)

1-4: 💤 Low value

Test file name should match the hook being tested.

The file is named useOctantVaultWithdraw.test.ts but tests useOctantVaultRedeem. Since the hook has been renamed from withdraw to redeem, the test file should be renamed to useOctantVaultRedeem.test.ts for consistency and discoverability.

Also applies to: 70-70, 88-88

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts`
around lines 1 - 4, Rename the test file and update imports so the filename
matches the hook name: change the test file from useOctantVaultWithdraw.test.ts
to useOctantVaultRedeem.test.ts, update any import statements referencing
useOctantVaultWithdraw to import useOctantVaultRedeem, and ensure any
describe/it titles or helper references (e.g., in test setup or mock files) also
use useOctantVaultRedeem to keep names consistent and discoverable.
packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts (1)

1-18: 💤 Low value

File name should match the exported hook.

The file is named useOctantVaultWithdraw.ts but exports useOctantVaultRedeem. Rename to useOctantVaultRedeem.ts for consistency with the module docblock (@module hooks/vault/useOctantVaultRedeem) and to match standard naming conventions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts` around lines 1 -
18, Filename mismatches the exported hook: rename the file from
useOctantVaultWithdraw.ts to useOctantVaultRedeem.ts so it matches the exported
symbol useOctantVaultRedeem and the module docblock (`@module`
hooks/vault/useOctantVaultRedeem); after renaming, update any imports that
reference useOctantVaultWithdraw to import useOctantVaultRedeem instead to avoid
broken imports and ensure consistency across the codebase.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/shared/src/i18n/es.json`:
- Around line 3601-3607: Several Spanish strings in the new /vaults keys miss
diacritics and need orthographic normalization; update the listed i18n keys to
use standard Spanish accents (e.g., change "donacion" → "donación", "numerico" →
"numérico", "esta" → "está") for consistency:
public.vaults.strategy.metric.loading,
public.vaults.strategy.metric.positiveBody, public.vaults.strategy.metric.title,
public.vaults.strategy.metric.unavailable,
public.vaults.strategy.metric.unavailableBody,
public.vaults.strategy.metric.zeroBody and also apply the same accent
normalization to the other affected blocks noted (around lines 3656, 3674–3677,
3685–3691, 3694–3696, 3700–3705, 3708–3710); keep the original meaning and
punctuation while only correcting spelling/accents.
- Around line 3432-3435: The Spanish strings for the campaign fallback keys are
missing diacritics; update the values for
"public.vaults.campaign.fallback.fundingPurpose",
"public.vaults.campaign.fallback.recipientLogic",
"public.vaults.campaign.fallback.riskNote", and
"public.vaults.campaign.fallback.summary" to include proper accents (e.g., "El
propósito de financiamiento está pendiente.", "El enrutamiento de destinatarios
está pendiente.", "Las transacciones están desactivadas hasta que se completen
los detalles de la campaña.", "La copia de campaña está pendiente."). Ensure
only the value strings change and keep the keys intact.

---

Nitpick comments:
In `@packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts`:
- Around line 1-4: Rename the test file and update imports so the filename
matches the hook name: change the test file from useOctantVaultWithdraw.test.ts
to useOctantVaultRedeem.test.ts, update any import statements referencing
useOctantVaultWithdraw to import useOctantVaultRedeem, and ensure any
describe/it titles or helper references (e.g., in test setup or mock files) also
use useOctantVaultRedeem to keep names consistent and discoverable.

In `@packages/shared/src/hooks/vault/useOctantVaultProjectSupportMetric.ts`:
- Around line 67-75: Inside the useOctantVaultProjectSupportMetric hook remove
the unreachable defensive early-return inside the queryFn (the if (!vaultAddress
|| !chainId) { return { sourceAddress: null, shareBalance: 0n, assetValue: 0n,
unavailableReason: "missing_vault" } } block) because React Query's enabled flag
already prevents queryFn execution when !enabled; update queryFn to assume
vaultAddress and chainId are present (or keep a very small assertion) and ensure
the hook's existing enabled logic and external fallback handling remain intact
so TypeScript types still match the expected query result shape.

In `@packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts`:
- Around line 1-18: Filename mismatches the exported hook: rename the file from
useOctantVaultWithdraw.ts to useOctantVaultRedeem.ts so it matches the exported
symbol useOctantVaultRedeem and the module docblock (`@module`
hooks/vault/useOctantVaultRedeem); after renaming, update any imports that
reference useOctantVaultWithdraw to import useOctantVaultRedeem instead to avoid
broken imports and ensure consistency across the codebase.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c60e2ef7-ad9c-422a-819d-51b278842517

📥 Commits

Reviewing files that changed from the base of the PR and between 9fe55ee and 740a824.

📒 Files selected for processing (28)
  • .plans/active/nyc-vault-crowdfunding/eval.md
  • .plans/active/nyc-vault-crowdfunding/plan.todo.md
  • .plans/active/nyc-vault-crowdfunding/status.json
  • packages/admin/src/__tests__/components/CookieJarManageModal.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/client/src/components/Public/VaultCheckoutDialog.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/client/src/views/Public/Vaults.tsx
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultPositions.test.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultProjectSupportMetric.test.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts
  • packages/shared/src/__tests__/hooks/vault/useVaultOperations.test.ts
  • packages/shared/src/__tests__/modules/vault-crowdfunding.test.ts
  • packages/shared/src/config/query-keys/vault.ts
  • packages/shared/src/hooks/index.ts
  • packages/shared/src/hooks/vault/useOctantVaultPositions.ts
  • packages/shared/src/hooks/vault/useOctantVaultProjectSupportMetric.ts
  • packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/i18n/en.json
  • packages/shared/src/i18n/es.json
  • packages/shared/src/i18n/pt.json
  • packages/shared/src/index.ts
  • packages/shared/src/modules/index.ts
  • packages/shared/src/modules/vault-crowdfunding.ts
  • packages/shared/src/utils/blockchain/abis/octant.ts
✅ Files skipped from review due to trivial changes (4)
  • packages/admin/src/tests/components/CookieJarManageModal.test.tsx
  • .plans/active/nyc-vault-crowdfunding/eval.md
  • packages/shared/src/i18n/pt.json
  • .plans/active/nyc-vault-crowdfunding/plan.todo.md
🚧 Files skipped from review as they are similar to previous changes (10)
  • packages/shared/src/modules/index.ts
  • packages/shared/src/config/query-keys/vault.ts
  • packages/shared/src/i18n/en.json
  • packages/shared/src/tests/hooks/vault/useVaultOperations.test.ts
  • packages/shared/src/hooks/index.ts
  • packages/shared/src/hooks/vault/useOctantVaultPositions.ts
  • .plans/active/nyc-vault-crowdfunding/status.json
  • packages/shared/src/index.ts
  • packages/client/src/components/Public/VaultCheckoutDialog.tsx
  • packages/shared/src/tests/modules/vault-crowdfunding.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
  • GitHub Check: Test
  • GitHub Check: CI Gate
  • GitHub Check: Build Docs
  • GitHub Check: Unit Tests
  • GitHub Check: Playwright Client CI
  • GitHub Check: Storybook
  • GitHub Check: Test
  • GitHub Check: Lint And Build
  • GitHub Check: Playwright Admin CI
  • GitHub Check: Test
  • GitHub Check: Lint And Build
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (javascript-typescript)
🧰 Additional context used
📓 Path-based instructions (32)
packages/shared/**

📄 CodeRabbit inference engine (.github/instructions/shared.instructions.md)

@green-goods/shared is the only home for reusable hooks, providers, stores, modules, types, i18n, and shared UI primitives

Files:

  • packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultProjectSupportMetric.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultProjectSupportMetric.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultPositions.test.ts
  • packages/shared/src/i18n/es.json
packages/shared/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/instructions/shared.instructions.md)

Use centralized queryKeys, event-driven invalidation, useCurrentChain() or DEFAULT_CHAIN_ID, logger, and typed domain models such as Address in @green-goods/shared

Keep reusable hooks, providers, stores, modules, and shared UI primitives in @green-goods/shared

Files:

  • packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultProjectSupportMetric.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultProjectSupportMetric.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultPositions.test.ts
packages/shared/src/**/*.{tsx,ts}

📄 CodeRabbit inference engine (.github/instructions/shared.instructions.md)

Shared UI primitive changes should ship with tests, barrel updates, and Storybook coverage in the same change when applicable

Files:

  • packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultProjectSupportMetric.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultProjectSupportMetric.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultPositions.test.ts
{.github/workflows/**,**/*.test.{js,ts,jsx,tsx},**/*.spec.{js,ts,jsx,tsx}}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use bun run test, never bun test

Files:

  • packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultProjectSupportMetric.test.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultPositions.test.ts
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx}: Default to single-chain behavior through getDefaultChain() or DEFAULT_CHAIN_ID
Use logger from shared instead of console.log
Use bun run format:check && bun lint for code quality checks

Files:

  • packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultProjectSupportMetric.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultProjectSupportMetric.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultPositions.test.ts
  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/client/src/views/Public/Vaults.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use the Address type for Ethereum addresses instead of raw string types

Files:

  • packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultProjectSupportMetric.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultProjectSupportMetric.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultPositions.test.ts
  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/client/src/views/Public/Vaults.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
**/*.{json,ts,tsx}?(locales|i18n|translations|lang)

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Add every new user-facing string to en, es, and pt language files

Files:

  • packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultProjectSupportMetric.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultProjectSupportMetric.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultPositions.test.ts
  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/client/src/views/Public/Vaults.tsx
  • packages/shared/src/i18n/es.json
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use bun run test for running tests

Files:

  • packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultProjectSupportMetric.test.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultPositions.test.ts
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/shared/**/*.{ts,tsx}

📄 CodeRabbit inference engine (packages/shared/AGENTS.md)

packages/shared/**/*.{ts,tsx}: Use centralized query keys from queryKeys in packages/shared. Do not invent ad-hoc query arrays.
Use useCurrentChain() or DEFAULT_CHAIN_ID for application defaults in packages/shared, not wallet chain state.
Prefer event-driven invalidation over polling in packages/shared hooks and queries.
Use logger and typed domain models (Address, discriminated unions, unknown for untrusted data) in packages/shared code.

Files:

  • packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultProjectSupportMetric.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultProjectSupportMetric.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultPositions.test.ts
**/*.test.{ts,tsx,js}

📄 CodeRabbit inference engine (CLAUDE.md)

Use bun run test instead of bun test for running tests — bun test uses bun's built-in runner (ignores vitest config), while bun run test runs the package.json script with proper vitest environment

Files:

  • packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultProjectSupportMetric.test.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultPositions.test.ts
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use Address type (not string) for Ethereum addresses in TypeScript across all packages

Files:

  • packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultProjectSupportMetric.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultProjectSupportMetric.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultPositions.test.ts
packages/{shared,client,admin}/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Never swallow errors — use parseContractError() + USER_FRIENDLY_ERRORS for contract errors, use createMutationErrorHandler() in shared mutation hooks, use logger from shared (not console.log)

Files:

  • packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultProjectSupportMetric.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultProjectSupportMetric.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultPositions.test.ts
  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/client/src/views/Public/Vaults.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

packages/**/*.{ts,tsx}: Use queryKeys.* helpers from shared for React Query key serialization — serialize objects in query keys
Do not use banned vocabulary in i18n strings (enforced by bun run lint:vocab): never use streak, countdown, leaderboard, FOMO, or growth-hacking language (urgent, limited time, re-engagement, retention hook)

Files:

  • packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultProjectSupportMetric.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultProjectSupportMetric.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultPositions.test.ts
  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/client/src/views/Public/Vaults.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/{contracts,agent,admin,shared}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use the Address type for Ethereum addresses.

Files:

  • packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultProjectSupportMetric.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultProjectSupportMetric.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultPositions.test.ts
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

Use logger from shared, never console.log.

Files:

  • packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultProjectSupportMetric.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultProjectSupportMetric.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultPositions.test.ts
  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/client/src/views/Public/Vaults.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/{client,admin,shared}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use Remixicon (Ri*Line), never lucide.

Files:

  • packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultProjectSupportMetric.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultProjectSupportMetric.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultPositions.test.ts
  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/client/src/views/Public/Vaults.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/{client,admin,shared}/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Any new user-facing string must be added to en, es, and pt.

Files:

  • packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultProjectSupportMetric.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultProjectSupportMetric.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultPositions.test.ts
  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/client/src/views/Public/Vaults.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/{client,admin,shared}/src/**/*.{ts,tsx,css}

📄 CodeRabbit inference engine (AGENTS.md)

packages/{client,admin,shared}/src/**/*.{ts,tsx,css}: Treat Baseline Widely Available as the baseline target for frontend changes. Use repo-installed Modern Web Guidance through bun run agentic:guidance before frontend, UI, CSS, accessibility, browser proof, or web-design changes.
Prefer semantic HTML, native controls, platform CSS, and browser primitives before custom JavaScript.

Files:

  • packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultProjectSupportMetric.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultProjectSupportMetric.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultPositions.test.ts
  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/client/src/views/Public/Vaults.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/{client,admin,shared}/src/**/*.{ts,tsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Banned vocabulary for any surface: streak, countdown, leaderboard, FOMO.

Files:

  • packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultProjectSupportMetric.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultProjectSupportMetric.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultPositions.test.ts
  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/client/src/views/Public/Vaults.tsx
  • packages/shared/src/i18n/es.json
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/client/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/instructions/client.instructions.md)

packages/client/**/*.{ts,tsx,js,jsx}: Hooks, providers, and most business logic should come from @green-goods/shared in packages/client
Do not add local hooks or providers when the logic belongs in shared
Preserve the offline-first queue flow for work submission; do not bypass the queue for passkey users
Keep authentication branches on shared auth APIs and shared default-chain helpers instead of wallet chain state
Manage blob URLs through shared utilities such as mediaResourceManager; do not leave orphaned URL.createObjectURL values behind
Prefer event-driven invalidation over polling

Files:

  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/client/src/views/Public/Vaults.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use Remixicon (Ri*Line), never lucide for UI icons

Files:

  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/client/src/views/Public/Vaults.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/client/**/*.{ts,tsx}

📄 CodeRabbit inference engine (packages/client/AGENTS.md)

packages/client/**/*.{ts,tsx}: Do not create local hooks or providers in the client package when the logic belongs in @green-goods/shared
Work submission must preserve the offline-first queue flow; do not bypass the queue for passkey users
Prefer event-driven invalidation over polling
Manage blob URLs through shared utilities such as mediaResourceManager; do not leave orphaned URL.createObjectURL values behind
Authentication branches must go through shared auth APIs; do not treat wallet chain state as the source of truth for app defaults

Files:

  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/client/src/views/Public/Vaults.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/client/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (packages/client/AGENTS.md)

New user-facing strings must be translated in all three locale files

Client-only banned vocabulary (never use in client PWA): operator cockpit, utility copy, KPI tile, dashboard, Plus Jakarta Sans

Client only: do not use operator cockpit, utility copy, Plus Jakarta Sans, KPI tile, dashboard.

Files:

  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/client/src/views/Public/Vaults.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/{client,admin}/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

packages/{client,admin}/src/**/*.{ts,tsx}: ALL React hooks MUST live in @green-goods/shared — client and admin packages must not define their own hooks and should import hooks from the shared package
Import hooks from @green-goods/shared using barrel imports: import { useAuth, useGardens } from '@green-goods/shared' — never use deep paths like @green-goods/shared/src/hooks/useAuth
Contract integration: Import deployment artifacts from ../../../contracts/deployments/11155111-latest.json (or appropriate chain ID), never hardcode Ethereum addresses in code
Use isGreenWillDeployed(chainId?) from @green-goods/shared to detect when a feature contract is undeployed (zero-address) on the active chain — render a 'not available on this network' branch instead of a generic empty state
When a useMemo depends on a value written to localStorage in the same tab (e.g., pending-join membership), include usePendingJoinsVersion() from @green-goods/shared in its useMemo deps — this returns an incrementing counter that ticks on every in-tab pending-join change

Files:

  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/client/src/views/Public/Vaults.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/{client,admin}/src/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

When debugging user-observed UI regressions, start from the rendered surface before tracing data flow — inspect DOM geometry, computed styles (bounding rect, width/height, opacity, display, pointer-events, z-index, overflow, disabled state, selected classes, border/ring), verify click/tap changes state, then trace visible element → component → state setter

Files:

  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/client/src/views/Public/Vaults.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/{client,admin,shared}/src/**/*.{tsx,css}

📄 CodeRabbit inference engine (CLAUDE.md)

Design System: Load design skill (direction) + ui skill (implementation) explicitly when paradigm, layout composition, new view, tokens, or PR review is at stake — for trivial edits (padding, copy, single component touch), use the rules in CLAUDE.md

Files:

  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/client/src/views/Public/Vaults.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/client/src/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Client PWA uses @green-goods/shared primitives + presentation-mode loaders/PublicShell/PwaRuntime/AppShell/SiteHeader/AppBar — do not invent component names; flag missing primitives instead

Files:

  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/client/src/views/Public/Vaults.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/{client,admin,shared}/src/**/*.{css,scss,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Design tokens: never hardcode cubic-bezier, duration, or raw color/radius values — use --spring-* (6 motion tokens), --color-*, --radius-*, --color-material-* + --blur-material-* from theme.css

Files:

  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/client/src/views/Public/Vaults.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/{client,admin}/src/**/*.{tsx,css}

📄 CodeRabbit inference engine (CLAUDE.md)

Volume hierarchy: canvas 80–90% / ink 8–15% / stone 3–5% / accent green 1–3% — flooding the screen with green is the #1 design failure mode

Files:

  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/client/src/views/Public/Vaults.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/{contracts,agent,client,admin}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Default to single-chain behavior through getDefaultChain() or DEFAULT_CHAIN_ID.

Files:

  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultManagePositionsPanel.tsx
  • packages/client/src/views/Public/Vaults.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/shared/src/i18n/{en,es,pt}.json

📄 CodeRabbit inference engine (.github/instructions/shared.instructions.md)

New user-facing strings must be added to src/i18n/en.json, src/i18n/es.json, and src/i18n/pt.json

Files:

  • packages/shared/src/i18n/es.json
packages/shared/src/i18n/*.json

📄 CodeRabbit inference engine (packages/shared/AGENTS.md)

Add every new user-facing string to src/i18n/en.json, src/i18n/es.json, and src/i18n/pt.json in the shared package. Do not hardcode user-facing strings.

Files:

  • packages/shared/src/i18n/es.json
🧠 Learnings (1)
📚 Learning: 2026-06-09T01:19:17.906Z
Learnt from: Oba-One
Repo: greenpill-dev-guild/green-goods PR: 543
File: packages/shared/src/hooks/vault/useWrapEthToWeth.ts:31-60
Timestamp: 2026-06-09T01:19:17.906Z
Learning: In this repo, `WalletSender` and `EmbeddedSender` already `await` `waitForTransactionReceipt` inside `sendContractCall(...)` and throw if the receipt indicates a revert before resolving. Therefore, hooks that call `sender.sendContractCall(...)` (e.g., wrapping/endow hooks) should NOT add an extra “confirm/wait for receipt” step after the call—the receipt is already guaranteed when the promise resolves. The only intentional exception is the Safe-style non-canonical hash path: keep the special logging/handling there because wagmi cannot receipt-poll it like a normal transaction hash.

Applied to files:

  • packages/shared/src/hooks/vault/useOctantVaultProjectSupportMetric.ts
  • packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts
  • packages/shared/src/hooks/vault/useWrapEthToWeth.ts
🔇 Additional comments (26)
packages/client/src/__tests__/views/PublicVaults.test.tsx (1)

1-1725: LGTM!

packages/client/src/__tests__/views/VaultManagePositions.test.tsx (1)

1-592: LGTM!

packages/client/src/views/Public/Vaults.tsx (2)

180-237: LGTM!


239-331: i18n message IDs present in all localespublic.vaults.strategy.metric.* (title, loading, unavailable, unavailableBody, zeroBody, positiveBody) are present in packages/shared/src/i18n/en.json, es.json, and pt.json.

packages/shared/src/__tests__/hooks/vault/useOctantVaultPositions.test.ts (1)

1-195: LGTM!

packages/shared/src/__tests__/hooks/vault/useOctantVaultProjectSupportMetric.test.ts (1)

1-130: LGTM!

packages/shared/src/hooks/vault/useOctantVaultProjectSupportMetric.ts (1)

1-173: LGTM!

packages/client/src/components/Public/VaultCardWalletManage.tsx (5)

1-27: LGTM!


29-82: LGTM!


84-194: LGTM!


196-273: LGTM!


275-454: LGTM!

packages/client/src/components/Public/VaultManagePositionsPanel.tsx (6)

1-28: LGTM!


30-161: LGTM!


163-250: LGTM!


252-396: LGTM!


398-517: LGTM!


519-897: LGTM!

packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts (2)

6-86: LGTM!


88-198: LGTM!

packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts (4)

20-43: LGTM!


45-70: LGTM!


71-119: LGTM!


121-157: LGTM!

packages/shared/src/hooks/vault/useWrapEthToWeth.ts (2)

1-20: LGTM!


22-74: LGTM!

Comment on lines +3432 to +3435
"public.vaults.campaign.fallback.fundingPurpose": "El proposito de financiamiento esta pendiente.",
"public.vaults.campaign.fallback.recipientLogic": "El ruteo de destinatarios esta pendiente.",
"public.vaults.campaign.fallback.riskNote": "Las transacciones estan desactivadas hasta que se completen los detalles de la campaña.",
"public.vaults.campaign.fallback.summary": "La copia de campaña esta pendiente.",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix missing Spanish diacritics in new fallback campaign copy.

These new user-facing strings have spelling regressions (missing accents), which lowers translation quality.

Suggested patch
-  "public.vaults.campaign.fallback.fundingPurpose": "El proposito de financiamiento esta pendiente.",
-  "public.vaults.campaign.fallback.recipientLogic": "El ruteo de destinatarios esta pendiente.",
-  "public.vaults.campaign.fallback.riskNote": "Las transacciones estan desactivadas hasta que se completen los detalles de la campaña.",
-  "public.vaults.campaign.fallback.summary": "La copia de campaña esta pendiente.",
+  "public.vaults.campaign.fallback.fundingPurpose": "El propósito de financiamiento está pendiente.",
+  "public.vaults.campaign.fallback.recipientLogic": "El ruteo de destinatarios está pendiente.",
+  "public.vaults.campaign.fallback.riskNote": "Las transacciones están desactivadas hasta que se completen los detalles de la campaña.",
+  "public.vaults.campaign.fallback.summary": "La copia de campaña está pendiente.",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"public.vaults.campaign.fallback.fundingPurpose": "El proposito de financiamiento esta pendiente.",
"public.vaults.campaign.fallback.recipientLogic": "El ruteo de destinatarios esta pendiente.",
"public.vaults.campaign.fallback.riskNote": "Las transacciones estan desactivadas hasta que se completen los detalles de la campaña.",
"public.vaults.campaign.fallback.summary": "La copia de campaña esta pendiente.",
"public.vaults.campaign.fallback.fundingPurpose": "El propósito de financiamiento está pendiente.",
"public.vaults.campaign.fallback.recipientLogic": "El ruteo de destinatarios está pendiente.",
"public.vaults.campaign.fallback.riskNote": "Las transacciones están desactivadas hasta que se completen los detalles de la campaña.",
"public.vaults.campaign.fallback.summary": "La copia de campaña está pendiente.",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/shared/src/i18n/es.json` around lines 3432 - 3435, The Spanish
strings for the campaign fallback keys are missing diacritics; update the values
for "public.vaults.campaign.fallback.fundingPurpose",
"public.vaults.campaign.fallback.recipientLogic",
"public.vaults.campaign.fallback.riskNote", and
"public.vaults.campaign.fallback.summary" to include proper accents (e.g., "El
propósito de financiamiento está pendiente.", "El enrutamiento de destinatarios
está pendiente.", "Las transacciones están desactivadas hasta que se completen
los detalles de la campaña.", "La copia de campaña está pendiente."). Ensure
only the value strings change and keep the keys intact.

Comment on lines +3601 to +3607
"public.vaults.strategy.metric.loading": "Leyendo el router configurado de apoyo al proyecto.",
"public.vaults.strategy.metric.positiveBody": "Estimado desde las participaciones de donacion mantenidas por el router configurado de apoyo al proyecto.",
"public.vaults.strategy.metric.title": "Valor generado para apoyar al proyecto",
"public.vaults.strategy.metric.unavailable": "No disponible",
"public.vaults.strategy.metric.unavailableBody": "No se muestra un valor numerico de apoyo hasta que se pueda probar el origen del router y la ruta de conversion.",
"public.vaults.strategy.metric.zeroBody": "El router de apoyo al proyecto esta probado, pero actualmente no mantiene participaciones de donacion.",
"public.vaults.strategy.source.architecture": "Arquitectura YDS",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Normalize Spanish copy in new /vaults strings (accent/orthography consistency).

This block introduces several accent omissions in visible UI text. Please normalize to standard Spanish spelling for consistency with the rest of es.json.

Suggested patch (representative corrections)
-  "public.vaults.strategy.metric.unavailableBody": "No se muestra un valor numerico de apoyo hasta que se pueda probar el origen del router y la ruta de conversion.",
+  "public.vaults.strategy.metric.unavailableBody": "No se muestra un valor numérico de apoyo hasta que se pueda probar el origen del router y la ruta de conversión.",

-  "public.vaults.manage.position.withdrawable": "Participaciones canjeables ahora",
+  "public.vaults.manage.position.withdrawable": "Participaciones canjeables ahora",

-  "public.vaults.manage.position.withdraw": "Canjear participaciones",
+  "public.vaults.manage.position.withdraw": "Canjear participaciones",

-  "public.vaults.manage.withdraw.amount": "Participaciones a canjear",
+  "public.vaults.manage.withdraw.amount": "Participaciones a canjear",

-  "public.vaults.manage.withdraw.review": "Revisar canje",
+  "public.vaults.manage.withdraw.review": "Revisar canje",

-  "public.vaults.manage.withdraw.confirmTitle": "Confirmar canje de participaciones",
+  "public.vaults.manage.withdraw.confirmTitle": "Confirmar canje de participaciones",

-  "public.vaults.manage.withdraw.pending": "Canjeando…",
+  "public.vaults.manage.withdraw.pending": "Canjeando…",

-  "public.vaults.manage.redeem.unavailableBody": "Este propietario tiene participaciones visibles del vault, pero el vault no informa participaciones canjeables con el límite de pérdida actual. Intenta más tarde o conserva la posición intacta.",
+  "public.vaults.manage.redeem.unavailableBody": "Este propietario tiene participaciones visibles del vault, pero el vault no informa participaciones canjeables con el límite de pérdida actual. Intenta más tarde o conserva la posición intacta.",

-  "public.vaults.manage.card.readOnly": "Solo lectura: restaura la billetera de email de arriba para canjear participaciones.",
+  "public.vaults.manage.card.readOnly": "Solo lectura: restaura la billetera de email de arriba para canjear participaciones."

Also applies to: 3656-3656, 3674-3677, 3685-3691, 3694-3696, 3700-3705, 3708-3710

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/shared/src/i18n/es.json` around lines 3601 - 3607, Several Spanish
strings in the new /vaults keys miss diacritics and need orthographic
normalization; update the listed i18n keys to use standard Spanish accents
(e.g., change "donacion" → "donación", "numerico" → "numérico", "esta" → "está")
for consistency: public.vaults.strategy.metric.loading,
public.vaults.strategy.metric.positiveBody, public.vaults.strategy.metric.title,
public.vaults.strategy.metric.unavailable,
public.vaults.strategy.metric.unavailableBody,
public.vaults.strategy.metric.zeroBody and also apply the same accent
normalization to the other affected blocks noted (around lines 3656, 3674–3677,
3685–3691, 3694–3696, 3700–3705, 3708–3710); keep the original meaning and
punctuation while only correcting spelling/accents.

Oba-One and others added 3 commits June 8, 2026 22:29
## Summary
- Collapse `/vaults` Card Endow to three visible steps, with Step 3
owning card polling, batch settlement, fallback, share proof, and
receipt proof.
- Configure the recovered Thirdweb in-app wallet for EIP-7702 where
supported, and only use the ordered approve/deposit batch when the batch
account remains the recovered receiver wallet.
- Keep the sequential approve-then-deposit path as the inline fallback,
with compact status copy and updated `en`, `es`, and `pt` strings.

## Validation
- [x] `bun run --filter @green-goods/client test -- PublicVaults`
- [x] `bun run lint:vocab`
- [x] `bun run --filter @green-goods/client build`
- [x] `git diff --check`
- [x] Mocked desktop/mobile browser proof for `/vaults` batch and
fallback states, with no live value movement
- [x] Pre-push hook passed; it emitted existing lint warnings outside
this diff.
setDepositTxHash(txHash);
setDepositStatus("deposited");
const shares = await readShareBalance(expectedFlowKey);
if (txHash !== null && shares !== null && shares > 0n) {

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/client/src/components/Public/VaultCardPaymentPanel.tsx (1)

364-376: 💤 Low value

Consider hiding the checkout link when card funding is complete.

The secure checkout link is rendered whenever session exists, but once cardFundingComplete is true, the payment phase is over and this link no longer serves a purpose. For consistency with the other UI elements that are hidden when cardFundingComplete is true (lines 245, 319, 329), consider gating this link as well:

-          {session ? (
+          {session && !cardFundingComplete ? (
             <a
               href={session.link}
               target="_blank"
               rel="noopener noreferrer"
               className={CHECKOUT_GHOST_BUTTON}
             >
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/client/src/components/Public/VaultCardPaymentPanel.tsx` around lines
364 - 376, The checkout anchor currently renders whenever session exists but
should also be hidden when cardFundingComplete is true; inside the
VaultCardPaymentPanel component, update the conditional that renders the anchor
(the JSX that references session, session.link and CHECKOUT_GHOST_BUTTON) to
require both session and !cardFundingComplete (i.e., gate the link on session &&
!cardFundingComplete) so the secure checkout link is not shown after funding
completes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/client/src/components/Public/VaultCardPaymentPanel.tsx`:
- Around line 364-376: The checkout anchor currently renders whenever session
exists but should also be hidden when cardFundingComplete is true; inside the
VaultCardPaymentPanel component, update the conditional that renders the anchor
(the JSX that references session, session.link and CHECKOUT_GHOST_BUTTON) to
require both session and !cardFundingComplete (i.e., gate the link on session &&
!cardFundingComplete) so the secure checkout link is not shown after funding
completes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8ea18c5b-825c-47e2-986e-e88a209b71c1

📥 Commits

Reviewing files that changed from the base of the PR and between 740a824 and e4f62f9.

📒 Files selected for processing (12)
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
  • packages/client/src/__tests__/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultCardEndowFlow.tsx
  • packages/client/src/components/Public/VaultCardPaymentPanel.tsx
  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/shared/src/__tests__/hooks/vault/useOctantVaultWithdraw.test.ts
  • packages/shared/src/__tests__/utils/blockchain/octant-abi.test.ts
  • packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts
  • packages/shared/src/i18n/en.json
  • packages/shared/src/i18n/es.json
  • packages/shared/src/i18n/pt.json
  • packages/shared/src/utils/blockchain/abis/octant.ts
🚧 Files skipped from review as they are similar to previous changes (7)
  • packages/shared/src/tests/hooks/vault/useOctantVaultWithdraw.test.ts
  • packages/shared/src/i18n/es.json
  • packages/client/src/tests/views/VaultManagePositions.test.tsx
  • packages/client/src/components/Public/VaultCardWalletManage.tsx
  • packages/client/src/components/Public/VaultCardEndowFlow.tsx
  • packages/shared/src/i18n/en.json
  • packages/shared/src/hooks/vault/useOctantVaultWithdraw.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: Test
  • GitHub Check: Unit Tests
  • GitHub Check: Lint And Build
  • GitHub Check: Lint And Build
  • GitHub Check: Storybook
  • GitHub Check: Playwright Client CI
  • GitHub Check: CI Gate
  • GitHub Check: Test
  • GitHub Check: Playwright Admin CI
  • GitHub Check: Test
🧰 Additional context used
📓 Path-based instructions (32)
packages/shared/**

📄 CodeRabbit inference engine (.github/instructions/shared.instructions.md)

@green-goods/shared is the only home for reusable hooks, providers, stores, modules, types, i18n, and shared UI primitives

Files:

  • packages/shared/src/__tests__/utils/blockchain/octant-abi.test.ts
  • packages/shared/src/i18n/pt.json
packages/shared/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/instructions/shared.instructions.md)

Use centralized queryKeys, event-driven invalidation, useCurrentChain() or DEFAULT_CHAIN_ID, logger, and typed domain models such as Address in @green-goods/shared

Keep reusable hooks, providers, stores, modules, and shared UI primitives in @green-goods/shared

Files:

  • packages/shared/src/__tests__/utils/blockchain/octant-abi.test.ts
packages/shared/src/**/*.{tsx,ts}

📄 CodeRabbit inference engine (.github/instructions/shared.instructions.md)

Shared UI primitive changes should ship with tests, barrel updates, and Storybook coverage in the same change when applicable

Files:

  • packages/shared/src/__tests__/utils/blockchain/octant-abi.test.ts
{.github/workflows/**,**/*.test.{js,ts,jsx,tsx},**/*.spec.{js,ts,jsx,tsx}}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use bun run test, never bun test

Files:

  • packages/shared/src/__tests__/utils/blockchain/octant-abi.test.ts
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx}: Default to single-chain behavior through getDefaultChain() or DEFAULT_CHAIN_ID
Use logger from shared instead of console.log
Use bun run format:check && bun lint for code quality checks

Files:

  • packages/shared/src/__tests__/utils/blockchain/octant-abi.test.ts
  • packages/client/src/components/Public/VaultCardPaymentPanel.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use the Address type for Ethereum addresses instead of raw string types

Files:

  • packages/shared/src/__tests__/utils/blockchain/octant-abi.test.ts
  • packages/client/src/components/Public/VaultCardPaymentPanel.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
**/*.{json,ts,tsx}?(locales|i18n|translations|lang)

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Add every new user-facing string to en, es, and pt language files

Files:

  • packages/shared/src/__tests__/utils/blockchain/octant-abi.test.ts
  • packages/shared/src/i18n/pt.json
  • packages/client/src/components/Public/VaultCardPaymentPanel.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use bun run test for running tests

Files:

  • packages/shared/src/__tests__/utils/blockchain/octant-abi.test.ts
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/shared/**/*.{ts,tsx}

📄 CodeRabbit inference engine (packages/shared/AGENTS.md)

packages/shared/**/*.{ts,tsx}: Use centralized query keys from queryKeys in packages/shared. Do not invent ad-hoc query arrays.
Use useCurrentChain() or DEFAULT_CHAIN_ID for application defaults in packages/shared, not wallet chain state.
Prefer event-driven invalidation over polling in packages/shared hooks and queries.
Use logger and typed domain models (Address, discriminated unions, unknown for untrusted data) in packages/shared code.

Files:

  • packages/shared/src/__tests__/utils/blockchain/octant-abi.test.ts
**/*.test.{ts,tsx,js}

📄 CodeRabbit inference engine (CLAUDE.md)

Use bun run test instead of bun test for running tests — bun test uses bun's built-in runner (ignores vitest config), while bun run test runs the package.json script with proper vitest environment

Files:

  • packages/shared/src/__tests__/utils/blockchain/octant-abi.test.ts
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use Address type (not string) for Ethereum addresses in TypeScript across all packages

Files:

  • packages/shared/src/__tests__/utils/blockchain/octant-abi.test.ts
packages/{shared,client,admin}/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Never swallow errors — use parseContractError() + USER_FRIENDLY_ERRORS for contract errors, use createMutationErrorHandler() in shared mutation hooks, use logger from shared (not console.log)

Files:

  • packages/shared/src/__tests__/utils/blockchain/octant-abi.test.ts
  • packages/client/src/components/Public/VaultCardPaymentPanel.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

packages/**/*.{ts,tsx}: Use queryKeys.* helpers from shared for React Query key serialization — serialize objects in query keys
Do not use banned vocabulary in i18n strings (enforced by bun run lint:vocab): never use streak, countdown, leaderboard, FOMO, or growth-hacking language (urgent, limited time, re-engagement, retention hook)

Files:

  • packages/shared/src/__tests__/utils/blockchain/octant-abi.test.ts
  • packages/client/src/components/Public/VaultCardPaymentPanel.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/{contracts,agent,admin,shared}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use the Address type for Ethereum addresses.

Files:

  • packages/shared/src/__tests__/utils/blockchain/octant-abi.test.ts
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

Use logger from shared, never console.log.

Files:

  • packages/shared/src/__tests__/utils/blockchain/octant-abi.test.ts
  • packages/client/src/components/Public/VaultCardPaymentPanel.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/{client,admin,shared}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use Remixicon (Ri*Line), never lucide.

Files:

  • packages/shared/src/__tests__/utils/blockchain/octant-abi.test.ts
  • packages/client/src/components/Public/VaultCardPaymentPanel.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/{client,admin,shared}/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Any new user-facing string must be added to en, es, and pt.

Files:

  • packages/shared/src/__tests__/utils/blockchain/octant-abi.test.ts
  • packages/client/src/components/Public/VaultCardPaymentPanel.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/{client,admin,shared}/src/**/*.{ts,tsx,css}

📄 CodeRabbit inference engine (AGENTS.md)

packages/{client,admin,shared}/src/**/*.{ts,tsx,css}: Treat Baseline Widely Available as the baseline target for frontend changes. Use repo-installed Modern Web Guidance through bun run agentic:guidance before frontend, UI, CSS, accessibility, browser proof, or web-design changes.
Prefer semantic HTML, native controls, platform CSS, and browser primitives before custom JavaScript.

Files:

  • packages/shared/src/__tests__/utils/blockchain/octant-abi.test.ts
  • packages/client/src/components/Public/VaultCardPaymentPanel.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/{client,admin,shared}/src/**/*.{ts,tsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Banned vocabulary for any surface: streak, countdown, leaderboard, FOMO.

Files:

  • packages/shared/src/__tests__/utils/blockchain/octant-abi.test.ts
  • packages/shared/src/i18n/pt.json
  • packages/client/src/components/Public/VaultCardPaymentPanel.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/shared/src/i18n/{en,es,pt}.json

📄 CodeRabbit inference engine (.github/instructions/shared.instructions.md)

New user-facing strings must be added to src/i18n/en.json, src/i18n/es.json, and src/i18n/pt.json

Files:

  • packages/shared/src/i18n/pt.json
packages/shared/src/i18n/*.json

📄 CodeRabbit inference engine (packages/shared/AGENTS.md)

Add every new user-facing string to src/i18n/en.json, src/i18n/es.json, and src/i18n/pt.json in the shared package. Do not hardcode user-facing strings.

Files:

  • packages/shared/src/i18n/pt.json
packages/client/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/instructions/client.instructions.md)

packages/client/**/*.{ts,tsx,js,jsx}: Hooks, providers, and most business logic should come from @green-goods/shared in packages/client
Do not add local hooks or providers when the logic belongs in shared
Preserve the offline-first queue flow for work submission; do not bypass the queue for passkey users
Keep authentication branches on shared auth APIs and shared default-chain helpers instead of wallet chain state
Manage blob URLs through shared utilities such as mediaResourceManager; do not leave orphaned URL.createObjectURL values behind
Prefer event-driven invalidation over polling

Files:

  • packages/client/src/components/Public/VaultCardPaymentPanel.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use Remixicon (Ri*Line), never lucide for UI icons

Files:

  • packages/client/src/components/Public/VaultCardPaymentPanel.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/client/**/*.{ts,tsx}

📄 CodeRabbit inference engine (packages/client/AGENTS.md)

packages/client/**/*.{ts,tsx}: Do not create local hooks or providers in the client package when the logic belongs in @green-goods/shared
Work submission must preserve the offline-first queue flow; do not bypass the queue for passkey users
Prefer event-driven invalidation over polling
Manage blob URLs through shared utilities such as mediaResourceManager; do not leave orphaned URL.createObjectURL values behind
Authentication branches must go through shared auth APIs; do not treat wallet chain state as the source of truth for app defaults

Files:

  • packages/client/src/components/Public/VaultCardPaymentPanel.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/client/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (packages/client/AGENTS.md)

New user-facing strings must be translated in all three locale files

Client-only banned vocabulary (never use in client PWA): operator cockpit, utility copy, KPI tile, dashboard, Plus Jakarta Sans

Client only: do not use operator cockpit, utility copy, Plus Jakarta Sans, KPI tile, dashboard.

Files:

  • packages/client/src/components/Public/VaultCardPaymentPanel.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/{client,admin}/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

packages/{client,admin}/src/**/*.{ts,tsx}: ALL React hooks MUST live in @green-goods/shared — client and admin packages must not define their own hooks and should import hooks from the shared package
Import hooks from @green-goods/shared using barrel imports: import { useAuth, useGardens } from '@green-goods/shared' — never use deep paths like @green-goods/shared/src/hooks/useAuth
Contract integration: Import deployment artifacts from ../../../contracts/deployments/11155111-latest.json (or appropriate chain ID), never hardcode Ethereum addresses in code
Use isGreenWillDeployed(chainId?) from @green-goods/shared to detect when a feature contract is undeployed (zero-address) on the active chain — render a 'not available on this network' branch instead of a generic empty state
When a useMemo depends on a value written to localStorage in the same tab (e.g., pending-join membership), include usePendingJoinsVersion() from @green-goods/shared in its useMemo deps — this returns an incrementing counter that ticks on every in-tab pending-join change

Files:

  • packages/client/src/components/Public/VaultCardPaymentPanel.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/{client,admin}/src/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

When debugging user-observed UI regressions, start from the rendered surface before tracing data flow — inspect DOM geometry, computed styles (bounding rect, width/height, opacity, display, pointer-events, z-index, overflow, disabled state, selected classes, border/ring), verify click/tap changes state, then trace visible element → component → state setter

Files:

  • packages/client/src/components/Public/VaultCardPaymentPanel.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/{client,admin,shared}/src/**/*.{tsx,css}

📄 CodeRabbit inference engine (CLAUDE.md)

Design System: Load design skill (direction) + ui skill (implementation) explicitly when paradigm, layout composition, new view, tokens, or PR review is at stake — for trivial edits (padding, copy, single component touch), use the rules in CLAUDE.md

Files:

  • packages/client/src/components/Public/VaultCardPaymentPanel.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/client/src/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Client PWA uses @green-goods/shared primitives + presentation-mode loaders/PublicShell/PwaRuntime/AppShell/SiteHeader/AppBar — do not invent component names; flag missing primitives instead

Files:

  • packages/client/src/components/Public/VaultCardPaymentPanel.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/{client,admin,shared}/src/**/*.{css,scss,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Design tokens: never hardcode cubic-bezier, duration, or raw color/radius values — use --spring-* (6 motion tokens), --color-*, --radius-*, --color-material-* + --blur-material-* from theme.css

Files:

  • packages/client/src/components/Public/VaultCardPaymentPanel.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/{client,admin}/src/**/*.{tsx,css}

📄 CodeRabbit inference engine (CLAUDE.md)

Volume hierarchy: canvas 80–90% / ink 8–15% / stone 3–5% / accent green 1–3% — flooding the screen with green is the #1 design failure mode

Files:

  • packages/client/src/components/Public/VaultCardPaymentPanel.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
packages/{contracts,agent,client,admin}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Default to single-chain behavior through getDefaultChain() or DEFAULT_CHAIN_ID.

Files:

  • packages/client/src/components/Public/VaultCardPaymentPanel.tsx
  • packages/client/src/__tests__/views/PublicVaults.test.tsx
🔇 Additional comments (5)
packages/client/src/__tests__/views/PublicVaults.test.tsx (1)

1-1879: LGTM!

The test file is comprehensive and well-structured. Key observations:

  1. Mock setup (lines 56-97, 167-211): The thirdweb mocks properly extend to include sendBatchTransaction, waitForReceipt, and adminAddress for the new EIP-7702 batch transaction flow.

  2. Test coverage for new behaviors:

    • Batch transaction flow with receipt confirmation (lines 1075-1116)
    • Fallback to sequential transactions when batch fails (lines 1275-1322)
    • Admin address mismatch handling (lines 1324-1345)
    • Status polling and error handling
  3. Proper reset in beforeEach (lines 442-453) ensures mock state is clean between tests.

packages/client/src/components/Public/VaultCardPaymentPanel.tsx (2)

218-225: LGTM!

The useEffect for auto-polling status is well-designed:

  • Uses statusCheckInFlightRef to prevent concurrent API calls
  • Applies a 5s delay for pending status to avoid aggressive polling
  • Correctly stops when cardFundingComplete or statusOutcome === "error"
  • Cleanup function properly clears the timeout

32-43: LGTM!

The tabnabbing mitigation and FAILED state handling from past review comments have been properly addressed:

  • Line 33: window.open now uses "noopener,noreferrer" features
  • Lines 202-206: FAILED status correctly resets session and phase to allow retry

Also applies to: 184-216

packages/shared/src/__tests__/utils/blockchain/octant-abi.test.ts (1)

1-18: LGTM!

This test provides a useful regression guard for the redeem function's ABI structure, ensuring the input parameters maintain their expected order and types (shares, receiver, owner, maxLoss, strategies). This is important since ABI mismatches can cause silent transaction failures.

packages/shared/src/i18n/pt.json (1)

3449-3450: LGTM!

Also applies to: 3453-3453, 3485-3486, 3548-3563, 3567-3571, 3574-3574, 3586-3587, 3589-3591

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

Labels

None yet

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

1 participant