@swype-org/deposit 0.3.20 → 0.3.22
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/dist/{chunk-VMXCXXVN.js → chunk-NZ7DOPZ5.js} +149 -15
- package/dist/chunk-NZ7DOPZ5.js.map +1 -0
- package/dist/index.cjs +147 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -4
- package/dist/index.d.ts +23 -4
- package/dist/index.js +1 -1
- package/dist/react.cjs +147 -13
- 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-Ds07N2zN.d.cts → types-iQf3f-_m.d.cts} +13 -0
- package/dist/{types-Ds07N2zN.d.ts → types-iQf3f-_m.d.ts} +13 -0
- package/package.json +1 -1
- package/dist/chunk-VMXCXXVN.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -98,7 +98,19 @@ function parseIframeReady(data) {
|
|
|
98
98
|
if (msg.type !== "blink:iframe-ready") {
|
|
99
99
|
return null;
|
|
100
100
|
}
|
|
101
|
-
return { type: "blink:iframe-ready" };
|
|
101
|
+
return { type: "blink:iframe-ready", capabilities: parseCapabilities(msg.capabilities) };
|
|
102
|
+
}
|
|
103
|
+
function parseCapabilities(value) {
|
|
104
|
+
if (!Array.isArray(value)) {
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
return value.filter((entry) => typeof entry === "string");
|
|
108
|
+
}
|
|
109
|
+
function buildViewportMessage(viewportLvh, safeAreaBottom) {
|
|
110
|
+
return { type: "blink:viewport", viewportLvh, safeAreaBottom };
|
|
111
|
+
}
|
|
112
|
+
function buildRevealMessage() {
|
|
113
|
+
return { type: "blink:reveal" };
|
|
102
114
|
}
|
|
103
115
|
function buildSignedPayloadMessage(merchantId, payload, signature) {
|
|
104
116
|
return {
|
|
@@ -505,6 +517,34 @@ function normalizeProviderError(err) {
|
|
|
505
517
|
return { code: -32603, message: typeof err === "string" ? err : "Provider error" };
|
|
506
518
|
}
|
|
507
519
|
|
|
520
|
+
// src/viewportMetrics.ts
|
|
521
|
+
function measureViewportMetrics() {
|
|
522
|
+
const unavailable = { viewportLvh: 0, safeAreaBottom: 0 };
|
|
523
|
+
if (typeof document === "undefined" || typeof window === "undefined" || typeof window.getComputedStyle !== "function" || !document.body) {
|
|
524
|
+
return unavailable;
|
|
525
|
+
}
|
|
526
|
+
try {
|
|
527
|
+
const probe = document.createElement("div");
|
|
528
|
+
probe.style.cssText = "position:fixed;top:0;left:0;width:0;visibility:hidden;pointer-events:none;height:100lvh;padding-bottom:env(safe-area-inset-bottom,0px)";
|
|
529
|
+
document.body.appendChild(probe);
|
|
530
|
+
let viewportLvh = 0;
|
|
531
|
+
let safeAreaBottom = 0;
|
|
532
|
+
try {
|
|
533
|
+
const computed = window.getComputedStyle(probe);
|
|
534
|
+
viewportLvh = Math.round(Number.parseFloat(computed.height) || 0);
|
|
535
|
+
safeAreaBottom = Math.round(Number.parseFloat(computed.paddingBottom) || 0);
|
|
536
|
+
} finally {
|
|
537
|
+
probe.remove();
|
|
538
|
+
}
|
|
539
|
+
if (viewportLvh <= 0) {
|
|
540
|
+
viewportLvh = Math.round(window.innerHeight || 0);
|
|
541
|
+
}
|
|
542
|
+
return { viewportLvh, safeAreaBottom };
|
|
543
|
+
} catch {
|
|
544
|
+
return unavailable;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
508
548
|
// src/iframe.ts
|
|
509
549
|
var STYLE_ID = "blink-deposit-styles";
|
|
510
550
|
var CLOSE_DURATION_MS = 280;
|
|
@@ -525,6 +565,8 @@ var STYLES = `
|
|
|
525
565
|
[data-blink-overlay][data-blink-mobile-sheet] [data-blink-container]{width:100%;max-width:100%;height:79vh;border-radius:24px 24px 0 0;box-shadow:0 -8px 40px rgba(0,0,0,.25);animation:blink-slide-up-full .35s cubic-bezier(.32,.72,0,1);padding-bottom:env(safe-area-inset-bottom,0px)}
|
|
526
566
|
[data-blink-overlay][data-blink-mobile-sheet][data-blink-closing] [data-blink-container]{opacity:1;animation:blink-slide-down-full ${CLOSE_DURATION_MS}ms ease-in forwards}
|
|
527
567
|
@media(max-width:${MOBILE_SHEET_MAX_VIEWPORT_PX}px){[data-blink-overlay]{align-items:flex-end;touch-action:none;overscroll-behavior:contain}[data-blink-container]{width:100%;max-width:100%;height:79vh;border-radius:24px 24px 0 0;box-shadow:0 -8px 40px rgba(0,0,0,.25);animation:blink-slide-up-full .35s cubic-bezier(.32,.72,0,1);padding-bottom:env(safe-area-inset-bottom,0px)}[data-blink-overlay][data-blink-closing] [data-blink-container]{opacity:1;animation:blink-slide-down-full ${CLOSE_DURATION_MS}ms ease-in forwards}}
|
|
568
|
+
[data-blink-overlay][data-blink-fluid] [data-blink-container],[data-blink-overlay][data-blink-fluid][data-blink-mobile-sheet] [data-blink-container]{width:100%;max-width:100%;height:100%;max-height:100%;border-radius:0;box-shadow:none;animation:none;background:transparent;padding-bottom:0}
|
|
569
|
+
[data-blink-overlay][data-blink-fluid][data-blink-closing] [data-blink-container]{animation:none;transition:none;opacity:1}
|
|
528
570
|
`;
|
|
529
571
|
function createIframe(url, containerElement, options) {
|
|
530
572
|
ensureStyles();
|
|
@@ -536,6 +578,9 @@ function createIframe(url, containerElement, options) {
|
|
|
536
578
|
if (shouldUseMobileSheetLayout()) {
|
|
537
579
|
overlay.setAttribute("data-blink-mobile-sheet", "");
|
|
538
580
|
}
|
|
581
|
+
if (options?.fluid) {
|
|
582
|
+
overlay.setAttribute("data-blink-fluid", "");
|
|
583
|
+
}
|
|
539
584
|
if (hidden) {
|
|
540
585
|
overlay.style.display = "none";
|
|
541
586
|
}
|
|
@@ -564,6 +609,37 @@ function createIframe(url, containerElement, options) {
|
|
|
564
609
|
};
|
|
565
610
|
attachBridge();
|
|
566
611
|
iframe.addEventListener("load", attachBridge);
|
|
612
|
+
function postReveal() {
|
|
613
|
+
if (closed) return;
|
|
614
|
+
iframe.contentWindow?.postMessage(buildRevealMessage(), iframeOrigin);
|
|
615
|
+
}
|
|
616
|
+
function postViewportMetrics() {
|
|
617
|
+
if (closed || !options?.fluid) return;
|
|
618
|
+
const metrics = measureViewportMetrics();
|
|
619
|
+
if (metrics.viewportLvh <= 0) return;
|
|
620
|
+
iframe.contentWindow?.postMessage(
|
|
621
|
+
buildViewportMessage(metrics.viewportLvh, metrics.safeAreaBottom),
|
|
622
|
+
iframeOrigin
|
|
623
|
+
);
|
|
624
|
+
}
|
|
625
|
+
let viewportPostScheduled = false;
|
|
626
|
+
const onViewportChange = () => {
|
|
627
|
+
if (viewportPostScheduled) return;
|
|
628
|
+
viewportPostScheduled = true;
|
|
629
|
+
requestAnimationFrame(() => {
|
|
630
|
+
viewportPostScheduled = false;
|
|
631
|
+
postViewportMetrics();
|
|
632
|
+
});
|
|
633
|
+
};
|
|
634
|
+
if (options?.fluid) {
|
|
635
|
+
window.addEventListener("resize", onViewportChange);
|
|
636
|
+
window.addEventListener("orientationchange", onViewportChange);
|
|
637
|
+
}
|
|
638
|
+
const onLoadReveal = () => {
|
|
639
|
+
postViewportMetrics();
|
|
640
|
+
if (!hidden) postReveal();
|
|
641
|
+
};
|
|
642
|
+
iframe.addEventListener("load", onLoadReveal);
|
|
567
643
|
let savedOverflow = "";
|
|
568
644
|
let scrollLocked = false;
|
|
569
645
|
const onBackdropClick = (event) => {
|
|
@@ -594,6 +670,8 @@ function createIframe(url, containerElement, options) {
|
|
|
594
670
|
overlay.removeEventListener("click", onBackdropClick);
|
|
595
671
|
overlay.removeEventListener("touchmove", onTouchMove);
|
|
596
672
|
document.removeEventListener("keydown", onKeyDown);
|
|
673
|
+
window.removeEventListener("resize", onViewportChange);
|
|
674
|
+
window.removeEventListener("orientationchange", onViewportChange);
|
|
597
675
|
}
|
|
598
676
|
function unlockScroll() {
|
|
599
677
|
if (!scrollLocked) return;
|
|
@@ -619,6 +697,7 @@ function createIframe(url, containerElement, options) {
|
|
|
619
697
|
}
|
|
620
698
|
function detachBridge() {
|
|
621
699
|
iframe.removeEventListener("load", attachBridge);
|
|
700
|
+
iframe.removeEventListener("load", onLoadReveal);
|
|
622
701
|
if (rpcHostHandle) {
|
|
623
702
|
rpcHostHandle.detach();
|
|
624
703
|
rpcHostHandle = null;
|
|
@@ -649,6 +728,14 @@ function createIframe(url, containerElement, options) {
|
|
|
649
728
|
overlay.style.display = "";
|
|
650
729
|
lockScroll();
|
|
651
730
|
attachDismissalListeners();
|
|
731
|
+
postViewportMetrics();
|
|
732
|
+
postReveal();
|
|
733
|
+
},
|
|
734
|
+
postReveal() {
|
|
735
|
+
postReveal();
|
|
736
|
+
},
|
|
737
|
+
downgradeToFixed() {
|
|
738
|
+
overlay.removeAttribute("data-blink-fluid");
|
|
652
739
|
},
|
|
653
740
|
onClose(callback) {
|
|
654
741
|
closeCallback = callback;
|
|
@@ -824,6 +911,8 @@ var DEFAULT_WEBVIEW_BASE_URL = "https://pay.blink.cash";
|
|
|
824
911
|
var SANDBOX_WEBVIEW_BASE_URL = "https://pay-sandbox.blink.cash";
|
|
825
912
|
var IFRAME_READY_TIMEOUT_MS = 2e3;
|
|
826
913
|
var WARM_IFRAME_READY_TIMEOUT_MS = 6e4;
|
|
914
|
+
var LAYOUT_FLUID_CAPABILITY = "layout-fluid";
|
|
915
|
+
var IFRAME_NOT_READY = { ready: false, fluidCapable: false };
|
|
827
916
|
function resolveWebviewBaseUrl(config) {
|
|
828
917
|
if (config.webviewBaseUrl) return config.webviewBaseUrl;
|
|
829
918
|
return config.environment === "sandbox" ? SANDBOX_WEBVIEW_BASE_URL : DEFAULT_WEBVIEW_BASE_URL;
|
|
@@ -894,7 +983,10 @@ var Deposit = class {
|
|
|
894
983
|
const webviewBaseUrl = resolveWebviewBaseUrl(this.config);
|
|
895
984
|
this.hostedOrigin = this.config.hostedFlowOrigin ?? new URL(webviewBaseUrl).origin;
|
|
896
985
|
const preloadUrl = this.buildPreloadUrl(webviewBaseUrl);
|
|
897
|
-
const iframe = createIframe(preloadUrl, this.config.containerElement, {
|
|
986
|
+
const iframe = createIframe(preloadUrl, this.config.containerElement, {
|
|
987
|
+
hidden: true,
|
|
988
|
+
fluid: this.isFluidLayout()
|
|
989
|
+
});
|
|
898
990
|
const ready = this.waitForIframeReady(iframe, WARM_IFRAME_READY_TIMEOUT_MS);
|
|
899
991
|
this.warmIframe = iframe;
|
|
900
992
|
this.warmIframeReady = ready.promise;
|
|
@@ -930,6 +1022,8 @@ var Deposit = class {
|
|
|
930
1022
|
preloadUrl.searchParams.set("merchantId", this.config.merchantId);
|
|
931
1023
|
}
|
|
932
1024
|
this.applyFullWidgetParam(preloadUrl);
|
|
1025
|
+
this.applyLayoutParam(preloadUrl);
|
|
1026
|
+
this.applyViewportParams(preloadUrl);
|
|
933
1027
|
return preloadUrl.toString();
|
|
934
1028
|
}
|
|
935
1029
|
/**
|
|
@@ -1075,6 +1169,35 @@ var Deposit = class {
|
|
|
1075
1169
|
url.searchParams.set("enableFullWidget", "false");
|
|
1076
1170
|
}
|
|
1077
1171
|
}
|
|
1172
|
+
/** Fluid is the default; `layout: 'fixed'` opts back into the legacy container. */
|
|
1173
|
+
isFluidLayout() {
|
|
1174
|
+
return this.config.layout !== "fixed";
|
|
1175
|
+
}
|
|
1176
|
+
/**
|
|
1177
|
+
* Marks the hosted-flow URL as fluid-layout: the iframe spans the full
|
|
1178
|
+
* viewport and the hosted flow renders the card/sheet chrome itself.
|
|
1179
|
+
* Only applied to preload URLs — the URL-param fallback path exists
|
|
1180
|
+
* precisely because the webview never signalled ready, so it cannot be
|
|
1181
|
+
* assumed to understand fluid layout and gets the fixed container.
|
|
1182
|
+
*/
|
|
1183
|
+
applyLayoutParam(url) {
|
|
1184
|
+
if (this.isFluidLayout()) {
|
|
1185
|
+
url.searchParams.set("layout", "fluid");
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
/**
|
|
1189
|
+
* Seeds the merchant page's large-viewport height and safe-area bottom
|
|
1190
|
+
* inset onto the fluid preload URL so the hosted flow can size the sheet
|
|
1191
|
+
* before its JS boots. `blink:viewport` messages keep the values fresh
|
|
1192
|
+
* afterwards (rotation, window resize) — see iframe.ts.
|
|
1193
|
+
*/
|
|
1194
|
+
applyViewportParams(url) {
|
|
1195
|
+
if (!this.isFluidLayout()) return;
|
|
1196
|
+
const metrics = measureViewportMetrics();
|
|
1197
|
+
if (metrics.viewportLvh <= 0) return;
|
|
1198
|
+
url.searchParams.set("viewportLvh", String(metrics.viewportLvh));
|
|
1199
|
+
url.searchParams.set("safeAreaBottom", String(metrics.safeAreaBottom));
|
|
1200
|
+
}
|
|
1078
1201
|
setStatus(status) {
|
|
1079
1202
|
if (this._status === status) return;
|
|
1080
1203
|
this.log(`Status: ${this._status} \u2192 ${status}`);
|
|
@@ -1098,7 +1221,7 @@ var Deposit = class {
|
|
|
1098
1221
|
iframeReadyPromise = Promise.race([
|
|
1099
1222
|
warm.ready,
|
|
1100
1223
|
new Promise(
|
|
1101
|
-
(resolve) => setTimeout(() => resolve(
|
|
1224
|
+
(resolve) => setTimeout(() => resolve(IFRAME_NOT_READY), IFRAME_READY_TIMEOUT_MS)
|
|
1102
1225
|
)
|
|
1103
1226
|
]).then((ready) => {
|
|
1104
1227
|
warm.cancelReady();
|
|
@@ -1108,7 +1231,8 @@ var Deposit = class {
|
|
|
1108
1231
|
} else {
|
|
1109
1232
|
preloadIframe = createIframe(
|
|
1110
1233
|
this.buildPreloadUrl(webviewBaseUrl),
|
|
1111
|
-
this.config.containerElement
|
|
1234
|
+
this.config.containerElement,
|
|
1235
|
+
{ fluid: this.isFluidLayout() }
|
|
1112
1236
|
);
|
|
1113
1237
|
iframeReadyPromise = this.waitForIframeReady(preloadIframe).promise;
|
|
1114
1238
|
}
|
|
@@ -1138,7 +1262,11 @@ var Deposit = class {
|
|
|
1138
1262
|
this.log("Request superseded or iframe dismissed during signer call");
|
|
1139
1263
|
return;
|
|
1140
1264
|
}
|
|
1141
|
-
if (iframeReady) {
|
|
1265
|
+
if (iframeReady.ready) {
|
|
1266
|
+
if (this.isFluidLayout() && !iframeReady.fluidCapable) {
|
|
1267
|
+
preloadIframe.downgradeToFixed();
|
|
1268
|
+
this.log("Webview lacks layout-fluid capability \u2014 downgraded to fixed container");
|
|
1269
|
+
}
|
|
1142
1270
|
const contentWindow = preloadIframe.contentWindow;
|
|
1143
1271
|
if (contentWindow) {
|
|
1144
1272
|
contentWindow.postMessage(
|
|
@@ -1193,8 +1321,10 @@ var Deposit = class {
|
|
|
1193
1321
|
}
|
|
1194
1322
|
}
|
|
1195
1323
|
/**
|
|
1196
|
-
* Resolves true when the iframe posts
|
|
1197
|
-
*
|
|
1324
|
+
* Resolves `{ ready: true, ... }` when the iframe posts
|
|
1325
|
+
* `blink:iframe-ready` (with `fluidCapable` reflecting its advertised
|
|
1326
|
+
* capabilities), or `{ ready: false, fluidCapable: false }` on timeout.
|
|
1327
|
+
* `cancel()` settles the promise as not-ready immediately and releases
|
|
1198
1328
|
* the listener + timer — used to reap the generous warm-up wait once it no
|
|
1199
1329
|
* longer matters (warm iframe consumed or discarded).
|
|
1200
1330
|
*/
|
|
@@ -1205,25 +1335,29 @@ var Deposit = class {
|
|
|
1205
1335
|
const handler = (event) => {
|
|
1206
1336
|
if (event.origin !== this.hostedOrigin) return;
|
|
1207
1337
|
if (event.source !== iframeHandle.contentWindow) return;
|
|
1208
|
-
|
|
1209
|
-
|
|
1338
|
+
const readyMessage = parseIframeReady(event.data);
|
|
1339
|
+
if (readyMessage) {
|
|
1340
|
+
finish({
|
|
1341
|
+
ready: true,
|
|
1342
|
+
fluidCapable: readyMessage.capabilities.includes(LAYOUT_FLUID_CAPABILITY)
|
|
1343
|
+
});
|
|
1210
1344
|
}
|
|
1211
1345
|
};
|
|
1212
1346
|
window.addEventListener("message", handler);
|
|
1213
1347
|
const timeout = setTimeout(() => {
|
|
1214
1348
|
this.log("Iframe ready timeout \u2014 falling back to URL params");
|
|
1215
|
-
finish(
|
|
1349
|
+
finish(IFRAME_NOT_READY);
|
|
1216
1350
|
}, timeoutMs);
|
|
1217
1351
|
let settled = false;
|
|
1218
|
-
finish = (
|
|
1352
|
+
finish = (result) => {
|
|
1219
1353
|
if (settled) return;
|
|
1220
1354
|
settled = true;
|
|
1221
1355
|
window.removeEventListener("message", handler);
|
|
1222
1356
|
clearTimeout(timeout);
|
|
1223
|
-
resolve(
|
|
1357
|
+
resolve(result);
|
|
1224
1358
|
};
|
|
1225
1359
|
});
|
|
1226
|
-
return { promise, cancel: () => finish(
|
|
1360
|
+
return { promise, cancel: () => finish(IFRAME_NOT_READY) };
|
|
1227
1361
|
}
|
|
1228
1362
|
startMessageListener(iframeHandle, onComplete) {
|
|
1229
1363
|
const handler = (event) => {
|