@ergoblockchain/sage-widget 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -7
- package/dist/index.cjs +24 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -3
- package/dist/index.d.ts +13 -3
- package/dist/index.js +23 -1
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +123 -6
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +123 -6
- package/dist/react.js.map +1 -1
- package/dist/{types-yv1THHVz.d.cts → types-B5V2rsYn.d.cts} +47 -1
- package/dist/{types-yv1THHVz.d.ts → types-B5V2rsYn.d.ts} +47 -1
- package/dist/vanilla.cjs +135 -0
- package/dist/vanilla.cjs.map +1 -1
- package/dist/vanilla.d.cts +4 -3
- package/dist/vanilla.d.ts +4 -3
- package/dist/vanilla.js +135 -0
- package/dist/vanilla.js.map +1 -1
- package/package.json +4 -4
package/dist/vanilla.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as SageActivityResponse,
|
|
2
|
-
export { D as DEFAULT_API_BASE, a as DEFAULT_LIMIT, b as DEFAULT_REFRESH_MS, S as SageActivityEvent, d as SageActivityType, f as SageChatRole, g as SageChatStreamEvent, h as SageChatStreamResult, i as SageChatTier, j as SagePaymentInstructions,
|
|
1
|
+
import { c as SageActivityResponse, y as SageWidgetOptions, e as SageChatMessage, m as SagePaymentPhase, s as SageQuoteResponse, k as SagePaymentIntent, v as SageVerifyPaymentResponse, t as SageReceiptBundle, n as SagePaymentWidgetOptions } from './types-B5V2rsYn.cjs';
|
|
2
|
+
export { D as DEFAULT_API_BASE, a as DEFAULT_LIMIT, b as DEFAULT_REFRESH_MS, S as SageActivityEvent, d as SageActivityType, f as SageChatRole, g as SageChatStreamEvent, h as SageChatStreamResult, i as SageChatTier, j as SagePaymentInstructions, l as SagePaymentNetwork, o as SagePaymentWidgetStatus, p as SagePremiumPaymentRequired, q as SagePremiumReason, r as SageQuote, u as SageTenantConfig, w as SageWalletLaunchResult, x as SageWalletLauncher } from './types-B5V2rsYn.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* mountSageFeed — framework-agnostic DOM mount for the Sage activity
|
|
@@ -39,6 +39,7 @@ interface MountSagePaymentWidgetHandle {
|
|
|
39
39
|
phase: SagePaymentPhase;
|
|
40
40
|
tier: "free" | "premium" | null;
|
|
41
41
|
quote: SageQuoteResponse["quote"] | null;
|
|
42
|
+
paymentIntent: SagePaymentIntent | null;
|
|
42
43
|
receipt: SageVerifyPaymentResponse | null;
|
|
43
44
|
receiptBundle: SageReceiptBundle | null;
|
|
44
45
|
error: string | null;
|
|
@@ -48,4 +49,4 @@ interface MountSagePaymentWidgetHandle {
|
|
|
48
49
|
}
|
|
49
50
|
declare function mountSagePaymentWidget(target: Element, opts?: SagePaymentWidgetOptions): MountSagePaymentWidgetHandle;
|
|
50
51
|
|
|
51
|
-
export { type MountSageFeedHandle, type MountSagePaymentWidgetHandle, SageActivityResponse, SageChatMessage, SagePaymentPhase, SagePaymentWidgetOptions, SageQuoteResponse, SageReceiptBundle, SageVerifyPaymentResponse, SageWidgetOptions, mountSageFeed, mountSagePaymentWidget };
|
|
52
|
+
export { type MountSageFeedHandle, type MountSagePaymentWidgetHandle, SageActivityResponse, SageChatMessage, SagePaymentIntent, SagePaymentPhase, SagePaymentWidgetOptions, SageQuoteResponse, SageReceiptBundle, SageVerifyPaymentResponse, SageWidgetOptions, mountSageFeed, mountSagePaymentWidget };
|
package/dist/vanilla.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as SageActivityResponse,
|
|
2
|
-
export { D as DEFAULT_API_BASE, a as DEFAULT_LIMIT, b as DEFAULT_REFRESH_MS, S as SageActivityEvent, d as SageActivityType, f as SageChatRole, g as SageChatStreamEvent, h as SageChatStreamResult, i as SageChatTier, j as SagePaymentInstructions,
|
|
1
|
+
import { c as SageActivityResponse, y as SageWidgetOptions, e as SageChatMessage, m as SagePaymentPhase, s as SageQuoteResponse, k as SagePaymentIntent, v as SageVerifyPaymentResponse, t as SageReceiptBundle, n as SagePaymentWidgetOptions } from './types-B5V2rsYn.js';
|
|
2
|
+
export { D as DEFAULT_API_BASE, a as DEFAULT_LIMIT, b as DEFAULT_REFRESH_MS, S as SageActivityEvent, d as SageActivityType, f as SageChatRole, g as SageChatStreamEvent, h as SageChatStreamResult, i as SageChatTier, j as SagePaymentInstructions, l as SagePaymentNetwork, o as SagePaymentWidgetStatus, p as SagePremiumPaymentRequired, q as SagePremiumReason, r as SageQuote, u as SageTenantConfig, w as SageWalletLaunchResult, x as SageWalletLauncher } from './types-B5V2rsYn.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* mountSageFeed — framework-agnostic DOM mount for the Sage activity
|
|
@@ -39,6 +39,7 @@ interface MountSagePaymentWidgetHandle {
|
|
|
39
39
|
phase: SagePaymentPhase;
|
|
40
40
|
tier: "free" | "premium" | null;
|
|
41
41
|
quote: SageQuoteResponse["quote"] | null;
|
|
42
|
+
paymentIntent: SagePaymentIntent | null;
|
|
42
43
|
receipt: SageVerifyPaymentResponse | null;
|
|
43
44
|
receiptBundle: SageReceiptBundle | null;
|
|
44
45
|
error: string | null;
|
|
@@ -48,4 +49,4 @@ interface MountSagePaymentWidgetHandle {
|
|
|
48
49
|
}
|
|
49
50
|
declare function mountSagePaymentWidget(target: Element, opts?: SagePaymentWidgetOptions): MountSagePaymentWidgetHandle;
|
|
50
51
|
|
|
51
|
-
export { type MountSageFeedHandle, type MountSagePaymentWidgetHandle, SageActivityResponse, SageChatMessage, SagePaymentPhase, SagePaymentWidgetOptions, SageQuoteResponse, SageReceiptBundle, SageVerifyPaymentResponse, SageWidgetOptions, mountSageFeed, mountSagePaymentWidget };
|
|
52
|
+
export { type MountSageFeedHandle, type MountSagePaymentWidgetHandle, SageActivityResponse, SageChatMessage, SagePaymentIntent, SagePaymentPhase, SagePaymentWidgetOptions, SageQuoteResponse, SageReceiptBundle, SageVerifyPaymentResponse, SageWidgetOptions, mountSageFeed, mountSagePaymentWidget };
|
package/dist/vanilla.js
CHANGED
|
@@ -52,6 +52,28 @@ async function fetchSageReceipt(id, opts = {}) {
|
|
|
52
52
|
if (!res.ok) throw new Error(readError(body, `sage receipt ${res.status}`));
|
|
53
53
|
return body;
|
|
54
54
|
}
|
|
55
|
+
function createSagePaymentIntent(opts) {
|
|
56
|
+
const base = trimSlash(opts.apiBase ?? DEFAULT_API_BASE);
|
|
57
|
+
return {
|
|
58
|
+
type: "sage.payment_intent.v1",
|
|
59
|
+
network: opts.network ?? "ergo-testnet",
|
|
60
|
+
createdAt: opts.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
61
|
+
question: opts.question,
|
|
62
|
+
...opts.tenant?.id || opts.tenant?.label ? { tenant: { id: opts.tenant.id, label: opts.tenant.label } } : {},
|
|
63
|
+
quote: opts.quote,
|
|
64
|
+
amountErg: opts.quote.price,
|
|
65
|
+
receiverAddress: opts.quote.receiverAddress,
|
|
66
|
+
reserveBoxId: opts.quote.reserveBoxId,
|
|
67
|
+
taskHash: opts.quote.taskHash,
|
|
68
|
+
expiresAt: opts.quote.expiresAt,
|
|
69
|
+
deadline: opts.quote.deadline,
|
|
70
|
+
verifyEndpoint: `${base}/api/sage/verify-payment`,
|
|
71
|
+
receiptEndpointTemplate: `${base}/api/sage/receipt/{receiptId}`
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function serializeSagePaymentIntent(intent) {
|
|
75
|
+
return JSON.stringify(intent, null, 2);
|
|
76
|
+
}
|
|
55
77
|
async function streamSageChat(opts) {
|
|
56
78
|
const res = await fetch(`${apiBase(opts)}/api/sage/chat`, {
|
|
57
79
|
method: "POST",
|
|
@@ -455,6 +477,7 @@ function mountSagePaymentWidget(target, opts = {}) {
|
|
|
455
477
|
let noteBoxId = "";
|
|
456
478
|
let activeQuestion = "";
|
|
457
479
|
let quoteResponse = null;
|
|
480
|
+
let paymentIntent = null;
|
|
458
481
|
let receipt = null;
|
|
459
482
|
let receiptBundle = null;
|
|
460
483
|
let error = null;
|
|
@@ -470,6 +493,7 @@ function mountSagePaymentWidget(target, opts = {}) {
|
|
|
470
493
|
inputValue = "";
|
|
471
494
|
noteBoxId = "";
|
|
472
495
|
quoteResponse = null;
|
|
496
|
+
paymentIntent = null;
|
|
473
497
|
receipt = null;
|
|
474
498
|
receiptBundle = null;
|
|
475
499
|
error = null;
|
|
@@ -491,6 +515,13 @@ function mountSagePaymentWidget(target, opts = {}) {
|
|
|
491
515
|
if (quote.premium) {
|
|
492
516
|
if (!quote.quote) throw new Error("Sage marked this question premium but did not return a quote.");
|
|
493
517
|
quoteResponse = quote;
|
|
518
|
+
paymentIntent = createSagePaymentIntent({
|
|
519
|
+
apiBase: apiBase2,
|
|
520
|
+
tenant: opts.tenant,
|
|
521
|
+
question,
|
|
522
|
+
quote: quote.quote
|
|
523
|
+
});
|
|
524
|
+
opts.onPaymentIntent?.(paymentIntent);
|
|
494
525
|
transition("payment_required");
|
|
495
526
|
render();
|
|
496
527
|
return;
|
|
@@ -525,6 +556,7 @@ function mountSagePaymentWidget(target, opts = {}) {
|
|
|
525
556
|
receipt = verified;
|
|
526
557
|
opts.onReceipt?.(verified);
|
|
527
558
|
quoteResponse = null;
|
|
559
|
+
paymentIntent = null;
|
|
528
560
|
noteBoxId = "";
|
|
529
561
|
transition("streaming");
|
|
530
562
|
try {
|
|
@@ -575,6 +607,13 @@ function mountSagePaymentWidget(target, opts = {}) {
|
|
|
575
607
|
});
|
|
576
608
|
opts.onQuote?.(quote);
|
|
577
609
|
quoteResponse = quote;
|
|
610
|
+
paymentIntent = quote.quote ? createSagePaymentIntent({
|
|
611
|
+
apiBase: apiBase2,
|
|
612
|
+
tenant: opts.tenant,
|
|
613
|
+
question: activeQuestion,
|
|
614
|
+
quote: quote.quote
|
|
615
|
+
}) : null;
|
|
616
|
+
if (paymentIntent) opts.onPaymentIntent?.(paymentIntent);
|
|
578
617
|
transition("payment_required");
|
|
579
618
|
render();
|
|
580
619
|
return;
|
|
@@ -587,6 +626,21 @@ function mountSagePaymentWidget(target, opts = {}) {
|
|
|
587
626
|
transition("idle");
|
|
588
627
|
render();
|
|
589
628
|
}
|
|
629
|
+
async function launchWallet() {
|
|
630
|
+
if (!paymentIntent || !opts.walletLauncher || isBusy()) return;
|
|
631
|
+
error = null;
|
|
632
|
+
try {
|
|
633
|
+
const result = await opts.walletLauncher(paymentIntent);
|
|
634
|
+
if (result?.ok === false) {
|
|
635
|
+
throw new Error(result.error ?? "Wallet flow did not produce a Note.");
|
|
636
|
+
}
|
|
637
|
+
if (result?.noteBoxId) noteBoxId = result.noteBoxId;
|
|
638
|
+
} catch (err) {
|
|
639
|
+
error = err instanceof Error ? err.message : "Wallet flow failed.";
|
|
640
|
+
opts.onError?.(err);
|
|
641
|
+
}
|
|
642
|
+
render();
|
|
643
|
+
}
|
|
590
644
|
function render() {
|
|
591
645
|
root.innerHTML = "";
|
|
592
646
|
const header = document.createElement("header");
|
|
@@ -691,6 +745,41 @@ function mountSagePaymentWidget(target, opts = {}) {
|
|
|
691
745
|
field("Reserve box", quote.reserveBoxId),
|
|
692
746
|
field("Task hash", quote.taskHash)
|
|
693
747
|
);
|
|
748
|
+
const testnetWarning = opts.testnetWarning === false ? null : opts.testnetWarning ?? "Testnet proof flow. The widget never signs funds; connect your own reviewed wallet layer before handling real value.";
|
|
749
|
+
if (testnetWarning) {
|
|
750
|
+
const warning = document.createElement("div");
|
|
751
|
+
warning.textContent = testnetWarning;
|
|
752
|
+
applyStyles2(warning, warningStyle);
|
|
753
|
+
panel.appendChild(warning);
|
|
754
|
+
}
|
|
755
|
+
if (opts.showPaymentIntent !== false && paymentIntent) {
|
|
756
|
+
const intent = document.createElement("div");
|
|
757
|
+
applyStyles2(intent, intentStyle);
|
|
758
|
+
const intentTop = document.createElement("div");
|
|
759
|
+
applyStyles2(intentTop, intentHeaderStyle);
|
|
760
|
+
const label2 = document.createElement("strong");
|
|
761
|
+
label2.textContent = "Payment intent";
|
|
762
|
+
const copy = document.createElement("button");
|
|
763
|
+
copy.type = "button";
|
|
764
|
+
copy.textContent = "Copy JSON";
|
|
765
|
+
copy.addEventListener("click", () => copyText(serializeSagePaymentIntent(paymentIntent)));
|
|
766
|
+
applyStyles2(copy, copyButtonStyle);
|
|
767
|
+
intentTop.append(label2, copy);
|
|
768
|
+
const code = document.createElement("code");
|
|
769
|
+
code.textContent = serializeSagePaymentIntent(paymentIntent);
|
|
770
|
+
applyStyles2(code, intentCodeStyle);
|
|
771
|
+
intent.append(intentTop, code);
|
|
772
|
+
panel.appendChild(intent);
|
|
773
|
+
}
|
|
774
|
+
if (opts.walletLauncher && paymentIntent) {
|
|
775
|
+
const wallet = document.createElement("button");
|
|
776
|
+
wallet.type = "button";
|
|
777
|
+
wallet.textContent = opts.paymentInstructions?.walletLauncherLabel ?? "Open wallet flow";
|
|
778
|
+
wallet.disabled = isBusy();
|
|
779
|
+
wallet.addEventListener("click", () => void launchWallet());
|
|
780
|
+
applyStyles2(wallet, secondaryButtonStyle);
|
|
781
|
+
panel.appendChild(wallet);
|
|
782
|
+
}
|
|
694
783
|
const label = document.createElement("label");
|
|
695
784
|
label.textContent = opts.paymentInstructions?.noteBoxLabel ?? "Note box id";
|
|
696
785
|
applyStyles2(label, labelStyle2);
|
|
@@ -751,6 +840,7 @@ function mountSagePaymentWidget(target, opts = {}) {
|
|
|
751
840
|
phase: next,
|
|
752
841
|
tier,
|
|
753
842
|
quote: quoteResponse?.quote ?? null,
|
|
843
|
+
paymentIntent,
|
|
754
844
|
receipt,
|
|
755
845
|
receiptBundle,
|
|
756
846
|
error,
|
|
@@ -770,6 +860,7 @@ function mountSagePaymentWidget(target, opts = {}) {
|
|
|
770
860
|
phase,
|
|
771
861
|
tier,
|
|
772
862
|
quote: quoteResponse?.quote ?? null,
|
|
863
|
+
paymentIntent,
|
|
773
864
|
receipt,
|
|
774
865
|
receiptBundle,
|
|
775
866
|
error,
|
|
@@ -949,6 +1040,50 @@ var primaryButtonStyle = {
|
|
|
949
1040
|
...sendButtonStyle,
|
|
950
1041
|
padding: "10px 12px"
|
|
951
1042
|
};
|
|
1043
|
+
var secondaryButtonStyle = {
|
|
1044
|
+
border: "1px solid rgba(103,232,249,.28)",
|
|
1045
|
+
background: "rgba(103,232,249,.08)",
|
|
1046
|
+
color: "#cffafe",
|
|
1047
|
+
borderRadius: "6px",
|
|
1048
|
+
padding: "10px 12px",
|
|
1049
|
+
fontWeight: "800",
|
|
1050
|
+
cursor: "pointer"
|
|
1051
|
+
};
|
|
1052
|
+
var warningStyle = {
|
|
1053
|
+
color: "#fde68a",
|
|
1054
|
+
background: "rgba(245,158,11,.1)",
|
|
1055
|
+
border: "1px solid rgba(245,158,11,.24)",
|
|
1056
|
+
borderRadius: "6px",
|
|
1057
|
+
padding: "8px 9px",
|
|
1058
|
+
fontSize: "12px",
|
|
1059
|
+
lineHeight: "1.45"
|
|
1060
|
+
};
|
|
1061
|
+
var intentStyle = {
|
|
1062
|
+
border: "1px solid rgba(255,255,255,.12)",
|
|
1063
|
+
background: "rgba(255,255,255,.04)",
|
|
1064
|
+
borderRadius: "6px",
|
|
1065
|
+
padding: "10px",
|
|
1066
|
+
display: "grid",
|
|
1067
|
+
gap: "8px"
|
|
1068
|
+
};
|
|
1069
|
+
var intentHeaderStyle = {
|
|
1070
|
+
display: "flex",
|
|
1071
|
+
justifyContent: "space-between",
|
|
1072
|
+
alignItems: "center",
|
|
1073
|
+
gap: "8px",
|
|
1074
|
+
color: "#e2e8f0",
|
|
1075
|
+
fontSize: "12px"
|
|
1076
|
+
};
|
|
1077
|
+
var intentCodeStyle = {
|
|
1078
|
+
display: "block",
|
|
1079
|
+
maxHeight: "130px",
|
|
1080
|
+
overflow: "auto",
|
|
1081
|
+
whiteSpace: "pre-wrap",
|
|
1082
|
+
wordBreak: "break-word",
|
|
1083
|
+
color: "#cbd5e1",
|
|
1084
|
+
fontSize: "10px",
|
|
1085
|
+
lineHeight: "1.45"
|
|
1086
|
+
};
|
|
952
1087
|
var receiptStyle = {
|
|
953
1088
|
display: "block",
|
|
954
1089
|
marginTop: "10px",
|