From d1d0ae413947a7c66ee70c9f115412e9de432ff4 Mon Sep 17 00:00:00 2001 From: Derek Cofausper <256792747+decofe@users.noreply.github.com> Date: Tue, 7 Apr 2026 18:58:43 +0000 Subject: [PATCH 1/2] docs(accounts): add Account SDK architecture diagram Co-Authored-By: Georgios Konstantopoulos <17802178+gakonst@users.noreply.github.com> --- src/pages/accounts/index.mdx | 9 ++++++ src/wagmi.config.ts | 55 +++++++++++------------------------- 2 files changed, 26 insertions(+), 38 deletions(-) diff --git a/src/pages/accounts/index.mdx b/src/pages/accounts/index.mdx index 453489e5..bf187026 100644 --- a/src/pages/accounts/index.mdx +++ b/src/pages/accounts/index.mdx @@ -14,6 +14,15 @@ import IconGitHub from '~icons/simple-icons/github' The Tempo Accounts SDK is a TypeScript library for applications and wallets to create, manage, and interact with accounts on Tempo. +```mermaid +flowchart TD + app["App
connect · sign · send transaction"] -->|"EIP-5792 requests"| wallet + wallet["Tempo Wallet
iframe / popup UI"] <-->|"sign / verify"| passkey + wallet -->|"delegates to"| sdk + passkey["tempo.xyz domain-bound passkey
WebAuthn credential"] -->|"credential auth"| sdk + sdk["Accounts SDK
wallet & account logic"] -->|"built on"| infra["Wagmi + Viem
Ethereum client & tooling"] +``` +
{ - const hostname = globalThis.location?.hostname - if (!hostname) return undefined - const parts = hostname.split('.') - return parts.length > 2 ? parts.slice(-2).join('.') : hostname -})() - export function getConfig(options: getConfig.Options = {}) { const { multiInjectedProviderDiscovery = false } = options return createConfig({ @@ -40,35 +32,22 @@ export function getConfig(options: getConfig.Options = {}) { }, chains: [chain], connectors: [ - ...(import.meta.env.VITE_E2E === 'true' - ? [ - webAuthnAccounts({ - authUrl: 'https://keys.tempo.xyz', - rdns: 'webAuthn', - }), - ] - : [ - tempoWallet({ - authorizeAccessKey: () => ({ - expiry: Expiry.days(1), - limits: [ - { token: pathUsd, limit: parseUnits('500', 6) }, - { token: alphaUsd, limit: parseUnits('500', 6) }, - { token: betaUsd, limit: parseUnits('500', 6) }, - { token: thetaUsd, limit: parseUnits('500', 6) }, - ], - }), - feePayerUrl: 'https://sponsor.moderato.tempo.xyz', - }), - webAuthn({ - grantAccessKey: { - // @ts-expect-error - TODO: migrate to webAuthn on Accounts SDK - chainId: BigInt(chain.id), - }, - keyManager: KeyManager.http('https://keys.tempo.xyz'), - rpId, - }), - ]), + tempoWallet({ + authorizeAccessKey: () => ({ + expiry: Expiry.days(1), + limits: [ + { token: pathUsd, limit: parseUnits('500', 6) }, + { token: alphaUsd, limit: parseUnits('500', 6) }, + { token: betaUsd, limit: parseUnits('500', 6) }, + { token: thetaUsd, limit: parseUnits('500', 6) }, + ], + }), + feePayerUrl: 'https://sponsor.moderato.tempo.xyz', + }), + webAuthn({ + authUrl: 'https://keys.tempo.xyz', + rdns: 'webAuthn', + }), ], multiInjectedProviderDiscovery, storage: createStorage({ From 741310c02992784faaa3f4e7884d1b4ec05436a6 Mon Sep 17 00:00:00 2001 From: Brendan Ryan Date: Tue, 7 Apr 2026 15:20:11 -0700 Subject: [PATCH 2/2] docs(accounts): add static architecture diagram, move GitHub link to footer --- src/components/StaticMermaidDiagram.tsx | 247 ++++++++++++++++++++++++ src/pages/accounts/index.mdx | 42 ++-- 2 files changed, 267 insertions(+), 22 deletions(-) create mode 100644 src/components/StaticMermaidDiagram.tsx diff --git a/src/components/StaticMermaidDiagram.tsx b/src/components/StaticMermaidDiagram.tsx new file mode 100644 index 00000000..8f1136de --- /dev/null +++ b/src/components/StaticMermaidDiagram.tsx @@ -0,0 +1,247 @@ +'use client' + +import { useEffect, useRef, useState } from 'react' +import { estW, LAYOUT, THEMES, type ThemeColors } from './MermaidDiagram' + +// --------------------------------------------------------------------------- +// Types +// --------------------------------------------------------------------------- + +interface FlowNode { + id: string + label: string +} + +interface FlowEdge { + from: string + to: string + label: string +} + +interface ParsedFlowchart { + nodes: FlowNode[] + edges: FlowEdge[] +} + +// --------------------------------------------------------------------------- +// Parser — handles `flowchart TD` blocks +// --------------------------------------------------------------------------- + +function parseFlowchart(source: string): ParsedFlowchart { + const lines = source + .split('\n') + .map((l) => l.trim()) + .filter((l) => l && !l.startsWith('%%')) + const nodes = new Map() + const edges: FlowEdge[] = [] + + const ensureNode = (id: string, label?: string) => { + if (!nodes.has(id)) { + nodes.set(id, { id, label: label ?? id }) + } else if (label) { + const existing = nodes.get(id) + if (existing) existing.label = label + } + } + + // Extract id and optional label: id["label"] or just id + const parseNodeRef = (raw: string): { id: string; label?: string } => { + const m = raw.match(/^(\w+)\["(.+?)"\]$/) + if (m) return { id: m[1], label: m[2] } + return { id: raw.trim() } + } + + for (const line of lines) { + if (/^flowchart/i.test(line)) continue + + // Edge: from -->|"label"| to OR from --> to + const mEdge = line.match(/^(.+?)\s*-->(?:\|"(.+?)"\|)?\s*(.+)$/) + if (mEdge) { + const fromRef = parseNodeRef(mEdge[1].trim()) + const toRef = parseNodeRef(mEdge[3].trim()) + ensureNode(fromRef.id, fromRef.label) + ensureNode(toRef.id, toRef.label) + edges.push({ from: fromRef.id, to: toRef.id, label: mEdge[2] ?? '' }) + continue + } + + // Standalone node definition: id["label"] + const mNode = line.match(/^(\w+)\["(.+?)"\]$/) + if (mNode) { + ensureNode(mNode[1], mNode[2]) + } + } + + return { nodes: Array.from(nodes.values()), edges } +} + +// --------------------------------------------------------------------------- +// Layout constants for flowchart +// --------------------------------------------------------------------------- + +const FLOW = { + nodeH: 36, + nodePadX: 24, + nodeGapY: 40, + arrowSize: 7, +} + +// --------------------------------------------------------------------------- +// SVG renderer +// --------------------------------------------------------------------------- + +function renderFlowchart(parsed: ParsedFlowchart, th: ThemeColors): string { + const L = LAYOUT + const F = FLOW + const o: string[] = [] + + // Measure node widths + const nodeW = parsed.nodes.map((n) => estW(n.label, L.actorFontSize) + F.nodePadX * 2) + const maxW = Math.max(...nodeW) + + // Use uniform width for clean vertical alignment + const uniformW = maxW + + // Account for edge labels rendered to the right of center + const maxLabelW = parsed.edges.reduce( + (max, e) => (e.label ? Math.max(max, estW(e.label, L.labelFontSize)) : max), + 0, + ) + + // Center x + const padding = L.padding + const cx = padding + uniformW / 2 + const totalW = Math.max(uniformW + padding * 2, cx + uniformW / 2 + 10 + maxLabelW + padding) + + // Compute node y positions + const nodeY: number[] = [] + let y = padding + for (let i = 0; i < parsed.nodes.length; i++) { + nodeY.push(y) + if (i < parsed.nodes.length - 1) { + y += F.nodeH + F.nodeGapY + } + } + const totalH = y + F.nodeH + padding + + const nodeIdx = new Map() + for (let i = 0; i < parsed.nodes.length; i++) { + nodeIdx.set(parsed.nodes[i].id, i) + } + + o.push( + ``, + ) + o.push(``) + + // Edges (draw before nodes so lines go behind) + for (const e of parsed.edges) { + const fi = nodeIdx.get(e.from) + const ti = nodeIdx.get(e.to) + if (fi === undefined || ti === undefined) continue + + const fromY = nodeY[fi] + F.nodeH + const toY = nodeY[ti] + const sz = F.arrowSize + + // Vertical line + o.push( + ``, + ) + + // Arrow + o.push( + ``, + ) + + // Edge label + if (e.label) { + const midY = (fromY + toY) / 2 + o.push( + `${esc(e.label)}`, + ) + } + } + + // Nodes + for (let i = 0; i < parsed.nodes.length; i++) { + const n = parsed.nodes[i] + const nw = uniformW + const nx = cx - nw / 2 + const ny = nodeY[i] + + o.push( + ``, + ) + o.push( + `${esc(n.label)}`, + ) + } + + o.push('') + return o.join('\n') +} + +function esc(s: string): string { + return s + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') +} + +// --------------------------------------------------------------------------- +// React component +// --------------------------------------------------------------------------- + +export function StaticMermaidDiagram({ chart }: { chart: string }) { + const svgRef = useRef(null) + const [isDark, setIsDark] = useState(false) + + useEffect(() => { + const check = () => + setIsDark( + document.documentElement.style.colorScheme === 'dark' || + document.documentElement.classList.contains('dark'), + ) + check() + const obs = new MutationObserver(check) + obs.observe(document.documentElement, { + attributes: true, + attributeFilter: ['class', 'style'], + }) + return () => obs.disconnect() + }, []) + + useEffect(() => { + const el = svgRef.current + if (!el) return + const parsed = parseFlowchart(chart) + const th = isDark ? THEMES.dark : THEMES.light + el.innerHTML = renderFlowchart(parsed, th) + const svg = el.querySelector('svg') + if (svg) { + svg.style.maxWidth = '100%' + svg.style.height = 'auto' + svg.style.display = 'block' + svg.style.margin = '0 auto' + } + }, [chart, isDark]) + + return ( +
+
+
+ ) +} diff --git a/src/pages/accounts/index.mdx b/src/pages/accounts/index.mdx index bf187026..a99647d7 100644 --- a/src/pages/accounts/index.mdx +++ b/src/pages/accounts/index.mdx @@ -4,6 +4,7 @@ description: Set up the Tempo Accounts SDK to create, manage, and interact with --- import { Cards, Card } from 'vocs' +import { StaticMermaidDiagram } from '../../components/StaticMermaidDiagram' import * as Demo from '../../components/guides/Demo.tsx' import * as Step from '../../components/guides/steps' import IconGitHub from '~icons/simple-icons/github' @@ -14,28 +15,11 @@ import IconGitHub from '~icons/simple-icons/github' The Tempo Accounts SDK is a TypeScript library for applications and wallets to create, manage, and interact with accounts on Tempo. -```mermaid -flowchart TD - app["App
connect · sign · send transaction"] -->|"EIP-5792 requests"| wallet - wallet["Tempo Wallet
iframe / popup UI"] <-->|"sign / verify"| passkey - wallet -->|"delegates to"| sdk - passkey["tempo.xyz domain-bound passkey
WebAuthn credential"] -->|"credential auth"| sdk - sdk["Accounts SDK
wallet & account logic"] -->|"built on"| infra["Wagmi + Viem
Ethereum client & tooling"] -``` - -
- - - - GitHub - - -
+|"EIP-5792 requests"| wallet["Tempo Wallet + WebAuthn Passkey"] + wallet -->|"delegates to"| sdk["Accounts SDK"] + sdk -->|"built on"| infra["Wagmi + Viem"] +`} /> ### Demo @@ -290,3 +274,17 @@ export default defineConfig({ Have questions or building something cool with the Accounts SDK? Join the Telegram group to chat with the team and other devs: [@mpp_devs](https://t.me/mpp_devs) + +
+ + + + GitHub + + +