Skip to content

Neobank demo - #9853

Open
georgeweiler wants to merge 72 commits into
mainfrom
neobank-demo
Open

Neobank demo#9853
georgeweiler wants to merge 72 commits into
mainfrom
neobank-demo

Conversation

@georgeweiler

@georgeweiler georgeweiler commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Explanation

References

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

High Risk
New identity/KYC orchestration, credential decryption, wallet signing, and neobank registration touch auth, PII, and money flows; large surface area with many async race/reset guards to validate in review.

Overview
Introduces @metamask/kyc-controller as a platform-agnostic package that orchestrates Universal KYC across MetaMask clients: KycController (phase machine, MoonPay Check/Auth frames + crypto, SumSub via injected launcher) and KycService (UKYC HTTP, optional separate neobank base URL).

Money / neobank path: Adds an Iron vendor flow that skips MoonPay frames—Iron customer + disclaimers, POST /consents, GET /kyc/status with refreshKycStatus / statusChanged polling—and registerMoneyAccountWallet, which resolves the MoonPay/Iron customer, signs a Monad ownership message, and registers via neobank-proxy (409 reconciliation, idempotency, UTC date rollover in messages). getCustomerIdentity exposes a session-scoped vendor customer id without reading full state.

Tooling & monorepo: Package dependencies and scripts (build:watch, mint:ukyc-token CLI), ARCHITECTURE.md, expanded CHANGELOG, Universal KYC CODEOWNERS, README dependency graph edges, and ESLint relaxations for packages/kyc-controller/scripts. transaction-pay-controller gains a money_account_utils dependency link in the root README graph.

Reviewed by Cursor Bugbot for commit b0d70fa. Bugbot is set up for automated code reviews on this repo. Configure here.

Akaryatrh and others added 30 commits July 24, 2026 12:26
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
…b flow opening

Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
… been reset

Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
@georgeweiler
georgeweiler requested review from a team as code owners August 12, 2026 21:41
@georgeweiler
georgeweiler deployed to default-branch August 12, 2026 21:41 — with GitHub Actions Active
@georgeweiler

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-previews

@socket-security

socket-security Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedchokidar-cli@​3.0.09910010083100

View full report

@socket-security

socket-security Bot commented Aug 12, 2026

Copy link
Copy Markdown

Caution

MetaMask internal reviewing guidelines:

  • Do not ignore-all
  • Each alert has instructions on how to review if you don't know what it means. If lost, ask your Security Liaison or the supply-chain group
  • Copy-paste ignore lines for specific packages or a group of one kind with a note on what research you did to deem it safe.
    @SocketSecurity ignore npm/PACKAGE@VERSION
Action Severity Alert  (click "▶" to expand/collapse)
Block Medium
System shell access: npm chokidar-cli in module child_process

Module: child_process

Location: Package overview

From: packages/kyc-controller/package.jsonnpm/chokidar-cli@3.0.0

ℹ Read more on: This package | This alert | What is shell access?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should avoid accessing the shell which can reduce portability, and make it easier for malicious shell access to be introduced.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/chokidar-cli@3.0.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn Low
Potential code anomaly (AI signal): npm chokidar-cli is 90.0% likely to have a medium risk anomaly

Notes: This module is a straightforward wrapper that spawns a shell to execute a provided command string. It is not itself malware, but it provides a high-impact sink: direct execution of arbitrary shell commands. If cmd is derived from untrusted input, this is a clear command-injection vulnerability. There is no obfuscation or evidence of deliberate malicious behavior in the file. Treat any use of run with untrusted input as dangerous and sanitize or avoid passing raw user input into the cmd parameter.

Confidence: 0.90

Severity: 0.60

From: packages/kyc-controller/package.jsonnpm/chokidar-cli@3.0.0

ℹ Read more on: This package | This alert | What is an AI-detected potential code anomaly?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: An AI system found a low-risk anomaly in this package. It may still be fine to use, but you should check that it is safe before proceeding.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/chokidar-cli@3.0.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn Low
Potential code anomaly (AI signal): npm y18n is 68.0% likely to have a medium risk anomaly

Notes: The code is a standard local i18n helper that caches locale strings and writes updates to disk. It does not contain obvious malware or backdoors. However, there are security concerns related to unvalidated locale inputs, potential path traversal when locale is attacker-controlled, and race conditions in multi-process environments. If used in attack-prone contexts, these issues should be mitigated by validating locale values, constraining file paths within the intended directory, and optionally disabling auto-write-back (updateFiles=false) in high-risk deployments.

Confidence: 0.68

Severity: 0.58

From: ?npm/chokidar-cli@3.0.0npm/y18n@4.0.3

ℹ Read more on: This package | This alert | What is an AI-detected potential code anomaly?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: An AI system found a low-risk anomaly in this package. It may still be fine to use, but you should check that it is safe before proceeding.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/y18n@4.0.3. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn Low
Potential code anomaly (AI signal): npm yargs is 61.0% likely to have a medium risk anomaly

Notes: The module implements a standard extends resolution with circular-extends protection and recursive merging. Primary security concerns are the potential execution of arbitrary code when extends points to a JS module and possible disclosure of local files via path-based extends. Treat untrusted inputs as a high-risk factor; consider enforcing whitelisting of allowed extends or sandboxing JS module extends. Overall risk is moderate due to code execution potential from untrusted configuration sources.

Confidence: 0.61

Severity: 0.58

From: ?npm/chokidar-cli@3.0.0npm/yargs@13.3.2

ℹ Read more on: This package | This alert | What is an AI-detected potential code anomaly?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: An AI system found a low-risk anomaly in this package. It may still be fine to use, but you should check that it is safe before proceeding.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/yargs@13.3.2. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn Low
Potential code anomaly (AI signal): npm yargs is 68.0% likely to have a medium risk anomaly

Notes: The provided code consists of harmless-looking shell completion templates used to generate Bash/Zsh completions by querying the application for possible commands via --get-yargs-completions. There is no malicious behavior evident in the template code itself. The main risk is dependency on the integrity of the app_path binary that provides completions; if that binary is compromised, it could influence completions or run unintended commands. Overall, low likelihood of malware in these templates themselves.

Confidence: 0.68

Severity: 0.60

From: ?npm/chokidar-cli@3.0.0npm/yargs@13.3.2

ℹ Read more on: This package | This alert | What is an AI-detected potential code anomaly?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: An AI system found a low-risk anomaly in this package. It may still be fine to use, but you should check that it is safe before proceeding.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/yargs@13.3.2. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

Comment thread packages/kyc-controller/src/KycController.ts
Comment thread packages/kyc-controller/src/KycController.ts
Autoramp creation needs the MoonPay customer id, which is owned by
KycController and captured from the Check/Auth frames. Rather than have
the UI read and plumb it, expose a narrow KycController:getCustomerIdentity
action returning the vendor-scoped { vendor, id } (or null before auth and
after reset), so consumers do not need access to the full KYC state, which
also holds session and access tokens.

RampsController.createAutoramp resolves that identity over the messenger,
injects customer_id into the request, forwards the body to
NeoBankService:createAutoramp, and applies the returned snapshot. The id is
session-scoped and is never persisted by RampsController.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread packages/kyc-controller/src/KycController.ts
@georgeweiler

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-previews

@amitabh94

Copy link
Copy Markdown
Contributor

KYC + Iron status on this demo branch: feat/kyc-controller is an ancestor, and Iron feature commit a40fa2fc3f is already merged here. Follow-up #9855 brings the remaining Iron CI lint/oxfmt fixes onto neobank-demo so preview/mobile pins match the Iron tip.

For mobile demo consumers: after #9855 merges, comment @metamaskbot publish-preview here (or on #9855) to publish @metamask/kyc-controller (and sibling packages as needed) for a mobile pin onto demo/vba-kyc.

## Summary
- `neobank-demo` already includes Sébastien’s `feat/kyc-controller`
stack and the Iron feature commit from #9852 (`a40fa2fc3f`, merged by
George).
- This PR cherry-picks the remaining #9852 CI fixes (`lint` / changelog
PR link / `oxfmt`) so the demo branch matches the Iron tip for package
publish/preview and mobile consumption.
- Keeps #9852 targeting `feat/kyc-controller` for the eventual mainline
path via #9615. Does **not** merge to `main`.

## Context (demo topology)
- Integration branch: `neobank-demo` (owner: @georgeweiler) — umbrella
PR #9853 → `main`
- Iron feature PR (mainline stack): #9852 → `feat/kyc-controller`
- KYC controller PR: #9615 → `main`

## Test plan
- [ ] Confirm diff is formatting/lint/changelog only (no Iron behavior
change)
- [ ] CI green on this PR
- [ ] After merge, `@metamaskbot publish-preview` on #9853 (or this PR)
if mobile needs a preview pin of `@metamask/kyc-controller`


Made with [Cursor](https://cursor.com)

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
@amitabh94

Copy link
Copy Markdown
Contributor

@metamaskbot publish-preview

georgeweiler and others added 6 commits August 12, 2026 16:35
The constant was annotated with the full RampsService/TransakService/
NeoBankService action unions, so spreading it into a messenger delegation
widened the element type to every service action. Hosts that only delegate
the actions RampsController actually calls (mobile) failed to typecheck once
NeoBankService grew Pix and quote methods.

Use `as const satisfies` so the type is the literal members while still being
checked against the service action unions. Also record the kyc-controller
dependency in the tsconfig project references so the package builds.

Co-authored-by: Cursor <cursoragent@cursor.com>
…demo

Keeps both sides of the KYC surface: the demo's `getCustomerIdentity`
action and the incoming Money Account wallet registration APIs.

Adds the missing `keyring-controller` project reference to the
kyc-controller tsconfigs, which the incoming ownership-message signing
imports but did not declare.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add an address-only KycController action that resolves the MoonPay customer, signs a Monad ownership proof, and registers the wallet through the MetaMask proxy.
Retarget Money Account self-hosted wallet registration from kyc-api
/vendors/moonpay/* to onramp-api neobank-proxy /neobank/... so Core
matches Money Movement ownership and transparent proxy semantics.
Prefer KycController identity when present, otherwise map the Profile
Sync id through NeoBankService.getCustomerByExternalId so autoramp
creation works before KYC has cached a MoonPay customer id.

Co-authored-by: Cursor <cursoragent@cursor.com>
Reconciles the independently pushed wallet-registration commits with the
local merge of feat/moonpay-wallet-registration-stacked.

Co-authored-by: Cursor <cursoragent@cursor.com>

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b0d70fa. Configure here.

throw new Error(
'Cannot create autoramp: wallet is not signed in to Profile Sync.',
);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Wrong profile id for customer lookup

High Severity

resolveAutorampCustomerId falls back to profile.profileId for the neobank external_id lookup, but MoonPay customers are keyed by the MetaMask canonical profile id. After multi-SRP pairing those values can diverge, so autoramp creation can fail to find a mapped customer even when one exists. The KYC path already prefers canonicalProfileId (with profileId only as fallback).

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit b0d70fa. Configure here.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants