Conversation
…ng code Para signing was retired in PR #983; this follow-up removes the now-dead surface area so Turnkey is the only wallet path. - Drop @getpara/ethers-v6-integration and @getpara/server-sdk from package.json + pnpm-lock; delete lib/para/, lib/encryption.ts (Para MPC user-share helpers), and Para spec docs. - Replace the Para-backed viem LocalAccount used by sponsored-client.ts with a Turnkey-backed adapter (lib/web3/turnkey-viem-account.ts) that signs through the Turnkey API client. Move org-scoped wallet helpers out of lib/para/ to lib/web3/wallet-helpers.ts and drop the deprecated user-id-keyed lookups. - Delete Para-only API routes (refresh-share, share) and strip the provider="turnkey" filter from export-key/verify since provider is going away. - Drop the Para columns (provider, para_wallet_id, user_share) and rename para_wallets -> organization_wallets via migration 0069. Update Drizzle schema, relations, and the prometheus / db-metrics collectors to drop the Para gauge and provider split. - Remove Para test infrastructure: delete the eip7702-spike integration test, the Para portal cleanup logic in the Playwright e2e helpers, and the seed-test-wallet / fund-test-wallet scripts. Update transaction-flow + write-contract-workflow tests to skip on missing Turnkey env (instead of missing PARA_*). - Strip PARA_* env vars from staging / prod / pr-environment helm values, the e2e GitHub workflow, and the setup-e2e-db action.
Renumbers KEEP-230 migration from 0069 to 0071 to land after staging's 0069_add_feedback_table and 0070_workflow_executions_billable. Restores the Turnkey-rewritten seed-test-wallet script that staging maintains for E2E (retargeted onto organization_wallets and stripped of the dropped provider column) along with its db:seed-test-wallet npm script. Cleans up remaining para_wallets references in agentic-wallet-workflow-binding test mock, playwright cleanup util, and schema-extensions header.
Renumbers KEEP-230 migration from 0071 to 0072 to land after the new 0071_keep_470_workflow_tx_hash_array migration on staging.
Renumbers KEEP-230 migration from 0072 to 0077 to land after staging's 0072-0076 (workflows seeded_at, executions error classification, soft delete, db indexes, wallet integration name backfill). Fixes stale @/lib/para/wallet-helpers imports in plugins/web3/steps/sign-typed-data-core.ts and two test mocks that were added on staging after this branch deleted that path; retargets them to @/lib/web3/wallet-helpers. Keeps both halves of the package.json scripts conflict so staging's db:seed-workflows + db:seed-all coexist with the restored db:seed-test-wallet entry that db:seed-all depends on. Restores staging's SYSTEM_ACTIONS/TEMPLATE_SYNTAX/TRIGGERS imports in app/api/mcp/schemas/route.ts.
Renumbers KEEP-230 migration from 0077 to 0079 to land after staging's 0077_keep_575_schedule_interval and 0078_error_type_label_rename.
Renumbers KEEP-230 migration from 0079 to 0082 to land after staging's 0079 safe_wallet_integration, 0080 safe_role direct rules, and 0081 address_book unique address. Fixes stale @/lib/para/wallet-helpers imports in three new Safe-related files added on staging (lib/safe/deployment.ts, roles-orchestrator.ts, signer-resolver.ts) and three test mocks; retargets them all to @/lib/web3/wallet-helpers. Restores db:seed-test-wallet npm script that staging's db:seed-all depends on, and keeps staging's test:protocol path move into tests/e2e/vitest/protocol-coverage.
Removes .claude/scheduled_tasks.lock and deploy/local/observability/ from the index. Both are local developer state, not PR content.
Para has been fully removed; the comment claiming the Safe owner could be a Turnkey or Para row was leftover from the dual-provider era.
paraWallets schema mock and the provider field on the wallet fixture are no longer read by anything; the schema export is gone and the column is dropped by migration 0082.
Postgres auto-rewires the FK target on RENAME TABLE but keeps the constraint name. Renaming the constraint here avoids a future drizzle-kit generate emitting a one-line rename migration of its own. Idempotent via pg_constraint lookup so reruns are safe.
Also drop WALLET_ENCRYPTION_KEY everywhere it was forwarded: the only consumer was the deleted lib/encryption.ts (Para MPC user-share helpers), so the executor config field, the k8s-job env propagation, the GitHub Actions composite (start-app/wallet_encryption_key input, e2e-tests-ephemeral.yml forwarding) and the helm values for staging / prod / pr-environment / executor / local-dev are all dead config now. Resolve conflicts: - app/api/user/wallet/export-key/request/route.ts -> accept staging's deletion (the endpoint was retired with the dual-factor MFA flow). - app/api/user/wallet/export-key/verify/route.ts -> keep staging's TOTP-only verify flow; the email-OTP code that this branch was cleaning up is now gone entirely. - app/api/user/wallet/withdraw/route.ts -> take staging's new requireOwnerWithMfa + helper imports, but point them at the new lib/web3/wallet-helpers path instead of the deleted lib/para path. - keeperhub-executor/startup-checks.ts -> keep staging's ephemeral-env downgrade + query timeout, but drop the provider="turnkey" filter since the provider column is being removed by migration 0092. - drizzle/meta/_journal.json -> renumber the Para decom migration from 0082 to 0092 to land after all of staging's interleaved migrations, and rename drizzle/0082_keep_230_decom_para.sql accordingly. - pnpm-lock.yaml -> take staging's lockfile and regenerate so the @getpara/* entries stay out and staging's additions are picked up. Drop specs/integration-based-wallet-creation.md (entirely Para-flow documentation, replaced by the Turnkey path) and update tests/README.md to point at the Turnkey provisioning env vars instead of the Para user-share / WALLET_ENCRYPTION_KEY pair.
Hard-grep sweep across the repo after the staging merge for any Para-flavoured strings the previous commits missed. - Spec docs: delete the historical Para handover / migration docs (organizations_migration_handover, wallet-migration-todo, organization-wallet-execution) that documented the Para-era flow end-to-end; rewrite the surviving organization / wallet-overlay specs and the logging-and-metrics example to use Turnkey naming and /lib/web3/wallet-helpers paths. - Executor helm charts (prod + staging + pr-environment): drop the PARA_API_KEY parameterStore entry and the PARA_ENVIRONMENT kv entry alongside the WALLET_ENCRYPTION_KEY removal. - Local dev: strip the PARA_API_KEY / PARA_ENVIRONMENT / NEXT_PUBLIC_PARA_* kv stanzas from values-keeperhub.template.yaml and the matching sed substitutions + help text from deploy.sh. - PR seed verifier: query organization_wallets instead of para_wallets. - Tests: drop the paraWallets mock from safe-roles-orchestrator and the stray "ParaWallet" comment in lib/auth.ts permissions config.
…aming The org-scoped wallet model documented here is still load-bearing architecture; only the signer backend changed Para -> Turnkey. The previous sweep deleted the file along with the genuinely obsolete handover / migration docs, which removed useful design context. Bring it back and rename the Para references inline: - initializeParaSigner -> initializeWalletSigner - Para signer -> Turnkey signer - ParaWallet / Para wallet -> Wallet - para_wallets -> organization_wallets - keeperhub/lib/para/wallet-helpers.ts -> lib/web3/wallet-helpers.ts
chore: KEEP-230 remove Para SDK and supporting code
…agers Replaces the email OTP <input> in DualFactorSteps with a contenteditable div so 1Password, Bitwarden, LastPass and Dashlane have no element to autofill. Data-* opt-outs were not enough: 1Password's TOTP-fill heuristic kept landing the authenticator code in the email slot because the only visible field on step 1 was a 6-digit numeric input. Password manager content scripts only target input/textarea/select, so a div with role="textbox" and inputMode="numeric" is fundamentally outside their reach while preserving the mobile numeric keyboard and visual parity with the existing Input component.
The contenteditable div was using flex justify-center, which centers child boxes but not the caret of an empty editable region — so the cursor sat at the far left. Switch to block + text-center and use text-indent to absorb tracking's trailing letter-space so the placeholder and typed digits also appear visually centered.
Enter in the contenteditable was inserting a newline. Suppress the default and trigger the Continue action when the 6-digit email code is ready, matching how a real <input type=text> in a form behaves.
Adds sanitizeNextPath which whitelists the value before it is fed back into the browser as a redirect. Rejects /monitoring (Sentry tunnel), /api/*, /_next/*, protocol-relative URLs, parent-traversal segments, and percent-encoded variants of any of those, falling back to "/" so the worst case is the home page rather than a dead-end internal route that 404s with the URL pinned in the address bar. Applied at every read site: the verify-mfa, verify-ip, and enroll-mfa pages, the OAuth callback intercept that builds the verify-mfa redirect, the OAuth-MFA and verify-IP finalize routes, and the client-side guard handler that captures window.location before bouncing to step-up. Also two local-dev helper scripts under scripts/miscellaneous: reset-mfa wipes a user's TOTP enrollment so they can re-enroll, and peek-email-otp decrypts the live email OTP from the verifications table using BETTER_AUTH_SECRET. Both refuse to run unless DATABASE_URL points at a localhost host.
These were committed by mistake. Both are local-debug utilities only, not appropriate for the repo. The OTP-peek script in particular documents the BETTER_AUTH_SECRET decrypt path against the verifications table, which we should not ship even with a localhost guard. Keep them out of tree; recreate locally as needed.
Extracts the contenteditable email-OTP slot from DualFactorSteps into a shared EmailOtpField component and applies it to the credentials-signin dialog's signin-email-otp view. The previous <Input autoComplete= "one-time-code" /> there was the actual bypass: 1Password's TOTP heuristic filled the 6-digit slot with the authenticator code and the surrounding <form> auto-submitted, advancing the wizard past step 1 without the user typing anything. Replacing the element with a div contentEditable puts the field outside the autofill domain so this cannot happen. Also fixes the SignInStepIndicator so the done step no longer paints in green: only the current step renders with the green bubble, matching DualFactorSteps. Done and pending labels are plain foreground (no muted gray) per design ask. Includes temporary [signin-flow] console.info breadcrumbs on the strict-signin start, the signin-email-otp submit, and the totp submit so the bypass can be reproduced and confirmed fixed end to end. Will be stripped before merge.
Swaps the email-OTP <Input autoComplete=one-time-code> for the
contenteditable EmailOtpField on the two remaining surfaces that pair
an email code with a TOTP code in the same flow:
- DualFactorInput (the always-mounted email + TOTP variant used by
settings/account-settings and overlays/api-keys-overlay).
- Forgot-password Reset Code in the auth dialog. The sibling
Authenticator code input on that same view is left as-is because
1Password autofill IS desired for the TOTP slot.
Standalone single-factor email-only surfaces (signup verify,
accept-invite) are intentionally not changed: the user has not enrolled
TOTP yet, so there is no second 6-digit field on the page for 1Password
to confuse with the email code.
Also strips the [signin-flow] console.info breadcrumbs added in the
previous commit now that the email-step bypass is confirmed fixed.
Adds <meta name="google" content="notranslate"> via the Metadata.other field plus translate="no" on the root <html> element. External translators (Chrome's built-in translator and translation extensions) swap text nodes in place; React's fiber tree keeps pointing at the original parents, so the next insertBefore/removeChild commits throw NotFoundError and crash the route. Three production Sentry groups (insertBefore on /, removeChild on / and on /workflows/:workflowId) share the same fingerprint: zh-CN locale, Asia/Shanghai timezone, no first-party frames in the stack, all manifesting on the same client. This is the canonical react/react#11538 pattern.
…ofill fix(auth): dual-factor email step hardening and redirect sanitization
…nd-translation fix(layout): opt out of in-page translation to stop React DOM crashes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.