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' ? `
+
` : ''}
+ ${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 `
+
+
+
+ ${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}
+
+
+ `;
+ }
+
+ private renderResult(): string {
+ const p = this.generatedPayment;
+ const amountDisplay = this.amountEditable && (!p.amount || p.amount === '0')
+ ? 'Any amount'
+ : `${p.amount} ${p.token}`;
+
+ return `
+
+
+
+
+ ${this.qrDataUrl
+ ? `

`
+ : `

`}
+
+
+
+
+
+
`;
+ }
+
+ 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
' : ''}
+
+ ${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(