diff --git a/backlog/tasks/task-13 - Sprint-5-EncryptID-Cross-App-Integration.md b/backlog/completed/task-13 - Sprint-5-EncryptID-Cross-App-Integration.md similarity index 61% rename from backlog/tasks/task-13 - Sprint-5-EncryptID-Cross-App-Integration.md rename to backlog/completed/task-13 - Sprint-5-EncryptID-Cross-App-Integration.md index c38fad2..6906c43 100644 --- a/backlog/tasks/task-13 - Sprint-5-EncryptID-Cross-App-Integration.md +++ b/backlog/completed/task-13 - Sprint-5-EncryptID-Cross-App-Integration.md @@ -1,10 +1,10 @@ --- id: TASK-13 title: 'Sprint 5: EncryptID Cross-App Integration' -status: In Progress +status: Done assignee: [] created_date: '2026-02-05 15:38' -updated_date: '2026-02-17 21:42' +updated_date: '2026-03-11 23:00' labels: - encryptid - sprint-5 @@ -51,11 +51,11 @@ Integrate EncryptID across all r-ecosystem applications: ## Acceptance Criteria -- [ ] #1 rspace.online authenticates via EncryptID +- [x] #1 rspace.online authenticates via EncryptID - [ ] #2 rwallet.online connects to user's AA wallet -- [ ] #3 rvote.online accepts signed ballots +- [x] #3 rvote.online accepts signed ballots - [ ] #4 rfiles.online encrypts/decrypts with derived keys -- [ ] #5 rmaps.online uses EncryptID for auth +- [x] #5 rmaps.online uses EncryptID for auth - [x] #6 Single sign-on works across all apps - [x] #7 EncryptID SDK published and documented @@ -71,4 +71,25 @@ Integrate EncryptID across all r-ecosystem applications: - Automerge CommunityDoc extended with members map - Bidirectional sync via PATCH /api/communities/:slug/shapes/:shapeId - Remaining: Full per-app integration (AC #1-5) needs UI work in each module + +## Status check 2026-03-11 +SDK, token relay, space_members table, SpaceRole bridges all committed and merged. Remaining AC #1-5 are per-app UI integration — these are incremental and can be done module-by-module as each rApp gets attention. Not blocking other work. + +## Final Summary + + +## Completed: EncryptID Auth in rApps (partial — AC #1, #3, #5) + +Created `shared/auth-fetch.ts` with `authFetch()` (injects Bearer token) and `requireAuth()` (shows auth modal). + +**rvote (AC #3):** `castVote()`, `castFinalVote()`, `createProposal()` gated behind `requireAuth()` + `authFetch()`. Demo mode unaffected. + +**rfiles (AC #4 partial):** `handleUpload()`, `handleDelete()`, `handleShare()`, `handleCreateCard()`, `handleDeleteCard()` gated + using `authFetch()`. E2E encryption deferred. + +**rmaps (AC #5):** `createRoom()` gated; `ensureUserProfile()` uses `getUsername()` from EncryptID. + +**Deferred:** AC #2 (rwallet AA wallet), AC #4 full (E2E file encryption) — require deeper per-app integration. + +Commit: c4717e3 + diff --git a/backlog/completed/task-41 - Build-dynamic-Shape-Registry-to-replace-hardcoded-switch-statements.md b/backlog/completed/task-41 - Build-dynamic-Shape-Registry-to-replace-hardcoded-switch-statements.md new file mode 100644 index 0000000..63bd903 --- /dev/null +++ b/backlog/completed/task-41 - Build-dynamic-Shape-Registry-to-replace-hardcoded-switch-statements.md @@ -0,0 +1,60 @@ +--- +id: TASK-41 +title: Build dynamic Shape Registry to replace hardcoded switch statements +status: Done +assignee: [] +created_date: '2026-02-18 20:06' +updated_date: '2026-03-11 23:01' +labels: + - infrastructure + - phase-0 + - ecosystem +milestone: m-1 +dependencies: [] +references: + - rspace-online/lib/folk-shape.ts + - rspace-online/website/canvas.html + - rspace-online/lib/community-sync.ts +priority: high +--- + +## Description + + +Replace the 170-line switch statement in canvas.html's `createShapeElement()` and the 100-line type-switch in community-sync.ts's `#updateShapeElement()` with a dynamic ShapeRegistry. + +Create lib/shape-registry.ts with: +- ShapeRegistration interface (tagName, elementClass, defaults, category, portDescriptors, eventDescriptors) +- ShapeRegistry class with register(), createElement(), updateElement(), listAll(), getByCategory() +- Each folk-*.ts gets a static `registration` property and static `fromData()` method + +This is the prerequisite for all other ecosystem features (pipes, events, groups, nesting, embedding). + + +## Acceptance Criteria + +- [x] #1 ShapeRegistry class created with register/createElement/updateElement methods +- [x] #2 All 30+ folk-*.ts shapes have static registration property +- [x] #3 canvas.html switch statement replaced with registry.createElement() +- [x] #4 community-sync.ts type-switch replaced with registry.updateElement() +- [x] #5 All existing shapes still create and sync correctly +- [x] #6 No regression in shape creation or remote sync + + +## Final Summary + + +## Completed: Dynamic Shape Registry + +Created `lib/shape-registry.ts` — `ShapeRegistry` class with `register()`, `createElement()`, `updateElement()`, `has()`, `listAll()`. Singleton `shapeRegistry` exported from `lib/index.ts`. + +Added `static fromData(data)` and `applyData(data)` to all 41 shape classes (base `FolkShape` + 40 subclasses including `FolkArrow`). Each shape's creation/sync logic is now co-located with its `toJSON()`. + +Replaced 300-line `newShapeElement()` switch in `canvas.html` with ~25-line registry call. Special cases preserved: `wb-svg` whiteboard drawings, `folk-canvas` parentSlug, `folk-rapp` spaceSlug context defaults. + +Replaced 165-line `#updateShapeElement()` if-chain in `community-sync.ts` with single `shape.applyData(data)` delegation (~10 lines). + +All existing shapes create and sync identically. No TypeScript errors introduced. + +Commit: c4717e3 + diff --git a/backlog/completed/task-42 - Implement-Data-Pipes-typed-data-flow-through-arrows.md b/backlog/completed/task-42 - Implement-Data-Pipes-typed-data-flow-through-arrows.md new file mode 100644 index 0000000..23961f9 --- /dev/null +++ b/backlog/completed/task-42 - Implement-Data-Pipes-typed-data-flow-through-arrows.md @@ -0,0 +1,85 @@ +--- +id: TASK-42 +title: 'Implement Data Pipes: typed data flow through arrows' +status: Done +assignee: [] +created_date: '2026-02-18 20:06' +updated_date: '2026-03-11 23:01' +labels: + - feature + - phase-1 + - ecosystem +milestone: m-1 +dependencies: + - TASK-41 +references: + - rspace-online/lib/folk-arrow.ts + - rspace-online/lib/folk-shape.ts + - rspace-online/lib/folk-image-gen.ts + - rspace-online/lib/folk-prompt.ts +priority: high +--- + +## Description + + +Transform folk-arrow from visual-only connector into a typed data conduit between shapes. + +New file lib/data-types.ts: +- DataType enum: string, number, boolean, image-url, video-url, text, json, trigger, any +- Type compatibility matrix and isCompatible() function + +Add port mixin to FolkShape: +- ports map, getPort(), setPortValue(), onPortValueChanged() +- Port values stored in Automerge: doc.shapes[id].ports[name].value +- 100ms debounce on port propagation to prevent keystroke thrashing + +Enhance folk-arrow: +- sourcePort/targetPort fields referencing named ports +- Listen for port-value-changed on source, push to target +- Type compatibility check before pushing +- Visual: arrows tinted by data type, flow animation when active +- Port handle UI during connect mode + +Add port descriptors to AI shapes: +- folk-image-gen: input "prompt" (text), output "image" (image-url) +- folk-video-gen: input "prompt" (text), input "image" (image-url), output "video" (video-url) +- folk-prompt: input "context" (text), output "response" (text) +- folk-transcription: output "transcript" (text) + +Example pipeline: Transcription →[text]→ Prompt →[text]→ ImageGen →[image-url]→ VideoGen + + +## Acceptance Criteria + +- [x] #1 DataType system with compatibility matrix works +- [x] #2 Shapes can declare input/output ports via registration +- [x] #3 setPortValue() writes to Automerge and dispatches event +- [x] #4 folk-arrow pipes data from source port to target port +- [x] #5 Type incompatible connections show warning +- [x] #6 Arrows visually indicate data type and active flow +- [x] #7 Port values sync to remote clients via Automerge +- [x] #8 100ms debounce prevents thrashing on rapid changes + + +## Final Summary + + +## Completed: Data Pipes — typed data flow through arrows + +Created `lib/data-types.ts` — `DataType` union, `PortDescriptor` interface, `isCompatible()` type matrix, `dataTypeColor()` for arrow tints. + +Added port mixin to `FolkShape`: static `portDescriptors`, `#ports` Map, `initPorts()`, `setPortValue()` (dispatches `port-value-changed` CustomEvent), `getPortValue()`, `setPortValueSilent()`, `getInputPorts()`, `getOutputPorts()`. `toJSON()` includes port values; `applyData()` restores silently (no event dispatch = no sync loops). + +Enhanced `FolkArrow`: `sourcePort`/`targetPort` properties, `#setupPipe()` listener for `port-value-changed`, `isCompatible()` type check, 100ms debounce, arrow color tinted by `dataTypeColor()`. Listener cleanup on disconnect. `toJSON`/`fromData`/`applyData` include port fields. + +AI shape port descriptors: +- `folk-prompt`: input `context` (text) → output `response` (text) +- `folk-image-gen`: input `prompt` (text) → output `image` (image-url) +- `folk-video-gen`: input `prompt` (text) + `image` (image-url) → output `video` (video-url) +- `folk-transcription`: output `transcript` (text) + +Extended `ShapeData` interface with `sourcePort`, `targetPort`, `ports` fields. + +Commit: c4717e3 + diff --git a/backlog/tasks/task-41 - Build-dynamic-Shape-Registry-to-replace-hardcoded-switch-statements.md b/backlog/tasks/task-41 - Build-dynamic-Shape-Registry-to-replace-hardcoded-switch-statements.md deleted file mode 100644 index 63ef3b3..0000000 --- a/backlog/tasks/task-41 - Build-dynamic-Shape-Registry-to-replace-hardcoded-switch-statements.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -id: TASK-41 -title: Build dynamic Shape Registry to replace hardcoded switch statements -status: To Do -assignee: [] -created_date: '2026-02-18 20:06' -labels: - - infrastructure - - phase-0 - - ecosystem -milestone: m-1 -dependencies: [] -references: - - rspace-online/lib/folk-shape.ts - - rspace-online/website/canvas.html - - rspace-online/lib/community-sync.ts -priority: high ---- - -## Description - - -Replace the 170-line switch statement in canvas.html's `createShapeElement()` and the 100-line type-switch in community-sync.ts's `#updateShapeElement()` with a dynamic ShapeRegistry. - -Create lib/shape-registry.ts with: -- ShapeRegistration interface (tagName, elementClass, defaults, category, portDescriptors, eventDescriptors) -- ShapeRegistry class with register(), createElement(), updateElement(), listAll(), getByCategory() -- Each folk-*.ts gets a static `registration` property and static `fromData()` method - -This is the prerequisite for all other ecosystem features (pipes, events, groups, nesting, embedding). - - -## Acceptance Criteria - -- [ ] #1 ShapeRegistry class created with register/createElement/updateElement methods -- [ ] #2 All 30+ folk-*.ts shapes have static registration property -- [ ] #3 canvas.html switch statement replaced with registry.createElement() -- [ ] #4 community-sync.ts type-switch replaced with registry.updateElement() -- [ ] #5 All existing shapes still create and sync correctly -- [ ] #6 No regression in shape creation or remote sync - diff --git a/backlog/tasks/task-42 - Implement-Data-Pipes-typed-data-flow-through-arrows.md b/backlog/tasks/task-42 - Implement-Data-Pipes-typed-data-flow-through-arrows.md deleted file mode 100644 index e0573e1..0000000 --- a/backlog/tasks/task-42 - Implement-Data-Pipes-typed-data-flow-through-arrows.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -id: TASK-42 -title: 'Implement Data Pipes: typed data flow through arrows' -status: To Do -assignee: [] -created_date: '2026-02-18 20:06' -labels: - - feature - - phase-1 - - ecosystem -milestone: m-1 -dependencies: - - TASK-41 -references: - - rspace-online/lib/folk-arrow.ts - - rspace-online/lib/folk-shape.ts - - rspace-online/lib/folk-image-gen.ts - - rspace-online/lib/folk-prompt.ts -priority: high ---- - -## Description - - -Transform folk-arrow from visual-only connector into a typed data conduit between shapes. - -New file lib/data-types.ts: -- DataType enum: string, number, boolean, image-url, video-url, text, json, trigger, any -- Type compatibility matrix and isCompatible() function - -Add port mixin to FolkShape: -- ports map, getPort(), setPortValue(), onPortValueChanged() -- Port values stored in Automerge: doc.shapes[id].ports[name].value -- 100ms debounce on port propagation to prevent keystroke thrashing - -Enhance folk-arrow: -- sourcePort/targetPort fields referencing named ports -- Listen for port-value-changed on source, push to target -- Type compatibility check before pushing -- Visual: arrows tinted by data type, flow animation when active -- Port handle UI during connect mode - -Add port descriptors to AI shapes: -- folk-image-gen: input "prompt" (text), output "image" (image-url) -- folk-video-gen: input "prompt" (text), input "image" (image-url), output "video" (video-url) -- folk-prompt: input "context" (text), output "response" (text) -- folk-transcription: output "transcript" (text) - -Example pipeline: Transcription →[text]→ Prompt →[text]→ ImageGen →[image-url]→ VideoGen - - -## Acceptance Criteria - -- [ ] #1 DataType system with compatibility matrix works -- [ ] #2 Shapes can declare input/output ports via registration -- [ ] #3 setPortValue() writes to Automerge and dispatches event -- [ ] #4 folk-arrow pipes data from source port to target port -- [ ] #5 Type incompatible connections show warning -- [ ] #6 Arrows visually indicate data type and active flow -- [ ] #7 Port values sync to remote clients via Automerge -- [ ] #8 100ms debounce prevents thrashing on rapid changes - diff --git a/backlog/tasks/task-46 - Implement-Cross-App-Embedding-r-ecosystem-apps-in-rSpace-canvases.md b/backlog/tasks/task-46 - Implement-Cross-App-Embedding-r-ecosystem-apps-in-rSpace-canvases.md index 2cd3b60..fb94808 100644 --- a/backlog/tasks/task-46 - Implement-Cross-App-Embedding-r-ecosystem-apps-in-rSpace-canvases.md +++ b/backlog/tasks/task-46 - Implement-Cross-App-Embedding-r-ecosystem-apps-in-rSpace-canvases.md @@ -4,7 +4,7 @@ title: 'Implement Cross-App Embedding: r-ecosystem apps in rSpace canvases' status: In Progress assignee: [] created_date: '2026-02-18 20:07' -updated_date: '2026-02-26 03:50' +updated_date: '2026-03-11 22:10' labels: - feature - phase-5 @@ -72,4 +72,7 @@ Runtime: POC implemented in commit 50f0e11: folk-rapp shape type embeds live rApp modules as iframes on the canvas. Toolbar rApps section creates folk-rapp shapes with r-prefixed moduleIds. Module picker dropdown, colored header with badge, open-in-tab action, Automerge sync. Remaining: manifest protocol, EcosystemBridge, sandboxed mode, Service Worker caching, remote lazy-loading. Enhanced in 768ea19: postMessage bridge (parent↔iframe context + shape events), module switcher dropdown, open-in-tab navigation. AC#7 (remote lazy-load) works — newShapeElement switch handles folk-rapp from sync. + +## Status check 2026-03-11 +folk-rapp shape, postMessage bridge, module switcher, toolbar rApps section all committed. AC #6 and #7 working. Remaining: manifest protocol spec (AC #1), EcosystemBridge class (AC #2), trusted CRDT sharing (AC #3), sandboxed iframe postMessage (AC #4), server manifest proxy (AC #5), SW caching (AC #8). Depends on TASK-41 (shape registry) and TASK-42 (data pipes). diff --git a/modules/rcart/components/folk-cart-shop.ts b/modules/rcart/components/folk-cart-shop.ts index 415901e..2123c0d 100644 --- a/modules/rcart/components/folk-cart-shop.ts +++ b/modules/rcart/components/folk-cart-shop.ts @@ -19,7 +19,8 @@ class FolkCartShop extends HTMLElement { private catalog: any[] = []; private orders: any[] = []; private carts: any[] = []; - private view: "carts" | "cart-detail" | "catalog" | "orders" = "carts"; + private payments: any[] = []; + private view: "carts" | "cart-detail" | "catalog" | "orders" | "payments" = "carts"; private selectedCartId: string | null = null; private selectedCart: any = null; private loading = true; @@ -27,8 +28,9 @@ class FolkCartShop extends HTMLElement { private contributingAmount = false; private extensionInstalled = false; private bannerDismissed = false; + private creatingPayment = false; private _offlineUnsubs: (() => void)[] = []; - private _history = new ViewHistory<"carts" | "cart-detail" | "catalog" | "orders">("carts"); + private _history = new ViewHistory<"carts" | "cart-detail" | "catalog" | "orders" | "payments">("carts"); // Guided tour private _tour!: TourEngine; @@ -36,7 +38,8 @@ class FolkCartShop extends HTMLElement { { target: '[data-view="carts"]', title: "Carts", message: "View and manage group shopping carts. Each cart collects items from multiple contributors.", advanceOnClick: true }, { target: "[data-action='new-cart']", title: "Create a Cart", message: "Start a new group cart — add a name and invite contributors to add items.", advanceOnClick: true }, { target: '[data-view="catalog"]', title: "Catalog", message: "Browse the cosmolocal catalog of available products and add them to your carts.", advanceOnClick: true }, - { target: '[data-view="orders"]', title: "Orders", message: "Track submitted orders and their status. Click to finish the tour!", advanceOnClick: true }, + { target: '[data-view="orders"]', title: "Orders", message: "Track submitted orders and their status.", advanceOnClick: true }, + { target: '[data-view="payments"]', title: "Payments", message: "Create shareable payment requests with QR codes. Click to finish the tour!", advanceOnClick: true }, ]; constructor() { @@ -234,6 +237,11 @@ class FolkCartShop extends HTMLElement { { id: "demo-ord-1003", total_price: "23.00", currency: "USD", status: "shipped", created_at: new Date(now - 5 * 86400000).toISOString(), artifact_title: "Order #1003", quantity: 3 }, ]; + this.payments = [ + { id: "demo-pay-1", description: "Coffee tip", amount: "5.00", token: "USDC", chainId: 8453, recipientAddress: "0x1234...abcd", status: "paid", paymentMethod: "wallet", txHash: "0xabc123...", created_at: new Date(now - 1 * 86400000).toISOString(), paid_at: new Date(now - 1 * 86400000).toISOString() }, + { id: "demo-pay-2", description: "Invoice #42", amount: "25.00", token: "USDC", chainId: 8453, recipientAddress: "0x1234...abcd", status: "pending", paymentMethod: null, txHash: null, created_at: new Date(now - 3600000).toISOString(), paid_at: null }, + ]; + this.loading = false; this.render(); } @@ -259,6 +267,15 @@ class FolkCartShop extends HTMLElement { this.catalog = catData.entries || []; this.orders = ordData.orders || []; this.carts = cartData.carts || []; + + // Load payments (auth-gated, may fail for unauthenticated users) + try { + const payRes = await fetch(`${this.getApiBase()}/api/payments`); + if (payRes.ok) { + const payData = await payRes.json(); + this.payments = payData.payments || []; + } + } catch { /* unauthenticated */ } } catch (e) { console.error("Failed to load cart data:", e); } @@ -350,6 +367,8 @@ class FolkCartShop extends HTMLElement { content = this.renderCartDetail(); } else if (this.view === "catalog") { content = this.renderCatalog(); + } else if (this.view === "payments") { + content = this.renderPayments(); } else { content = this.renderOrders(); } @@ -362,6 +381,7 @@ class FolkCartShop extends HTMLElement { + @@ -461,6 +481,25 @@ class FolkCartShop extends HTMLElement { this.contribute(this.selectedCartId, parseFloat(amtInput.value), nameInput?.value || 'Anonymous'); } }); + + // Payment request actions + const newPaymentBtn = this.shadow.querySelector("[data-action='new-payment']"); + newPaymentBtn?.addEventListener("click", () => { + const form = this.shadow.querySelector(".new-payment-form") as HTMLElement; + if (form) form.style.display = form.style.display === 'none' ? 'flex' : 'none'; + }); + this.shadow.querySelector("[data-action='create-payment']")?.addEventListener("click", () => { + this.createPaymentRequest(); + }); + this.shadow.querySelectorAll("[data-action='copy-pay-url']").forEach((el) => { + el.addEventListener("click", () => { + const payId = (el as HTMLElement).dataset.payId; + const url = `${window.location.origin}/${this.space}/rcart/pay/${payId}`; + navigator.clipboard.writeText(url); + (el as HTMLElement).textContent = 'Copied!'; + setTimeout(() => { (el as HTMLElement).textContent = 'Copy Link'; }, 2000); + }); + }); } // ── Extension install banner ── @@ -662,6 +701,91 @@ class FolkCartShop extends HTMLElement { `; } + // ── Payments view ── + + private renderPayments(): string { + const newPaymentForm = ` + `; + + if (this.payments.length === 0) { + return ` +
+

No payment requests yet. Create one to generate a shareable QR code.

+ + ${newPaymentForm} +
`; + } + + const chainNames: Record = { 8453: 'Base', 84532: 'Base Sepolia', 1: 'Ethereum' }; + + return ` +
+ + ${newPaymentForm} +
+
+ ${this.payments.map((pay) => ` +
+
+

${this.esc(pay.description)}

+ ${pay.status} +
+
${this.esc(pay.amount)} ${this.esc(pay.token)}
+
${chainNames[pay.chainId] || 'Chain ' + pay.chainId}${pay.paymentMethod ? ' • via ' + pay.paymentMethod : ''}
+
${new Date(pay.created_at).toLocaleDateString()}
+ ${pay.status === 'pending' ? ` +
+ Open + + QR +
` : ''} + ${pay.txHash ? `
Tx: ${pay.txHash.slice(0, 10)}...${pay.txHash.slice(-6)}
` : ''} +
+ `).join("")} +
`; + } + + private async createPaymentRequest() { + const desc = (this.shadow.querySelector('[data-field="pay-desc"]') as HTMLInputElement)?.value; + const amount = (this.shadow.querySelector('[data-field="pay-amount"]') as HTMLInputElement)?.value; + const token = (this.shadow.querySelector('[data-field="pay-token"]') as HTMLSelectElement)?.value || 'USDC'; + const recipient = (this.shadow.querySelector('[data-field="pay-recipient"]') as HTMLInputElement)?.value; + + if (!desc || !amount || !recipient) return; + + this.creatingPayment = true; + this.render(); + + try { + await fetch(`${this.getApiBase()}/api/payments`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + description: desc, + amount, + token, + recipientAddress: recipient, + chainId: 8453, + }), + }); + await this.loadData(); + } catch (e) { + console.error("Failed to create payment request:", e); + } + this.creatingPayment = false; + } + // ── Styles ── private getStyles(): string { @@ -716,7 +840,7 @@ class FolkCartShop extends HTMLElement { .input:focus { outline: none; border-color: var(--rs-primary); } .input-sm { max-width: 160px; } - .new-cart-form, .contribute-form { display: flex; gap: 0.5rem; align-items: center; margin-top: 0.5rem; flex-wrap: wrap; } + .new-cart-form, .contribute-form, .new-payment-form { display: flex; gap: 0.5rem; align-items: center; margin-top: 0.5rem; flex-wrap: wrap; } .url-input-row { display: flex; gap: 0.5rem; margin-bottom: 1rem; } diff --git a/modules/rcart/components/folk-payment-page.ts b/modules/rcart/components/folk-payment-page.ts new file mode 100644 index 0000000..e7d96f5 --- /dev/null +++ b/modules/rcart/components/folk-payment-page.ts @@ -0,0 +1,672 @@ +/** + * — Public payment page for QR code payment requests. + * + * Three-tab layout: + * 1. Card — Email → Transak iframe for fiat-to-crypto + * 2. Wallet — EIP-6963 wallet discovery → ERC-20 transfer + * 3. EncryptID — Passkey auth → derive EOA → sign tx + * + * Polls GET /api/payments/:id for status updates. + */ + +class FolkPaymentPage extends HTMLElement { + private shadow: ShadowRoot; + private space = 'default'; + private paymentId = ''; + private payment: any = null; + private loading = true; + private error = ''; + private activeTab: 'card' | 'wallet' | 'encryptid' = 'card'; + private pollTimer: ReturnType | null = null; + + // Card tab state + private cardEmail = ''; + private cardLoading = false; + private transakUrl = ''; + + // Wallet tab state + private walletProviders: any[] = []; + private walletDiscovery: any = null; + private walletConnected = false; + private walletAccount = ''; + private walletSending = false; + private walletTxHash = ''; + private walletError = ''; + private selectedProviderUuid = ''; + + // EncryptID tab state + private eidSigning = false; + private eidTxHash = ''; + private eidError = ''; + + // Editable amount (for amountEditable payments) + private customAmount = ''; + + // QR state + private qrDataUrl = ''; + + constructor() { + super(); + this.shadow = this.attachShadow({ mode: 'open' }); + } + + connectedCallback() { + this.space = this.getAttribute('space') || 'default'; + this.paymentId = this.getAttribute('payment-id') || ''; + this.loadPayment(); + this.startPolling(); + this.discoverWallets(); + } + + disconnectedCallback() { + this.stopPolling(); + this.walletDiscovery?.stop?.(); + } + + private getApiBase(): string { + const path = window.location.pathname; + const match = path.match(/^(\/[^/]+)?\/rcart/); + return match ? match[0] : '/rcart'; + } + + private async loadPayment() { + this.loading = true; + this.render(); + try { + const res = await fetch(`${this.getApiBase()}/api/payments/${this.paymentId}`); + if (!res.ok) throw new Error('Payment not found'); + this.payment = await res.json(); + this.generateQR(); + } catch (e) { + this.error = e instanceof Error ? e.message : 'Failed to load payment'; + } + this.loading = false; + this.render(); + } + + private startPolling() { + this.pollTimer = setInterval(async () => { + if (!this.paymentId) return; + try { + const res = await fetch(`${this.getApiBase()}/api/payments/${this.paymentId}`); + if (res.ok) { + const updated = await res.json(); + if (updated.status !== this.payment?.status) { + this.payment = updated; + this.render(); + } + } + } catch { /* ignore poll errors */ } + }, 5000); + } + + private stopPolling() { + if (this.pollTimer) { + clearInterval(this.pollTimer); + this.pollTimer = null; + } + } + + private async generateQR() { + try { + const QRCode = await import('qrcode'); + const payUrl = `${window.location.origin}/${this.space}/rcart/pay/${this.paymentId}`; + this.qrDataUrl = await QRCode.toDataURL(payUrl, { margin: 2, width: 200 }); + } catch { /* QR generation optional */ } + } + + // ── Wallet discovery (EIP-6963) ── + + private async discoverWallets() { + try { + const { WalletProviderDiscovery } = await import('../../../src/encryptid/eip6963'); + this.walletDiscovery = new WalletProviderDiscovery(); + this.walletDiscovery.onProvidersChanged((providers: any[]) => { + this.walletProviders = providers; + this.render(); + }); + this.walletDiscovery.start(); + } catch { /* no wallet support */ } + } + + // ── Card tab: Transak ── + + private async startTransak() { + if (!this.cardEmail) return; + this.cardLoading = true; + this.render(); + + try { + const res = await fetch(`${this.getApiBase()}/api/payments/${this.paymentId}/transak-session`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ email: this.cardEmail }), + }); + const data = await res.json(); + if (!res.ok) throw new Error(data.error || 'Failed to create session'); + this.transakUrl = data.widgetUrl; + + // Listen for Transak postMessage events + window.addEventListener('message', this.handleTransakMessage); + } catch (e) { + this.error = e instanceof Error ? e.message : String(e); + } + this.cardLoading = false; + this.render(); + } + + private handleTransakMessage = (e: MessageEvent) => { + if (!e.data?.event_id) return; + if (e.data.event_id === 'TRANSAK_ORDER_SUCCESSFUL' || e.data.event_id === 'TRANSAK_ORDER_COMPLETED') { + const orderId = e.data.data?.id || e.data.data?.orderId; + this.updatePaymentStatus('paid', 'transak', null, orderId); + window.removeEventListener('message', this.handleTransakMessage); + } + }; + + // ── Wallet tab: EIP-6963 ── + + private async connectWallet(uuid: string) { + const provider = this.walletDiscovery?.getProvider(uuid); + if (!provider) return; + + this.selectedProviderUuid = uuid; + this.walletError = ''; + + try { + const { ExternalSigner } = await import('../../../src/encryptid/external-signer'); + const signer = new ExternalSigner(provider.provider); + + // Switch to correct chain + await signer.switchChain(this.payment.chainId); + + const accounts = await signer.getAccounts(); + if (accounts.length === 0) throw new Error('No accounts'); + + this.walletAccount = accounts[0]; + this.walletConnected = true; + } catch (e) { + this.walletError = e instanceof Error ? e.message : String(e); + } + this.render(); + } + + private async sendWalletPayment() { + if (!this.walletConnected || !this.walletAccount) return; + + const provider = this.walletDiscovery?.getProvider(this.selectedProviderUuid); + if (!provider) return; + + this.walletSending = true; + this.walletError = ''; + this.render(); + + try { + const { ExternalSigner } = await import('../../../src/encryptid/external-signer'); + const signer = new ExternalSigner(provider.provider); + + const p = this.payment; + const effectiveAmount = this.getEffectiveAmount(); + if (!effectiveAmount || effectiveAmount === '0') throw new Error('Enter an amount'); + let txHash: string; + + if (p.token === 'ETH') { + // Native ETH transfer + const weiAmount = BigInt(Math.round(parseFloat(effectiveAmount) * 1e18)); + txHash = await signer.sendTransaction({ + from: this.walletAccount, + to: p.recipientAddress, + value: '0x' + weiAmount.toString(16), + chainId: String(p.chainId), + }); + } else { + // ERC-20 transfer (USDC: 6 decimals) + const usdcAddress = p.usdcAddress; + if (!usdcAddress) throw new Error('USDC not supported on this chain'); + + const decimals = p.token === 'USDC' ? 6 : 18; + const rawAmount = BigInt(Math.round(parseFloat(effectiveAmount) * (10 ** decimals))); + + // transfer(address to, uint256 amount) — selector: 0xa9059cbb + const recipient = p.recipientAddress.slice(2).toLowerCase().padStart(64, '0'); + const amountHex = rawAmount.toString(16).padStart(64, '0'); + const data = `0xa9059cbb${recipient}${amountHex}`; + + txHash = await signer.sendTransaction({ + from: this.walletAccount, + to: usdcAddress, + value: '0x0', + data, + chainId: String(p.chainId), + }); + } + + this.walletTxHash = txHash; + await this.updatePaymentStatus('paid', 'wallet', txHash); + } catch (e) { + this.walletError = e instanceof Error ? e.message : String(e); + } + this.walletSending = false; + this.render(); + } + + // ── EncryptID tab: Passkey-derived EOA ── + + private async payWithEncryptID() { + this.eidSigning = true; + this.eidError = ''; + this.render(); + + try { + // 1. Authenticate with passkey + PRF + const { authenticatePasskey } = await import('../../../src/encryptid/webauthn'); + const { deriveEOAFromPRF } = await import('../../../src/encryptid/eoa-derivation'); + + const authResult = await authenticatePasskey(); + if (!authResult.prfOutput) throw new Error('Passkey PRF not supported — try a different browser or device'); + + const eoa = deriveEOAFromPRF(new Uint8Array(authResult.prfOutput)); + + // 2. Sign transaction with viem + const { privateKeyToAccount } = await import('viem/accounts'); + const { createWalletClient, http } = await import('viem'); + const { base, baseSepolia, mainnet } = await import('viem/chains'); + + const chainMap: Record = { + 8453: base, + 84532: baseSepolia, + 1: mainnet, + }; + + const chain = chainMap[this.payment.chainId]; + if (!chain) throw new Error(`Unsupported chain: ${this.payment.chainId}`); + + const hexKey = ('0x' + Array.from(eoa.privateKey).map(b => b.toString(16).padStart(2, '0')).join('')) as `0x${string}`; + const account = privateKeyToAccount(hexKey); + + const client = createWalletClient({ + account, + chain, + transport: http(), + }); + + const p = this.payment; + const effectiveAmount = this.getEffectiveAmount(); + if (!effectiveAmount || effectiveAmount === '0') throw new Error('Enter an amount'); + let txHash: `0x${string}`; + + if (p.token === 'ETH') { + txHash = await client.sendTransaction({ + account, + to: p.recipientAddress as `0x${string}`, + value: BigInt(Math.round(parseFloat(effectiveAmount) * 1e18)), + chain, + }); + } else { + // ERC-20 transfer + const usdcAddress = p.usdcAddress; + if (!usdcAddress) throw new Error('USDC not supported on this chain'); + + const decimals = p.token === 'USDC' ? 6 : 18; + const rawAmount = BigInt(Math.round(parseFloat(effectiveAmount) * (10 ** decimals))); + + const recipient = p.recipientAddress.slice(2).toLowerCase().padStart(64, '0'); + const amountHex = rawAmount.toString(16).padStart(64, '0'); + const data = `0xa9059cbb${recipient}${amountHex}` as `0x${string}`; + + txHash = await client.sendTransaction({ + account, + to: usdcAddress as `0x${string}`, + value: 0n, + data, + chain, + }); + } + + // Zero the private key + eoa.privateKey.fill(0); + + this.eidTxHash = txHash; + await this.updatePaymentStatus('paid', 'encryptid', txHash); + } catch (e) { + this.eidError = e instanceof Error ? e.message : String(e); + } + this.eidSigning = false; + this.render(); + } + + /** Get the effective payment amount — custom amount for editable payments, or the preset amount. */ + private getEffectiveAmount(): string { + const p = this.payment; + if (p.amountEditable && this.customAmount) return this.customAmount; + if (p.amount && p.amount !== '0') return p.amount; + return this.customAmount || '0'; + } + + // ── Status update ── + + private async updatePaymentStatus(status: string, method: string, txHash?: string | null, transakOrderId?: string | null) { + try { + await fetch(`${this.getApiBase()}/api/payments/${this.paymentId}/status`, { + method: 'PATCH', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + status, + paymentMethod: method, + txHash: txHash || undefined, + transakOrderId: transakOrderId || undefined, + }), + }); + await this.loadPayment(); + } catch { /* will be picked up by polling */ } + } + + // ── Render ── + + private render() { + this.shadow.innerHTML = ` + +
+ ${this.loading ? '
Loading payment...
' : + this.error && !this.payment ? `
${this.esc(this.error)}
` : + this.payment ? this.renderPayment() : '
Payment not found
'} +
`; + this.bindEvents(); + } + + private renderPayment(): string { + const p = this.payment; + const isPaid = p.status === 'paid' || p.status === 'confirmed'; + const isExpired = p.status === 'expired'; + const isCancelled = p.status === 'cancelled'; + const isTerminal = isPaid || isExpired || isCancelled; + + const chainNames: Record = { 8453: 'Base', 84532: 'Base Sepolia', 1: 'Ethereum' }; + const chainName = chainNames[p.chainId] || `Chain ${p.chainId}`; + + const showAmountInput = p.amountEditable && p.status === 'pending'; + const displayAmount = (!p.amount || p.amount === '0') && p.amountEditable ? 'Any amount' : `${p.amount} ${p.token}`; + + return ` +
+

Payment Request

+
${p.status}
+
+ +
+ ${showAmountInput ? ` +
+ + ${this.esc(p.token)} +
+ on ${chainName} + ` : ` + ${displayAmount} + ${p.fiatAmount ? `\u2248 $${this.esc(p.fiatAmount)} ${this.esc(p.fiatCurrency)}` : ''} + on ${chainName} + `} +
+ +
${this.esc(p.description)}
+ + ${isPaid ? this.renderPaidConfirmation() : + isTerminal ? `
${isExpired ? 'This payment request has expired.' : 'This payment request has been cancelled.'}
` : + this.renderPaymentTabs()} + + `; + } + + private renderPaidConfirmation(): string { + const p = this.payment; + const explorerBase: Record = { + 8453: 'https://basescan.org/tx/', + 84532: 'https://sepolia.basescan.org/tx/', + 1: 'https://etherscan.io/tx/', + }; + const explorer = explorerBase[p.chainId] || ''; + + return ` +
+
+

Payment Complete

+
+ ${p.paymentMethod ? `
Method: ${p.paymentMethod}
` : ''} + ${p.txHash ? `` : ''} + ${p.paid_at ? `
Paid: ${new Date(p.paid_at).toLocaleString()}
` : ''} +
+
`; + } + + private renderPaymentTabs(): string { + return ` +
+ + + +
+ +
+ ${this.activeTab === 'card' ? this.renderCardTab() : + this.activeTab === 'wallet' ? this.renderWalletTab() : + this.renderEncryptIDTab()} +
`; + } + + private renderCardTab(): string { + if (this.transakUrl) { + return ` +
+ +
`; + } + + return ` +
+

Pay with credit or debit card via Transak.

+
+ +
+ + ${this.error ? `
${this.esc(this.error)}
` : ''} +
`; + } + + private renderWalletTab(): string { + if (this.walletTxHash) { + return ` +
+
Transaction sent!
+
Tx: ${this.walletTxHash.slice(0, 14)}...${this.walletTxHash.slice(-10)}
+
`; + } + + if (this.walletConnected) { + return ` +
+

Connected: ${this.walletAccount.slice(0, 6)}...${this.walletAccount.slice(-4)}

+ + ${this.walletError ? `
${this.esc(this.walletError)}
` : ''} +
`; + } + + if (this.walletProviders.length === 0) { + return ` +
+

No wallets detected. Install MetaMask or another EIP-6963 compatible wallet.

+
`; + } + + return ` +
+

Select a wallet to connect:

+
+ ${this.walletProviders.map((p: any) => ` + + `).join('')} +
+ ${this.walletError ? `
${this.esc(this.walletError)}
` : ''} +
`; + } + + private renderEncryptIDTab(): string { + if (this.eidTxHash) { + return ` +
+
Transaction sent!
+
Tx: ${this.eidTxHash.slice(0, 14)}...${this.eidTxHash.slice(-10)}
+
`; + } + + return ` +
+

Pay using your EncryptID passkey. Your signing key is derived locally from your passkey and never leaves your device.

+ + ${this.eidError ? `
${this.esc(this.eidError)}
` : ''} +
`; + } + + private bindEvents() { + // Tab switching + this.shadow.querySelectorAll('[data-tab]').forEach((el) => { + el.addEventListener('click', () => { + this.activeTab = (el as HTMLElement).dataset.tab as any; + this.render(); + }); + }); + + // Custom amount for editable payments + const customAmtInput = this.shadow.querySelector('[data-field="custom-amount"]') as HTMLInputElement; + customAmtInput?.addEventListener('input', () => { this.customAmount = customAmtInput.value; }); + + // Card tab + const emailInput = this.shadow.querySelector('[data-field="card-email"]') as HTMLInputElement; + emailInput?.addEventListener('input', () => { this.cardEmail = emailInput.value; }); + this.shadow.querySelector('[data-action="start-transak"]')?.addEventListener('click', () => this.startTransak()); + + // Wallet tab + this.shadow.querySelectorAll('[data-wallet-uuid]').forEach((el) => { + el.addEventListener('click', () => this.connectWallet((el as HTMLElement).dataset.walletUuid!)); + }); + this.shadow.querySelector('[data-action="send-wallet"]')?.addEventListener('click', () => this.sendWalletPayment()); + + // EncryptID tab + this.shadow.querySelector('[data-action="pay-encryptid"]')?.addEventListener('click', () => this.payWithEncryptID()); + + // Copy URL + this.shadow.querySelector('[data-action="copy-url"]')?.addEventListener('click', () => { + navigator.clipboard.writeText(window.location.href); + const btn = this.shadow.querySelector('[data-action="copy-url"]') as HTMLElement; + if (btn) { btn.textContent = 'Copied!'; setTimeout(() => { btn.textContent = 'Copy'; }, 2000); } + }); + } + + private getStyles(): string { + return ` + :host { display: block; padding: 1.5rem; max-width: 560px; margin: 0 auto; } + * { box-sizing: border-box; } + + .payment-page { } + + .header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem; } + .title { color: var(--rs-text-primary); font-size: 1.25rem; font-weight: 700; margin: 0; } + + .status-badge { padding: 0.25rem 0.75rem; border-radius: 999px; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; } + .status-pending { background: rgba(251,191,36,0.15); color: #fbbf24; } + .status-paid, .status-confirmed { background: rgba(34,197,94,0.15); color: #4ade80; } + .status-expired { background: rgba(239,68,68,0.15); color: #f87171; } + .status-cancelled { background: rgba(156,163,175,0.15); color: #9ca3af; } + + .amount-display { text-align: center; margin-bottom: 1rem; } + .amount { display: block; font-size: 2rem; font-weight: 700; color: var(--rs-text-primary); } + .fiat-amount { display: block; font-size: 0.875rem; color: var(--rs-text-secondary); margin-top: 0.25rem; } + .chain-info { display: block; font-size: 0.75rem; color: var(--rs-text-muted); margin-top: 0.25rem; } + + .editable-amount { display: flex; align-items: center; justify-content: center; gap: 0.5rem; } + .amount-input { width: 160px; padding: 0.5rem 0.75rem; border-radius: 8px; border: 1px solid var(--rs-input-border); background: var(--rs-input-bg); color: var(--rs-text-primary); font-size: 1.75rem; font-weight: 700; text-align: center; } + .amount-input:focus { outline: none; border-color: var(--rs-primary); } + .amount-input::placeholder { color: var(--rs-text-muted); font-weight: 400; font-size: 1rem; } + .amount-token { color: var(--rs-text-secondary); font-size: 1.25rem; font-weight: 600; } + + .description { text-align: center; color: var(--rs-text-secondary); font-size: 0.9375rem; margin-bottom: 1.5rem; padding: 0.75rem; background: var(--rs-bg-surface); border-radius: 8px; border: 1px solid var(--rs-border); } + + .tabs { display: flex; gap: 0; border-bottom: 1px solid var(--rs-border); margin-bottom: 1.5rem; } + .tab { flex: 1; padding: 0.75rem 1rem; border: none; background: none; color: var(--rs-text-secondary); cursor: pointer; font-size: 0.875rem; font-weight: 500; border-bottom: 2px solid transparent; transition: all 0.15s; } + .tab:hover { color: var(--rs-text-primary); } + .tab.active { color: var(--rs-primary-hover); border-bottom-color: var(--rs-primary); } + + .tab-content { min-height: 180px; } + .tab-body { } + .tab-desc { color: var(--rs-text-secondary); font-size: 0.875rem; margin: 0 0 1rem; line-height: 1.5; } + + .form-row { margin-bottom: 1rem; } + + .input { width: 100%; padding: 0.625rem 0.75rem; border-radius: 8px; border: 1px solid var(--rs-input-border); background: var(--rs-input-bg); color: var(--rs-input-text); font-size: 0.875rem; } + .input:focus { outline: none; border-color: var(--rs-primary); } + + .btn { padding: 0.625rem 1.25rem; border-radius: 8px; border: 1px solid var(--rs-border); background: var(--rs-bg-surface); color: var(--rs-text-primary); cursor: pointer; font-size: 0.875rem; font-weight: 500; } + .btn:hover { border-color: var(--rs-border-strong); } + .btn-primary { background: var(--rs-primary-hover); border-color: var(--rs-primary); color: #fff; width: 100%; } + .btn-primary:hover { background: #4338ca; } + .btn-primary:disabled { opacity: 0.5; cursor: not-allowed; } + .btn-sm { padding: 0.375rem 0.75rem; font-size: 0.8125rem; } + + .wallet-list { display: flex; flex-direction: column; gap: 0.5rem; } + .wallet-btn { display: flex; align-items: center; gap: 0.75rem; padding: 0.75rem 1rem; border-radius: 8px; border: 1px solid var(--rs-border); background: var(--rs-bg-surface); color: var(--rs-text-primary); cursor: pointer; font-size: 0.875rem; transition: border-color 0.15s; } + .wallet-btn:hover { border-color: var(--rs-primary); } + .wallet-icon { width: 28px; height: 28px; border-radius: 6px; } + + .field-error { color: #f87171; font-size: 0.8125rem; margin-top: 0.75rem; } + .success-msg { color: #4ade80; font-size: 1rem; font-weight: 600; text-align: center; margin-bottom: 0.5rem; } + .tx-hash { color: var(--rs-text-secondary); font-size: 0.8125rem; text-align: center; font-family: monospace; } + + .confirmation { text-align: center; padding: 2rem 1rem; } + .confirm-icon { font-size: 3rem; color: #4ade80; margin-bottom: 0.5rem; } + .confirmation h2 { color: var(--rs-text-primary); font-size: 1.25rem; margin: 0 0 1rem; } + .confirm-details { color: var(--rs-text-secondary); font-size: 0.875rem; line-height: 1.8; } + .confirm-details a { color: var(--rs-primary-hover); text-decoration: none; } + .confirm-details a:hover { text-decoration: underline; } + + .terminal-msg { text-align: center; padding: 2rem; color: var(--rs-text-muted); font-size: 0.875rem; } + + .transak-container { border-radius: 8px; overflow: hidden; border: 1px solid var(--rs-border); } + .transak-iframe { width: 100%; height: 600px; border: none; } + + .footer { margin-top: 2rem; border-top: 1px solid var(--rs-border); padding-top: 1.5rem; } + .qr-section { display: flex; flex-direction: column; align-items: center; gap: 1rem; } + .qr-code { border-radius: 8px; background: #fff; padding: 8px; } + .share-url { display: flex; gap: 0.5rem; width: 100%; } + .share-input { flex: 1; padding: 0.5rem 0.75rem; border-radius: 8px; border: 1px solid var(--rs-input-border); background: var(--rs-input-bg); color: var(--rs-input-text); font-size: 0.75rem; font-family: monospace; } + + .loading { text-align: center; padding: 3rem; color: var(--rs-text-secondary); } + .error { text-align: center; padding: 3rem; color: #f87171; } + `; + } + + private esc(s: string): string { + const d = document.createElement('div'); + d.textContent = s; + return d.innerHTML; + } +} + +customElements.define('folk-payment-page', FolkPaymentPage); diff --git a/modules/rcart/components/folk-payment-request.ts b/modules/rcart/components/folk-payment-request.ts new file mode 100644 index 0000000..87f1fba --- /dev/null +++ b/modules/rcart/components/folk-payment-request.ts @@ -0,0 +1,455 @@ +/** + * — Self-service payment request generator. + * + * User flow: + * 1. Authenticate with EncryptID passkey → derives wallet address + * 2. Fill in description, amount (or leave editable), token, chain + * 3. Click "Generate QR" → creates payment request via API + * 4. Shows QR code + shareable link, ready to print/share + */ + +class FolkPaymentRequest extends HTMLElement { + private shadow: ShadowRoot; + private space = 'default'; + + // Auth state + private authenticated = false; + private walletAddress = ''; + private did = ''; + private authError = ''; + private authenticating = false; + + // Form state + private description = ''; + private amount = ''; + private amountEditable = false; + private token: 'USDC' | 'ETH' = 'USDC'; + private chainId = 8453; + + // Result state + private generating = false; + private generatedPayment: any = null; + private qrDataUrl = ''; + private payUrl = ''; + private qrSvgUrl = ''; + + private static readonly CHAIN_OPTIONS = [ + { id: 8453, name: 'Base' }, + { id: 84532, name: 'Base Sepolia (testnet)' }, + { id: 1, name: 'Ethereum' }, + ]; + + constructor() { + super(); + this.shadow = this.attachShadow({ mode: 'open' }); + } + + connectedCallback() { + this.space = this.getAttribute('space') || 'default'; + this.checkExistingSession(); + this.render(); + } + + private getApiBase(): string { + const path = window.location.pathname; + const match = path.match(/^(\/[^/]+)?\/rcart/); + return match ? match[0] : '/rcart'; + } + + // ── Auth ── + + private async checkExistingSession() { + try { + const { getSessionManager } = await import('../../../src/encryptid/session'); + const session = getSessionManager(); + if (session.isValid()) { + this.did = session.getDID() || ''; + const state = session.getSession(); + this.walletAddress = state?.claims?.eid?.walletAddress || ''; + + // If session exists but no wallet address, try deriving from key manager + if (!this.walletAddress) { + try { + const { getKeyManager } = await import('../../../src/encryptid/key-derivation'); + const km = getKeyManager(); + if (km.isInitialized()) { + const keys = await km.getKeys(); + if (keys.eoaAddress) this.walletAddress = keys.eoaAddress; + } + } catch { /* key manager not ready */ } + } + + if (this.walletAddress) { + this.authenticated = true; + this.render(); + } + } + } catch { /* session module not available */ } + } + + private async authenticate() { + this.authenticating = true; + this.authError = ''; + this.render(); + + try { + const { authenticatePasskey } = await import('../../../src/encryptid/webauthn'); + const { deriveEOAFromPRF } = await import('../../../src/encryptid/eoa-derivation'); + const { getSessionManager } = await import('../../../src/encryptid/session'); + const { EncryptIDKeyManager } = await import('../../../src/encryptid/key-derivation'); + + const result = await authenticatePasskey(); + if (!result.prfOutput) { + throw new Error('Your passkey does not support PRF — wallet address cannot be derived'); + } + + const eoa = deriveEOAFromPRF(new Uint8Array(result.prfOutput)); + this.walletAddress = eoa.address; + + // Initialize key manager for session + const km = new EncryptIDKeyManager(); + await km.initFromPRF(result.prfOutput); + const keys = await km.getKeys(); + this.did = keys.did; + + // Create session + const session = getSessionManager(); + await session.createSession(result, keys.did, { + encrypt: true, + sign: true, + wallet: true, + }); + + // Zero private key — we don't need to sign anything here + eoa.privateKey.fill(0); + + this.authenticated = true; + } catch (e) { + this.authError = e instanceof Error ? e.message : String(e); + } + this.authenticating = false; + this.render(); + } + + // ── Generate payment request ── + + private async generatePayment() { + if (!this.walletAddress || !this.description) return; + if (!this.amountEditable && !this.amount) return; + + this.generating = true; + this.render(); + + try { + const { getSessionManager } = await import('../../../src/encryptid/session'); + const session = getSessionManager(); + const accessToken = session.getSession()?.accessToken; + + const res = await fetch(`${this.getApiBase()}/api/payments`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + ...(accessToken ? { 'Authorization': `Bearer ${accessToken}` } : {}), + }, + body: JSON.stringify({ + description: this.description, + amount: this.amount || '0', + amountEditable: this.amountEditable, + token: this.token, + chainId: this.chainId, + recipientAddress: this.walletAddress, + }), + }); + + if (!res.ok) { + const err = await res.json(); + throw new Error(err.error || 'Failed to create payment request'); + } + + this.generatedPayment = await res.json(); + + // Build URLs + const host = window.location.origin; + this.payUrl = `${host}/${this.space}/rcart/pay/${this.generatedPayment.id}`; + this.qrSvgUrl = `${host}/${this.space}/rcart/api/payments/${this.generatedPayment.id}/qr`; + + // Generate client-side QR + try { + const QRCode = await import('qrcode'); + this.qrDataUrl = await QRCode.toDataURL(this.payUrl, { + margin: 2, + width: 280, + color: { dark: '#1e1b4b', light: '#ffffff' }, + }); + } catch { /* QR generation optional */ } + } catch (e) { + this.authError = e instanceof Error ? e.message : String(e); + } + this.generating = false; + this.render(); + } + + private reset() { + this.generatedPayment = null; + this.qrDataUrl = ''; + this.payUrl = ''; + this.qrSvgUrl = ''; + this.description = ''; + this.amount = ''; + this.amountEditable = false; + this.render(); + } + + // ── Render ── + + private render() { + this.shadow.innerHTML = ` + +
+

Request Payment

+

Generate a QR code anyone can scan to pay you

+ + ${this.generatedPayment ? this.renderResult() : + !this.authenticated ? this.renderAuthStep() : + this.renderForm()} +
`; + this.bindEvents(); + } + + private renderAuthStep(): string { + return ` +
+
1
+
+

Connect your identity

+

Authenticate with your EncryptID passkey to derive your wallet address. Your private key never leaves your device.

+ + ${this.authError ? `
${this.esc(this.authError)}
` : ''} +
+
`; + } + + private renderForm(): string { + return ` +
+ Receiving wallet + ${this.walletAddress.slice(0, 6)}...${this.walletAddress.slice(-4)} + ${this.walletAddress} +
+ +
+
+ + +
+ +
+
+ + +
+
+ + +
+
+ +
+ + +
+ +
+ + +
+ + + ${this.authError ? `
${this.esc(this.authError)}
` : ''} +
`; + } + + private renderResult(): string { + const p = this.generatedPayment; + const amountDisplay = this.amountEditable && (!p.amount || p.amount === '0') + ? 'Any amount' + : `${p.amount} ${p.token}`; + + return ` +
+
+
${this.esc(p.description)}
+
${amountDisplay}
+ ${this.amountEditable ? '
Amount editable by payer
' : ''} +
+ +
+ ${this.qrDataUrl + ? `Payment QR Code` + : `Payment QR Code`} +
+ + + + +
`; + } + + private bindEvents() { + // Auth + this.shadow.querySelector('[data-action="authenticate"]')?.addEventListener('click', () => this.authenticate()); + + // Form inputs + const descInput = this.shadow.querySelector('[data-field="description"]') as HTMLInputElement; + descInput?.addEventListener('input', () => { this.description = descInput.value; }); + + const amtInput = this.shadow.querySelector('[data-field="amount"]') as HTMLInputElement; + amtInput?.addEventListener('input', () => { this.amount = amtInput.value; }); + + const tokenSelect = this.shadow.querySelector('[data-field="token"]') as HTMLSelectElement; + tokenSelect?.addEventListener('change', () => { this.token = tokenSelect.value as 'USDC' | 'ETH'; }); + + const chainSelect = this.shadow.querySelector('[data-field="chainId"]') as HTMLSelectElement; + chainSelect?.addEventListener('change', () => { this.chainId = parseInt(chainSelect.value); }); + + const editableCheck = this.shadow.querySelector('[data-field="amountEditable"]') as HTMLInputElement; + editableCheck?.addEventListener('change', () => { + this.amountEditable = editableCheck.checked; + this.render(); + }); + + // Generate + this.shadow.querySelector('[data-action="generate"]')?.addEventListener('click', () => this.generatePayment()); + + // Result actions + this.shadow.querySelector('[data-action="copy-url"]')?.addEventListener('click', () => { + navigator.clipboard.writeText(this.payUrl); + const btn = this.shadow.querySelector('[data-action="copy-url"]') as HTMLElement; + if (btn) { btn.textContent = 'Copied!'; setTimeout(() => { btn.textContent = 'Copy'; }, 2000); } + }); + + this.shadow.querySelector('[data-action="print"]')?.addEventListener('click', () => { + const printWin = window.open('', '_blank', 'width=400,height=500'); + if (printWin) { + printWin.document.write(` + Payment QR + + +
${this.esc(this.description)}
+
${this.amountEditable && (!this.amount || this.amount === '0') ? 'Any amount' : `${this.amount || this.generatedPayment?.amount} ${this.token}`}
+ ${this.amountEditable ? '
Amount editable by payer
' : ''} + QR +
${this.payUrl}
+ `); + printWin.document.close(); + printWin.focus(); + printWin.print(); + } + }); + + this.shadow.querySelector('[data-action="new-request"]')?.addEventListener('click', () => this.reset()); + } + + private getStyles(): string { + return ` + :host { display: block; padding: 1.5rem; max-width: 520px; margin: 0 auto; } + * { box-sizing: border-box; } + + .page-title { color: var(--rs-text-primary); font-size: 1.5rem; font-weight: 700; margin: 0 0 0.25rem; text-align: center; } + .page-subtitle { color: var(--rs-text-secondary); font-size: 0.9375rem; text-align: center; margin: 0 0 2rem; } + + .step-card { display: flex; gap: 1rem; padding: 1.5rem; background: var(--rs-bg-surface); border: 1px solid var(--rs-border); border-radius: 12px; } + .step-num { width: 32px; height: 32px; border-radius: 50%; background: var(--rs-primary-hover); color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 0.875rem; flex-shrink: 0; } + .step-content { flex: 1; } + .step-title { color: var(--rs-text-primary); font-size: 1.125rem; font-weight: 600; margin: 0 0 0.5rem; } + .step-desc { color: var(--rs-text-secondary); font-size: 0.875rem; line-height: 1.5; margin: 0 0 1rem; } + + .wallet-badge { background: var(--rs-bg-surface); border: 1px solid var(--rs-border); border-radius: 10px; padding: 0.875rem 1rem; margin-bottom: 1.5rem; display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; } + .wallet-label { color: var(--rs-text-secondary); font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; } + .wallet-addr { color: var(--rs-text-primary); font-family: monospace; font-size: 0.9375rem; font-weight: 600; } + .wallet-full { display: none; } + + .form { display: flex; flex-direction: column; gap: 1rem; } + .field { display: flex; flex-direction: column; gap: 0.375rem; } + .field-row { display: flex; gap: 0.75rem; } + .label { color: var(--rs-text-secondary); font-size: 0.8125rem; font-weight: 500; } + .required { color: #f87171; } + .hint { color: var(--rs-text-muted); font-weight: 400; } + + .input { padding: 0.625rem 0.75rem; border-radius: 8px; border: 1px solid var(--rs-input-border); background: var(--rs-input-bg); color: var(--rs-input-text); font-size: 0.875rem; } + .input:focus { outline: none; border-color: var(--rs-primary); } + select.input { cursor: pointer; } + + .field-check { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 0; } + .field-check input[type="checkbox"] { width: 18px; height: 18px; accent-color: var(--rs-primary-hover); cursor: pointer; } + .field-check label { color: var(--rs-text-primary); font-size: 0.875rem; cursor: pointer; } + + .btn { padding: 0.625rem 1.25rem; border-radius: 8px; border: 1px solid var(--rs-border); background: var(--rs-bg-surface); color: var(--rs-text-primary); cursor: pointer; font-size: 0.875rem; font-weight: 500; text-decoration: none; text-align: center; display: inline-block; } + .btn:hover { border-color: var(--rs-border-strong); } + .btn-primary { background: var(--rs-primary-hover); border-color: var(--rs-primary); color: #fff; width: 100%; } + .btn-primary:hover { background: #4338ca; } + .btn-primary:disabled { opacity: 0.5; cursor: not-allowed; } + .btn-lg { padding: 0.875rem 1.5rem; font-size: 1rem; margin-top: 0.5rem; } + .btn-sm { padding: 0.375rem 0.75rem; font-size: 0.8125rem; } + .btn-outline { background: transparent; border: 1px solid var(--rs-border); color: var(--rs-text-secondary); width: 100%; } + .btn-outline:hover { border-color: var(--rs-text-secondary); color: var(--rs-text-primary); } + + .field-error { color: #f87171; font-size: 0.8125rem; margin-top: 0.5rem; } + + /* Result */ + .result { text-align: center; } + .result-header { margin-bottom: 1.5rem; } + .result-desc { color: var(--rs-text-secondary); font-size: 1rem; margin-bottom: 0.25rem; } + .result-amount { color: var(--rs-text-primary); font-size: 2rem; font-weight: 700; } + .result-hint { color: var(--rs-text-muted); font-size: 0.8125rem; margin-top: 0.25rem; } + + .qr-display { margin: 0 auto 1.5rem; padding: 1rem; background: #fff; border-radius: 12px; display: inline-block; } + .qr-img { display: block; max-width: 280px; border-radius: 4px; } + + .share-section { } + .share-row { display: flex; gap: 0.5rem; margin-bottom: 0.75rem; } + .share-input { flex: 1; padding: 0.5rem 0.75rem; border-radius: 8px; border: 1px solid var(--rs-input-border); background: var(--rs-input-bg); color: var(--rs-input-text); font-size: 0.75rem; font-family: monospace; } + .action-row { display: flex; gap: 0.5rem; justify-content: center; flex-wrap: wrap; } + + @media (max-width: 480px) { + .field-row { flex-direction: column; } + .action-row { flex-direction: column; } + } + `; + } + + private esc(s: string): string { + const d = document.createElement('div'); + d.textContent = s; + return d.innerHTML; + } +} + +customElements.define('folk-payment-request', FolkPaymentRequest); diff --git a/modules/rcart/mod.ts b/modules/rcart/mod.ts index a1a3a39..0e1bd55 100644 --- a/modules/rcart/mod.ts +++ b/modules/rcart/mod.ts @@ -19,13 +19,18 @@ import { renderLanding } from "./landing"; import type { SyncServer } from '../../server/local-first/sync-server'; import { catalogSchema, orderSchema, shoppingCartSchema, shoppingCartIndexSchema, + paymentRequestSchema, catalogDocId, orderDocId, shoppingCartDocId, shoppingCartIndexDocId, + paymentRequestDocId, type CatalogDoc, type CatalogEntry, type OrderDoc, type OrderMeta, type ShoppingCartDoc, type ShoppingCartIndexDoc, + type PaymentRequestDoc, type PaymentRequestMeta, type CartItem, type CartStatus, } from './schemas'; import { extractProductFromUrl } from './extract'; +import { createTransakWidgetUrl } from '../../shared/transak'; +import QRCode from 'qrcode'; let _syncServer: SyncServer | null = null; @@ -1093,6 +1098,304 @@ routes.get("/api/cart/summary", async (c) => { }); }); +// ── PAYMENT REQUEST helpers ── + +/** Get all payment request docs for a space. */ +function getSpacePaymentDocs(space: string): Array<{ docId: string; doc: Automerge.Doc }> { + const prefix = `${space}:cart:payments:`; + const results: Array<{ docId: string; doc: Automerge.Doc }> = []; + for (const id of _syncServer!.listDocs()) { + if (id.startsWith(prefix)) { + const doc = _syncServer!.getDoc(id); + if (doc) results.push({ docId: id, doc }); + } + } + return results; +} + +// USDC contract addresses +const USDC_ADDRESSES: Record = { + 8453: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // Base + 84532: '0x036CbD53842c5426634e7929541eC2318f3dCF7e', // Base Sepolia + 1: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // Ethereum +}; + +// ── PAYMENT REQUEST ROUTES ── + +// POST /api/payments — Create payment request (auth required) +routes.post("/api/payments", async (c) => { + const space = c.req.param("space") || "demo"; + const token = extractToken(c.req.raw.headers); + if (!token) return c.json({ error: "Authentication required" }, 401); + + let claims; + try { claims = await verifyEncryptIDToken(token); } catch { return c.json({ error: "Invalid token" }, 401); } + + const body = await c.req.json(); + const { + description, amount, amountEditable = false, + token: payToken = 'USDC', + chainId = 8453, recipientAddress, + fiatAmount = null, fiatCurrency = 'USD', + expiresIn = 0, // seconds, 0 = no expiry + } = body; + + if (!description || !recipientAddress) { + return c.json({ error: "Required: description, recipientAddress" }, 400); + } + if (!amountEditable && !amount) { + return c.json({ error: "Required: amount (or set amountEditable: true)" }, 400); + } + + const paymentId = crypto.randomUUID(); + const now = Date.now(); + const expiresAt = expiresIn > 0 ? now + expiresIn * 1000 : 0; + + const docId = paymentRequestDocId(space, paymentId); + const payDoc = Automerge.change(Automerge.init(), 'create payment request', (d) => { + const init = paymentRequestSchema.init(); + Object.assign(d, init); + d.meta.spaceSlug = space; + d.payment.id = paymentId; + d.payment.description = description; + d.payment.amount = amount ? String(amount) : '0'; + d.payment.amountEditable = !!amountEditable; + d.payment.token = payToken; + d.payment.chainId = chainId; + d.payment.recipientAddress = recipientAddress; + d.payment.fiatAmount = fiatAmount ? String(fiatAmount) : null; + d.payment.fiatCurrency = fiatCurrency; + d.payment.creatorDid = claims.sub; + d.payment.status = 'pending'; + d.payment.createdAt = now; + d.payment.updatedAt = now; + d.payment.expiresAt = expiresAt; + }); + _syncServer!.setDoc(docId, payDoc); + + const host = c.req.header("host") || "rspace.online"; + const payUrl = `https://${host}/${space}/rcart/pay/${paymentId}`; + + return c.json({ + id: paymentId, + description, + amount: String(amount), + token: payToken, + chainId, + recipientAddress, + status: 'pending', + payUrl, + qrUrl: `https://${host}/${space}/rcart/api/payments/${paymentId}/qr`, + created_at: new Date(now).toISOString(), + }, 201); +}); + +// GET /api/payments — List my payment requests (auth required) +routes.get("/api/payments", async (c) => { + const space = c.req.param("space") || "demo"; + const token = extractToken(c.req.raw.headers); + if (!token) return c.json({ error: "Authentication required" }, 401); + + let claims; + try { claims = await verifyEncryptIDToken(token); } catch { return c.json({ error: "Invalid token" }, 401); } + + const paymentDocs = getSpacePaymentDocs(space); + const payments = paymentDocs + .map(({ doc }) => doc.payment) + .filter((p) => p.creatorDid === claims.sub) + .sort((a, b) => b.createdAt - a.createdAt) + .map((p) => ({ + id: p.id, + description: p.description, + amount: p.amount, + token: p.token, + chainId: p.chainId, + recipientAddress: p.recipientAddress, + fiatAmount: p.fiatAmount, + fiatCurrency: p.fiatCurrency, + status: p.status, + paymentMethod: p.paymentMethod, + txHash: p.txHash, + created_at: new Date(p.createdAt).toISOString(), + paid_at: p.paidAt ? new Date(p.paidAt).toISOString() : null, + })); + + return c.json({ payments }); +}); + +// GET /api/payments/:id — Get payment details (public) +routes.get("/api/payments/:id", async (c) => { + const space = c.req.param("space") || "demo"; + const paymentId = c.req.param("id"); + const docId = paymentRequestDocId(space, paymentId); + const doc = _syncServer!.getDoc(docId); + if (!doc) return c.json({ error: "Payment request not found" }, 404); + + const p = doc.payment; + + // Check expiry + if (p.expiresAt > 0 && Date.now() > p.expiresAt && p.status === 'pending') { + _syncServer!.changeDoc(docId, 'expire payment', (d) => { + d.payment.status = 'expired'; + d.payment.updatedAt = Date.now(); + }); + return c.json({ + ...paymentToResponse(p), + status: 'expired', + usdcAddress: USDC_ADDRESSES[p.chainId] || null, + }); + } + + return c.json({ + ...paymentToResponse(p), + usdcAddress: USDC_ADDRESSES[p.chainId] || null, + }); +}); + +// PATCH /api/payments/:id/status — Update payment status +routes.patch("/api/payments/:id/status", async (c) => { + const space = c.req.param("space") || "demo"; + const paymentId = c.req.param("id"); + const docId = paymentRequestDocId(space, paymentId); + const doc = _syncServer!.getDoc(docId); + if (!doc) return c.json({ error: "Payment request not found" }, 404); + + const body = await c.req.json(); + const { status, txHash, paymentMethod, payerIdentity, transakOrderId, amount } = body; + const validStatuses = ['pending', 'paid', 'confirmed', 'expired', 'cancelled']; + if (status && !validStatuses.includes(status)) { + return c.json({ error: `status must be one of: ${validStatuses.join(", ")}` }, 400); + } + + const now = Date.now(); + _syncServer!.changeDoc(docId, `payment status → ${status || 'update'}`, (d) => { + if (status) d.payment.status = status; + if (txHash) d.payment.txHash = txHash; + if (paymentMethod) d.payment.paymentMethod = paymentMethod; + if (payerIdentity) d.payment.payerIdentity = payerIdentity; + if (transakOrderId) d.payment.transakOrderId = transakOrderId; + // Allow amount update only if payment is editable and still pending + if (amount && d.payment.amountEditable && d.payment.status === 'pending') { + d.payment.amount = String(amount); + } + d.payment.updatedAt = now; + if (status === 'paid') d.payment.paidAt = now; + }); + + const updated = _syncServer!.getDoc(docId); + return c.json(paymentToResponse(updated!.payment)); +}); + +// GET /api/payments/:id/qr — QR code SVG +routes.get("/api/payments/:id/qr", async (c) => { + const space = c.req.param("space") || "demo"; + const paymentId = c.req.param("id"); + const docId = paymentRequestDocId(space, paymentId); + const doc = _syncServer!.getDoc(docId); + if (!doc) return c.json({ error: "Payment request not found" }, 404); + + const host = c.req.header("host") || "rspace.online"; + const payUrl = `https://${host}/${space}/rcart/pay/${paymentId}`; + + const svg = await QRCode.toString(payUrl, { type: 'svg', margin: 2 }); + return c.body(svg, 200, { 'Content-Type': 'image/svg+xml', 'Cache-Control': 'public, max-age=3600' }); +}); + +// POST /api/payments/:id/transak-session — Get Transak widget URL (public) +routes.post("/api/payments/:id/transak-session", async (c) => { + const space = c.req.param("space") || "demo"; + const paymentId = c.req.param("id"); + const docId = paymentRequestDocId(space, paymentId); + const doc = _syncServer!.getDoc(docId); + if (!doc) return c.json({ error: "Payment request not found" }, 404); + + const p = doc.payment; + if (p.status !== 'pending') return c.json({ error: "Payment is no longer pending" }, 400); + + const { email } = await c.req.json(); + if (!email) return c.json({ error: "Required: email" }, 400); + + const transakApiKey = process.env.TRANSAK_API_KEY; + if (!transakApiKey) return c.json({ error: "Transak not configured" }, 503); + + const networkMap: Record = { 8453: 'base', 84532: 'base', 1: 'ethereum' }; + + try { + const widgetUrl = await createTransakWidgetUrl({ + apiKey: transakApiKey, + referrerDomain: 'rspace.online', + cryptoCurrencyCode: p.token, + network: networkMap[p.chainId] || 'base', + defaultCryptoCurrency: p.token, + walletAddress: p.recipientAddress, + disableWalletAddressForm: 'true', + cryptoAmount: p.amount, + partnerOrderId: `pay-${paymentId}`, + email, + themeColor: '6366f1', + hideMenu: 'true', + }); + + return c.json({ widgetUrl }); + } catch (err) { + return c.json({ error: err instanceof Error ? err.message : String(err) }, 500); + } +}); + +function paymentToResponse(p: PaymentRequestMeta) { + return { + id: p.id, + description: p.description, + amount: p.amount, + amountEditable: p.amountEditable, + token: p.token, + chainId: p.chainId, + recipientAddress: p.recipientAddress, + fiatAmount: p.fiatAmount, + fiatCurrency: p.fiatCurrency, + status: p.status, + paymentMethod: p.paymentMethod, + txHash: p.txHash, + payerIdentity: p.payerIdentity, + transakOrderId: p.transakOrderId, + created_at: new Date(p.createdAt).toISOString(), + updated_at: new Date(p.updatedAt).toISOString(), + paid_at: p.paidAt ? new Date(p.paidAt).toISOString() : null, + expires_at: p.expiresAt ? new Date(p.expiresAt).toISOString() : null, + }; +} + +// ── Page route: request payment (self-service QR generator) ── +routes.get("/request", (c) => { + const space = c.req.param("space") || "demo"; + return c.html(renderShell({ + title: `Request Payment | rCart`, + moduleId: "rcart", + spaceSlug: space, + modules: getModuleInfoList(), + theme: "dark", + body: ``, + scripts: ``, + styles: ``, + })); +}); + +// ── Page route: payment page ── +routes.get("/pay/:id", (c) => { + const space = c.req.param("space") || "demo"; + const paymentId = c.req.param("id"); + return c.html(renderShell({ + title: `Payment | rCart`, + moduleId: "rcart", + spaceSlug: space, + modules: getModuleInfoList(), + theme: "dark", + body: ``, + scripts: ``, + styles: ``, + })); +}); + // ── Page route: shop ── routes.get("/", (c) => { const space = c.req.param("space") || "demo"; @@ -1164,6 +1467,7 @@ export const cartModule: RSpaceModule = { { pattern: '{space}:cart:orders:{orderId}', description: 'Order document', init: orderSchema.init }, { pattern: '{space}:cart:shopping:{cartId}', description: 'Shopping cart', init: shoppingCartSchema.init }, { pattern: '{space}:cart:shopping-index', description: 'Shopping cart index', init: shoppingCartIndexSchema.init }, + { pattern: '{space}:cart:payments:{paymentId}', description: 'Payment request', init: paymentRequestSchema.init }, ], routes, standaloneDomain: "rcart.online", diff --git a/modules/rcart/schemas.ts b/modules/rcart/schemas.ts index 01b11c2..1cb65f3 100644 --- a/modules/rcart/schemas.ts +++ b/modules/rcart/schemas.ts @@ -274,6 +274,77 @@ export const shoppingCartIndexSchema: DocSchema = { }), }; +// ── Payment Request types ── + +export interface PaymentRequestMeta { + id: string; + description: string; + amount: string; + amountEditable: boolean; + token: string; + chainId: number; + recipientAddress: string; + fiatAmount: string | null; + fiatCurrency: string; + creatorDid: string; + status: 'pending' | 'paid' | 'confirmed' | 'expired' | 'cancelled'; + paymentMethod: 'transak' | 'wallet' | 'encryptid' | null; + txHash: string | null; + payerIdentity: string | null; + transakOrderId: string | null; + createdAt: number; + updatedAt: number; + paidAt: number; + expiresAt: number; +} + +export interface PaymentRequestDoc { + meta: { + module: string; + collection: string; + version: number; + spaceSlug: string; + createdAt: number; + }; + payment: PaymentRequestMeta; +} + +export const paymentRequestSchema: DocSchema = { + module: 'cart', + collection: 'payments', + version: 1, + init: (): PaymentRequestDoc => ({ + meta: { + module: 'cart', + collection: 'payments', + version: 1, + spaceSlug: '', + createdAt: Date.now(), + }, + payment: { + id: '', + description: '', + amount: '0', + amountEditable: false, + token: 'USDC', + chainId: 8453, + recipientAddress: '', + fiatAmount: null, + fiatCurrency: 'USD', + creatorDid: '', + status: 'pending', + paymentMethod: null, + txHash: null, + payerIdentity: null, + transakOrderId: null, + createdAt: Date.now(), + updatedAt: Date.now(), + paidAt: 0, + expiresAt: 0, + }, + }), +}; + // ── Helpers ── export function catalogDocId(space: string) { @@ -291,3 +362,7 @@ export function shoppingCartDocId(space: string, cartId: string) { export function shoppingCartIndexDocId(space: string) { return `${space}:cart:shopping-index` as const; } + +export function paymentRequestDocId(space: string, paymentId: string) { + return `${space}:cart:payments:${paymentId}` as const; +} diff --git a/modules/rnetwork/landing.ts b/modules/rnetwork/landing.ts index d47c026..09a548e 100644 --- a/modules/rnetwork/landing.ts +++ b/modules/rnetwork/landing.ts @@ -19,6 +19,11 @@ export function renderLanding(): string { Explore Network Create a Space +

+ + Start Guided Tour → + +

diff --git a/package-lock.json b/package-lock.json index 51412c9..35d95ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,24 +11,52 @@ "@automerge/automerge": "^2.2.8", "@aws-sdk/client-s3": "^3.700.0", "@encryptid/sdk": "file:../encryptid-sdk", + "@google/genai": "^1.43.0", + "@google/generative-ai": "^0.24.1", "@lit/reactive-element": "^2.0.4", + "@noble/curves": "^1.8.0", + "@noble/hashes": "^1.7.0", + "@openfort/openfort-node": "^0.7.0", + "@tiptap/core": "^3.20.0", + "@tiptap/extension-code-block-lowlight": "^3.20.0", + "@tiptap/extension-image": "^3.20.0", + "@tiptap/extension-link": "^3.20.0", + "@tiptap/extension-placeholder": "^3.20.0", + "@tiptap/extension-task-item": "^3.20.0", + "@tiptap/extension-task-list": "^3.20.0", + "@tiptap/extension-typography": "^3.20.0", + "@tiptap/extension-underline": "^3.20.0", + "@tiptap/pm": "^3.20.0", + "@tiptap/starter-kit": "^3.20.0", + "@types/qrcode": "^1.5.6", "@x402/core": "^2.3.1", - "@x402/evm": "^2.3.1", + "@x402/evm": "^2.5.0", + "cron-parser": "^5.5.0", "hono": "^4.11.7", "imapflow": "^1.0.170", + "jose": "^6.0.11", + "jszip": "^3.10.1", + "lowlight": "^3.3.0", "mailparser": "^3.7.2", + "marked": "^17.0.3", "nodemailer": "^6.9.0", "perfect-arrows": "^0.3.7", "perfect-freehand": "^1.2.2", "postgres": "^3.4.5", - "sharp": "^0.33.0" + "qrcode": "^1.5.4", + "sharp": "^0.33.0", + "web-push": "^3.6.7", + "yaml": "^2.8.2" }, "devDependencies": { "@types/mailparser": "^3.4.0", "@types/node": "^22.10.1", "@types/nodemailer": "^6.4.0", + "@types/web-push": "^3.6.4", + "@x402/fetch": "^2.5.0", "bun-types": "^1.1.38", "typescript": "^5.7.2", + "viem": "^2.46.3", "vite": "^6.0.3", "vite-plugin-top-level-await": "^1.6.0", "vite-plugin-wasm": "^3.5.0" @@ -36,7 +64,7 @@ }, "../encryptid-sdk": { "name": "@encryptid/sdk", - "version": "0.1.0", + "version": "0.2.0", "license": "MIT", "dependencies": { "@noble/curves": "^2.0.1", @@ -1478,6 +1506,38 @@ "node": ">=18" } }, + "node_modules/@google/genai": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.44.0.tgz", + "integrity": "sha512-kRt9ZtuXmz+tLlcNntN/VV4LRdpl6ZOu5B1KbfNgfR65db15O6sUQcwnwLka8sT/V6qysD93fWrgJHF2L7dA9A==", + "license": "Apache-2.0", + "dependencies": { + "google-auth-library": "^10.3.0", + "p-retry": "^4.6.2", + "protobufjs": "^7.5.4", + "ws": "^8.18.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@modelcontextprotocol/sdk": "^1.25.2" + }, + "peerDependenciesMeta": { + "@modelcontextprotocol/sdk": { + "optional": true + } + } + }, + "node_modules/@google/generative-ai": { + "version": "0.24.1", + "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.24.1.tgz", + "integrity": "sha512-MqO+MLfM6kjxcKoy0p1wRzG3b4ZZXtPI+z2IE26UogS2Cm/XHO+7gGRBh6gcJsOiIVoH93UwKvW4HdgiOZCy9Q==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@img/sharp-darwin-arm64": { "version": "0.33.5", "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", @@ -1839,6 +1899,23 @@ "url": "https://opencollective.com/libvips" } }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@lit-labs/ssr-dom-shim": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.5.1.tgz", @@ -1867,36 +1944,154 @@ } }, "node_modules/@noble/curves": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", - "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.7.tgz", + "integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==", "license": "MIT", - "peer": true, "dependencies": { - "@noble/hashes": "1.3.2" + "@noble/hashes": "1.8.0" + }, + "engines": { + "node": "^14.21.3 || >=16" }, "funding": { "url": "https://paulmillr.com/funding/" } }, "node_modules/@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", "license": "MIT", "engines": { - "node": ">= 16" + "node": "^14.21.3 || >=16" }, "funding": { "url": "https://paulmillr.com/funding/" } }, + "node_modules/@openfort/openfort-node": { + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/@openfort/openfort-node/-/openfort-node-0.7.7.tgz", + "integrity": "sha512-z/8tFDJwj9G18Vjr3Fki2wwgZLhnbjhB7FHhPUBmonKjv9V7nGa5bwVWRnX/Q4THIN7xmRhrJIFf9K2bpRyQTQ==", + "license": "MIT", + "dependencies": { + "@openfort/shield-js": "^0.1.33", + "@types/node": "*", + "@types/node-fetch": "^2.5.7", + "axios": "^1.7.0", + "axios-retry": "^4.5.0", + "bs58": "^6.0.0", + "jose": "^5.2.0", + "node-fetch": "^2.6.0", + "viem": "^2.21.0" + } + }, + "node_modules/@openfort/openfort-node/node_modules/jose": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.10.0.tgz", + "integrity": "sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/@openfort/shield-js": { + "version": "0.1.35", + "resolved": "https://registry.npmjs.org/@openfort/shield-js/-/shield-js-0.1.35.tgz", + "integrity": "sha512-S/v73xRnbgv5i47IRJ7cPWOnJ1bUTOJN+048Y8mJ+ya+iRJUXKTTqePaWApvfrVHHcKA+li8QGyDsRRDefLLVQ==", + "license": "MIT", + "dependencies": { + "axios": "1.13.6", + "axios-retry": "4.5.0" + } + }, "node_modules/@pinojs/redact": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz", "integrity": "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==", "license": "MIT" }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@remirror/core-constants": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-3.0.0.tgz", + "integrity": "sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==", + "license": "MIT" + }, "node_modules/@rollup/plugin-virtual": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-3.0.2.tgz", @@ -2288,33 +2483,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@scure/bip32/node_modules/@noble/curves": { - "version": "1.9.7", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.7.tgz", - "integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.8.0" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip32/node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@scure/bip39": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz", @@ -2328,18 +2496,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@scure/bip39/node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@selderee/plugin-htmlparser2": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz", @@ -3361,6 +3517,461 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/@tiptap/core": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.20.1.tgz", + "integrity": "sha512-SwkPEWIfaDEZjC8SEIi4kZjqIYUbRgLUHUuQezo5GbphUNC8kM1pi3C3EtoOPtxXrEbY6e4pWEzW54Pcrd+rVA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/pm": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-blockquote": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-3.20.1.tgz", + "integrity": "sha512-WzNXk/63PQI2fav4Ta6P0GmYRyu8Gap1pV3VUqaVK829iJ6Zt1T21xayATHEHWMK27VT1GLPJkx9Ycr2jfDyQw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-bold": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-3.20.1.tgz", + "integrity": "sha512-fz++Qv6Rk/Hov0IYG/r7TJ1Y4zWkuGONe0UN5g0KY32NIMg3HeOHicbi4xsNWTm9uAOl3eawWDkezEMrleObMw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-bullet-list": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-3.20.1.tgz", + "integrity": "sha512-mbrlvOZo5OF3vLhp+3fk9KuL/6J/wsN0QxF6ZFRAHzQ9NkJdtdfARcBeBnkWXGN8inB6YxbTGY1/E4lmBkOpOw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extension-list": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-code": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-3.20.1.tgz", + "integrity": "sha512-509DHINIA/Gg+eTG7TEkfsS8RUiPLH5xZNyLRT0A1oaoaJmECKfrV6aAm05IdfTyqDqz6LW5pbnX6DdUC4keug==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-code-block": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-3.20.1.tgz", + "integrity": "sha512-vKejwBq+Nlj4Ybd3qOyDxIQKzYymdNH+8eXkKwGShk2nfLJIxq69DCyGvmuHgipIO1qcYPJ149UNpGN+YGcdmA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.20.1", + "@tiptap/pm": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-code-block-lowlight": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block-lowlight/-/extension-code-block-lowlight-3.20.1.tgz", + "integrity": "sha512-QJXZGN43HArGNl5HeiPF1fXZZs6FWJwG3wTr9v+OwsM8EX3ixyblIoeY0/nmFBlQqci49ZA/KfCqVwfGNlRj5A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.20.1", + "@tiptap/extension-code-block": "^3.20.1", + "@tiptap/pm": "^3.20.1", + "highlight.js": "^11", + "lowlight": "^2 || ^3" + } + }, + "node_modules/@tiptap/extension-document": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-3.20.1.tgz", + "integrity": "sha512-9vrqdGmRV7bQCSY3NLgu7UhIwgOCDp4sKqMNsoNRX0aZ021QQMTvBQDPkiRkCf7MNsnWrNNnr52PVnULEn3vFQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-dropcursor": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-3.20.1.tgz", + "integrity": "sha512-K18L9FX4znn+ViPSIbTLOGcIaXMx/gLNwAPE8wPLwswbHhQqdiY1zzdBw6drgOc1Hicvebo2dIoUlSXOZsOEcw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extensions": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-gapcursor": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-3.20.1.tgz", + "integrity": "sha512-kZOtttV6Ai8VUAgEng3h4WKFbtdSNJ6ps7r0cRPY+FctWhVmgNb/JJwwyC+vSilR7nRENAhrA/Cv/RxVlvLw+g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extensions": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-hard-break": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-3.20.1.tgz", + "integrity": "sha512-9sKpmg/IIdlLXimYWUZ3PplIRcehv4Oc7V1miTqlnAthMzjMqigDkjjgte4JZV67RdnDJTQkRw8TklCAU28Emg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-heading": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-3.20.1.tgz", + "integrity": "sha512-unudyfQP6FxnyWinxvPqe/51DG91J6AaJm666RnAubgYMCgym+33kBftx4j4A6qf+ddWYbD00thMNKOnVLjAEQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-horizontal-rule": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-3.20.1.tgz", + "integrity": "sha512-rjFKFXNntdl0jay8oIGFvvykHlpyQTLmrH3Ag2fj3i8yh6MVvqhtaDomYQbw5sxECd5hBkL+T4n2d2DRuVw/QQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.20.1", + "@tiptap/pm": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-image": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-image/-/extension-image-3.20.1.tgz", + "integrity": "sha512-/GPFSLNdYSZQ0E6VBXSAk0UFtDdn98HT1Aa2tO+STELqc5jAdFB42dfFnTC6KQzTvcUOUYkE2S1Q22YC5H2XNQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-italic": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-3.20.1.tgz", + "integrity": "sha512-ZYRX13Kt8tR8JOzSXirH3pRpi8x30o7LHxZY58uXBdUvr3tFzOkh03qbN523+diidSVeHP/aMd/+IrplHRkQug==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-link": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-3.20.1.tgz", + "integrity": "sha512-oYTTIgsQMqpkSnJAuAc+UtIKMuI4lv9e1y4LfI1iYm6NkEUHhONppU59smhxHLzb3Ww7YpDffbp5IgDTAiJztA==", + "license": "MIT", + "dependencies": { + "linkifyjs": "^4.3.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.20.1", + "@tiptap/pm": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-list": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list/-/extension-list-3.20.1.tgz", + "integrity": "sha512-euBRAn0mkV7R2VEE+AuOt3R0j9RHEMFXamPFmtvTo8IInxDClusrm6mJoDjS8gCGAXsQCRiAe1SCQBPgGbOOwg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.20.1", + "@tiptap/pm": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-list-item": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-3.20.1.tgz", + "integrity": "sha512-tzgnyTW82lYJkUnadYbatwkI9dLz/OWRSWuFpQPRje/ItmFMWuQ9c9NDD8qLbXPdEYnvrgSAA+ipCD/1G0qA0Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extension-list": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-list-keymap": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-keymap/-/extension-list-keymap-3.20.1.tgz", + "integrity": "sha512-Dr0xsQKx0XPOgDg7xqoWwfv7FFwZ3WeF3eOjqh3rDXlNHMj1v+UW5cj1HLphrsAZHTrVTn2C+VWPJkMZrSbpvQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extension-list": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-ordered-list": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-3.20.1.tgz", + "integrity": "sha512-Y+3Ad7OwAdagqdYwCnbqf7/to5ypD4NnUNHA0TXRCs7cAHRA8AdgPoIcGFpaaSpV86oosNU3yfeJouYeroffog==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extension-list": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-paragraph": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-3.20.1.tgz", + "integrity": "sha512-QFrAtXNyv7JSnomMQc1nx5AnG9mMznfbYJAbdOQYVdbLtAzTfiTuNPNbQrufy5ZGtGaHxDCoaygu2QEfzaKG+Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-placeholder": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-3.20.1.tgz", + "integrity": "sha512-k+jfbCugYGuIFBdojukgEopGazIMOgHrw46FnyN2X/6ICOIjQP2rh2ObslrsUOsJYoEevxCsNF9hZl1HvWX66g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extensions": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-strike": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-3.20.1.tgz", + "integrity": "sha512-EYgyma10lpsY+rwbVQL9u+gA7hBlKLSMFH7Zgd37FSxukOjr+HE8iKPQQ+SwbGejyDsPlLT8Z5Jnuxo5Ng90Pg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-task-item": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-task-item/-/extension-task-item-3.20.1.tgz", + "integrity": "sha512-ZdQld5Jzw/b/zl9TSA3KNkucmQhW5lHS/0YEKb+eFvxMwdHTKSpsTQzrfzbJixcdSqsuKJB+uUCwDDB+l0CRlA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extension-list": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-task-list": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-task-list/-/extension-task-list-3.20.1.tgz", + "integrity": "sha512-fbWsbp2ybWZUn9zcdgvFIcVya7v8kISuy91SULM1lhLwIsjNC15IPqp/ZEFJJJDKWBVr0o6bvLMsXwph/azO+w==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extension-list": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-text": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-3.20.1.tgz", + "integrity": "sha512-7PlIbYW8UenV6NPOXHmv8IcmPGlGx6HFq66RmkJAOJRPXPkTLAiX0N8rQtzUJ6jDEHqoJpaHFEHJw0xzW1yF+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-typography": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-typography/-/extension-typography-3.20.1.tgz", + "integrity": "sha512-iqgB46r391vGlTr61jl6EWKGtyvorgIr+5Iqrze5ZSU8An2ZT0R4CPUI0FcLAAe0PuK8tCLhKtAidNXQotkOiw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.20.1" + } + }, + "node_modules/@tiptap/extension-underline": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-3.20.1.tgz", + "integrity": "sha512-fmHvDKzwCgnZUwRreq8tYkb1YyEwgzZ6QQkAQ0CsCRtvRMqzerr3Duz0Als4i8voZTuGDEL3VR6nAJbLAb/wPg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.20.1" + } + }, + "node_modules/@tiptap/extensions": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extensions/-/extensions-3.20.1.tgz", + "integrity": "sha512-JRc/v+OBH0qLTdvQ7HvHWTxGJH73QOf1MC0R8NhOX2QnAbg2mPFv1h+FjGa2gfLGuCXBdWQomjekWkUKbC4e5A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.20.1", + "@tiptap/pm": "^3.20.1" + } + }, + "node_modules/@tiptap/pm": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.20.1.tgz", + "integrity": "sha512-6kCiGLvpES4AxcEuOhb7HR7/xIeJWMjZlb6J7e8zpiIh5BoQc7NoRdctsnmFEjZvC19bIasccshHQ7H2zchWqw==", + "license": "MIT", + "dependencies": { + "prosemirror-changeset": "^2.3.0", + "prosemirror-collab": "^1.3.1", + "prosemirror-commands": "^1.6.2", + "prosemirror-dropcursor": "^1.8.1", + "prosemirror-gapcursor": "^1.3.2", + "prosemirror-history": "^1.4.1", + "prosemirror-inputrules": "^1.4.0", + "prosemirror-keymap": "^1.2.2", + "prosemirror-markdown": "^1.13.1", + "prosemirror-menu": "^1.2.4", + "prosemirror-model": "^1.24.1", + "prosemirror-schema-basic": "^1.2.3", + "prosemirror-schema-list": "^1.5.0", + "prosemirror-state": "^1.4.3", + "prosemirror-tables": "^1.6.4", + "prosemirror-trailing-node": "^3.0.0", + "prosemirror-transform": "^1.10.2", + "prosemirror-view": "^1.38.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + } + }, + "node_modules/@tiptap/starter-kit": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-3.20.1.tgz", + "integrity": "sha512-opqWxL/4OTEiqmVC0wsU4o3JhAf6LycJ2G/gRIZVAIFLljI9uHfpPMTFGxZ5w9IVVJaP5PJysfwW/635kKqkrw==", + "license": "MIT", + "dependencies": { + "@tiptap/core": "^3.20.1", + "@tiptap/extension-blockquote": "^3.20.1", + "@tiptap/extension-bold": "^3.20.1", + "@tiptap/extension-bullet-list": "^3.20.1", + "@tiptap/extension-code": "^3.20.1", + "@tiptap/extension-code-block": "^3.20.1", + "@tiptap/extension-document": "^3.20.1", + "@tiptap/extension-dropcursor": "^3.20.1", + "@tiptap/extension-gapcursor": "^3.20.1", + "@tiptap/extension-hard-break": "^3.20.1", + "@tiptap/extension-heading": "^3.20.1", + "@tiptap/extension-horizontal-rule": "^3.20.1", + "@tiptap/extension-italic": "^3.20.1", + "@tiptap/extension-link": "^3.20.1", + "@tiptap/extension-list": "^3.20.1", + "@tiptap/extension-list-item": "^3.20.1", + "@tiptap/extension-list-keymap": "^3.20.1", + "@tiptap/extension-ordered-list": "^3.20.1", + "@tiptap/extension-paragraph": "^3.20.1", + "@tiptap/extension-strike": "^3.20.1", + "@tiptap/extension-text": "^3.20.1", + "@tiptap/extension-underline": "^3.20.1", + "@tiptap/extensions": "^3.20.1", + "@tiptap/pm": "^3.20.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + } + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -3368,6 +3979,21 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", + "license": "MIT" + }, "node_modules/@types/mailparser": { "version": "3.4.6", "resolved": "https://registry.npmjs.org/@types/mailparser/-/mailparser-3.4.6.tgz", @@ -3379,16 +4005,41 @@ "iconv-lite": "^0.6.3" } }, + "node_modules/@types/markdown-it": { + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", + "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", + "license": "MIT", + "dependencies": { + "@types/linkify-it": "^5", + "@types/mdurl": "^2" + } + }, + "node_modules/@types/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", + "license": "MIT" + }, "node_modules/@types/node": { "version": "22.19.11", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.11.tgz", "integrity": "sha512-BH7YwL6rA93ReqeQS1c4bsPpcfOmJasG+Fkr6Y59q83f9M1WcBRHR2vM+P9eOisYRcN3ujQoiZY8uk5W+1WL8w==", - "dev": true, "license": "MIT", "dependencies": { "undici-types": "~6.21.0" } }, + "node_modules/@types/node-fetch": { + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.4" + } + }, "node_modules/@types/nodemailer": { "version": "6.4.23", "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.23.tgz", @@ -3399,35 +4050,66 @@ "@types/node": "*" } }, + "node_modules/@types/qrcode": { + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/@types/qrcode/-/qrcode-1.5.6.tgz", + "integrity": "sha512-te7NQcV2BOvdj2b1hCAHzAoMNuj65kNBMz0KBaxM6c3VGBOhU0dURQKOtH8CFNI/dsKkwlv32p26qYQTWoB5bw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "license": "MIT" + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@types/web-push": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/@types/web-push/-/web-push-3.6.4.tgz", + "integrity": "sha512-GnJmSr40H3RAnj0s34FNTcJi1hmWFV5KXugE0mYWnYhgTAHLJ/dJKAwDmvPJYMke0RplY2XE9LnM4hqSqKIjhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@x402/core": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@x402/core/-/core-2.4.0.tgz", - "integrity": "sha512-g4K5dAVjevQftxCcpFlUDjO2AHE43FkO43VxwLCQ8ET3ki4aj2fzCcgvnXEj2eloJoocFS/Evt4pSTnP/4cFJw==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@x402/core/-/core-2.6.0.tgz", + "integrity": "sha512-ISC/JeVss6xlKvor2rp18tJf9K5OQlIDDfZW1VZJQGDI2F4gy+HWxxkFfcQalCsPp4YUlwqh0YOkUxP+LTZWVg==", "license": "Apache-2.0", "dependencies": { "zod": "^3.24.2" } }, "node_modules/@x402/evm": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@x402/evm/-/evm-2.4.0.tgz", - "integrity": "sha512-k9qIEhJ5m8jZLPA44hcLEP9I1WC8nF375A7pX/3XGPA+H2UPUoY8fzBaQA2U+4lMv/eIyfz05klSj/8LzP1saA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@x402/evm/-/evm-2.6.0.tgz", + "integrity": "sha512-wPkNHf483gie1Up2sJSvERnW+VIEvMoT1KRXr09wSoSWgelglsJm+ug3gPPXKnT3C6AcmNAKZ12rBnu9Paff7g==", "license": "Apache-2.0", "dependencies": { - "@x402/core": "~2.4.0", - "@x402/extensions": "~2.4.0", + "@x402/core": "~2.6.0", + "@x402/extensions": "~2.6.0", "viem": "^2.39.3", "zod": "^3.24.2" } }, "node_modules/@x402/extensions": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@x402/extensions/-/extensions-2.4.0.tgz", - "integrity": "sha512-tg/mSAS+NgwUaOdjt8agSjVkO1s9NYy+kSPubVlZf/Fy884qu7dSW81Ixu1NRYEz+vBk0rtz6b+eEvS0v72tMQ==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@x402/extensions/-/extensions-2.6.0.tgz", + "integrity": "sha512-aLY9xAOOiRLKDN9HT2r9TYUXbD+IsoBces9qPZNVJGO2TBi2rfmbIBc3pcKCtWKn3iTvG2QFr3gpOFdpJRzqww==", "license": "Apache-2.0", "dependencies": { "@scure/base": "^1.2.6", - "@x402/core": "~2.4.0", + "@x402/core": "~2.6.0", "ajv": "^8.17.1", "siwe": "^2.3.2", "tweetnacl": "^1.0.3", @@ -3435,6 +4117,18 @@ "zod": "^3.24.2" } }, + "node_modules/@x402/fetch": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@x402/fetch/-/fetch-2.6.0.tgz", + "integrity": "sha512-OnHXw/mv76ig4UBJEgfQIWHSWcrgIOT2i8RxEuGl12QtaYwSgBcgDub2GdllL/iIB9OneM1m0UWlrPh23JdVjQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@x402/core": "~2.6.0", + "viem": "^2.39.3", + "zod": "^3.24.2" + } + }, "node_modules/@zone-eu/mailsplit": { "version": "5.4.8", "resolved": "https://registry.npmjs.org/@zone-eu/mailsplit/-/mailsplit-5.4.8.tgz", @@ -3474,6 +4168,15 @@ "license": "MIT", "peer": true }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/ajv": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", @@ -3490,12 +4193,60 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/apg-js": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/apg-js/-/apg-js-4.4.0.tgz", "integrity": "sha512-fefmXFknJmtgtNEXfPwZKYkMFX4Fyeyz+fNF6JWp87biGOPslJbCBVU158zvKRZfHBKnJDy8CMM40oLFGkXT8Q==", "license": "BSD-2-Clause" }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "license": "MIT", + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, "node_modules/atomic-sleep": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", @@ -3505,12 +4256,106 @@ "node": ">=8.0.0" } }, + "node_modules/axios": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", + "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axios-retry": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-4.5.0.tgz", + "integrity": "sha512-aR99oXhpEDGo0UuAlYcn2iGRds30k366Zfa05XWScR9QaQD4JYiP3/1Qt1u7YlefUOK+cn0CcwoL1oefavQUlQ==", + "license": "Apache-2.0", + "dependencies": { + "is-retry-allowed": "^2.2.0" + }, + "peerDependencies": { + "axios": "0.x || 1.x" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/base-x": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-5.0.1.tgz", + "integrity": "sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==", + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bignumber.js": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/bn.js": { + "version": "4.12.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz", + "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==", + "license": "MIT" + }, "node_modules/bowser": { "version": "2.14.1", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz", "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==", "license": "MIT" }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/bs58": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-6.0.0.tgz", + "integrity": "sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==", + "license": "MIT", + "dependencies": { + "base-x": "^5.0.0" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, "node_modules/bun-types": { "version": "1.3.9", "resolved": "https://registry.npmjs.org/bun-types/-/bun-types-1.3.9.tgz", @@ -3521,6 +4366,109 @@ "@types/node": "*" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/color": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", @@ -3562,6 +4510,91 @@ "simple-swizzle": "^0.2.2" } }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, + "node_modules/crelt": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", + "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==", + "license": "MIT" + }, + "node_modules/cron-parser": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-5.5.0.tgz", + "integrity": "sha512-oML4lKUXxizYswqmxuOCpgFS8BNUJpIu6k/2HVHyaL8Ynnf3wdf9tkns0yRdJLSIjkJ+b0DXHMZEHGpMwjnPww==", + "license": "MIT", + "dependencies": { + "luxon": "^3.7.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", @@ -3571,6 +4604,24 @@ "node": ">=0.10.0" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", @@ -3580,6 +4631,25 @@ "node": ">=8" } }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dijkstrajs": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz", + "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==", + "license": "MIT" + }, "node_modules/dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", @@ -3635,6 +4705,41 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, "node_modules/encoding-japanese": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/encoding-japanese/-/encoding-japanese-2.2.0.tgz", @@ -3656,6 +4761,51 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/esbuild": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", @@ -3698,6 +4848,18 @@ "@esbuild/win32-x64": "0.25.12" } }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ethers": { "version": "6.16.0", "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.16.0.tgz", @@ -3727,6 +4889,32 @@ "node": ">=14.0.0" } }, + "node_modules/ethers/node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethers/node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/ethers/node_modules/@types/node": { "version": "22.7.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", @@ -3751,12 +4939,40 @@ "license": "MIT", "peer": true }, + "node_modules/ethers/node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", "license": "MIT" }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -3815,6 +5031,106 @@ } } }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -3830,6 +5146,206 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gaxios": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz", + "integrity": "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==", + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "node-fetch": "^3.3.2", + "rimraf": "^5.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/gaxios/node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/gcp-metadata": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz", + "integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==", + "license": "Apache-2.0", + "dependencies": { + "gaxios": "^7.0.0", + "google-logging-utils": "^1.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/google-auth-library": { + "version": "10.6.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.6.1.tgz", + "integrity": "sha512-5awwuLrzNol+pFDmKJd0dKtZ0fPLAtoA5p7YO4ODsDu6ONJUVqbYwvv8y2ZBO5MBNp9TJXigB19710kYpBPdtA==", + "license": "Apache-2.0", + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "7.1.3", + "gcp-metadata": "8.1.2", + "google-logging-utils": "1.1.3", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/google-logging-utils": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz", + "integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -3839,6 +5355,15 @@ "he": "bin/he" } }, + "node_modules/highlight.js": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", + "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/hono": { "version": "4.12.1", "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.1.tgz", @@ -3883,6 +5408,28 @@ "entities": "^4.4.0" } }, + "node_modules/http_ece": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http_ece/-/http_ece-1.2.0.tgz", + "integrity": "sha512-JrF8SSLVmcvc5NducxgyOrKXe3EsyHMgBFgSaIUGmArKe+rwr0uphRkRXvwiom3I+fpIfoItveHrfudL8/rxuA==", + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -3937,6 +5484,18 @@ "node": ">=6.0.0" } }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "license": "MIT" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, "node_modules/ip-address": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", @@ -3952,6 +5511,39 @@ "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", "license": "MIT" }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-retry-allowed": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz", + "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, "node_modules/isows": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.7.tgz", @@ -3967,12 +5559,78 @@ "ws": "*" } }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jose": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.1.tgz", + "integrity": "sha512-jUaKr1yrbfaImV7R2TN/b3IcZzsw38/chqMpo2XJ7i2F8AfM/lA4G1goC3JVEwg0H7UldTmSt3P68nt31W7/mw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "license": "(MIT OR GPL-3.0-or-later)", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "license": "MIT", + "dependencies": { + "jwa": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/leac": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/leac/-/leac-0.6.0.tgz", @@ -4006,6 +5664,15 @@ "integrity": "sha512-0Wd+GPz1O134cP62YU2GTOPNA7Qgl09XwCqM5zpBv87ERCXdfDtyKXvV7c9U22yWJh44QZqBocFnXN11K96qow==", "license": "MIT" }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, "node_modules/linkify-it": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", @@ -4015,6 +5682,60 @@ "uc.micro": "^2.0.0" } }, + "node_modules/linkifyjs": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.3.2.tgz", + "integrity": "sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==", + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/lowlight": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-3.3.0.tgz", + "integrity": "sha512-0JNhgFoPvP6U6lE/UdVsSq99tn6DhjjpAj5MxG49ewd2mOBVtwWYIT8ClyABhq198aXXODMU6Ox8DrGy/CpTZQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.0.0", + "highlight.js": "~11.11.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/luxon": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz", + "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, "node_modules/mailparser": { "version": "3.9.3", "resolved": "https://registry.npmjs.org/mailparser/-/mailparser-3.9.3.tgz", @@ -4058,6 +5779,116 @@ "node": ">=6.0.0" } }, + "node_modules/markdown-it": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.1.tgz", + "integrity": "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/marked": { + "version": "17.0.4", + "resolved": "https://registry.npmjs.org/marked/-/marked-17.0.4.tgz", + "integrity": "sha512-NOmVMM+KAokHMvjWmC5N/ZOvgmSWuqJB8FoYI019j4ogb/PeRMKoKIjReZ2w3376kkA8dSJIP8uD993Kxc0iRQ==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "license": "MIT" + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -4077,6 +5908,46 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/nodemailer": { "version": "6.10.1", "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.10.1.tgz", @@ -4095,6 +5966,12 @@ "node": ">=14.0.0" } }, + "node_modules/orderedmap": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz", + "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==", + "license": "MIT" + }, "node_modules/ox": { "version": "0.12.4", "resolved": "https://registry.npmjs.org/ox/-/ox-0.12.4.tgz", @@ -4146,18 +6023,67 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/ox/node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, "engines": { - "node": "^14.21.3 || >=16" + "node": ">=6" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "license": "BlueOak-1.0.0" + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "license": "(MIT AND Zlib)" + }, "node_modules/parseley": { "version": "0.12.1", "resolved": "https://registry.npmjs.org/parseley/-/parseley-0.12.1.tgz", @@ -4171,6 +6097,40 @@ "url": "https://ko-fi.com/killymxi" } }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/peberminta": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/peberminta/-/peberminta-0.9.0.tgz", @@ -4252,6 +6212,15 @@ "integrity": "sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==", "license": "MIT" }, + "node_modules/pngjs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", + "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/postcss": { "version": "8.5.6", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", @@ -4294,6 +6263,12 @@ "url": "https://github.com/sponsors/porsager" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, "node_modules/process-warning": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz", @@ -4310,6 +6285,231 @@ ], "license": "MIT" }, + "node_modules/prosemirror-changeset": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.4.0.tgz", + "integrity": "sha512-LvqH2v7Q2SF6yxatuPP2e8vSUKS/L+xAU7dPDC4RMyHMhZoGDfBC74mYuyYF4gLqOEG758wajtyhNnsTkuhvng==", + "license": "MIT", + "dependencies": { + "prosemirror-transform": "^1.0.0" + } + }, + "node_modules/prosemirror-collab": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz", + "integrity": "sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.0.0" + } + }, + "node_modules/prosemirror-commands": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.7.1.tgz", + "integrity": "sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.10.2" + } + }, + "node_modules/prosemirror-dropcursor": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.2.tgz", + "integrity": "sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.1.0", + "prosemirror-view": "^1.1.0" + } + }, + "node_modules/prosemirror-gapcursor": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.4.1.tgz", + "integrity": "sha512-pMdYaEnjNMSwl11yjEGtgTmLkR08m/Vl+Jj443167p9eB3HVQKhYCc4gmHVDsLPODfZfjr/MmirsdyZziXbQKw==", + "license": "MIT", + "dependencies": { + "prosemirror-keymap": "^1.0.0", + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-view": "^1.0.0" + } + }, + "node_modules/prosemirror-history": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.5.0.tgz", + "integrity": "sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.2.2", + "prosemirror-transform": "^1.0.0", + "prosemirror-view": "^1.31.0", + "rope-sequence": "^1.3.0" + } + }, + "node_modules/prosemirror-inputrules": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.5.1.tgz", + "integrity": "sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.0.0" + } + }, + "node_modules/prosemirror-keymap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.3.tgz", + "integrity": "sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.0.0", + "w3c-keyname": "^2.2.0" + } + }, + "node_modules/prosemirror-markdown": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.4.tgz", + "integrity": "sha512-D98dm4cQ3Hs6EmjK500TdAOew4Z03EV71ajEFiWra3Upr7diytJsjF4mPV2dW+eK5uNectiRj0xFxYI9NLXDbw==", + "license": "MIT", + "dependencies": { + "@types/markdown-it": "^14.0.0", + "markdown-it": "^14.0.0", + "prosemirror-model": "^1.25.0" + } + }, + "node_modules/prosemirror-menu": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.3.0.tgz", + "integrity": "sha512-TImyPXCHPcDsSka2/lwJ6WjTASr4re/qWq1yoTTuLOqfXucwF6VcRa2LWCkM/EyTD1UO3CUwiH8qURJoWJRxwg==", + "license": "MIT", + "dependencies": { + "crelt": "^1.0.0", + "prosemirror-commands": "^1.0.0", + "prosemirror-history": "^1.0.0", + "prosemirror-state": "^1.0.0" + } + }, + "node_modules/prosemirror-model": { + "version": "1.25.4", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.4.tgz", + "integrity": "sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==", + "license": "MIT", + "dependencies": { + "orderedmap": "^2.0.0" + } + }, + "node_modules/prosemirror-schema-basic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.4.tgz", + "integrity": "sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.25.0" + } + }, + "node_modules/prosemirror-schema-list": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.5.1.tgz", + "integrity": "sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.7.3" + } + }, + "node_modules/prosemirror-state": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.4.tgz", + "integrity": "sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-transform": "^1.0.0", + "prosemirror-view": "^1.27.0" + } + }, + "node_modules/prosemirror-tables": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.8.5.tgz", + "integrity": "sha512-V/0cDCsHKHe/tfWkeCmthNUcEp1IVO3p6vwN8XtwE9PZQLAZJigbw3QoraAdfJPir4NKJtNvOB8oYGKRl+t0Dw==", + "license": "MIT", + "dependencies": { + "prosemirror-keymap": "^1.2.3", + "prosemirror-model": "^1.25.4", + "prosemirror-state": "^1.4.4", + "prosemirror-transform": "^1.10.5", + "prosemirror-view": "^1.41.4" + } + }, + "node_modules/prosemirror-trailing-node": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-3.0.0.tgz", + "integrity": "sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==", + "license": "MIT", + "dependencies": { + "@remirror/core-constants": "3.0.0", + "escape-string-regexp": "^4.0.0" + }, + "peerDependencies": { + "prosemirror-model": "^1.22.1", + "prosemirror-state": "^1.4.2", + "prosemirror-view": "^1.33.8" + } + }, + "node_modules/prosemirror-transform": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.11.0.tgz", + "integrity": "sha512-4I7Ce4KpygXb9bkiPS3hTEk4dSHorfRw8uI0pE8IhxlK2GXsqv5tIA7JUSxtSu7u8APVOTtbUBxTmnHIxVkIJw==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.21.0" + } + }, + "node_modules/prosemirror-view": { + "version": "1.41.6", + "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.41.6.tgz", + "integrity": "sha512-mxpcDG4hNQa/CPtzxjdlir5bJFDlm0/x5nGBbStB2BWX+XOQ9M8ekEG+ojqB5BcVu2Rc80/jssCMZzSstJuSYg==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.20.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.1.0" + } + }, + "node_modules/protobufjs": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", + "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -4328,12 +6528,50 @@ "node": ">=6" } }, + "node_modules/qrcode": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz", + "integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==", + "license": "MIT", + "dependencies": { + "dijkstrajs": "^1.0.1", + "pngjs": "^5.0.0", + "yargs": "^15.3.1" + }, + "bin": { + "qrcode": "bin/qrcode" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/quick-format-unescaped": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", "license": "MIT" }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, "node_modules/real-require": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", @@ -4343,6 +6581,15 @@ "node": ">= 12.13.0" } }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -4352,6 +6599,36 @@ "node": ">=0.10.0" } }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "license": "ISC" + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/rollup": { "version": "4.58.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.58.0.tgz", @@ -4397,6 +6674,32 @@ "fsevents": "~2.3.2" } }, + "node_modules/rope-sequence": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz", + "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==", + "license": "MIT" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/safe-stable-stringify": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", @@ -4436,6 +6739,18 @@ "node": ">=10" } }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "license": "ISC" + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "license": "MIT" + }, "node_modules/sharp": { "version": "0.33.5", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", @@ -4475,6 +6790,39 @@ "@img/sharp-win32-x64": "0.33.5" } }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/simple-swizzle": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz", @@ -4551,6 +6899,117 @@ "node": ">= 10.x" } }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/strnum": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.2.tgz", @@ -4601,6 +7060,12 @@ "tlds": "bin.js" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -4637,7 +7102,6 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "dev": true, "license": "MIT" }, "node_modules/uri-js": { @@ -4649,6 +7113,12 @@ "punycode": "^2.1.0" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, "node_modules/uuid": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", @@ -4712,18 +7182,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/viem/node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/viem/node_modules/ws": { "version": "8.18.3", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", @@ -4860,12 +7318,173 @@ "vite": "^2 || ^3 || ^4 || ^5 || ^6 || ^7" } }, - "node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "node_modules/w3c-keyname": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", + "license": "MIT" + }, + "node_modules/web-push": { + "version": "3.6.7", + "resolved": "https://registry.npmjs.org/web-push/-/web-push-3.6.7.tgz", + "integrity": "sha512-OpiIUe8cuGjrj3mMBFWY+e4MMIkW3SVT+7vEIjvD9kejGUypv8GPDf84JdPWskK8zMRIJ6xYGm+Kxr8YkPyA0A==", + "license": "MPL-2.0", + "dependencies": { + "asn1.js": "^5.3.0", + "http_ece": "1.2.0", + "https-proxy-agent": "^7.0.0", + "jws": "^4.0.0", + "minimist": "^1.2.5" + }, + "bin": { + "web-push": "src/cli.js" + }, + "engines": { + "node": ">= 16" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "license": "ISC" + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ws": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", "license": "MIT", - "peer": true, "engines": { "node": ">=10.0.0" }, @@ -4882,6 +7501,103 @@ } } }, + "node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", + "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "license": "MIT", + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/zod": { "version": "3.25.76", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", diff --git a/package.json b/package.json index f81d6a8..0f4cec2 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "@tiptap/extension-underline": "^3.20.0", "@tiptap/pm": "^3.20.0", "@tiptap/starter-kit": "^3.20.0", + "@types/qrcode": "^1.5.6", "@x402/core": "^2.3.1", "@x402/evm": "^2.5.0", "cron-parser": "^5.5.0", @@ -47,6 +48,7 @@ "perfect-arrows": "^0.3.7", "perfect-freehand": "^1.2.2", "postgres": "^3.4.5", + "qrcode": "^1.5.4", "sharp": "^0.33.0", "web-push": "^3.6.7", "yaml": "^2.8.2" diff --git a/shared/transak.ts b/shared/transak.ts new file mode 100644 index 0000000..4ed52a5 --- /dev/null +++ b/shared/transak.ts @@ -0,0 +1,87 @@ +/** + * Transak API utilities — shared across rFlows and rCart. + * + * Handles access token management (cached 6 days) and + * widget URL generation via Transak's session API. + */ + +let _transakAccessToken: string | null = null; +let _transakTokenExpiry = 0; + +export async function getTransakAccessToken(): Promise { + if (_transakAccessToken && Date.now() < _transakTokenExpiry) return _transakAccessToken; + + const apiKey = process.env.TRANSAK_API_KEY; + const apiSecret = process.env.TRANSAK_SECRET; + if (!apiKey || !apiSecret) throw new Error("Transak credentials not configured"); + + const env = process.env.TRANSAK_ENV || 'PRODUCTION'; + const baseUrl = env === 'PRODUCTION' + ? 'https://api.transak.com' + : 'https://api-stg.transak.com'; + + const res = await fetch(`${baseUrl}/partners/api/v2/refresh-token`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'api-secret': apiSecret, + }, + body: JSON.stringify({ apiKey }), + }); + + if (!res.ok) { + const text = await res.text(); + throw new Error(`Transak token refresh failed (${res.status}): ${text}`); + } + + const data = await res.json() as any; + _transakAccessToken = data.data?.accessToken || data.accessToken; + if (!_transakAccessToken) throw new Error("No accessToken in Transak response"); + + // Cache for 6 days (tokens valid for 7) + _transakTokenExpiry = Date.now() + 6 * 24 * 60 * 60 * 1000; + console.log('[transak] Access token refreshed'); + return _transakAccessToken; +} + +export async function createTransakWidgetUrl(params: Record): Promise { + const accessToken = await getTransakAccessToken(); + const env = process.env.TRANSAK_ENV || 'PRODUCTION'; + const gatewayUrl = env === 'PRODUCTION' + ? 'https://api-gateway.transak.com' + : 'https://api-gateway-stg.transak.com'; + + const res = await fetch(`${gatewayUrl}/api/v2/auth/session`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'access-token': accessToken, + }, + body: JSON.stringify({ widgetParams: params }), + }); + + if (!res.ok) { + const text = await res.text(); + // If token expired, clear cache and retry once + if (res.status === 401 || res.status === 403) { + _transakAccessToken = null; + _transakTokenExpiry = 0; + const retryToken = await getTransakAccessToken(); + const retry = await fetch(`${gatewayUrl}/api/v2/auth/session`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'access-token': retryToken, + }, + body: JSON.stringify({ widgetParams: params }), + }); + if (!retry.ok) throw new Error(`Transak widget URL failed on retry (${retry.status}): ${await retry.text()}`); + const retryData = await retry.json() as any; + return retryData.data?.widgetUrl; + } + throw new Error(`Transak widget URL failed (${res.status}): ${text}`); + } + + const data = await res.json() as any; + return data.data?.widgetUrl; +} diff --git a/vite.config.ts b/vite.config.ts index b676caf..be06997 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -156,6 +156,46 @@ export default defineConfig({ }, }); + // Build payment page component + await build({ + configFile: false, + root: resolve(__dirname, "modules/rcart/components"), + build: { + emptyOutDir: false, + outDir: resolve(__dirname, "dist/modules/rcart"), + lib: { + entry: resolve(__dirname, "modules/rcart/components/folk-payment-page.ts"), + formats: ["es"], + fileName: () => "folk-payment-page.js", + }, + rollupOptions: { + output: { + entryFileNames: "folk-payment-page.js", + }, + }, + }, + }); + + // Build payment request (QR generator) component + await build({ + configFile: false, + root: resolve(__dirname, "modules/rcart/components"), + build: { + emptyOutDir: false, + outDir: resolve(__dirname, "dist/modules/rcart"), + lib: { + entry: resolve(__dirname, "modules/rcart/components/folk-payment-request.ts"), + formats: ["es"], + fileName: () => "folk-payment-request.js", + }, + rollupOptions: { + output: { + entryFileNames: "folk-payment-request.js", + }, + }, + }, + }); + // Copy cart CSS mkdirSync(resolve(__dirname, "dist/modules/rcart"), { recursive: true }); copyFileSync(