@klappay/one 1.3.0 → 1.5.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 CHANGED
@@ -1,9 +1,9 @@
1
1
  # @klappay/one
2
2
 
3
3
  The embeddable payment button for Klappay One. Drop it on any page — it
4
- opens a modal (an iframe, on desktop) or a popup (mobile) that handles
5
- identity, wallet connection, and payment approval entirely on Klappay's
6
- own origin, then reports the result back to you.
4
+ opens a modal (an iframe, by default) or a popup that handles identity,
5
+ wallet connection, and payment approval entirely on Klappay's own origin,
6
+ then reports the result back to you.
7
7
 
8
8
  ## Install
9
9
 
@@ -39,7 +39,7 @@ is a moving target and can't carry a fixed hash.
39
39
  Both are wired up automatically once the script loads — no JavaScript
40
40
  required for either. Both also accept `mode="iframe"` / `mode="popup"`
41
41
  (`data-klappay-one-mode` for the plain button) to force a mode instead of
42
- the mobile/desktop default.
42
+ the iframe default.
43
43
 
44
44
  ### Programmatic
45
45
 
@@ -59,7 +59,7 @@ const klappayOne = createKlappayOne({
59
59
  klappayOne.open()
60
60
  ```
61
61
 
62
- Defaults to an iframe/modal on desktop and a popup on mobile — pass
62
+ Defaults to an iframe/modal on every device — pass
63
63
  `mode: 'iframe' | 'popup'` to force one or the other.
64
64
 
65
65
  ### React
package/dist/index.d.ts CHANGED
@@ -23,11 +23,14 @@ interface KlappayOneConfig {
23
23
  onSuccess?: (result: PaymentResult) => void;
24
24
  onError?: (error: KlappayOneError) => void;
25
25
  onCancel?: (reason: 'user' | 'closed') => void;
26
+ onReconnecting?: (state: ReconnectState) => void;
26
27
  }
27
28
  interface KlappayOne {
28
29
  open: () => void;
29
30
  }
30
31
 
32
+ type ReconnectState = 'started' | 'recovered' | 'failed';
33
+
31
34
  interface GlobalConfig {
32
35
  origin?: string;
33
36
  locale?: string;
@@ -35,4 +38,4 @@ interface GlobalConfig {
35
38
  declare function configure(config: GlobalConfig): void;
36
39
  declare function createKlappayOne(config: KlappayOneConfig): KlappayOne;
37
40
 
38
- export { type KlappayOne, type KlappayOneConfig, type KlappayOneError, type PaymentResult, configure, createKlappayOne };
41
+ export { type KlappayOne, type KlappayOneConfig, type KlappayOneError, type PaymentResult, type ReconnectState, configure, createKlappayOne };
@@ -1,4 +1,4 @@
1
- "use strict";var KlappayOne=(()=>{var y=Object.defineProperty;var Y=Object.getOwnPropertyDescriptor;var G=Object.getOwnPropertyNames;var Z=Object.prototype.hasOwnProperty;var j=(e,t)=>{for(var o in t)y(e,o,{get:t[o],enumerable:!0})},F=(e,t,o,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of G(t))!Z.call(e,i)&&i!==o&&y(e,i,{get:()=>t[i],enumerable:!(a=Y(t,i))||a.enumerable});return e};var X=e=>F(y({},"__esModule",{value:!0}),e);var fe={};j(fe,{configure:()=>k,createKlappayOne:()=>m});function V(e){return typeof e=="object"&&e!==null&&"type"in e&&typeof e.type=="string"&&e.type.startsWith("klappay:")&&"requestId"in e&&typeof e.requestId=="string"}function v(e,t,o){let a=!1,i=setTimeout(()=>{a||o.onTimeout?.()},1e4);function r(n){if(n.origin!==e||!V(n.data)||n.data.requestId!==t)return;let s=n.data;switch(s.type){case"klappay:ready":a=!0,clearTimeout(i),o.onReady?.();return;case"klappay:success":o.onSuccess?.(s.result);return;case"klappay:error":o.onError?.(s.error);return;case"klappay:cancel":o.onCancel?.("user");return;case"klappay:pending":o.onPending?.();return;case"klappay:confirming":o.onConfirming?.({txHash:s.txHash,network:s.network});return;case"klappay:resize":o.onResize?.(s.height);return}}return window.addEventListener("message",r),()=>{clearTimeout(i),window.removeEventListener("message",r)}}function E(e){let t=new URL("/id/",e.klapOneOrigin);return t.searchParams.set("chargeId",e.chargeId),t.searchParams.set("requestId",e.requestId),t.searchParams.set("returnOrigin",window.location.origin),e.locale&&t.searchParams.set("locale",e.locale),t.toString()}var q=/Android|iPhone|iPad|iPod/i;function C(e){return q.test(e)}var b="cubic-bezier(0.16, 1, 0.3, 1)",Q=`
1
+ "use strict";var KlappayOne=(()=>{var A=Object.defineProperty;var D=Object.getOwnPropertyDescriptor;var Y=Object.getOwnPropertyNames;var Z=Object.prototype.hasOwnProperty;var G=(e,t)=>{for(var n in t)A(e,n,{get:t[n],enumerable:!0})},j=(e,t,n,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Y(t))!Z.call(e,r)&&r!==n&&A(e,r,{get:()=>t[r],enumerable:!(s=D(t,r))||s.enumerable});return e};var F=e=>j(A({},"__esModule",{value:!0}),e);var Ee={};G(Ee,{configure:()=>k,createKlappayOne:()=>f});var X=["started","recovered","failed"];function V(e){if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.txHash=="string"&&typeof t.walletAddress=="string"&&typeof t.network=="string"&&typeof t.amount=="string"&&typeof t.confirmedAt=="string"}function q(e){if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.code=="string"&&typeof t.message=="string"}function Q(e){if(typeof e!="object"||e===null)return!1;let t=e;if(typeof t.type!="string"||typeof t.requestId!="string")return!1;switch(t.type){case"klappay:ready":case"klappay:pending":case"klappay:cancel":return!0;case"klappay:resize":return typeof t.height=="number";case"klappay:confirming":return typeof t.txHash=="string"&&typeof t.network=="string";case"klappay:success":return V(t.result);case"klappay:error":return q(t.error);case"klappay:reconnecting":return typeof t.state=="string"&&X.includes(t.state);default:return!1}}function v(e,t,n){let s=!1,r,i=setTimeout(()=>{s||n.onTimeout?.()},1e4);function o(a){if(a.origin!==e||!Q(a.data)||a.data.requestId!==t)return;let l=a.data;switch(l.type){case"klappay:ready":s=!0,clearTimeout(i),n.onReady?.();return;case"klappay:success":n.onSuccess?.(l.result);return;case"klappay:error":n.onError?.(l.error);return;case"klappay:cancel":n.onCancel?.("user");return;case"klappay:pending":n.onPending?.();return;case"klappay:confirming":n.onConfirming?.({txHash:l.txHash,network:l.network});return;case"klappay:resize":n.onResize?.(l.height);return;case"klappay:reconnecting":if(l.state===r)return;r=l.state,n.onReconnecting?.(l.state);return}}return window.addEventListener("message",o),()=>{clearTimeout(i),window.removeEventListener("message",o)}}function E(e){let t=new URL("/id/",e.klapOneOrigin);return t.searchParams.set("chargeId",e.chargeId),t.searchParams.set("requestId",e.requestId),t.searchParams.set("returnOrigin",window.location.origin),e.locale&&t.searchParams.set("locale",e.locale),t.toString()}var b="cubic-bezier(0.16, 1, 0.3, 1)",J=`
2
2
  .backdrop {
3
3
  position: fixed;
4
4
  inset: 0;
@@ -63,10 +63,10 @@
63
63
  opacity: 1;
64
64
  transform: translateY(0) scale(1);
65
65
  }
66
- `;function x(e,t){let o=document.createElement("div"),a=o.attachShadow({mode:"open"}),i=document.createElement("style");i.textContent=Q;let r=!0,n=document.createElement("div");n.className="backdrop",n.addEventListener("click",c=>{c.target===n&&r&&t()});let s=document.createElement("iframe");s.className="frame",s.src=e,n.append(s),a.append(i,n),document.body.append(o);function u(c){let f=n.scrollTop<=0,A=n.scrollTop+n.clientHeight>=n.scrollHeight;(c.deltaY<0&&f||c.deltaY>0&&A)&&c.preventDefault()}document.addEventListener("wheel",u,{passive:!1});let p=!1;function d(){p||(p=!0,n.classList.add("visible"),s.classList.add("visible"))}requestAnimationFrame(d),setTimeout(d,320);let l=!1;function N(){if(l)return;l=!0;let c=!1;function f(){c||(c=!0,document.removeEventListener("wheel",u),o.remove())}function A(D){D.target===n&&(n.removeEventListener("transitionend",A),f())}n.addEventListener("transitionend",A),setTimeout(f,370),n.classList.remove("visible"),s.classList.remove("visible")}return{close:N,resize:c=>{s.style.height=`${c}px`},setDismissable:c=>{r=c}}}var J="klappay-one";function R(e){let t=window.screenX+(window.outerWidth-420)/2,o=window.screenY+(window.outerHeight-720)/2;return window.open(e,J,`width=420,height=720,left=${t},top=${o}`)}function w(e){return e===null||e.closed}var W={code:"POPUP_BLOCKED",message:"The Klappay One popup was blocked."},_={code:"FRAME_TIMEOUT",message:"The Klappay One popup did not respond in time."},$=500,S={};function k(e){S=e}function g(){return S}function ee(e){return e.mode??(C(navigator.userAgent)?"popup":"iframe")}function m(e){function t(){ee(e)==="popup"?o():a()}function o(){let i=crypto.randomUUID(),r=E({klapOneOrigin:e.origin,chargeId:e.chargeId,requestId:i,locale:e.locale}),n=R(r);if(w(n)){e.onError?.(W);return}let s=v(e.origin,i,{onReady:e.onReady,onPending:e.onPending,onConfirming:e.onConfirming,onSuccess:d=>{p(),e.onSuccess?.(d)},onError:d=>{p(),e.onError?.(d)},onCancel:d=>{p(),e.onCancel?.(d)},onTimeout:()=>{p(),e.onError?.(_)}}),u=setInterval(()=>{w(n)&&(p(),e.onCancel?.("closed"))},$);function p(){clearInterval(u),s()}}function a(){let i=crypto.randomUUID(),r=E({klapOneOrigin:e.origin,chargeId:e.chargeId,requestId:i,locale:e.locale}),n=!1;function s(l){n||(n=!0,d(),l())}let u=x(r,()=>s(()=>e.onCancel?.("user"))),p=v(e.origin,i,{onReady:e.onReady,onPending:()=>{u.setDismissable(!1),e.onPending?.()},onConfirming:e.onConfirming,onSuccess:l=>s(()=>e.onSuccess?.(l)),onError:l=>s(()=>e.onError?.(l)),onCancel:l=>s(()=>e.onCancel?.(l)),onResize:l=>u.resize(l),onTimeout:()=>s(o)});function d(){p(),u.close()}}return{open:t}}var h="data-klappay-one",O="data-klappay-one-origin",te="data-klappay-one-locale",ne="data-klappay-one-mode",P="data-klappay-one-wired",I="data-klappay-one-busy";function T(e){e.hasAttribute(P)||(e.setAttribute(P,""),e.addEventListener("click",()=>{if(e.hasAttribute(I))return;let t=e.getAttribute(h);if(!t)return;let o=e.getAttribute(O)??g().origin;if(!o){console.error(`[${h}] has no origin \u2014 set ${O} or call KlappayOne.configure({ origin }).`);return}let a=e.getAttribute(te)??g().locale,i=e.getAttribute(ne);e.setAttribute(I,"");let r=()=>{e.removeAttribute(I)};m({chargeId:t,origin:o,locale:a,mode:i==="iframe"||i==="popup"?i:void 0,onPending:()=>{e.dispatchEvent(new CustomEvent("pending"))},onConfirming:n=>{e.dispatchEvent(new CustomEvent("confirming",{detail:n}))},onSuccess:n=>{r(),e.dispatchEvent(new CustomEvent("success",{detail:n}))},onError:n=>{r(),e.dispatchEvent(new CustomEvent("error",{detail:n}))},onCancel:n=>{r(),e.dispatchEvent(new CustomEvent("cancel",{detail:{reason:n}}))}}).open()}))}function U(e=document){for(let t of e.querySelectorAll(`[${h}]`))T(t)}function M(e=document.body){let t=new MutationObserver(o=>{for(let a of o)for(let i of a.addedNodes)if(i instanceof Element){i.hasAttribute(h)&&T(i);for(let r of i.querySelectorAll(`[${h}]`))T(r)}});return t.observe(e,{childList:!0,subtree:!0}),()=>t.disconnect()}var L="klappay-button",H=["white","yellow","black"],K=["sm","md","lg"],oe="black",ie="md",re={sm:{height:"32px",fontSize:"13px",padding:"0 14px",logoSize:"14px"},md:{height:"40px",fontSize:"14px",padding:"0 18px",logoSize:"16px"},lg:{height:"48px",fontSize:"16px",padding:"0 24px",logoSize:"18px"}},ae="data:image/webp;base64,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",se="data:image/webp;base64,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",le="data:image/webp;base64,UklGRmwFAABXRUJQVlA4TGAFAAAvJ8AJEDXRjbZ/ld2ImZmZmZnhMjMzMzMcMzO3oCZ/wR4wx7/oKjO2wf6bamCMaJ3hFiEqwnA0J1YFvrljj0OHLuBmvw48ys6MI5egMgxNbPybcagKVtSBIvXgSKFLuNm/hQ23EAcEghDxfzMG0rYJ9y952yVBkm3aVti2bdu2jZGNmW2/923bto1n27Z58O7GBODD6B4wxcKSB5sCM5bCn0RwLHl5SCmwI+KjZj0C0SQG8SYFawVOrIEnSTxiqMlHW4HbSB7cBdjk4tuAkAJrLD4jAP3AO+iuQ9Z89ON07MuQzyR2GLAveBvLJ0vhiMZiOqS9go0GFI0EYT8VeiRwN/dORpA6BNQTPAhcS56rI5xzYwErWUzi3kBwH7A/SwqCRUiuYakXmMYCL8fcyDbSB4BpOKiQkhp0l/Z2iWZCfF8JVzDfbDuVlyv++/3BbSS6Yjhjs8jkzz1wG4nDZgoM4onQBXjcRdxIUG+w8GNEQfImfAaB5HL2rtConaxfB08xxtOhWC6EvhHzMtRK8alFzdTlquXCUJAU69m8FKMQemweBsql5lb4d/kV2xPBl1ZsKpDaxJzFnnw+taC2hYkxgJ3M3giXjtMKvK5fIhj0sMefboXgKQDBw4HVBJaRcYBHgqrwT6LyAFlLIBX0g/juEVMBtyGtIwXjXTyIJuSf69CdBkOQL4VnZVwcDCaxmcVL0ZnDIVvhW0cmn17nJyu4kE5WF7+exY97YNMCuDawY48HJnP6dC2pEwHMIw5FUbOcLUFWvH2O4t/r/HoqtXOgPGsgcvGaDdkbLBZBXYuhqQVwbPVbtjyRwvEmJEL520k8BdjAraeIR4HaODYKSLyCg99ncFRBwpb/rODRoGYK9sGC2gDTBzMBQn4aQc2lGOxlzSK5kAM/+gXxTI5GA4h8CTwtISucq53siab3KoRcCpymBt4KRwrnv2Y+nsfJbCIfYRLzISxSf7KQxi0sWXIe9CW41aBUzOVqKhUEtfBwer22ibriqb3czltMxERMTEQfFhA+F+pAE0lXobyOWevrWiJ0mDnIhjApSU4CZlO3gzFBesVSiFROJ9Nah9Zuxmw5H7oNFx14QUH8V4vE35nWJHWRHU/b/5uY9smuUs6d14M7YC3FfQJAENtMxETswMRd2ZRMgiEGgdN4d9jUhWYV6eMBvcFkWG5jLYz/g0Fnr0beRIN3U1LAi042xF83E+3H5E9o9Fwtd0MYDuCrxxDJbJ7XoZUHmwPADLADnIAQwKtRxb3jkTQtZ1kYolXsX4skIiLABvgAH4FJYBHoBlgR8cLh6xDPwiuRpi1QJZStZEeqsBaPASmYOwBywDSwC2wCn4A0L+I+WNLRyeb3QojZ0JtYy6K1Il7F8s1S0XuggTgHgAWQBmQAvj+8iHgnQn7seKSUlu1jItb3ehHHHNDr9ToREa9EZC+7PklELJmMLoYqxUjF0enu9naUoJRP0QbGpkF2SiajPAZYSawCt5YbEARKgKYf0DxSjEgYRpFUfeaRxESsxZ5U7uxHzR8BB+AnsAd0AJLoeL4evfC5s5gtwaT3QAwPr4HP1AL8gNVXgfOAqFvl3LECitO321VcnQhhExE7yDHBKCY7FO5zqA0YAHcAI4Db7VRB81g4oQlMJjKwtS5s5/diyBO2ENY40B7+hOKcBZ+JOruf6XYi4kUgElD2IpqnM1AM4d5S1vxYruZbA2+S+R9E6y7+RHKjHLdGxDrwXvS+9jNQ6UZENPf/Fkfl2cUc+rFQg7MCv+s/vFefAZoAEtBQQXS6LwLiR914bwP2wBZwD2BDnU6894H8d/716rkvATUg/Kjz/nGfAw==",ce={black:ae,yellow:le,white:se},pe={white:{background:"#ffffff",color:"#111111",border:"1px solid #e5e5e5"},yellow:{background:"#f2b90c",color:"#111111",border:"none"},black:{background:"#111111",color:"#ffffff",border:"none"}};function de(e){return H.includes(e)}function ue(e){return K.includes(e)}var ge=typeof HTMLElement<"u"?HTMLElement:class{},me=(()=>{let e=H.map(o=>{let{background:a,color:i,border:r}=pe[o];return`button[data-variant="${o}"] { background: var(--klappay-background, ${a}); color: var(--klappay-color, ${i}); border: ${r}; }`}).join(`
67
- `),t=K.map(o=>{let{height:a,fontSize:i,padding:r,logoSize:n}=re[o];return`
68
- button[data-size="${o}"] { height: var(--klappay-button-height, ${a}); font-size: ${i}; padding: ${r}; }
69
- button[data-size="${o}"] img { width: ${n}; height: ${n}; }
66
+ `;function R(e,t){let n=document.createElement("div"),s=n.attachShadow({mode:"open"}),r=document.createElement("style");r.textContent=J;let i=!0,o=document.createElement("div");o.className="backdrop",o.addEventListener("click",p=>{p.target===o&&i&&t()});let a=document.createElement("iframe");a.className="frame",a.src=e,a.allow="storage-access",o.append(a),s.append(r,o),document.body.append(n);function l(p){let m=o.scrollTop<=0,y=o.scrollTop+o.clientHeight>=o.scrollHeight;(p.deltaY<0&&m||p.deltaY>0&&y)&&p.preventDefault()}document.addEventListener("wheel",l,{passive:!1});let u=!1;function d(){u||(u=!0,o.classList.add("visible"),a.classList.add("visible"))}requestAnimationFrame(d),setTimeout(d,320);let c=!1;function z(){if(c)return;c=!0;let p=!1;function m(){p||(p=!0,document.removeEventListener("wheel",l),n.remove())}function y(N){N.target===o&&(o.removeEventListener("transitionend",y),m())}o.addEventListener("transitionend",y),setTimeout(m,370),o.classList.remove("visible"),a.classList.remove("visible")}return{close:z,resize:p=>{a.style.height=`${p}px`},setDismissable:p=>{i=p}}}var W="klappay-one";function C(e){let t=window.screenX+(window.outerWidth-420)/2,n=window.screenY+(window.outerHeight-720)/2;return window.open(e,W,`width=420,height=720,left=${t},top=${n}`)}function w(e){return e===null||e.closed}var _={code:"POPUP_BLOCKED",message:"The Klappay One popup was blocked."},$={code:"FRAME_TIMEOUT",message:"The Klappay One popup did not respond in time."},ee=500,S={};function k(e){S=e}function g(){return S}function te(e){return e.mode??"iframe"}function f(e){function t(){te(e)==="popup"?n():s()}function n(){let r=crypto.randomUUID(),i=E({klapOneOrigin:e.origin,chargeId:e.chargeId,requestId:r,locale:e.locale}),o=C(i);if(w(o)){e.onError?.(_);return}let a=v(e.origin,r,{onReady:e.onReady,onPending:e.onPending,onConfirming:e.onConfirming,onSuccess:d=>{u(),e.onSuccess?.(d)},onError:d=>{u(),e.onError?.(d)},onCancel:d=>{u(),e.onCancel?.(d)},onTimeout:()=>{u(),e.onError?.($)},onReconnecting:e.onReconnecting}),l=setInterval(()=>{w(o)&&(u(),e.onCancel?.("closed"))},ee);function u(){clearInterval(l),a()}}function s(){let r=crypto.randomUUID(),i=E({klapOneOrigin:e.origin,chargeId:e.chargeId,requestId:r,locale:e.locale}),o=!1;function a(c){o||(o=!0,d(),c())}let l=R(i,()=>a(()=>e.onCancel?.("user"))),u=v(e.origin,r,{onReady:e.onReady,onPending:()=>{l.setDismissable(!1),e.onPending?.()},onConfirming:e.onConfirming,onSuccess:c=>a(()=>e.onSuccess?.(c)),onError:c=>a(()=>e.onError?.(c)),onCancel:c=>a(()=>e.onCancel?.(c)),onResize:c=>l.resize(c),onTimeout:()=>a(n),onReconnecting:e.onReconnecting});function d(){u(),l.close()}}return{open:t}}var h="data-klappay-one",x="data-klappay-one-origin",ne="data-klappay-one-locale",oe="data-klappay-one-mode",O="data-klappay-one-wired",I="data-klappay-one-busy";function T(e){e.hasAttribute(O)||(e.setAttribute(O,""),e.addEventListener("click",()=>{if(e.hasAttribute(I))return;let t=e.getAttribute(h);if(!t)return;let n=e.getAttribute(x)??g().origin;if(!n){console.error(`[${h}] has no origin \u2014 set ${x} or call KlappayOne.configure({ origin }).`);return}let s=e.getAttribute(ne)??g().locale,r=e.getAttribute(oe);e.setAttribute(I,"");let i=()=>{e.removeAttribute(I)};f({chargeId:t,origin:n,locale:s,mode:r==="iframe"||r==="popup"?r:void 0,onPending:()=>{e.dispatchEvent(new CustomEvent("pending"))},onConfirming:o=>{e.dispatchEvent(new CustomEvent("confirming",{detail:o}))},onSuccess:o=>{i(),e.dispatchEvent(new CustomEvent("success",{detail:o}))},onError:o=>{i(),e.dispatchEvent(new CustomEvent("error",{detail:o}))},onCancel:o=>{i(),e.dispatchEvent(new CustomEvent("cancel",{detail:{reason:o}}))}}).open()}))}function L(e=document){for(let t of e.querySelectorAll(`[${h}]`))T(t)}function P(e=document.body){let t=new MutationObserver(n=>{for(let s of n)for(let r of s.addedNodes)if(r instanceof Element){r.hasAttribute(h)&&T(r);for(let i of r.querySelectorAll(`[${h}]`))T(i)}});return t.observe(e,{childList:!0,subtree:!0}),()=>t.disconnect()}var K="klappay-button",U=["white","yellow","black"],H=["sm","md","lg"],re=["full","short"],ie="black",ae="md",se="full",le={full:"Pay with Klappay One",short:"Klappay One"},ce={sm:{height:"32px",fontSize:"13px",padding:"0 14px",logoSize:"18px"},md:{height:"40px",fontSize:"14px",padding:"0 18px",logoSize:"21px"},lg:{height:"48px",fontSize:"16px",padding:"0 24px",logoSize:"23px"}},pe="data:image/webp;base64,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",ue="data:image/webp;base64,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",de="data:image/webp;base64,UklGRmwFAABXRUJQVlA4TGAFAAAvJ8AJEDXRjbZ/ld2ImZmZmZnhMjMzMzMcMzO3oCZ/wR4wx7/oKjO2wf6bamCMaJ3hFiEqwnA0J1YFvrljj0OHLuBmvw48ys6MI5egMgxNbPybcagKVtSBIvXgSKFLuNm/hQ23EAcEghDxfzMG0rYJ9y952yVBkm3aVti2bdu2jZGNmW2/923bto1n27Z58O7GBODD6B4wxcKSB5sCM5bCn0RwLHl5SCmwI+KjZj0C0SQG8SYFawVOrIEnSTxiqMlHW4HbSB7cBdjk4tuAkAJrLD4jAP3AO+iuQ9Z89ON07MuQzyR2GLAveBvLJ0vhiMZiOqS9go0GFI0EYT8VeiRwN/dORpA6BNQTPAhcS56rI5xzYwErWUzi3kBwH7A/SwqCRUiuYakXmMYCL8fcyDbSB4BpOKiQkhp0l/Z2iWZCfF8JVzDfbDuVlyv++/3BbSS6Yjhjs8jkzz1wG4nDZgoM4onQBXjcRdxIUG+w8GNEQfImfAaB5HL2rtConaxfB08xxtOhWC6EvhHzMtRK8alFzdTlquXCUJAU69m8FKMQemweBsql5lb4d/kV2xPBl1ZsKpDaxJzFnnw+taC2hYkxgJ3M3giXjtMKvK5fIhj0sMefboXgKQDBw4HVBJaRcYBHgqrwT6LyAFlLIBX0g/juEVMBtyGtIwXjXTyIJuSf69CdBkOQL4VnZVwcDCaxmcVL0ZnDIVvhW0cmn17nJyu4kE5WF7+exY97YNMCuDawY48HJnP6dC2pEwHMIw5FUbOcLUFWvH2O4t/r/HoqtXOgPGsgcvGaDdkbLBZBXYuhqQVwbPVbtjyRwvEmJEL520k8BdjAraeIR4HaODYKSLyCg99ncFRBwpb/rODRoGYK9sGC2gDTBzMBQn4aQc2lGOxlzSK5kAM/+gXxTI5GA4h8CTwtISucq53siab3KoRcCpymBt4KRwrnv2Y+nsfJbCIfYRLzISxSf7KQxi0sWXIe9CW41aBUzOVqKhUEtfBwer22ibriqb3czltMxERMTEQfFhA+F+pAE0lXobyOWevrWiJ0mDnIhjApSU4CZlO3gzFBesVSiFROJ9Nah9Zuxmw5H7oNFx14QUH8V4vE35nWJHWRHU/b/5uY9smuUs6d14M7YC3FfQJAENtMxETswMRd2ZRMgiEGgdN4d9jUhWYV6eMBvcFkWG5jLYz/g0Fnr0beRIN3U1LAi042xF83E+3H5E9o9Fwtd0MYDuCrxxDJbJ7XoZUHmwPADLADnIAQwKtRxb3jkTQtZ1kYolXsX4skIiLABvgAH4FJYBHoBlgR8cLh6xDPwiuRpi1QJZStZEeqsBaPASmYOwBywDSwC2wCn4A0L+I+WNLRyeb3QojZ0JtYy6K1Il7F8s1S0XuggTgHgAWQBmQAvj+8iHgnQn7seKSUlu1jItb3ehHHHNDr9ToREa9EZC+7PklELJmMLoYqxUjF0enu9naUoJRP0QbGpkF2SiajPAZYSawCt5YbEARKgKYf0DxSjEgYRpFUfeaRxESsxZ5U7uxHzR8BB+AnsAd0AJLoeL4evfC5s5gtwaT3QAwPr4HP1AL8gNVXgfOAqFvl3LECitO321VcnQhhExE7yDHBKCY7FO5zqA0YAHcAI4Db7VRB81g4oQlMJjKwtS5s5/diyBO2ENY40B7+hOKcBZ+JOruf6XYi4kUgElD2IpqnM1AM4d5S1vxYruZbA2+S+R9E6y7+RHKjHLdGxDrwXvS+9jNQ6UZENPf/Fkfl2cUc+rFQg7MCv+s/vFefAZoAEtBQQXS6LwLiR914bwP2wBZwD2BDnU6894H8d/716rkvATUg/Kjz/nGfAw==",ge={black:pe,yellow:de,white:ue},fe={white:{background:"#ffffff",color:"#111111",border:"1px solid #e5e5e5"},yellow:{background:"#f2b90c",color:"#111111",border:"none"},black:{background:"#111111",color:"#ffffff",border:"none"}};function he(e){return U.includes(e)}function me(e){return H.includes(e)}function ye(e){return re.includes(e)}var be=typeof HTMLElement<"u"?HTMLElement:class{},Ae=(()=>{let e=U.map(n=>{let{background:s,color:r,border:i}=fe[n];return`button[data-variant="${n}"] { background: var(--klappay-background, ${s}); color: var(--klappay-color, ${r}); border: ${i}; }`}).join(`
67
+ `),t=H.map(n=>{let{height:s,fontSize:r,padding:i,logoSize:o}=ce[n];return`
68
+ button[data-size="${n}"] { height: var(--klappay-button-height, ${s}); font-size: ${r}; padding: ${i}; }
69
+ button[data-size="${n}"] img { width: ${o}; height: ${o}; }
70
70
  `}).join(`
71
71
  `);return`
72
72
  button {
@@ -86,4 +86,4 @@
86
86
  button:disabled { opacity: 0.6; cursor: not-allowed; }
87
87
  ${e}
88
88
  ${t}
89
- `})(),B=class extends ge{static get observedAttributes(){return["variant","size","charge-id","origin"]}#e;#t;#o=!1;constructor(){super();let t=this.attachShadow({mode:"open"}),o=document.createElement("style");o.textContent=me,this.#t=document.createElement("img"),this.#t.alt="",this.#t.setAttribute("aria-hidden","true");let a=document.createElement("span");a.textContent="Pay with Klappay",this.#e=document.createElement("button"),this.#e.type="button",this.#e.append(this.#t,a),this.#e.addEventListener("click",()=>this.#s()),t.append(o,this.#e),this.#i(),this.#r(),this.#n()}attributeChangedCallback(t){t==="variant"&&this.#i(),t==="size"&&this.#r(),(t==="charge-id"||t==="origin")&&this.#n()}get variant(){let t=this.getAttribute("variant")??"";return de(t)?t:oe}set variant(t){this.setAttribute("variant",t)}get size(){let t=this.getAttribute("size")??"";return ue(t)?t:ie}set size(t){this.setAttribute("size",t)}#i(){this.#e.setAttribute("data-variant",this.variant),this.#t.src=ce[this.variant]}#r(){this.#e.setAttribute("data-size",this.size)}#a(){let t=this.getAttribute("charge-id"),o=this.getAttribute("origin")??g().origin;return!!(t&&o)}#n(){this.#e.disabled=this.#o||!this.#a()}#s(){if(this.#e.disabled)return;let t=this.getAttribute("charge-id");if(!t){console.error("<klappay-button> is missing a required charge-id attribute.");return}let o=this.getAttribute("origin")??g().origin;if(!o){console.error("<klappay-button> has no origin \u2014 set the origin attribute or call KlappayOne.configure({ origin }).");return}let a=this.getAttribute("locale")??g().locale,i=this.getAttribute("mode");this.#o=!0,this.#n();let r=()=>{this.#o=!1,this.#n()};m({chargeId:t,origin:o,locale:a,mode:i==="iframe"||i==="popup"?i:void 0,onPending:()=>{this.dispatchEvent(new CustomEvent("pending"))},onConfirming:n=>{this.dispatchEvent(new CustomEvent("confirming",{detail:n}))},onSuccess:n=>{r(),this.dispatchEvent(new CustomEvent("success",{detail:n}))},onError:n=>{r(),this.dispatchEvent(new CustomEvent("error",{detail:n}))},onCancel:n=>{r(),this.dispatchEvent(new CustomEvent("cancel",{detail:{reason:n}}))}}).open()}};function z(){typeof customElements>"u"||customElements.get(L)||customElements.define(L,B)}z();if(typeof document<"u"){let e=function(){U(),M()};he=e,document.readyState==="loading"?document.addEventListener("DOMContentLoaded",e):e()}var he;return X(fe);})();
89
+ `})(),B=class extends be{static get observedAttributes(){return["variant","size","label","charge-id","origin"]}#e;#t;#o;#r=!1;constructor(){super();let t=this.attachShadow({mode:"open"}),n=document.createElement("style");n.textContent=Ae,this.#t=document.createElement("img"),this.#t.alt="",this.#t.setAttribute("aria-hidden","true"),this.#o=document.createElement("span"),this.#e=document.createElement("button"),this.#e.type="button",this.#e.append(this.#t,this.#o),this.#e.addEventListener("click",()=>this.#c()),t.append(n,this.#e),this.#i(),this.#a(),this.#s(),this.#n()}attributeChangedCallback(t){t==="variant"&&this.#i(),t==="size"&&this.#a(),t==="label"&&this.#s(),(t==="charge-id"||t==="origin")&&this.#n()}get variant(){let t=this.getAttribute("variant")??"";return he(t)?t:ie}set variant(t){this.setAttribute("variant",t)}get size(){let t=this.getAttribute("size")??"";return me(t)?t:ae}set size(t){this.setAttribute("size",t)}get label(){let t=this.getAttribute("label")??"";return ye(t)?t:se}set label(t){this.setAttribute("label",t)}#i(){this.#e.setAttribute("data-variant",this.variant),this.#t.src=ge[this.variant]}#a(){this.#e.setAttribute("data-size",this.size)}#s(){this.#o.textContent=le[this.label]}#l(){let t=this.getAttribute("charge-id"),n=this.getAttribute("origin")??g().origin;return!!(t&&n)}#n(){this.#e.disabled=this.#r||!this.#l()}#c(){if(this.#e.disabled)return;let t=this.getAttribute("charge-id");if(!t){console.error("<klappay-button> is missing a required charge-id attribute.");return}let n=this.getAttribute("origin")??g().origin;if(!n){console.error("<klappay-button> has no origin \u2014 set the origin attribute or call KlappayOne.configure({ origin }).");return}let s=this.getAttribute("locale")??g().locale,r=this.getAttribute("mode");this.#r=!0,this.#n();let i=()=>{this.#r=!1,this.#n()};f({chargeId:t,origin:n,locale:s,mode:r==="iframe"||r==="popup"?r:void 0,onPending:()=>{this.dispatchEvent(new CustomEvent("pending"))},onConfirming:o=>{this.dispatchEvent(new CustomEvent("confirming",{detail:o}))},onSuccess:o=>{i(),this.dispatchEvent(new CustomEvent("success",{detail:o}))},onError:o=>{i(),this.dispatchEvent(new CustomEvent("error",{detail:o}))},onCancel:o=>{i(),this.dispatchEvent(new CustomEvent("cancel",{detail:{reason:o}}))}}).open()}};function M(){typeof customElements>"u"||customElements.get(K)||customElements.define(K,B)}M();if(typeof document<"u"){let e=function(){L(),P()};ve=e,document.readyState==="loading"?document.addEventListener("DOMContentLoaded",e):e()}var ve;return F(Ee);})();
package/dist/index.js CHANGED
@@ -1,10 +1,42 @@
1
1
  // src/core/bridge.ts
2
2
  var READY_TIMEOUT_MS = 1e4;
3
+ var RECONNECT_STATES = ["started", "recovered", "failed"];
4
+ function isPaymentResult(value) {
5
+ if (typeof value !== "object" || value === null) return false;
6
+ const result = value;
7
+ return typeof result.txHash === "string" && typeof result.walletAddress === "string" && typeof result.network === "string" && typeof result.amount === "string" && typeof result.confirmedAt === "string";
8
+ }
9
+ function isKlappayOneError(value) {
10
+ if (typeof value !== "object" || value === null) return false;
11
+ const error = value;
12
+ return typeof error.code === "string" && typeof error.message === "string";
13
+ }
3
14
  function isBridgeMessage(data) {
4
- return typeof data === "object" && data !== null && "type" in data && typeof data.type === "string" && data.type.startsWith("klappay:") && "requestId" in data && typeof data.requestId === "string";
15
+ if (typeof data !== "object" || data === null) return false;
16
+ const envelope = data;
17
+ if (typeof envelope.type !== "string" || typeof envelope.requestId !== "string") return false;
18
+ switch (envelope.type) {
19
+ case "klappay:ready":
20
+ case "klappay:pending":
21
+ case "klappay:cancel":
22
+ return true;
23
+ case "klappay:resize":
24
+ return typeof envelope.height === "number";
25
+ case "klappay:confirming":
26
+ return typeof envelope.txHash === "string" && typeof envelope.network === "string";
27
+ case "klappay:success":
28
+ return isPaymentResult(envelope.result);
29
+ case "klappay:error":
30
+ return isKlappayOneError(envelope.error);
31
+ case "klappay:reconnecting":
32
+ return typeof envelope.state === "string" && RECONNECT_STATES.includes(envelope.state);
33
+ default:
34
+ return false;
35
+ }
5
36
  }
6
37
  function listen(klapOneOrigin, requestId, handlers) {
7
38
  let ready = false;
39
+ let lastReconnectState;
8
40
  const timeout = setTimeout(() => {
9
41
  if (!ready) handlers.onTimeout?.();
10
42
  }, READY_TIMEOUT_MS);
@@ -36,6 +68,11 @@ function listen(klapOneOrigin, requestId, handlers) {
36
68
  case "klappay:resize":
37
69
  handlers.onResize?.(message.height);
38
70
  return;
71
+ case "klappay:reconnecting":
72
+ if (message.state === lastReconnectState) return;
73
+ lastReconnectState = message.state;
74
+ handlers.onReconnecting?.(message.state);
75
+ return;
39
76
  }
40
77
  }
41
78
  window.addEventListener("message", onMessage);
@@ -53,12 +90,6 @@ function buildFrameUrl(params) {
53
90
  return url.toString();
54
91
  }
55
92
 
56
- // src/core/device.ts
57
- var MOBILE_USER_AGENT_PATTERN = /Android|iPhone|iPad|iPod/i;
58
- function isMobileUserAgent(userAgent) {
59
- return MOBILE_USER_AGENT_PATTERN.test(userAgent);
60
- }
61
-
62
93
  // src/core/iframe.ts
63
94
  var FRAME_WIDTH = 420;
64
95
  var LOADING_FRAME_HEIGHT = 360;
@@ -145,6 +176,7 @@ function openIframe(url, onDismiss) {
145
176
  const frame = document.createElement("iframe");
146
177
  frame.className = "frame";
147
178
  frame.src = url;
179
+ frame.allow = "storage-access";
148
180
  backdrop.append(frame);
149
181
  shadow.append(style, backdrop);
150
182
  document.body.append(host);
@@ -229,7 +261,7 @@ function getGlobalConfig() {
229
261
  return globalConfig;
230
262
  }
231
263
  function resolveMode(config) {
232
- return config.mode ?? (isMobileUserAgent(navigator.userAgent) ? "popup" : "iframe");
264
+ return config.mode ?? "iframe";
233
265
  }
234
266
  function createKlappayOne(config) {
235
267
  function open() {
@@ -271,7 +303,11 @@ function createKlappayOne(config) {
271
303
  onTimeout: () => {
272
304
  stop();
273
305
  config.onError?.(FRAME_TIMEOUT);
274
- }
306
+ },
307
+ // A popup tab is exactly as exposed to backgrounding as an iframe
308
+ // is (see resolveMode's comment above) — never gated to the iframe
309
+ // path only.
310
+ onReconnecting: config.onReconnecting
275
311
  });
276
312
  const pollClosed = setInterval(() => {
277
313
  if (isPopupClosed(popup)) {
@@ -318,7 +354,13 @@ function createKlappayOne(config) {
318
354
  // otherwise leave the iframe silently blank forever — one automatic
319
355
  // fallback to the popup renderer before giving up and reporting
320
356
  // FRAME_TIMEOUT (which openViaPopup does on its own if it also fails).
321
- onTimeout: () => settleOnce(openViaPopup)
357
+ onTimeout: () => settleOnce(openViaPopup),
358
+ // Not wrapped in settleOnce — like onPending/onConfirming, this is
359
+ // informational, never terminal. one-id drives this autonomously
360
+ // once it detects its own WalletConnect relay coming back from a
361
+ // background/foreground cycle; nothing here needs to send anything
362
+ // back into the iframe for it to act on.
363
+ onReconnecting: config.onReconnecting
322
364
  });
323
365
  function stop() {
324
366
  stopListening();
@@ -402,12 +444,18 @@ function observeNewElements(root = document.body) {
402
444
  var KLAPPAY_BUTTON_TAG = "klappay-button";
403
445
  var VARIANTS = ["white", "yellow", "black"];
404
446
  var SIZES = ["sm", "md", "lg"];
447
+ var LABELS = ["full", "short"];
405
448
  var DEFAULT_VARIANT = "black";
406
449
  var DEFAULT_SIZE = "md";
450
+ var DEFAULT_LABEL = "full";
451
+ var LABEL_TEXT = {
452
+ full: "Pay with Klappay One",
453
+ short: "Klappay One"
454
+ };
407
455
  var SIZE_STYLES = {
408
- sm: { height: "32px", fontSize: "13px", padding: "0 14px", logoSize: "14px" },
409
- md: { height: "40px", fontSize: "14px", padding: "0 18px", logoSize: "16px" },
410
- lg: { height: "48px", fontSize: "16px", padding: "0 24px", logoSize: "18px" }
456
+ sm: { height: "32px", fontSize: "13px", padding: "0 14px", logoSize: "18px" },
457
+ md: { height: "40px", fontSize: "14px", padding: "0 18px", logoSize: "21px" },
458
+ lg: { height: "48px", fontSize: "16px", padding: "0 24px", logoSize: "23px" }
411
459
  };
412
460
  var LOGO_NO_BLACK_INK_DATA_URI = "data:image/webp;base64,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";
413
461
  var LOGO_BLACK_INK_DATA_URI = "data:image/webp;base64,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";
@@ -428,6 +476,9 @@ function isVariant(value) {
428
476
  function isSize(value) {
429
477
  return SIZES.includes(value);
430
478
  }
479
+ function isLabel(value) {
480
+ return LABELS.includes(value);
481
+ }
431
482
  var KlappayButtonBase = typeof HTMLElement !== "undefined" ? HTMLElement : class {
432
483
  };
433
484
  var BUTTON_CSS = (() => {
@@ -464,10 +515,11 @@ var BUTTON_CSS = (() => {
464
515
  })();
465
516
  var KlappayButtonElement = class extends KlappayButtonBase {
466
517
  static get observedAttributes() {
467
- return ["variant", "size", "charge-id", "origin"];
518
+ return ["variant", "size", "label", "charge-id", "origin"];
468
519
  }
469
520
  #button;
470
521
  #logo;
522
+ #labelEl;
471
523
  #busy = false;
472
524
  constructor() {
473
525
  super();
@@ -477,20 +529,21 @@ var KlappayButtonElement = class extends KlappayButtonBase {
477
529
  this.#logo = document.createElement("img");
478
530
  this.#logo.alt = "";
479
531
  this.#logo.setAttribute("aria-hidden", "true");
480
- const label = document.createElement("span");
481
- label.textContent = "Pay with Klappay";
532
+ this.#labelEl = document.createElement("span");
482
533
  this.#button = document.createElement("button");
483
534
  this.#button.type = "button";
484
- this.#button.append(this.#logo, label);
535
+ this.#button.append(this.#logo, this.#labelEl);
485
536
  this.#button.addEventListener("click", () => this.#handleClick());
486
537
  shadow.append(style, this.#button);
487
538
  this.#applyVariant();
488
539
  this.#applySize();
540
+ this.#applyLabel();
489
541
  this.#applyDisabled();
490
542
  }
491
543
  attributeChangedCallback(name) {
492
544
  if (name === "variant") this.#applyVariant();
493
545
  if (name === "size") this.#applySize();
546
+ if (name === "label") this.#applyLabel();
494
547
  if (name === "charge-id" || name === "origin") this.#applyDisabled();
495
548
  }
496
549
  get variant() {
@@ -507,6 +560,13 @@ var KlappayButtonElement = class extends KlappayButtonBase {
507
560
  set size(value) {
508
561
  this.setAttribute("size", value);
509
562
  }
563
+ get label() {
564
+ const value = this.getAttribute("label") ?? "";
565
+ return isLabel(value) ? value : DEFAULT_LABEL;
566
+ }
567
+ set label(value) {
568
+ this.setAttribute("label", value);
569
+ }
510
570
  #applyVariant() {
511
571
  this.#button.setAttribute("data-variant", this.variant);
512
572
  this.#logo.src = VARIANT_LOGO_DATA_URI[this.variant];
@@ -514,6 +574,9 @@ var KlappayButtonElement = class extends KlappayButtonBase {
514
574
  #applySize() {
515
575
  this.#button.setAttribute("data-size", this.size);
516
576
  }
577
+ #applyLabel() {
578
+ this.#labelEl.textContent = LABEL_TEXT[this.label];
579
+ }
517
580
  // Only checks the origin *attribute*, not a `configure()` call made after
518
581
  // this element was already upgraded — there's no subscription mechanism
519
582
  // for global config changes. Set `origin` before this element is parsed,
@@ -1,5 +1,8 @@
1
+ type ReconnectState = 'started' | 'recovered' | 'failed';
2
+
1
3
  type KlappayButtonVariant = 'white' | 'yellow' | 'black';
2
4
  type KlappayButtonSize = 'sm' | 'md' | 'lg';
5
+ type KlappayButtonLabel = 'full' | 'short';
3
6
  interface KlappayOneError {
4
7
  code: string;
5
8
  message: string;
@@ -25,6 +28,7 @@ interface KlappayOneConfig {
25
28
  onSuccess?: (result: PaymentResult) => void;
26
29
  onError?: (error: KlappayOneError) => void;
27
30
  onCancel?: (reason: 'user' | 'closed') => void;
31
+ onReconnecting?: (state: ReconnectState) => void;
28
32
  }
29
33
 
30
34
  declare function useKlappayOne(config: KlappayOneConfig): {
@@ -36,6 +40,7 @@ interface KlappayButtonProps {
36
40
  locale?: string;
37
41
  variant?: KlappayButtonVariant;
38
42
  size?: KlappayButtonSize;
43
+ label?: KlappayButtonLabel;
39
44
  onSuccess?: (result: PaymentResult) => void;
40
45
  onError?: (error: KlappayOneError) => void;
41
46
  onCancel?: () => void;
@@ -49,6 +54,7 @@ declare global {
49
54
  locale?: string;
50
55
  variant?: KlappayButtonVariant;
51
56
  size?: KlappayButtonSize;
57
+ label?: KlappayButtonLabel;
52
58
  };
53
59
  }
54
60
  }
@@ -3,11 +3,43 @@ import { useEffect, useRef } from "react";
3
3
 
4
4
  // src/core/bridge.ts
5
5
  var READY_TIMEOUT_MS = 1e4;
6
+ var RECONNECT_STATES = ["started", "recovered", "failed"];
7
+ function isPaymentResult(value) {
8
+ if (typeof value !== "object" || value === null) return false;
9
+ const result = value;
10
+ return typeof result.txHash === "string" && typeof result.walletAddress === "string" && typeof result.network === "string" && typeof result.amount === "string" && typeof result.confirmedAt === "string";
11
+ }
12
+ function isKlappayOneError(value) {
13
+ if (typeof value !== "object" || value === null) return false;
14
+ const error = value;
15
+ return typeof error.code === "string" && typeof error.message === "string";
16
+ }
6
17
  function isBridgeMessage(data) {
7
- return typeof data === "object" && data !== null && "type" in data && typeof data.type === "string" && data.type.startsWith("klappay:") && "requestId" in data && typeof data.requestId === "string";
18
+ if (typeof data !== "object" || data === null) return false;
19
+ const envelope = data;
20
+ if (typeof envelope.type !== "string" || typeof envelope.requestId !== "string") return false;
21
+ switch (envelope.type) {
22
+ case "klappay:ready":
23
+ case "klappay:pending":
24
+ case "klappay:cancel":
25
+ return true;
26
+ case "klappay:resize":
27
+ return typeof envelope.height === "number";
28
+ case "klappay:confirming":
29
+ return typeof envelope.txHash === "string" && typeof envelope.network === "string";
30
+ case "klappay:success":
31
+ return isPaymentResult(envelope.result);
32
+ case "klappay:error":
33
+ return isKlappayOneError(envelope.error);
34
+ case "klappay:reconnecting":
35
+ return typeof envelope.state === "string" && RECONNECT_STATES.includes(envelope.state);
36
+ default:
37
+ return false;
38
+ }
8
39
  }
9
40
  function listen(klapOneOrigin, requestId, handlers) {
10
41
  let ready = false;
42
+ let lastReconnectState;
11
43
  const timeout = setTimeout(() => {
12
44
  if (!ready) handlers.onTimeout?.();
13
45
  }, READY_TIMEOUT_MS);
@@ -39,6 +71,11 @@ function listen(klapOneOrigin, requestId, handlers) {
39
71
  case "klappay:resize":
40
72
  handlers.onResize?.(message.height);
41
73
  return;
74
+ case "klappay:reconnecting":
75
+ if (message.state === lastReconnectState) return;
76
+ lastReconnectState = message.state;
77
+ handlers.onReconnecting?.(message.state);
78
+ return;
42
79
  }
43
80
  }
44
81
  window.addEventListener("message", onMessage);
@@ -56,12 +93,6 @@ function buildFrameUrl(params) {
56
93
  return url.toString();
57
94
  }
58
95
 
59
- // src/core/device.ts
60
- var MOBILE_USER_AGENT_PATTERN = /Android|iPhone|iPad|iPod/i;
61
- function isMobileUserAgent(userAgent) {
62
- return MOBILE_USER_AGENT_PATTERN.test(userAgent);
63
- }
64
-
65
96
  // src/core/iframe.ts
66
97
  var FRAME_WIDTH = 420;
67
98
  var LOADING_FRAME_HEIGHT = 360;
@@ -148,6 +179,7 @@ function openIframe(url, onDismiss) {
148
179
  const frame = document.createElement("iframe");
149
180
  frame.className = "frame";
150
181
  frame.src = url;
182
+ frame.allow = "storage-access";
151
183
  backdrop.append(frame);
152
184
  shadow.append(style, backdrop);
153
185
  document.body.append(host);
@@ -229,7 +261,7 @@ function getGlobalConfig() {
229
261
  return globalConfig;
230
262
  }
231
263
  function resolveMode(config) {
232
- return config.mode ?? (isMobileUserAgent(navigator.userAgent) ? "popup" : "iframe");
264
+ return config.mode ?? "iframe";
233
265
  }
234
266
  function createKlappayOne(config) {
235
267
  function open() {
@@ -271,7 +303,11 @@ function createKlappayOne(config) {
271
303
  onTimeout: () => {
272
304
  stop();
273
305
  config.onError?.(FRAME_TIMEOUT);
274
- }
306
+ },
307
+ // A popup tab is exactly as exposed to backgrounding as an iframe
308
+ // is (see resolveMode's comment above) — never gated to the iframe
309
+ // path only.
310
+ onReconnecting: config.onReconnecting
275
311
  });
276
312
  const pollClosed = setInterval(() => {
277
313
  if (isPopupClosed(popup)) {
@@ -318,7 +354,13 @@ function createKlappayOne(config) {
318
354
  // otherwise leave the iframe silently blank forever — one automatic
319
355
  // fallback to the popup renderer before giving up and reporting
320
356
  // FRAME_TIMEOUT (which openViaPopup does on its own if it also fails).
321
- onTimeout: () => settleOnce(openViaPopup)
357
+ onTimeout: () => settleOnce(openViaPopup),
358
+ // Not wrapped in settleOnce — like onPending/onConfirming, this is
359
+ // informational, never terminal. one-id drives this autonomously
360
+ // once it detects its own WalletConnect relay coming back from a
361
+ // background/foreground cycle; nothing here needs to send anything
362
+ // back into the iframe for it to act on.
363
+ onReconnecting: config.onReconnecting
322
364
  });
323
365
  function stop() {
324
366
  stopListening();
@@ -332,12 +374,18 @@ function createKlappayOne(config) {
332
374
  var KLAPPAY_BUTTON_TAG = "klappay-button";
333
375
  var VARIANTS = ["white", "yellow", "black"];
334
376
  var SIZES = ["sm", "md", "lg"];
377
+ var LABELS = ["full", "short"];
335
378
  var DEFAULT_VARIANT = "black";
336
379
  var DEFAULT_SIZE = "md";
380
+ var DEFAULT_LABEL = "full";
381
+ var LABEL_TEXT = {
382
+ full: "Pay with Klappay One",
383
+ short: "Klappay One"
384
+ };
337
385
  var SIZE_STYLES = {
338
- sm: { height: "32px", fontSize: "13px", padding: "0 14px", logoSize: "14px" },
339
- md: { height: "40px", fontSize: "14px", padding: "0 18px", logoSize: "16px" },
340
- lg: { height: "48px", fontSize: "16px", padding: "0 24px", logoSize: "18px" }
386
+ sm: { height: "32px", fontSize: "13px", padding: "0 14px", logoSize: "18px" },
387
+ md: { height: "40px", fontSize: "14px", padding: "0 18px", logoSize: "21px" },
388
+ lg: { height: "48px", fontSize: "16px", padding: "0 24px", logoSize: "23px" }
341
389
  };
342
390
  var LOGO_NO_BLACK_INK_DATA_URI = "data:image/webp;base64,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";
343
391
  var LOGO_BLACK_INK_DATA_URI = "data:image/webp;base64,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";
@@ -358,6 +406,9 @@ function isVariant(value) {
358
406
  function isSize(value) {
359
407
  return SIZES.includes(value);
360
408
  }
409
+ function isLabel(value) {
410
+ return LABELS.includes(value);
411
+ }
361
412
  var KlappayButtonBase = typeof HTMLElement !== "undefined" ? HTMLElement : class {
362
413
  };
363
414
  var BUTTON_CSS = (() => {
@@ -394,10 +445,11 @@ var BUTTON_CSS = (() => {
394
445
  })();
395
446
  var KlappayButtonElement = class extends KlappayButtonBase {
396
447
  static get observedAttributes() {
397
- return ["variant", "size", "charge-id", "origin"];
448
+ return ["variant", "size", "label", "charge-id", "origin"];
398
449
  }
399
450
  #button;
400
451
  #logo;
452
+ #labelEl;
401
453
  #busy = false;
402
454
  constructor() {
403
455
  super();
@@ -407,20 +459,21 @@ var KlappayButtonElement = class extends KlappayButtonBase {
407
459
  this.#logo = document.createElement("img");
408
460
  this.#logo.alt = "";
409
461
  this.#logo.setAttribute("aria-hidden", "true");
410
- const label = document.createElement("span");
411
- label.textContent = "Pay with Klappay";
462
+ this.#labelEl = document.createElement("span");
412
463
  this.#button = document.createElement("button");
413
464
  this.#button.type = "button";
414
- this.#button.append(this.#logo, label);
465
+ this.#button.append(this.#logo, this.#labelEl);
415
466
  this.#button.addEventListener("click", () => this.#handleClick());
416
467
  shadow.append(style, this.#button);
417
468
  this.#applyVariant();
418
469
  this.#applySize();
470
+ this.#applyLabel();
419
471
  this.#applyDisabled();
420
472
  }
421
473
  attributeChangedCallback(name) {
422
474
  if (name === "variant") this.#applyVariant();
423
475
  if (name === "size") this.#applySize();
476
+ if (name === "label") this.#applyLabel();
424
477
  if (name === "charge-id" || name === "origin") this.#applyDisabled();
425
478
  }
426
479
  get variant() {
@@ -437,6 +490,13 @@ var KlappayButtonElement = class extends KlappayButtonBase {
437
490
  set size(value) {
438
491
  this.setAttribute("size", value);
439
492
  }
493
+ get label() {
494
+ const value = this.getAttribute("label") ?? "";
495
+ return isLabel(value) ? value : DEFAULT_LABEL;
496
+ }
497
+ set label(value) {
498
+ this.setAttribute("label", value);
499
+ }
440
500
  #applyVariant() {
441
501
  this.#button.setAttribute("data-variant", this.variant);
442
502
  this.#logo.src = VARIANT_LOGO_DATA_URI[this.variant];
@@ -444,6 +504,9 @@ var KlappayButtonElement = class extends KlappayButtonBase {
444
504
  #applySize() {
445
505
  this.#button.setAttribute("data-size", this.size);
446
506
  }
507
+ #applyLabel() {
508
+ this.#labelEl.textContent = LABEL_TEXT[this.label];
509
+ }
447
510
  // Only checks the origin *attribute*, not a `configure()` call made after
448
511
  // this element was already upgraded — there's no subscription mechanism
449
512
  // for global config changes. Set `origin` before this element is parsed,
@@ -555,7 +618,8 @@ function KlappayButton(props) {
555
618
  origin: props.origin,
556
619
  locale: props.locale,
557
620
  variant: props.variant,
558
- size: props.size
621
+ size: props.size,
622
+ label: props.label
559
623
  }
560
624
  );
561
625
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@klappay/one",
3
- "version": "1.3.0",
3
+ "version": "1.5.0",
4
4
  "license": "MIT",
5
5
  "description": "Klappay One's embeddable payment button — opens the hosted identity/wallet popup (one-id) and relays the result via postMessage. Never touches a private key or a session token; framework-agnostic core with a thin React wrapper.",
6
6
  "keywords": [