@swype-org/deposit 0.3.26 → 0.3.32
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 +171 -0
- package/dist/{chunk-S3SPMEXQ.js → chunk-MJSD7JWR.js} +534 -98
- package/dist/chunk-MJSD7JWR.js.map +1 -0
- package/dist/index.cjs +533 -97
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +142 -5
- package/dist/index.d.ts +142 -5
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +532 -96
- 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 +2 -2
- package/dist/{types-BjnQ2ux2.d.cts → types-QRkKxsoP.d.cts} +128 -1
- package/dist/{types-BjnQ2ux2.d.ts → types-QRkKxsoP.d.ts} +128 -1
- package/package.json +1 -1
- package/dist/chunk-S3SPMEXQ.js.map +0 -1
|
@@ -507,21 +507,84 @@ function parseCapabilities(value) {
|
|
|
507
507
|
}
|
|
508
508
|
return value.filter((entry) => typeof entry === "string");
|
|
509
509
|
}
|
|
510
|
-
function buildViewportMessage(viewportLvh, safeAreaBottom) {
|
|
511
|
-
return {
|
|
510
|
+
function buildViewportMessage(viewportLvh, safeAreaBottom, embedMaxHeightPx) {
|
|
511
|
+
return {
|
|
512
|
+
type: "blink:viewport",
|
|
513
|
+
viewportLvh,
|
|
514
|
+
safeAreaBottom,
|
|
515
|
+
...embedMaxHeightPx === void 0 ? {} : { embedMaxHeightPx }
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
var MAX_CONTENT_HEIGHT_PX = 2e4;
|
|
519
|
+
function parseContentHeight(data) {
|
|
520
|
+
if (!data || typeof data !== "object") {
|
|
521
|
+
return null;
|
|
522
|
+
}
|
|
523
|
+
const msg = data;
|
|
524
|
+
if (msg.type !== "blink:content-height") {
|
|
525
|
+
return null;
|
|
526
|
+
}
|
|
527
|
+
const raw = msg.heightPx;
|
|
528
|
+
if (typeof raw !== "number" || !Number.isFinite(raw)) {
|
|
529
|
+
return null;
|
|
530
|
+
}
|
|
531
|
+
const heightPx = Math.round(raw);
|
|
532
|
+
if (heightPx <= 0 || heightPx > MAX_CONTENT_HEIGHT_PX) {
|
|
533
|
+
return null;
|
|
534
|
+
}
|
|
535
|
+
return {
|
|
536
|
+
type: "blink:content-height",
|
|
537
|
+
heightPx,
|
|
538
|
+
...parseWidthHint("preferredWidthPx", msg.preferredWidthPx),
|
|
539
|
+
...parseWidthHint("minWidthPx", msg.minWidthPx)
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
function parseWidthHint(key, value) {
|
|
543
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return {};
|
|
544
|
+
const px = Math.round(value);
|
|
545
|
+
if (px <= 0 || px > MAX_CONTENT_HEIGHT_PX) return {};
|
|
546
|
+
return { [key]: px };
|
|
512
547
|
}
|
|
513
548
|
function buildRevealMessage() {
|
|
514
549
|
return { type: "blink:reveal" };
|
|
515
550
|
}
|
|
516
|
-
function buildSignedPayloadMessage(merchantId, payload, signature) {
|
|
551
|
+
function buildSignedPayloadMessage(merchantId, payload, signature, balance) {
|
|
517
552
|
return {
|
|
518
553
|
type: "blink:signed-payload",
|
|
519
554
|
merchantId,
|
|
520
555
|
payload,
|
|
521
|
-
signature
|
|
556
|
+
signature,
|
|
557
|
+
...balance === void 0 ? {} : { balance }
|
|
522
558
|
};
|
|
523
559
|
}
|
|
524
560
|
|
|
561
|
+
// src/brandParam.ts
|
|
562
|
+
var BRAND_COLOR_PARAM_KEYS = {
|
|
563
|
+
colorPrimary: "p",
|
|
564
|
+
colorBackground: "bg",
|
|
565
|
+
colorText: "t",
|
|
566
|
+
colorDanger: "d",
|
|
567
|
+
colorBorder: "b"
|
|
568
|
+
};
|
|
569
|
+
function normalizeBrandHex(value) {
|
|
570
|
+
if (typeof value !== "string") return null;
|
|
571
|
+
const hex = value.trim().toLowerCase();
|
|
572
|
+
if (!/^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/.test(hex)) return null;
|
|
573
|
+
const digits = hex.slice(1);
|
|
574
|
+
if (digits.length === 6) return `#${digits}`;
|
|
575
|
+
return `#${digits[0]}${digits[0]}${digits[1]}${digits[1]}${digits[2]}${digits[2]}`;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
// src/balanceParam.ts
|
|
579
|
+
var MAX_BALANCE_USD = 1e12;
|
|
580
|
+
function normalizeDisplayBalance(value) {
|
|
581
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return null;
|
|
582
|
+
if (value < 0 || value >= MAX_BALANCE_USD) return null;
|
|
583
|
+
const cents = Math.floor(Number((value * 100).toPrecision(15)));
|
|
584
|
+
if (cents < 0 || cents >= MAX_BALANCE_USD * 100) return null;
|
|
585
|
+
return (cents / 100).toFixed(2);
|
|
586
|
+
}
|
|
587
|
+
|
|
525
588
|
// src/viewportMetrics.ts
|
|
526
589
|
function measureViewportMetrics() {
|
|
527
590
|
const unavailable = { viewportLvh: 0, safeAreaBottom: 0 };
|
|
@@ -550,6 +613,84 @@ function measureViewportMetrics() {
|
|
|
550
613
|
}
|
|
551
614
|
}
|
|
552
615
|
|
|
616
|
+
// src/iframeCore.ts
|
|
617
|
+
function createFrameElement(url) {
|
|
618
|
+
const iframe = document.createElement("iframe");
|
|
619
|
+
iframe.src = url;
|
|
620
|
+
const iframeOrigin = new URL(url).origin;
|
|
621
|
+
iframe.allow = `publickey-credentials-get ${iframeOrigin}; publickey-credentials-create ${iframeOrigin}; clipboard-write ${iframeOrigin}; web-share ${iframeOrigin}`;
|
|
622
|
+
return { iframe, iframeOrigin };
|
|
623
|
+
}
|
|
624
|
+
function attachFrameBridges(options) {
|
|
625
|
+
const { iframe, iframeOrigin, postViewport, getEmbedMaxHeightPx, shouldRevealOnLoad } = options;
|
|
626
|
+
let detached = false;
|
|
627
|
+
const discoverer = createWalletDiscoverer();
|
|
628
|
+
let rpcHostHandle = null;
|
|
629
|
+
const attachBridge = () => {
|
|
630
|
+
if (rpcHostHandle) return;
|
|
631
|
+
if (!iframe.contentWindow) return;
|
|
632
|
+
rpcHostHandle = attachRpcHost({
|
|
633
|
+
iframeWindow: iframe.contentWindow,
|
|
634
|
+
iframeOrigin,
|
|
635
|
+
discoverer
|
|
636
|
+
});
|
|
637
|
+
};
|
|
638
|
+
attachBridge();
|
|
639
|
+
iframe.addEventListener("load", attachBridge);
|
|
640
|
+
function postReveal() {
|
|
641
|
+
if (detached) return;
|
|
642
|
+
iframe.contentWindow?.postMessage(buildRevealMessage(), iframeOrigin);
|
|
643
|
+
}
|
|
644
|
+
function postViewportMetrics() {
|
|
645
|
+
if (detached || !postViewport) return;
|
|
646
|
+
const metrics = measureViewportMetrics();
|
|
647
|
+
if (metrics.viewportLvh <= 0) return;
|
|
648
|
+
iframe.contentWindow?.postMessage(
|
|
649
|
+
buildViewportMessage(
|
|
650
|
+
metrics.viewportLvh,
|
|
651
|
+
metrics.safeAreaBottom,
|
|
652
|
+
getEmbedMaxHeightPx?.()
|
|
653
|
+
),
|
|
654
|
+
iframeOrigin
|
|
655
|
+
);
|
|
656
|
+
}
|
|
657
|
+
let viewportPostScheduled = false;
|
|
658
|
+
const onViewportChange = () => {
|
|
659
|
+
if (viewportPostScheduled) return;
|
|
660
|
+
viewportPostScheduled = true;
|
|
661
|
+
requestAnimationFrame(() => {
|
|
662
|
+
viewportPostScheduled = false;
|
|
663
|
+
postViewportMetrics();
|
|
664
|
+
});
|
|
665
|
+
};
|
|
666
|
+
if (postViewport) {
|
|
667
|
+
window.addEventListener("resize", onViewportChange);
|
|
668
|
+
window.addEventListener("orientationchange", onViewportChange);
|
|
669
|
+
}
|
|
670
|
+
const onLoadReveal = () => {
|
|
671
|
+
postViewportMetrics();
|
|
672
|
+
if (shouldRevealOnLoad()) postReveal();
|
|
673
|
+
};
|
|
674
|
+
iframe.addEventListener("load", onLoadReveal);
|
|
675
|
+
return {
|
|
676
|
+
postReveal,
|
|
677
|
+
postViewportMetrics,
|
|
678
|
+
detach() {
|
|
679
|
+
if (detached) return;
|
|
680
|
+
detached = true;
|
|
681
|
+
iframe.removeEventListener("load", attachBridge);
|
|
682
|
+
iframe.removeEventListener("load", onLoadReveal);
|
|
683
|
+
window.removeEventListener("resize", onViewportChange);
|
|
684
|
+
window.removeEventListener("orientationchange", onViewportChange);
|
|
685
|
+
if (rpcHostHandle) {
|
|
686
|
+
rpcHostHandle.detach();
|
|
687
|
+
rpcHostHandle = null;
|
|
688
|
+
}
|
|
689
|
+
discoverer.destroy();
|
|
690
|
+
}
|
|
691
|
+
};
|
|
692
|
+
}
|
|
693
|
+
|
|
553
694
|
// src/iframe.ts
|
|
554
695
|
var STYLE_ID = "blink-deposit-styles";
|
|
555
696
|
var CLOSE_DURATION_MS = 280;
|
|
@@ -591,60 +732,20 @@ function createIframe(url, containerElement, options) {
|
|
|
591
732
|
}
|
|
592
733
|
const container = document.createElement("div");
|
|
593
734
|
container.setAttribute("data-blink-container", "");
|
|
594
|
-
const iframe =
|
|
595
|
-
iframe.src = url;
|
|
596
|
-
const iframeOrigin = new URL(url).origin;
|
|
597
|
-
iframe.allow = `publickey-credentials-get ${iframeOrigin}; publickey-credentials-create ${iframeOrigin}; clipboard-write ${iframeOrigin}`;
|
|
735
|
+
const { iframe, iframeOrigin } = createFrameElement(url);
|
|
598
736
|
const handle = document.createElement("div");
|
|
599
737
|
container.appendChild(handle);
|
|
600
738
|
container.appendChild(iframe);
|
|
601
739
|
overlay.appendChild(container);
|
|
602
740
|
const mountTarget = containerElement ?? document.body;
|
|
603
741
|
mountTarget.appendChild(overlay);
|
|
604
|
-
const
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
iframeOrigin,
|
|
612
|
-
discoverer
|
|
613
|
-
});
|
|
614
|
-
};
|
|
615
|
-
attachBridge();
|
|
616
|
-
iframe.addEventListener("load", attachBridge);
|
|
617
|
-
function postReveal() {
|
|
618
|
-
if (closed) return;
|
|
619
|
-
iframe.contentWindow?.postMessage(buildRevealMessage(), iframeOrigin);
|
|
620
|
-
}
|
|
621
|
-
function postViewportMetrics() {
|
|
622
|
-
if (closed || !options?.fluid) return;
|
|
623
|
-
const metrics = measureViewportMetrics();
|
|
624
|
-
if (metrics.viewportLvh <= 0) return;
|
|
625
|
-
iframe.contentWindow?.postMessage(
|
|
626
|
-
buildViewportMessage(metrics.viewportLvh, metrics.safeAreaBottom),
|
|
627
|
-
iframeOrigin
|
|
628
|
-
);
|
|
629
|
-
}
|
|
630
|
-
let viewportPostScheduled = false;
|
|
631
|
-
const onViewportChange = () => {
|
|
632
|
-
if (viewportPostScheduled) return;
|
|
633
|
-
viewportPostScheduled = true;
|
|
634
|
-
requestAnimationFrame(() => {
|
|
635
|
-
viewportPostScheduled = false;
|
|
636
|
-
postViewportMetrics();
|
|
637
|
-
});
|
|
638
|
-
};
|
|
639
|
-
if (options?.fluid) {
|
|
640
|
-
window.addEventListener("resize", onViewportChange);
|
|
641
|
-
window.addEventListener("orientationchange", onViewportChange);
|
|
642
|
-
}
|
|
643
|
-
const onLoadReveal = () => {
|
|
644
|
-
postViewportMetrics();
|
|
645
|
-
if (!hidden) postReveal();
|
|
646
|
-
};
|
|
647
|
-
iframe.addEventListener("load", onLoadReveal);
|
|
742
|
+
const bridges = attachFrameBridges({
|
|
743
|
+
iframe,
|
|
744
|
+
iframeOrigin,
|
|
745
|
+
// Only fluid needs them: the legacy fixed overlay sizes the iframe itself.
|
|
746
|
+
postViewport: options?.fluid === true,
|
|
747
|
+
shouldRevealOnLoad: () => !hidden
|
|
748
|
+
});
|
|
648
749
|
let savedOverflow = "";
|
|
649
750
|
let scrollLocked = false;
|
|
650
751
|
const onBackdropClick = (event) => {
|
|
@@ -675,8 +776,6 @@ function createIframe(url, containerElement, options) {
|
|
|
675
776
|
overlay.removeEventListener("click", onBackdropClick);
|
|
676
777
|
overlay.removeEventListener("touchmove", onTouchMove);
|
|
677
778
|
document.removeEventListener("keydown", onKeyDown);
|
|
678
|
-
window.removeEventListener("resize", onViewportChange);
|
|
679
|
-
window.removeEventListener("orientationchange", onViewportChange);
|
|
680
779
|
}
|
|
681
780
|
function unlockScroll() {
|
|
682
781
|
if (!scrollLocked) return;
|
|
@@ -687,7 +786,7 @@ function createIframe(url, containerElement, options) {
|
|
|
687
786
|
if (closed) return;
|
|
688
787
|
closed = true;
|
|
689
788
|
removeListeners();
|
|
690
|
-
|
|
789
|
+
bridges.detach();
|
|
691
790
|
overlay.setAttribute("data-blink-closing", "");
|
|
692
791
|
let removed = false;
|
|
693
792
|
const removeOverlay = () => {
|
|
@@ -700,15 +799,6 @@ function createIframe(url, containerElement, options) {
|
|
|
700
799
|
container.addEventListener("animationend", removeOverlay, { once: true });
|
|
701
800
|
setTimeout(removeOverlay, CLOSE_DURATION_MS + 50);
|
|
702
801
|
}
|
|
703
|
-
function detachBridge() {
|
|
704
|
-
iframe.removeEventListener("load", attachBridge);
|
|
705
|
-
iframe.removeEventListener("load", onLoadReveal);
|
|
706
|
-
if (rpcHostHandle) {
|
|
707
|
-
rpcHostHandle.detach();
|
|
708
|
-
rpcHostHandle = null;
|
|
709
|
-
}
|
|
710
|
-
discoverer.destroy();
|
|
711
|
-
}
|
|
712
802
|
return {
|
|
713
803
|
get contentWindow() {
|
|
714
804
|
return iframe.contentWindow;
|
|
@@ -733,15 +823,17 @@ function createIframe(url, containerElement, options) {
|
|
|
733
823
|
overlay.style.display = "";
|
|
734
824
|
lockScroll();
|
|
735
825
|
attachDismissalListeners();
|
|
736
|
-
postViewportMetrics();
|
|
737
|
-
postReveal();
|
|
826
|
+
bridges.postViewportMetrics();
|
|
827
|
+
bridges.postReveal();
|
|
738
828
|
},
|
|
739
829
|
postReveal() {
|
|
740
|
-
postReveal();
|
|
830
|
+
bridges.postReveal();
|
|
741
831
|
},
|
|
742
832
|
downgradeToFixed() {
|
|
743
833
|
overlay.removeAttribute("data-blink-fluid");
|
|
744
834
|
},
|
|
835
|
+
applyContentHeight() {
|
|
836
|
+
},
|
|
745
837
|
onClose(callback) {
|
|
746
838
|
closeCallback = callback;
|
|
747
839
|
},
|
|
@@ -750,7 +842,7 @@ function createIframe(url, containerElement, options) {
|
|
|
750
842
|
if (!closed) {
|
|
751
843
|
closed = true;
|
|
752
844
|
removeListeners();
|
|
753
|
-
|
|
845
|
+
bridges.detach();
|
|
754
846
|
overlay.remove();
|
|
755
847
|
unlockScroll();
|
|
756
848
|
}
|
|
@@ -787,6 +879,117 @@ function shouldUseMobileSheetLayout() {
|
|
|
787
879
|
return shortestScreenSide > 0 && shortestScreenSide <= MOBILE_SHEET_MAX_SCREEN_PX;
|
|
788
880
|
}
|
|
789
881
|
|
|
882
|
+
// src/embeddedIframe.ts
|
|
883
|
+
var EMBED_STYLE_ID = "blink-deposit-embed-styles";
|
|
884
|
+
var EMBED_STYLES = `
|
|
885
|
+
[data-blink-embed]{display:block;width:100%;position:relative}
|
|
886
|
+
[data-blink-embed][data-blink-embed-hidden]{height:0;overflow:hidden;visibility:hidden;pointer-events:none}
|
|
887
|
+
[data-blink-embed] iframe{display:block;width:100%;height:0;border:none;background:transparent;color-scheme:light}
|
|
888
|
+
`;
|
|
889
|
+
function createEmbeddedIframe(url, containerElement, options) {
|
|
890
|
+
ensureEmbedStyles();
|
|
891
|
+
if (!containerElement.isConnected) {
|
|
892
|
+
console.warn(
|
|
893
|
+
"[blink] The containerElement passed to Deposit is not in the document. Embedded mode renders into it for the life of the instance, so it must be a stable node \u2014 render the slot once and hide it with `visibility: hidden` (NOT `display: none`, which removes its layout and leaves the warming flow unable to measure itself) instead of unmounting it, or construct a new Deposit against the new node."
|
|
894
|
+
);
|
|
895
|
+
}
|
|
896
|
+
let closed = false;
|
|
897
|
+
let hidden = options?.hidden === true;
|
|
898
|
+
let closeCallback = null;
|
|
899
|
+
const readEmbedMaxHeightPx = () => typeof options?.embedMaxHeightPx === "function" ? options.embedMaxHeightPx() : options?.embedMaxHeightPx;
|
|
900
|
+
const wrapper = document.createElement("div");
|
|
901
|
+
wrapper.setAttribute("data-blink-embed", "");
|
|
902
|
+
if (hidden) {
|
|
903
|
+
wrapper.setAttribute("data-blink-embed-hidden", "");
|
|
904
|
+
}
|
|
905
|
+
const { iframe, iframeOrigin } = createFrameElement(url);
|
|
906
|
+
iframe.setAttribute("scrolling", "no");
|
|
907
|
+
const initialBudget = readEmbedMaxHeightPx();
|
|
908
|
+
if (initialBudget !== void 0) {
|
|
909
|
+
iframe.style.height = `${initialBudget}px`;
|
|
910
|
+
}
|
|
911
|
+
wrapper.appendChild(iframe);
|
|
912
|
+
containerElement.appendChild(wrapper);
|
|
913
|
+
const bridges = attachFrameBridges({
|
|
914
|
+
iframe,
|
|
915
|
+
iframeOrigin,
|
|
916
|
+
// Embedded always needs them: the flow has no usable viewport of its own,
|
|
917
|
+
// so the basis it sizes against can only come from here.
|
|
918
|
+
postViewport: true,
|
|
919
|
+
getEmbedMaxHeightPx: readEmbedMaxHeightPx,
|
|
920
|
+
shouldRevealOnLoad: () => !hidden
|
|
921
|
+
});
|
|
922
|
+
function teardown() {
|
|
923
|
+
closed = true;
|
|
924
|
+
bridges.detach();
|
|
925
|
+
wrapper.remove();
|
|
926
|
+
}
|
|
927
|
+
return {
|
|
928
|
+
get contentWindow() {
|
|
929
|
+
return iframe.contentWindow;
|
|
930
|
+
},
|
|
931
|
+
close() {
|
|
932
|
+
if (closed) return;
|
|
933
|
+
teardown();
|
|
934
|
+
closeCallback?.();
|
|
935
|
+
},
|
|
936
|
+
isClosed() {
|
|
937
|
+
return closed;
|
|
938
|
+
},
|
|
939
|
+
isHidden() {
|
|
940
|
+
return hidden;
|
|
941
|
+
},
|
|
942
|
+
reveal() {
|
|
943
|
+
if (closed || !hidden) return;
|
|
944
|
+
hidden = false;
|
|
945
|
+
wrapper.removeAttribute("data-blink-embed-hidden");
|
|
946
|
+
warnIfContainerNotRendered(containerElement);
|
|
947
|
+
bridges.postViewportMetrics();
|
|
948
|
+
bridges.postReveal();
|
|
949
|
+
},
|
|
950
|
+
postReveal() {
|
|
951
|
+
bridges.postReveal();
|
|
952
|
+
},
|
|
953
|
+
downgradeToFixed() {
|
|
954
|
+
},
|
|
955
|
+
applyContentHeight(heightPx) {
|
|
956
|
+
if (closed) return;
|
|
957
|
+
const budget = readEmbedMaxHeightPx();
|
|
958
|
+
const capped = budget === void 0 ? heightPx : Math.min(heightPx, budget);
|
|
959
|
+
iframe.style.height = `${Math.max(0, Math.round(capped))}px`;
|
|
960
|
+
},
|
|
961
|
+
onClose(callback) {
|
|
962
|
+
closeCallback = callback;
|
|
963
|
+
},
|
|
964
|
+
destroy() {
|
|
965
|
+
closeCallback = null;
|
|
966
|
+
if (!closed) teardown();
|
|
967
|
+
}
|
|
968
|
+
};
|
|
969
|
+
}
|
|
970
|
+
function warnIfContainerNotRendered(containerElement) {
|
|
971
|
+
if (typeof containerElement.getBoundingClientRect !== "function") return;
|
|
972
|
+
const rect = containerElement.getBoundingClientRect();
|
|
973
|
+
if (rect.width > 0 || rect.height > 0) return;
|
|
974
|
+
const display = typeof getComputedStyle === "function" ? getComputedStyle(containerElement).display : "";
|
|
975
|
+
console.warn(
|
|
976
|
+
`[blink] The containerElement has no layout at the moment the flow is revealed${display === "none" ? " (display: none)" : ""}. A display:none subtree cannot be measured, so the flow may report no height and the panel stays blank at its budget height. Hide the slot with \`visibility: hidden\` (plus \`height: 0; overflow: hidden\`) instead of \`display: none\`, so it keeps its box while it warms up.`
|
|
977
|
+
);
|
|
978
|
+
}
|
|
979
|
+
function ensureEmbedStyles() {
|
|
980
|
+
const existingStyle = document.getElementById(EMBED_STYLE_ID);
|
|
981
|
+
if (existingStyle) {
|
|
982
|
+
if (existingStyle.textContent !== EMBED_STYLES) {
|
|
983
|
+
existingStyle.textContent = EMBED_STYLES;
|
|
984
|
+
}
|
|
985
|
+
return;
|
|
986
|
+
}
|
|
987
|
+
const style = document.createElement("style");
|
|
988
|
+
style.id = EMBED_STYLE_ID;
|
|
989
|
+
style.textContent = EMBED_STYLES;
|
|
990
|
+
document.head.appendChild(style);
|
|
991
|
+
}
|
|
992
|
+
|
|
790
993
|
// src/signer.ts
|
|
791
994
|
var DEFAULT_SIGNER_TIMEOUT_MS = 15e3;
|
|
792
995
|
async function callSigner(signer, request, timeoutMs) {
|
|
@@ -917,6 +1120,13 @@ var SANDBOX_WEBVIEW_BASE_URL = "https://pay-sandbox.blink.cash";
|
|
|
917
1120
|
var IFRAME_READY_TIMEOUT_MS = 2e3;
|
|
918
1121
|
var WARM_IFRAME_READY_TIMEOUT_MS = 6e4;
|
|
919
1122
|
var LAYOUT_FLUID_CAPABILITY = "layout-fluid";
|
|
1123
|
+
var DEFAULT_EMBED_MAX_HEIGHT_FRACTION = 0.9;
|
|
1124
|
+
function dismissedError() {
|
|
1125
|
+
return new DepositError(
|
|
1126
|
+
"DEPOSIT_DISMISSED",
|
|
1127
|
+
"The deposit was dismissed before the transfer completed."
|
|
1128
|
+
);
|
|
1129
|
+
}
|
|
920
1130
|
var IFRAME_NOT_READY = { ready: false, fluidCapable: false };
|
|
921
1131
|
function resolveWebviewBaseUrl(config) {
|
|
922
1132
|
if (config.webviewBaseUrl) return config.webviewBaseUrl;
|
|
@@ -937,11 +1147,20 @@ var Deposit = class {
|
|
|
937
1147
|
warmIframe = null;
|
|
938
1148
|
warmIframeReady = null;
|
|
939
1149
|
warmIframeReadyCancel = null;
|
|
1150
|
+
/** Resolved embedded-vs-overlay decision; see {@link Deposit.isEmbedded}. */
|
|
1151
|
+
embeddedResolved = null;
|
|
1152
|
+
/**
|
|
1153
|
+
* Settles the in-flight `requestDeposit()` as a dismissal. Non-null exactly
|
|
1154
|
+
* while a flow is in progress, so {@link Deposit.close} can reject the promise
|
|
1155
|
+
* the caller is awaiting instead of tearing the frame down under it.
|
|
1156
|
+
*/
|
|
1157
|
+
dismissActiveFlow = null;
|
|
940
1158
|
listeners = {
|
|
941
1159
|
complete: /* @__PURE__ */ new Set(),
|
|
942
1160
|
error: /* @__PURE__ */ new Set(),
|
|
943
1161
|
close: /* @__PURE__ */ new Set(),
|
|
944
|
-
"status-change": /* @__PURE__ */ new Set()
|
|
1162
|
+
"status-change": /* @__PURE__ */ new Set(),
|
|
1163
|
+
resize: /* @__PURE__ */ new Set()
|
|
945
1164
|
};
|
|
946
1165
|
/** Current phase of the deposit flow. */
|
|
947
1166
|
get status() {
|
|
@@ -959,10 +1178,40 @@ var Deposit = class {
|
|
|
959
1178
|
get isActive() {
|
|
960
1179
|
return this._status === "signer-loading" || this._status === "iframe-active";
|
|
961
1180
|
}
|
|
1181
|
+
/**
|
|
1182
|
+
* How this instance will actually present: `'embedded'` renders inline in
|
|
1183
|
+
* `containerElement`, `'overlay'` covers the page.
|
|
1184
|
+
*
|
|
1185
|
+
* Not simply an echo of the config — a host that asked for `'embedded'` gets
|
|
1186
|
+
* `'overlay'` on mobile, where a phone-sized method panel cannot hold the
|
|
1187
|
+
* flow (see {@link Deposit.isEmbedded}). Read it when laying out the panel:
|
|
1188
|
+
* on `'overlay'` no `resize` event ever fires, so a panel sized from those
|
|
1189
|
+
* reports would sit empty behind the overlay — collapse or skip it.
|
|
1190
|
+
*
|
|
1191
|
+
* Live until the SDK builds its first (warm-up) frame and fixed from then on,
|
|
1192
|
+
* so re-read it on resize rather than caching it at mount.
|
|
1193
|
+
*/
|
|
1194
|
+
get presentation() {
|
|
1195
|
+
return this.isEmbedded() ? "embedded" : "overlay";
|
|
1196
|
+
}
|
|
962
1197
|
constructor(config) {
|
|
963
1198
|
if (!config.signer || typeof config.signer !== "string" && typeof config.signer !== "function") {
|
|
964
1199
|
throw new DepositError("INVALID_REQUEST", "DepositConfig.signer is required (URL string or SignerFunction).");
|
|
965
1200
|
}
|
|
1201
|
+
if (config.presentation === "embedded") {
|
|
1202
|
+
if (!config.containerElement) {
|
|
1203
|
+
throw new DepositError(
|
|
1204
|
+
"INVALID_REQUEST",
|
|
1205
|
+
'DepositConfig.containerElement is required when presentation is "embedded".'
|
|
1206
|
+
);
|
|
1207
|
+
}
|
|
1208
|
+
if (config.layout === "fixed") {
|
|
1209
|
+
throw new DepositError(
|
|
1210
|
+
"INVALID_REQUEST",
|
|
1211
|
+
'DepositConfig.layout "fixed" is an overlay-only escape hatch and cannot be combined with presentation "embedded".'
|
|
1212
|
+
);
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
966
1215
|
this.config = config;
|
|
967
1216
|
this.log("Deposit instance created", {
|
|
968
1217
|
signer: typeof config.signer === "string" ? config.signer : "<function>"
|
|
@@ -988,10 +1237,7 @@ var Deposit = class {
|
|
|
988
1237
|
const webviewBaseUrl = resolveWebviewBaseUrl(this.config);
|
|
989
1238
|
this.hostedOrigin = this.config.hostedFlowOrigin ?? new URL(webviewBaseUrl).origin;
|
|
990
1239
|
const preloadUrl = this.buildPreloadUrl(webviewBaseUrl);
|
|
991
|
-
const iframe =
|
|
992
|
-
hidden: true,
|
|
993
|
-
fluid: this.isFluidLayout()
|
|
994
|
-
});
|
|
1240
|
+
const iframe = this.createPresentedIframe(preloadUrl, { hidden: true });
|
|
995
1241
|
const ready = this.waitForIframeReady(iframe, WARM_IFRAME_READY_TIMEOUT_MS);
|
|
996
1242
|
this.warmIframe = iframe;
|
|
997
1243
|
this.warmIframeReady = ready.promise;
|
|
@@ -1020,6 +1266,83 @@ var Deposit = class {
|
|
|
1020
1266
|
window.addEventListener("load", whenIdle, { once: true });
|
|
1021
1267
|
}
|
|
1022
1268
|
}
|
|
1269
|
+
/**
|
|
1270
|
+
* Whether the flow renders inline in the host's element rather than as an
|
|
1271
|
+
* overlay.
|
|
1272
|
+
*
|
|
1273
|
+
* `presentation: 'embedded'` is a request, not a guarantee: **on mobile the
|
|
1274
|
+
* flow presents as the normal overlay** even for an embedded host. An
|
|
1275
|
+
* aggregator's method panel is a narrow, short column on a phone, and the
|
|
1276
|
+
* flow inside it is a payment journey with a keypad, wallet lists and a QR
|
|
1277
|
+
* code — it needs the screen. The overlay is exactly what a phone user gets
|
|
1278
|
+
* from every other Blink integration, and the host's own dialog stays behind
|
|
1279
|
+
* it. Desktop keeps the inline card, where the panel has room.
|
|
1280
|
+
*
|
|
1281
|
+
* **The decision lives with the frame.** Read live until a frame is built,
|
|
1282
|
+
* then committed for good ({@link Deposit.createPresentedIframe}) — `preload()`
|
|
1283
|
+
* warms a frame from these same predicates and the flow that later adopts it
|
|
1284
|
+
* must agree, because a frame warmed at `layout=embed` handed to the overlay
|
|
1285
|
+
* presenter (or the reverse) is a blank modal. Committing at frame creation
|
|
1286
|
+
* rather than at construction matters: a host that constructs `Deposit` before
|
|
1287
|
+
* layout settles — a widget mounting inside a transition, a background or
|
|
1288
|
+
* prerendered tab — reports a zero-width viewport, and `(max-width: 640px)`
|
|
1289
|
+
* matches at zero, so caching then would lock a desktop user into the overlay
|
|
1290
|
+
* over a viewport that never existed. The warm-up already waits for `load`
|
|
1291
|
+
* plus an idle callback, so by the time it commits the measurement is real.
|
|
1292
|
+
*/
|
|
1293
|
+
isEmbedded() {
|
|
1294
|
+
if (this.config.presentation !== "embedded") return false;
|
|
1295
|
+
if (this.embeddedResolved !== null) return this.embeddedResolved;
|
|
1296
|
+
if (typeof window === "undefined") return true;
|
|
1297
|
+
const viewportWidth = window.visualViewport?.width ?? window.innerWidth;
|
|
1298
|
+
if (!(viewportWidth > 0)) return true;
|
|
1299
|
+
return !shouldUseMobileSheetLayout();
|
|
1300
|
+
}
|
|
1301
|
+
/**
|
|
1302
|
+
* The host's height budget for the inline iframe. Explicit config wins;
|
|
1303
|
+
* otherwise most of the host viewport, which keeps a tall flow from
|
|
1304
|
+
* outgrowing the page it is embedded in.
|
|
1305
|
+
*/
|
|
1306
|
+
resolveEmbedMaxHeightPx() {
|
|
1307
|
+
if (this.config.embedMaxHeightPx !== void 0) return this.config.embedMaxHeightPx;
|
|
1308
|
+
if (typeof window === "undefined") return void 0;
|
|
1309
|
+
const derived = Math.round(window.innerHeight * DEFAULT_EMBED_MAX_HEIGHT_FRACTION);
|
|
1310
|
+
return derived > 0 ? derived : void 0;
|
|
1311
|
+
}
|
|
1312
|
+
/** Build the iframe for the configured presentation. */
|
|
1313
|
+
createPresentedIframe(url, options) {
|
|
1314
|
+
if (this.config.presentation === "embedded" && this.embeddedResolved === null) {
|
|
1315
|
+
this.embeddedResolved = this.isEmbedded();
|
|
1316
|
+
if (!this.embeddedResolved) {
|
|
1317
|
+
this.log("Mobile device: presenting the embedded flow as an overlay");
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
if (this.isEmbedded()) {
|
|
1321
|
+
return createEmbeddedIframe(url, this.config.containerElement, {
|
|
1322
|
+
hidden: options.hidden,
|
|
1323
|
+
// A getter, not a value: the default is derived from the host
|
|
1324
|
+
// viewport, which changes on rotation and window resize.
|
|
1325
|
+
embedMaxHeightPx: () => this.resolveEmbedMaxHeightPx()
|
|
1326
|
+
});
|
|
1327
|
+
}
|
|
1328
|
+
return createIframe(url, this.overlayMountTarget(), {
|
|
1329
|
+
hidden: options.hidden,
|
|
1330
|
+
fluid: this.isFluidLayout()
|
|
1331
|
+
});
|
|
1332
|
+
}
|
|
1333
|
+
/**
|
|
1334
|
+
* Where the overlay mounts. `containerElement` means two different things by
|
|
1335
|
+
* presentation: an overlay mount point (`presentation: 'overlay'`) or the
|
|
1336
|
+
* aggregator's inline panel slot (`'embedded'`). When an embedded flow
|
|
1337
|
+
* presents as an overlay on mobile, that slot must NOT be the mount point —
|
|
1338
|
+
* `position: fixed` resolves against the nearest transformed/filtered/
|
|
1339
|
+
* contained ancestor, and an aggregator's animated dialog is exactly that, so
|
|
1340
|
+
* the "full-screen" overlay would end up positioned inside their panel.
|
|
1341
|
+
* Falls through to `document.body`.
|
|
1342
|
+
*/
|
|
1343
|
+
overlayMountTarget() {
|
|
1344
|
+
return this.config.presentation === "embedded" ? void 0 : this.config.containerElement;
|
|
1345
|
+
}
|
|
1023
1346
|
buildPreloadUrl(webviewBaseUrl) {
|
|
1024
1347
|
const preloadUrl = new URL(webviewBaseUrl);
|
|
1025
1348
|
preloadUrl.searchParams.set("preload", "true");
|
|
@@ -1085,6 +1408,7 @@ var Deposit = class {
|
|
|
1085
1408
|
const settle = (fn) => {
|
|
1086
1409
|
if (this.requestId !== currentRequestId || settled) return;
|
|
1087
1410
|
settled = true;
|
|
1411
|
+
this.dismissActiveFlow = null;
|
|
1088
1412
|
fn();
|
|
1089
1413
|
};
|
|
1090
1414
|
const onComplete = (result) => {
|
|
@@ -1110,6 +1434,12 @@ var Deposit = class {
|
|
|
1110
1434
|
reject(error);
|
|
1111
1435
|
});
|
|
1112
1436
|
};
|
|
1437
|
+
this.dismissActiveFlow = () => {
|
|
1438
|
+
settle(() => {
|
|
1439
|
+
this.cleanup();
|
|
1440
|
+
reject(dismissedError());
|
|
1441
|
+
});
|
|
1442
|
+
};
|
|
1113
1443
|
if (this.config.flowTimeoutMs != null && this.config.flowTimeoutMs > 0) {
|
|
1114
1444
|
this.flowTimer = setTimeout(() => {
|
|
1115
1445
|
onError(
|
|
@@ -1136,9 +1466,29 @@ var Deposit = class {
|
|
|
1136
1466
|
/** No-op — retained for API compatibility with the popup-based SDK. */
|
|
1137
1467
|
focus() {
|
|
1138
1468
|
}
|
|
1139
|
-
/**
|
|
1469
|
+
/**
|
|
1470
|
+
* Close the deposit iframe without waiting for completion — the host's own
|
|
1471
|
+
* back button or dialog chrome.
|
|
1472
|
+
*
|
|
1473
|
+
* This **settles a flow in progress** by rejecting its `requestDeposit()`
|
|
1474
|
+
* promise with `DEPOSIT_DISMISSED`, exactly as the flow's own close control
|
|
1475
|
+
* does. It has to: `cleanup()` destroys the frame through `destroy()`, which
|
|
1476
|
+
* drops the handle's close callback on purpose, so without this the caller's
|
|
1477
|
+
* `await` never returns. An aggregator whose back button awaited that promise
|
|
1478
|
+
* to restore its method list was left showing an empty panel — the flow gone,
|
|
1479
|
+
* its own list still not rendered, and no error to explain why.
|
|
1480
|
+
*
|
|
1481
|
+
* The rejection code is the same `DEPOSIT_DISMISSED` the in-flow control
|
|
1482
|
+
* produces, so a host writes one dismissal branch rather than one per
|
|
1483
|
+
* affordance. What it deliberately does not do is report an error: no `error`
|
|
1484
|
+
* event, and `status` lands on 'idle' as it always has, because the host
|
|
1485
|
+
* initiated this. With no flow in progress it is a plain teardown, unchanged.
|
|
1486
|
+
*/
|
|
1140
1487
|
close() {
|
|
1141
1488
|
this.log("close() called");
|
|
1489
|
+
const dismiss = this.dismissActiveFlow;
|
|
1490
|
+
this.dismissActiveFlow = null;
|
|
1491
|
+
dismiss?.();
|
|
1142
1492
|
this.cleanup();
|
|
1143
1493
|
this.setStatus("idle");
|
|
1144
1494
|
this.emit("close");
|
|
@@ -1191,10 +1541,80 @@ var Deposit = class {
|
|
|
1191
1541
|
if (theme === "dark" || theme === "system") {
|
|
1192
1542
|
url.searchParams.set("appearance", theme);
|
|
1193
1543
|
}
|
|
1544
|
+
this.applyBrandParam(url);
|
|
1545
|
+
}
|
|
1546
|
+
/**
|
|
1547
|
+
* Appends the merchant's brand colors as `brand=p-0f62fe.bg-ffffff…`.
|
|
1548
|
+
*
|
|
1549
|
+
* On the URL rather than a message because the hosted flow's loading shell
|
|
1550
|
+
* paints from its entry chunk, hundreds of ms before React mounts: a palette
|
|
1551
|
+
* that arrived by `postMessage` would show Blink's own card color first and
|
|
1552
|
+
* then become the merchant's. Unreserved characters only, so the param costs
|
|
1553
|
+
* ~50 bytes of the URL budget rather than triple that in percent-encoding.
|
|
1554
|
+
*
|
|
1555
|
+
* Validated here purely so the merchant sees the complaint in their OWN
|
|
1556
|
+
* console — the hosted flow re-validates everything it decodes, since the URL
|
|
1557
|
+
* is host-controlled input that ends up in a stylesheet. Silence would be the
|
|
1558
|
+
* worst outcome: a dropped color that nobody is told about looks like the SDK
|
|
1559
|
+
* ignoring the config.
|
|
1560
|
+
*/
|
|
1561
|
+
applyBrandParam(url) {
|
|
1562
|
+
const variables = this.config.appearance?.variables;
|
|
1563
|
+
if (!variables) return;
|
|
1564
|
+
const accepted = {};
|
|
1565
|
+
for (const [key, value] of Object.entries(variables)) {
|
|
1566
|
+
if (value === void 0 || value === null) continue;
|
|
1567
|
+
if (!BRAND_COLOR_PARAM_KEYS[key]) {
|
|
1568
|
+
console.error(
|
|
1569
|
+
`[blink] appearance.variables.${key} is not a supported brand color. Supported: ${Object.keys(BRAND_COLOR_PARAM_KEYS).join(", ")}.`
|
|
1570
|
+
);
|
|
1571
|
+
continue;
|
|
1572
|
+
}
|
|
1573
|
+
const hex = normalizeBrandHex(value);
|
|
1574
|
+
if (!hex) {
|
|
1575
|
+
console.error(
|
|
1576
|
+
`[blink] appearance.variables.${key} must be opaque hex (#rgb or #rrggbb); received ${JSON.stringify(value)}. Ignoring it.`
|
|
1577
|
+
);
|
|
1578
|
+
continue;
|
|
1579
|
+
}
|
|
1580
|
+
accepted[key] = hex;
|
|
1581
|
+
}
|
|
1582
|
+
const encoded = Object.keys(BRAND_COLOR_PARAM_KEYS).filter((key) => accepted[key] !== void 0).map((key) => `${BRAND_COLOR_PARAM_KEYS[key]}-${accepted[key].slice(1)}`).join(".");
|
|
1583
|
+
if (encoded) url.searchParams.set("brand", encoded);
|
|
1584
|
+
}
|
|
1585
|
+
/**
|
|
1586
|
+
* Normalizes the display-only {@link DepositRequest.balance} for the wire,
|
|
1587
|
+
* or returns `undefined` to omit it everywhere — the `blink:signed-payload`
|
|
1588
|
+
* sibling field and the legacy fallback URL param alike. Additive wire
|
|
1589
|
+
* discipline: an unset or rejected balance leaves both channels
|
|
1590
|
+
* byte-for-byte what they always were, and old webviews ignore the field
|
|
1591
|
+
* by construction.
|
|
1592
|
+
*
|
|
1593
|
+
* Validated here purely so the merchant sees the complaint in their OWN
|
|
1594
|
+
* console (same rationale as {@link applyBrandParam}); the hosted flow
|
|
1595
|
+
* re-validates whatever arrives, since both channels are host-controlled
|
|
1596
|
+
* input. A rejected balance never blocks the deposit — the flow proceeds
|
|
1597
|
+
* without the subtitle.
|
|
1598
|
+
*/
|
|
1599
|
+
normalizeRequestBalance(balance) {
|
|
1600
|
+
if (balance === void 0 || balance === null) return void 0;
|
|
1601
|
+
const normalized = normalizeDisplayBalance(balance);
|
|
1602
|
+
if (normalized === null) {
|
|
1603
|
+
const received = typeof balance === "number" ? String(balance) : JSON.stringify(balance) ?? String(balance);
|
|
1604
|
+
console.error(
|
|
1605
|
+
`[blink] balance must be a finite number >= 0 and < 1e12 (USD, display only); received ${received}. Ignoring it.`
|
|
1606
|
+
);
|
|
1607
|
+
return void 0;
|
|
1608
|
+
}
|
|
1609
|
+
return normalized;
|
|
1194
1610
|
}
|
|
1195
|
-
/**
|
|
1611
|
+
/**
|
|
1612
|
+
* Fluid is the default; `layout: 'fixed'` opts back into the legacy
|
|
1613
|
+
* container. Embedded is a separate presentation and never fluid — the
|
|
1614
|
+
* constructor rejects the combination outright.
|
|
1615
|
+
*/
|
|
1196
1616
|
isFluidLayout() {
|
|
1197
|
-
return this.config.layout !== "fixed";
|
|
1617
|
+
return !this.isEmbedded() && this.config.layout !== "fixed";
|
|
1198
1618
|
}
|
|
1199
1619
|
/**
|
|
1200
1620
|
* Marks the hosted-flow URL as fluid-layout: the iframe spans the full
|
|
@@ -1204,6 +1624,10 @@ var Deposit = class {
|
|
|
1204
1624
|
* assumed to understand fluid layout and gets the fixed container.
|
|
1205
1625
|
*/
|
|
1206
1626
|
applyLayoutParam(url) {
|
|
1627
|
+
if (this.isEmbedded()) {
|
|
1628
|
+
url.searchParams.set("layout", "embed");
|
|
1629
|
+
return;
|
|
1630
|
+
}
|
|
1207
1631
|
if (this.isFluidLayout()) {
|
|
1208
1632
|
url.searchParams.set("layout", "fluid");
|
|
1209
1633
|
}
|
|
@@ -1215,7 +1639,14 @@ var Deposit = class {
|
|
|
1215
1639
|
* afterwards (rotation, window resize) — see iframe.ts.
|
|
1216
1640
|
*/
|
|
1217
1641
|
applyViewportParams(url) {
|
|
1218
|
-
|
|
1642
|
+
const embedded = this.isEmbedded();
|
|
1643
|
+
if (!this.isFluidLayout() && !embedded) return;
|
|
1644
|
+
if (embedded) {
|
|
1645
|
+
const embedMaxHeightPx = this.resolveEmbedMaxHeightPx();
|
|
1646
|
+
if (embedMaxHeightPx !== void 0) {
|
|
1647
|
+
url.searchParams.set("embedMaxHeight", String(embedMaxHeightPx));
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1219
1650
|
const metrics = measureViewportMetrics();
|
|
1220
1651
|
if (metrics.viewportLvh <= 0) return;
|
|
1221
1652
|
url.searchParams.set("viewportLvh", String(metrics.viewportLvh));
|
|
@@ -1235,6 +1666,7 @@ var Deposit = class {
|
|
|
1235
1666
|
signer: typeof this.config.signer === "string" ? this.config.signer : "<function>"
|
|
1236
1667
|
});
|
|
1237
1668
|
const signerRequest = buildSignerRequest(request, webviewBaseUrl);
|
|
1669
|
+
const displayBalance = this.normalizeRequestBalance(request.balance);
|
|
1238
1670
|
let preloadIframe;
|
|
1239
1671
|
let iframeReadyPromise;
|
|
1240
1672
|
const warm = this.takeWarmIframe();
|
|
@@ -1252,21 +1684,12 @@ var Deposit = class {
|
|
|
1252
1684
|
});
|
|
1253
1685
|
this.log("Reusing warm preload iframe");
|
|
1254
1686
|
} else {
|
|
1255
|
-
preloadIframe =
|
|
1256
|
-
this.buildPreloadUrl(webviewBaseUrl),
|
|
1257
|
-
this.config.containerElement,
|
|
1258
|
-
{ fluid: this.isFluidLayout() }
|
|
1259
|
-
);
|
|
1687
|
+
preloadIframe = this.createPresentedIframe(this.buildPreloadUrl(webviewBaseUrl), {});
|
|
1260
1688
|
iframeReadyPromise = this.waitForIframeReady(preloadIframe).promise;
|
|
1261
1689
|
}
|
|
1262
1690
|
this.iframe = preloadIframe;
|
|
1263
1691
|
preloadIframe.onClose(() => {
|
|
1264
|
-
onError(
|
|
1265
|
-
new DepositError(
|
|
1266
|
-
"DEPOSIT_DISMISSED",
|
|
1267
|
-
"The deposit was dismissed before the transfer completed."
|
|
1268
|
-
)
|
|
1269
|
-
);
|
|
1692
|
+
onError(dismissedError());
|
|
1270
1693
|
this.cleanup();
|
|
1271
1694
|
this.emit("close");
|
|
1272
1695
|
});
|
|
@@ -1296,7 +1719,8 @@ var Deposit = class {
|
|
|
1296
1719
|
buildSignedPayloadMessage(
|
|
1297
1720
|
signerResponse.merchantId,
|
|
1298
1721
|
signerResponse.payload,
|
|
1299
|
-
signerResponse.signature
|
|
1722
|
+
signerResponse.signature,
|
|
1723
|
+
displayBalance
|
|
1300
1724
|
),
|
|
1301
1725
|
this.hostedOrigin
|
|
1302
1726
|
);
|
|
@@ -1310,17 +1734,19 @@ var Deposit = class {
|
|
|
1310
1734
|
hostedUrl.searchParams.set("merchantId", signerResponse.merchantId);
|
|
1311
1735
|
hostedUrl.searchParams.set("payload", signerResponse.payload);
|
|
1312
1736
|
hostedUrl.searchParams.set("signature", signerResponse.signature);
|
|
1737
|
+
if (displayBalance !== void 0) {
|
|
1738
|
+
hostedUrl.searchParams.set("balance", displayBalance);
|
|
1739
|
+
}
|
|
1313
1740
|
this.applyFullWidgetParam(hostedUrl);
|
|
1741
|
+
if (this.isEmbedded()) {
|
|
1742
|
+
this.applyLayoutParam(hostedUrl);
|
|
1743
|
+
this.applyViewportParams(hostedUrl);
|
|
1744
|
+
}
|
|
1314
1745
|
const targetUrl = hostedUrl.toString();
|
|
1315
|
-
const iframeHandle =
|
|
1746
|
+
const iframeHandle = this.createPresentedIframe(targetUrl, {});
|
|
1316
1747
|
this.iframe = iframeHandle;
|
|
1317
1748
|
iframeHandle.onClose(() => {
|
|
1318
|
-
onError(
|
|
1319
|
-
new DepositError(
|
|
1320
|
-
"DEPOSIT_DISMISSED",
|
|
1321
|
-
"The deposit was dismissed before the transfer completed."
|
|
1322
|
-
)
|
|
1323
|
-
);
|
|
1749
|
+
onError(dismissedError());
|
|
1324
1750
|
this.cleanup();
|
|
1325
1751
|
this.emit("close");
|
|
1326
1752
|
});
|
|
@@ -1396,6 +1822,16 @@ var Deposit = class {
|
|
|
1396
1822
|
iframeHandle.close();
|
|
1397
1823
|
return;
|
|
1398
1824
|
}
|
|
1825
|
+
const contentHeight = parseContentHeight(event.data);
|
|
1826
|
+
if (contentHeight) {
|
|
1827
|
+
iframeHandle.applyContentHeight(contentHeight.heightPx);
|
|
1828
|
+
this.emit("resize", {
|
|
1829
|
+
heightPx: contentHeight.heightPx,
|
|
1830
|
+
...contentHeight.preferredWidthPx === void 0 ? {} : { preferredWidthPx: contentHeight.preferredWidthPx },
|
|
1831
|
+
...contentHeight.minWidthPx === void 0 ? {} : { minWidthPx: contentHeight.minWidthPx }
|
|
1832
|
+
});
|
|
1833
|
+
return;
|
|
1834
|
+
}
|
|
1399
1835
|
const message = parseTransferComplete(event.data);
|
|
1400
1836
|
if (!message) {
|
|
1401
1837
|
return;
|
|
@@ -1473,5 +1909,5 @@ function detectMerchantColorScheme() {
|
|
|
1473
1909
|
var Checkout = Deposit;
|
|
1474
1910
|
|
|
1475
1911
|
export { ALLOWED_RPC_METHODS, BRIDGE_PROTOCOL_VERSION, Checkout, CheckoutError, DEFAULT_WEBVIEW_BASE_URL, Deposit, DepositError, SANDBOX_WEBVIEW_BASE_URL, attachRpcHost, createWalletDiscoverer, getDisplayMessage, parseBridgeMessage };
|
|
1476
|
-
//# sourceMappingURL=chunk-
|
|
1477
|
-
//# sourceMappingURL=chunk-
|
|
1912
|
+
//# sourceMappingURL=chunk-MJSD7JWR.js.map
|
|
1913
|
+
//# sourceMappingURL=chunk-MJSD7JWR.js.map
|