Skip to content

Create new production release - #1369

Merged
ebma merged 64 commits into
mainfrom
staging
Sep 11, 2026
Merged

ebma merged 64 commits into
mainfrom
staging

Conversation

@ebma

@ebma ebma commented Sep 11, 2026

Copy link
Copy Markdown
Member

No description provided.

ebma added 30 commits July 13, 2026 11:08
Renumber the Monerium B2B migrations 051/052 to 069/070 past staging's
current head (068); README additions ported into the rewritten layout.
The workspace and its scripts were committed without the matching bun.lock
entry, so frozen-lockfile installs failed on this branch.
With the models registered, the postgres dropTable assigns
options.supportsSearchPath during ENUM-type cleanup and throws on an
undefined options argument. The migrator test suite now reverts across
this migration (revertMigration to 066), so a bare dropTable aborted
down() midway and left the schema partially dropped for every later
integration suite.
Corporates that Monerium onboards to the whitelabel app under the
partner's KYC reliance enter Vortex through an idempotent admin
endpoint: it provisions the managed child (business entity), mirrors
the approved KYB into provider_customers/kyc_cases, and binds the
deployed forwarder as a monerium account owned by that profile via the
new vortex_profile_id link. Divergent replays are conflicts, never
overwrites; pre-mapping account rows are adopted when they match.
The keeper now advances every mapped onboarding account: attestor-signed
address link and IBAN request run through the profile-scoped
financial_operations ledger (exactly-once across crashes and retries),
and the issued IBAN is recorded from the iban.updated webhook without
ever overwriting an existing one (an IBAN change is the association
monitor's alert condition). Activation after the penny test moves from
raw SQL to an admin status endpoint gated on the issued IBAN.
GET /v1/monerium-b2b/account and /deposits let the partner manager (via
X-Managed-Profile-Id delegation) or the child's own credential poll the
account state and deposit-to-conversion history. Strictly effective-user
scoped with the standard EU/business managed-profile policy; R09
unattributed inflows never surface. Docs and security spec updated for
the EU corridor's B2B account scope.
DEPOSIT_RECEIVED and DEPOSIT_CONVERTED extend the webhook contract for
business EUR onramp accounts: quoteless envelopes carrying the deposit
and its conversion outcome, deliverable to the account's controlling
manager. Existing transaction payloads are unchanged.
Deposit-family subscriptions register without a quote or session, are
profile-owned only, and can never be mixed with transaction events or
silently defaulted. Delivery goes through a new durable outbox
(webhook_deliveries + claim-based dispatch worker with backoff, no
webhook deactivation on outages) instead of the in-process retry loop.
The monerium keeper emits DEPOSIT_RECEIVED at mint and DEPOSIT_CONVERTED
at the 32-block notification depth, marked per deposit so each event
fires exactly once and history never replays to late subscribers. Also
fixes the webhook model validator that still hardcoded the legacy event
pair.
The webhooks page gains the deposit-event family (registration rules,
payload examples, durable at-least-once delivery semantics), the
managed-profiles page narrows its no-webhooks statement to transaction
events, and security-spec invariant 9 records the manager-owner
delivery branch and the outbox.
The controller's own quoteId/sessionId presence check fired before the
service's account-family branch, so the documented deposit-event
registration always returned 400. The service owns that validation
(transaction events need exactly one target, deposit events none); the
new HTTP-level regression test goes through the real route, which the
service-level tests bypassed.
ebma and others added 25 commits August 26, 2026 10:53
Every open parameter gets a concrete recommendation to accept or
overrule before deploy; T1 is rewritten as an open three-way decision,
recording the pilot-only permissive-validator option under
consideration together with the redeem-path and custody tradeoffs it
carries.
One maintained end-to-end picture — onboarding and deposit-to-payout
sequences, batching semantics, fee immutability, and the data model —
with the security spec, registry, and runbooks as the detail layers.
A deposit bigger than perSwapCap could never be selected for any
execution (eureIn is capped and only shrinks as the balance drains), so
it stayed unallocated forever and head-of-line blocked attribution for
every deposit behind it — DEPOSIT_CONVERTED never fired even though the
funds converted correctly on chain. An oversized oldest deposit now
attaches to the execution that begins converting it, with its pro-rata
share clamped to the swapped amount so the allocation still sums
exactly. Found while walking a worked example, not by the review.
P11 records the guardian-settable feeBps direction (timelocked
increases, MAX_FEE_BPS cap) pending the 24h-vs-48h timelock choice; O1
records the backend-enforced migration procedure and why an on-chain
timelock cannot gate an IBAN move.
P11 decided (Marcel, 2026-08-26): feeBps becomes guardian-adjustable
within the immutable MAX_FEE_BPS. Increases announce on-chain and apply
permissionlessly only after FEE_INCREASE_TIMELOCK (24 h), so a client
whose SEPA transfer is in flight cannot be swapped under a silently
higher fee; decreases and cancel-via-restate are immediate. The
invariant suite's config-integrity check now tracks every legal fee
transition through a ghost model instead of asserting immutability, and
the backend config monitor reconciles guardian fee changes like other
authorized transitions instead of alarming.
System map, onboarding and deposit-to-payout sequence diagrams,
watcher/cursor mechanics, lifecycle state diagrams, an ER view of the
data model, and the monitoring section — plus explicit labeling that
the monerium_* tables belong exclusively to the B2B flow (the legacy
OAuth integration owns no tables).
The forwarder whitelists the exact link/recovery message hashes, so an
unannounced message change on Monerium's side fail-closes onboarding of
new clients; an advance-notice obligation makes that a planned
implementation update instead of a surprise outage.
The shared MoneriumApiService is now the single Monerium transport: the
B2B module's internal whitelabel client is deleted and onboarding and
monitoring call the shared client through a narrow adapter, keeping the
dependency-injection seams intact. Credentials consolidate on
MONERIUM_WHITELABEL_CLIENT_ID/SECRET and MONERIUM_API_URL (one whitelabel
app = one credential set); MONERIUM_B2B_* keeps only the chain/keeper
settings. The attestor's link message now aliases the shared constant so
the signed and transmitted bytes cannot drift.
The committed vortex.openapi.d.ts predated a path reordering in
vortex.openapi.json, so docs:api:check failed on a clean tree; this is
the pinned generator's output for the unchanged spec.
Monerium confirmed (verbally, 2026-08-26) that issuer recovery presents
the same 'I hereby declare that I am the address owner.' message as
linking, whose hash the forwarder already whitelists: recovery works
with the constrained validator as built, RECOVERY_HASH stays zero, and
the pilot permissive-validator option is withdrawn. Written
confirmation folds into G1 item 3. Also adds the O2 registry row: the
immutable FEE_RECIPIENT treasury address and guardian key custody are
deploy-time decisions.
P8 was decided 2026-07-17 (Chainlink EUR/USD weekend gaps observed up
to 48h) and confirmed final today; the unit/fork/invariant configs
still carried the 26h placeholder that would revert most weekends.
The docs/prd working set and docs/runbooks are absorbed into four
maintained documents per docs/README.md rules: adr-0005 (decisions,
final parameter registry, accepted risks), the architecture doc,
operations-monerium-b2b-rollout (gates, deploy checklist, terms
inputs), and operations-monerium-b2b-runbook (onboarding, incidents,
triage, dormancy, migration). The consumer PRD survives as
proposal-monerium-consumer-onramp; everything else lives in git
history. All code and spec cross-references repointed.
The site emitted no description or og:* tags, so LinkedIn, X, Slack and
messaging apps could not build a link preview for vortexfinance.co. The
og:image is the existing 512px mark padded to 1200x630 on white so the
preview works today; swap in a designed asset at public/og-image.png
without touching code.
The placeholder was the 32px circle icon upscaled to 1200x630, so link
previews were visibly pixelated. Render the navbar wordmark (blue.svg,
recolored white) on the landing page's blue-950 background instead.
Monerium B2B onramp: forwarder contracts, keeper, managed-profile wiring, and deposit webhooks
Add Open Graph meta tags for link previews
@netlify

netlify Bot commented Sep 11, 2026

Copy link
Copy Markdown

Deploy Preview for vortexfi ready!

Name Link
🔨 Latest commit d6e5435
🔍 Latest deploy log https://app.netlify.com/projects/vortexfi/deploys/6aa410f834c18e0008ad62a1
😎 Deploy Preview https://deploy-preview-1369--vortexfi.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@ebma
ebma merged commit 37d8f16 into main Sep 11, 2026
6 of 7 checks passed
@netlify

netlify Bot commented Sep 11, 2026

Copy link
Copy Markdown

Deploy Preview for vrtx-dashboard canceled.

Name Link
🔨 Latest commit d6e5435
🔍 Latest deploy log https://app.netlify.com/projects/vrtx-dashboard/deploys/6aa410f9e9df000008bcd877

@netlify

netlify Bot commented Sep 11, 2026

Copy link
Copy Markdown

Deploy Preview for vortex-sandbox ready!

Name Link
🔨 Latest commit d6e5435
🔍 Latest deploy log https://app.netlify.com/projects/vortex-sandbox/deploys/6aa410f94abcd6000860d7c2
😎 Deploy Preview https://deploy-preview-1369--vortex-sandbox.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

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.

2 participants