Recurring Executor (new module):
- Server-managed relayer keypair derived deterministically via HKDF
- Checks on-chain ERC-20 allowance before pulling funds
- Executes transferFrom when subscriptions are due
- Supports Base, Base Sepolia, and Ethereum mainnet
New API Endpoints:
- GET /api/payments/:id/subscription-info — returns relayer address and
approve calldata for the client to authorize recurring pulls
- POST /api/payments/:id/subscribe — registers a subscription after
payer approves on-chain allowance, verifies allowance exists
Scheduler Upgrade:
- Attempts automated pull first for subscriptions with approved allowance
- Falls back to email reminder if auto-pull fails or is not configured
- Sends branded receipt email after successful automated payments
- Extracted email templates into reusable helper functions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Layer 1 — Schema & History:
- Added PaymentRecord type for individual payment tracking
- Added interval (weekly/biweekly/monthly/quarterly/yearly), nextDueAt,
subscriberEmail, and paymentHistory[] to PaymentRequestMeta
- Payment history records txHash, method, amount, paidAt for each payment
Layer 2 — Server-Side Scheduler:
- Hourly subscription reminder scheduler sends email notifications
when recurring payments are due (based on nextDueAt)
- nextDueAt auto-computed after each successful subscription payment
- Grace period prevents duplicate reminders
- Branded HTML reminder emails with "Pay Now" button
UI Updates:
- Billing interval selector (weekly through yearly) shown for
subscription and payer_choice payment types
- Payment page shows subscription badge with interval and history count
- Next due date displayed for active subscriptions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace parseFloat * 10^decimals with string-based decimal parsing to
avoid precision loss for 18-decimal tokens (ETH). Affects both MetaMask
and EncryptID payment paths.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Payment schema now includes creatorUsername, displayed alongside the
truncated wallet address on the payer-facing payment page
- New "Share by email" feature on the payment request page: enter
comma-separated emails to send branded payment links via email
- New POST /api/payments/:id/share-email endpoint with HTML email template
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wallets stored in local WalletStore are now bidirectionally synced with
the encrypted AccountVault on the server. On login, vault wallets are
restored to the local store; on wallet changes, local state is pushed
back to the vault. The server user profile wallet_address is also set
on login so mobile devices (without PRF) get the address via JWT.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add intermediate breakpoints (960px, 1024px, 900px, 640px, 600px) for tablets and fold
devices across all 12 rApp components. Add touch-action: manipulation and
-webkit-tap-highlight-color to eliminate 300ms tap delay. Fix undersized tap targets
(<36px) in rtasks, rfiles, rinbox, and rcart. Replace HTML5 drag API with pointer events
in rtasks kanban and rchoices ranking for touch/pen/mouse parity. Replace mouseenter/
mouseleave with pointerenter/pointerleave in rchoices spider chart with click toggle.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The sendVerificationEmail function was hardcoding noreply@ridentity.online
as the sender, but SMTP authenticates as noreply@rspace.online. Mailcow
rejected the mismatch with 553 "Sender address rejected: not owned by user".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add intermediate breakpoints (960px, 1024px, 900px, 640px, 600px) for tablets and fold
devices across all 12 rApp components. Add touch-action: manipulation and
-webkit-tap-highlight-color to eliminate 300ms tap delay. Fix undersized tap targets
(<36px) in rtasks, rfiles, rinbox, and rcart. Replace HTML5 drag API with pointer events
in rtasks kanban and rchoices ranking for touch/pen/mouse parity. Replace mouseenter/
mouseleave with pointerenter/pointerleave in rchoices spider chart with click toggle.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Payment page now shows recipient info and available payment methods
- Testnet chains show staging environment disclaimer
- Transak widget receives effective amount for editable-amount payments
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
WebAuthn PRF extension is unsupported on most mobile browsers, causing
"Could not derive wallet address" error. Added 3-layer fallback:
1. Client-side PRF derivation (desktop)
2. Server-side wallet lookup via session API
3. DID-based deterministic address provisioning
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The sendVerificationEmail function was hardcoding noreply@ridentity.online
as the sender, but SMTP authenticates as noreply@rspace.online. Mailcow
rejected the mismatch with 553 "Sender address rejected: not owned by user".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sends an HTML email with payment details, rFlows CTA, and resource links
when a card/Transak payment completes. Fire-and-forget (never blocks response).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Payment pages (folk-payment-page, folk-payment-request, folk-group-buy-page)
had zero or minimal media queries — now stack headers, reduce padding, and
resize iframes for 375px viewports. Other rApp dashboards (rchoices, rwallet,
rnotes, rfiles, rinbox, rforum, rtasks, rvote) gain consistent 768px/480px
breakpoints: collapsing grids to 1-column, shrinking fonts and padding, and
stacking flex rows on mobile. Also adds folk-payments-dashboard to the flex
centering rule in cart.css.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pass fiatAmount, defaultFiatAmount, fiatCurrency, and defaultFiatCurrency
to the Transak widget URL so users see the transaction total immediately
without manual entry. Applied to both rcart payment sessions and rflows
onramp adapter.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Swap interaction model: click+drag is now marquee selection (was pan),
hold-and-drag or space/middle-click is pan
- Ctrl+A / Cmd+A selects all visible shapes on the canvas
- Deleting more than 5 elements shows a confirmation dialog requiring
the user to click DELETE to proceed
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add getTransakApiKey() and getTransakWebhookSecret() helpers that
resolve TRANSAK_API_KEY_STAGING or TRANSAK_API_KEY_PRODUCTION based
on TRANSAK_ENV, with fallback to legacy TRANSAK_API_KEY. All consumers
(rcart, rflows, transak-onramp) now use the shared helpers instead of
reading env vars directly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The rspace module's outputPaths caused renderModuleSubNav to render an
unwanted "rspace | Canvases" bar across the canvas. Skip subnav for the
root rspace module since the canvas has its own chrome.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Switch TRANSAK_ENV default from PRODUCTION to STAGING in shared/transak.ts,
docker-compose.yml, and rflows config endpoint. All card purchases now
route through Transak's staging gateway until production is ready.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Every EncryptID identity has two wallets: a CRDT wallet (DID-based for
local tokens) and an EVM wallet (passkey-derived for on-chain tokens).
The My Wallets tab now always shows both in a dedicated EncryptID card
with distinct sections, rather than burying CRDT tokens as a subsection
that only appears when balances are non-empty.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Restructure rWallet with a top-level tab system: "My Wallets" (default
for authenticated users) shows wallet cards with on-chain balances and
CRDT tokens, while "Wallet Visualizer" preserves existing explore-any-
address functionality. View Flows button bridges the two tabs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix z-index (9000 → 10001) so popup renders above header and tab bar
- Center popup as a proper modal with blurred backdrop overlay
- Header now shows module emoji icon + name (fetched from API)
- Bigger, bolder CTA buttons with gradient fills and hover effects
- Tour/guide links auto-promoted to prominent purple-accent buttons
- Loading spinner animation, Escape key to dismiss, click-outside-to-close
- Mobile: slides up from bottom instead of top-right corner
- Also: rcart/rwallet subnav route support, rcart tour simplification
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New folk-payments-dashboard component shows payment requests in/out with
status badges, links to pay pages, and a create button. Resolves 404 on
the existing Payments outputPath.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolves T-INF-101 Access Denied when accessing payment links from
subdomains like demo.rspace.online. Adds extractRootDomain() helper
to shared/transak.ts, used by both rcart and rflows onramp adapters.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
nodeThreeObject callback was returning a Promise (from async
createNodeObjectAsync) because THREE wasn't cached yet. Pre-load
THREE via import("three") before creating the graph so the callback
always returns a synchronous Three.js object.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ESM builds on esm.sh kept resolving transitive deps to latest versions
that import three/webgpu. Switch to the pre-built UMD bundle from
jsdelivr which bundles all deps including Three.js. Keep separate
import map entry for "three" ESM for custom node object creation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
esm.sh was resolving three-render-objects@^1.29 to latest 1.x which
imports three/webgpu. The * prefix locks transitive dependency
versions to those specified in the package's own dependency tree.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
three.webgpu.js doesn't export legacy utilities like UniformsUtils
needed by Three.js addons. Pin 3d-force-graph to 1.73.4 which
predates the three/webgpu dependency, and use three.module.js.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Map both "three" and "three/webgpu" to three.webgpu.js so only one
copy loads and WebGPURenderer is available. Also externalize
three/webgpu in esm.sh URL so it uses the import map.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove .linkLineDash() chain call — only exists in 2D force-graph,
not 3d-force-graph. Dashed edges were visual-only, no functional loss.
- Map three/webgpu to three.module.js instead of three.webgpu.js to
avoid loading two full copies of Three.js.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The esm.sh bundle of 3d-force-graph@1.79.1 imports "three/webgpu"
which wasn't in the import map. Map it to the jsdelivr CDN path.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Switch 3d-force-graph CDN from jsdelivr to esm.sh with bundle-deps
to resolve missing "three-forcegraph" bare specifier error
- Fix storeCredential() to pass displayName and DID to createUser()
(prevents NULL did column for credential-first user creation)
- Fix invite acceptance to use claims.did instead of claims.sub for
space_members.user_did (DID format consistency)
- Fix session refresh to look up username from DB when missing from
old token (prevents empty username after token refresh)
- Fix resolveCallerRole() in spaces.ts to check both claims.sub and
claims.did against ownerDID and member keys (auto-provisioned spaces
store ownerDID as did🔑, API-created as raw userId)
- Refactor CRM route to use URL subpath tabs with renderCrm helper
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Subnav and tabbar were rendered outside <main id="app">, causing them
to be hidden behind the fixed header. Move them inside <main>, add
sticky positioning (top: 92px), and consolidate pill CSS into a shared
.rapp-nav-pill class. Also refactors tabbar to use URL subpaths instead
of ?tab= query params.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add threadId config field to publish-thread nodes
- Add "Create Thread" / "Edit Thread" button in config panel
- Opens thread editor in new tab (new or edit by ID)
- Styled button matching indigo accent theme
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix height to account for shell header (92px not 60px)
- Add min-height:0 on flex children to prevent overflow
- Replace text zoom buttons with SVG icons matching rFlows pattern
- Add fit-to-view icon (corner brackets) with separators
- Add category class per node (trigger/delay/condition/action)
with tinted backgrounds and category badge chips
- Add keyboard shortcuts: F=fit, +/-=zoom
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SVG text labels were rendering alongside HTML span labels, causing
each input/output name to appear twice on drag & drop nodes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Key derivation: replace random crypto.subtle.generateKey with deterministic
P-256 via @noble/curves/p256 and real Ed25519 did:key generation via
@noble/curves/ed25519 with multicodec prefix + base58btc encoding
- Guardian recovery: wire RecoveryManager to server API (GET/POST/DELETE
/api/guardians) instead of localStorage-only persistence. Server handles
invite emails, client syncs guardian list on load and merges with local
type metadata. verifyGuardian checks actual server acceptance status.
- Notifications dispatch CustomEvents on document for UI integration
- GuardianSetupElement awaits server sync before first render
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Port HolonShapeUtil from canvas-website to rSpace web components.
Replaces dead HoloSphere/GunDB stub with local-first CRDT storage
via window.__rspaceOfflineRuntime. H3 geospatial hierarchy via pure
h3-js. Data model designed for future AD4M Perspective bridging.
- lib/holon-service.ts: Automerge-backed holon registry + lens docs
- lib/folk-holon.ts: Main holon shape (ID entry → connected view with 16 lenses)
- lib/folk-holon-browser.ts: Search/browse shape with open-holon event
- Registered in canvas.html: imports, define, registry, CSS, toolbar, sizes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comprehensive smoke tests covering every module, landing pages, auth flows,
navigation, API endpoints, and shell UI — across Chromium, Firefox, and
mobile Chrome. 147 tests, all green against production.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add POPULAR_TOKENS map (USDC, USDT, DAI, WETH) for 7 chains
- Add ERC-20 balanceOf scanning to EOA balance endpoint
- Add /api/eoa/:address/all-balances and /api/safe/:address/all-balances
endpoints that fan out to all chains in parallel
- Replace single-chain view with unified multi-chain balance table
- Add Chain column with colored dots, "All" filter button
- Merge CRDT tokens into unified table (chainId="local")
- Enable testnets by default
- Chain buttons now act as filters (no extra API call)
- Stats aggregate across all chains regardless of filter
- Bump JS cache version to v=6
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
JWT sub contains the userId (not the DID). The DID is in claims.did.
Without this fix, my-balances never matches any token holder.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of showing an empty form, rWallet now automatically detects and
loads the user's EncryptID wallet address, or Vitalik.eth as a demo if
not logged in. URL ?address= param still takes priority.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>