Release: develop -> main#4308
Merged
Merged
Conversation
…4228) * feat(bank-account): reload bankAccounts with specific error result * feat(bank-account): improve code
github-actions
Bot
requested review from
TaprootFreak and
davidleomay
as code owners
July 22, 2026 12:50
…W2W gas wallet (#3820) * feat(realunit): add gasless wallet-to-wallet transfer with dedicated W2W gas wallet Add user-initiated RealUnit (REALU) wallet-to-wallet transfer reusing the existing gasless EIP-7702 relay mechanism, but paying gas from a dedicated, separate W2W gas-funding wallet (never the Sell/OTC relayer). - Config: REALUNIT_W2W_GAS_WALLET_PRIVATE_KEY / _ADDRESS / _LOW_BALANCE_THRESHOLD - Thread an optional relayerPrivateKeyOverride into transferTokenWithUserDelegation (defaults to getRelayerPrivateKey, so Sell/OTC paths are unchanged) - Persist transfer intent (RealUnitTransferRequest entity + migration): the blanket EIP-7702 delegation does not bind recipient/amount, so they are stored at prepare and relayed verbatim at confirm (never from untrusted client input) - Endpoints PUT /v1/realunit/transfer and /transfer/:id/confirm (JWT + USER + active, KYC30 + registration gating, limit-exempt on-chain self-custody movement) - Balance-monitoring observer with standard low-balance mail alert - Jest specs + CONTRIBUTING route-taxonomy rows * fix(realunit): address review on W2W transfer (deterministic migration names, typed caveats, KYC context) - Use TypeORM deterministic sha1 constraint names in the transfer-request migration (PK/UQ/FK 27, IDX 26) instead of human-readable ones; update up + down - Replace the DTO message.caveats `any[]` with a typed Eip712CaveatDto (enforcer + terms) - Add KycContext.REALUNIT_TRANSFER and use it for the transfer registration/KYC exceptions instead of reusing REALUNIT_SELL - Drop the unused getW2wGasWalletBalance service method (observer reads the balance itself) - Stop loading user.userData in confirmTransfer (user is eager, userData unused) - Fix import ordering in the service spec (realunit-dev before realunit) * test(realunit): cover W2W transfer branches and relayer override to 100% Add diff-coverage for every changed executable line and branch in the W2W transfer flow: - prepareTransfer/confirmTransfer: REALU asset-not-found, W2W gas wallet key/address unset (ServiceUnavailable), bare-key 0x normalization - W2W gas observer: address-unset early return and mainnet (Ethereum) client branch - eip7702 transferTokenWithUserDelegation: unsupported-chain throw, relayer-override path (W2W key used, not getRelayerPrivateKey) and default fallback - contextRequiredSteps: REALUNIT_TRANSFER returns no extra steps - thin controller delegations for the two transfer endpoints * fix(realunit): set W2W transfer delegation delegate to the W2W gas wallet (fixes on-chain InvalidDelegate revert) * fix(realunit): align W2W prepare user load with async registration gate Registration is resolved via AktionariatRegistrationRepository on develop, so prepareTransfer only needs userData (not kycSteps). Update the thin controller spec and prettier-format the migration/CONTRIBUTING table. * fix(realunit): harden W2W transfer against double-relay, gas drain and config drift - confirmTransfer is now idempotent: atomic CREATED->PROCESSING claim, txHash persisted before broadcast (keccak256 of the signed tx), reverted receipts mark the request FAILED, and a 5-min reconciliation cron resolves stuck PROCESSING requests, so a retry/timeout/double-tap can no longer relay the blanket delegation twice. - preflight the on-chain REALU balance and re-check the W2W gas wallet funding in confirm, so an under-funded sender can no longer drain the dedicated gas wallet via reverting relays. - pin the delegation delegate to the W2W gas wallet and derive that wallet's address from its key (fail loud if REALUNIT_W2W_GAS_WALLET_ADDRESS disagrees). - key the relayer nonce lock per account so the W2W path never blocks the Sell/OTC relayer. - validate REALUNIT_W2W_GAS_LOW_BALANCE_THRESHOLD (fail loud instead of a silent NaN/0) and parse the confirm :id via ParseIntPipe. * test(realunit): stub viem keccak256 in the eip7702 sell spec The W2W hardening computes keccak256(signedTx) before broadcast; the sell spec mocks viem and must provide keccak256 (returning the mocked sendRawTransaction hash) so the post-broadcast hash assertion holds. * fix(realunit): make W2W transfer reconciliation state changes atomic - reconcile stale requests via a conditional update (status=PROCESSING, txHash IS NULL) instead of a full-entity save, so a concurrent confirm that has since persisted the txHash is never clobbered or wrongly marked FAILED - apply the same conditional, PROCESSING-guarded transition to the receipt-confirmed and reverted paths * fix(realunit): return 400 on W2W validation errors and require the gas threshold env - map EIP-7702 delegation/authorization/signature validation failures to BadRequestException (400) instead of a raw 500 on the confirm endpoint - fail loud when REALUNIT_W2W_GAS_LOW_BALANCE_THRESHOLD is unset instead of a silent 0.05 default; wire a jest env setup so specs keep constructing the config - move the transfer-request migration after the latest migration on develop * chore(migration): reorder the W2W transfer-request migration after the latest on develop * fix(realunit): return 400 for insufficient REALU balance and document the W2W gas wallet env vars - throw BadRequestException instead of ConflictException when the sender lacks enough REALU, consistent with the insufficient-gas check - add the REALUNIT_W2W_GAS_WALLET_ADDRESS / _PRIVATE_KEY placeholders to .env.example
TaprootFreak
approved these changes
Jul 22, 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.
Automatic Release PR
This PR was automatically created after changes were pushed to develop.
Commits: 1 new commit(s)
Checklist