Repository navigation
feat(wallets): add self-custody support to blockchain wallets - #78
Merged
Merged
Conversation
Add is_self_custody to blockchain wallet responses and as an optional input on createWithAddress/createWithHash, a setSelfCustody method (PATCH on the customers route), and the blockchainWallet.update webhook event.
Contributor
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
…odeled The spec snapshot already carries this nested shape and map.test.ts has been failing on main because of it.
andremayer
approved these changes
Sep 30, 2026
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.
Why
BCB Resolution 588 requires us to report to COAF any transfer of US$10k or more to or from a self-custodied wallet. To do that, we need to know, per external wallet, whether the customer holds the keys. This only applies to Brazilian customers and external blockchain wallets (custodial/offramp wallets are unaffected).
The backend side is in blindpaylabs/blindpay-v2#2632: https://github.com/blindpaylabs/blindpay-v2/pull/2632
Merge order: this PR must merge (and release) only after blindpay-v2#2632 is deployed. Until then the API ignores the new input and the PATCH route does not exist.
What changed
wallets.blockchain: wallet responses (list,get,createWithAddress,createWithHash) now includeis_self_custody: boolean | null(null= never answered).createWithAddress/createWithHashaccept an optionalis_self_custody: boolean. The API requires it when the customer's country is BR (400self_custody_required).wallets.blockchain.setSelfCustody({ customer_id, id, is_self_custody })→PATCH /v1/instances/{instance_id}/customers/{customer_id}/blockchain-wallets/{id}. It can be set only once, while the value isnull; afterwards the API returns 409self_custody_already_set. Returns the wallet.blockchainWallet.updateinWebhookEvents(same payload asblockchainWallet.new)..api-sync/contract-check-allowlist.json: 6 entries foris_self_custody, since the committed spec snapshot does not have the field yet. Remove them once api-sync refreshes the snapshot after v2#2632 ships.Follow-up risk:
/receivers/→/customers/redirectThe API renamed
/receivers/to/customers/, and/receivers/now answers with a 301. Withfetch, following a 301 on a POST can turn it into a GET, which silently breaks wallet creation. On currentmainthis SDK already calls/customers/everywhere, andsetSelfCustodyuses/customers/too. Any integrator still on an older SDK major that calls/receivers/is exposed to this and should upgrade. This PR does not change any existing paths.Testing
bun run check-types: passbun run lint:check: pass (3 existing warnings, none new)node scripts/contract-check.mjs: OKbun scripts/api-sync/index.ts --check: OK, no driftbun run test: all blockchain wallet and webhook tests pass. The new tests check the method, URL and body of the PATCH, and thatis_self_custodyis sent on create. 2 failures inscripts/api-sync(map.test.tsspec-map nested shape forPayinOut, plus the golden test that re-runs the suite) also fail onmainbefore this change and are unrelated.Unrelated CI fix
scripts/api-sync/map.test.tswas failing onmainbecause the spec snapshot hastracking_payment.review_contextsonPayinOut/CreatePayinOutwith no recorded omission. Second commit records it in.api-sync/unmodeled.jsonso the suite is green (183/183 locally).