@cowprotocol/widget-lib 4.0.5 → 4.2.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.
@@ -0,0 +1 @@
1
+ export declare function isAllowedWindowOpenUrl(url: string): boolean;
package/index.cjs CHANGED
@@ -1 +1,53 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const S=require("@cowprotocol/iframe-transport"),G=require("@cowprotocol/events"),N="allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox",v="strict-origin-when-cross-origin",U="clipboard-read; clipboard-write";var c=(e=>(e.ACTIVATE="ACTIVATE",e.READY="READY",e.UPDATE_HEIGHT="UPDATE_HEIGHT",e.SET_FULL_HEIGHT="SET_FULL_HEIGHT",e.EMIT_COW_EVENT="EMIT_COW_EVENT",e.PROVIDER_RPC_REQUEST="PROVIDER_RPC_REQUEST",e.INTERCEPT_WINDOW_OPEN="INTERCEPT_WINDOW_OPEN",e.PROCESS_HOOK="PROCESS_HOOK",e))(c||{}),O=(e=>(e.UPDATE_PARAMS="UPDATE_PARAMS",e.UPDATE_APP_DATA="UPDATE_APP_DATA",e.PROVIDER_RPC_RESPONSE="PROVIDER_RPC_RESPONSE",e.PROVIDER_ON_EVENT="PROVIDER_ON_EVENT",e.HOOK_RESULT="HOOK_RESULT",e))(O||{}),p=(e=>(e.ON_BEFORE_APPROVAL="ON_BEFORE_APPROVAL",e.ON_BEFORE_TRADE="ON_BEFORE_TRADE",e.ON_BEFORE_WRAP_UNWRAP="ON_BEFORE_WRAP_UNWRAP",e.ON_BEFORE_ORDER_CANCEL="ON_BEFORE_ORDER_CANCEL",e.ON_BEFORE_ORDERS_CANCEL="ON_BEFORE_ORDERS_CANCEL",e))(p||{}),h=(e=>(e.SWAP="swap",e.LIMIT="limit",e.ADVANCED="advanced",e.YIELD="yield",e))(h||{});const $=["primary","background","paper","text","danger","warning","alert","info","success"],d=new S.IframeTransport("cowSwapWidget");class j{constructor(t,n,o,r=[]){this.contentWindow=t,this.updateListeners(r),this.widgetListener=d.listenToMessageFromWindow(this.contentWindow,o,c.EMIT_COW_EVENT,i=>this.eventEmitter.emit(i.event,i.payload),n)}eventEmitter=new G.SimpleCowEventEmitter;listeners=[];widgetListener;stopListeningIframe(){d.stopListeningWindowListener(this.contentWindow,this.widgetListener)}updateListeners(t){for(const n of this.listeners)this.eventEmitter.off(n);this.listeners=t||[];for(const n of this.listeners)this.eventEmitter.on(n)}}class x{constructor(t,n){this.appWindow=t,this.iframeWidow=n,this.forwardSdkMessage=o=>{Q(o.data)&&(typeof window<"u"&&o.origin===window.location.origin||(K(o.data)?this.appWindow.parent.postMessage(o.data,"*"):Y(o.data)&&this.iframeWidow.postMessage(o.data,"*")))},this.startListening()}forwardSdkMessage;startListening(){this.appWindow.addEventListener("message",this.forwardSdkMessage)}stopListening(){this.appWindow.removeEventListener("message",this.forwardSdkMessage)}}function Q(e){return typeof e=="object"&&e!==null&&"id"in e&&typeof e.id=="string"}function K(e){return"method"in e&&typeof e.method=="string"&&"params"in e&&"env"in e&&typeof e.env=="object"&&e.env!==null&&"sdkVersion"in e.env}function Y(e){return"success"in e&&typeof e.success=="boolean"&&"version"in e&&typeof e.version=="string"}function X(e="Default",t="#1c5dbf",...n){console.debug(`%c [COW][${e}]`,`font-weight: bold; color: ${t}`,...n)}function z(...e){process.env.NODE_ENV!=="test"&&X("Widget","#47aba8",...e)}const F="https://swap.cow.fi";function b(e){return!!(e&&typeof e=="object")}const m="_",J="CoW Swap widget: invalid baseUrl.",H=!1;function Z(e){return e==="localhost"||e==="127.0.0.1"||e==="::1"||e.endsWith(".localhost")}function g(e,t){const n=`${J} ${e}`;if(t)throw new Error(n);return console.error("[CoW Widget]",n),F}function y(e,t=H){const n=typeof e=="string"?e.trim():"";if(!n)return F;let o;try{o=new URL(n)}catch{return g(`Not a valid URL: ${JSON.stringify(n)}`,t)}if(o.username||o.password)return g("Userinfo (username/password) in URL is not allowed.",t);const r=o.protocol==="https:",i=o.protocol==="http:"&&Z(o.hostname);if(!r&&!i)return g(`Use https, or http only on localhost / 127.0.0.1 / ::1 / *.localhost (got ${o.protocol}//${o.hostname}).`,t);const u=o.pathname==="/"||o.pathname===""?"":o.pathname.replace(/\/+$/,"");return`${o.origin}${u}`}function q(e){const t=y(e.baseUrl),n=B(e);return t+"/#"+n+"?"+M(e)}function B(e){const{chainId:t=1,sell:n,buy:o,tradeType:r=h.SWAP}=e,i=[n?.asset||m,o?.asset||m].map(encodeURIComponent).join("/");return`/${t}/widget/${r}/${i}`}function M(e){const t=new URLSearchParams;return re(oe(ne(te(ee(t,e),e),e),e),e)}function ee(e,t){const{sell:n,buy:o}=t;return n?.amount&&e.append("sellAmount",n.amount),o?.amount&&e.append("buyAmount",o.amount),e}function te(e,t){const n=t.theme;return n?(b(n)?(e.append("palette",encodeURIComponent(JSON.stringify(n))),e.append("theme",n.baseTheme)):(e.append("palette","null"),e.append("theme",n)),e):(e.append("palette","null"),e)}function ne(e,t){return t.targetChainId&&e.append("targetChainId",t.targetChainId.toString()),e}function oe(e,t){return t.locale&&e.append("lng",t.locale),e}function re(e,t){return ie(t.hooks)?e.append("hooksEnabled","true"):e.delete("hooksEnabled"),e}function ie(e){return!!e&&Object.values(e).some(Boolean)}const V="640px",se="450px",ae=20,de={iframe:null,updateParams:()=>{},updateListeners:()=>{},updateProvider:()=>{},destroy:()=>{}};function le(e,t){const{params:n,provider:o,listeners:r,onReady:i}=t;let u=o,f=n;if(typeof window>"u")return de;const l=ce(n),s=ue(l);z("Resolved trusted iframe origin",{iframeOrigin:s});const _=[];e.innerHTML="",e.appendChild(l);const{contentWindow:a}=l;if(!a)throw console.error("Iframe does not contain a window",l),new Error("Iframe does not contain a window!");i&&_.push(pe(a,s,i)),_.push(Ee(a,s,n.appCode)),_.push(...Re(l,s,n.height,n.maxHeight));let T=null;function L(){a&&(T&&window.removeEventListener("message",T),!f.disableWindowOpen&&(T=fe(s,a),_.push(T)))}let A=null;function I(){a&&(A&&window.removeEventListener("message",A),A=Ae(a,s,f.hooks),_.push(A))}L(),I();const W=new j(window,s,a,r);let P=C(a,s,null,u);l.addEventListener("load",()=>{D(a,s,f,u)});const k=new x(window,a);return{iframe:l,updateParams:E=>{f=E,D(a,s,f,u),L(),I()},updateListeners:E=>W.updateListeners(E),updateProvider:E=>{u=E,P=C(a,s,P,E)},destroy:()=>{P.disconnect(),W.stopListeningIframe(),_.forEach(E=>window.removeEventListener("message",E)),k.stopListening(),e.removeChild(l)}}}function C(e,t,n,o){n&&n.disconnect();const r=n||new S.IframeRpcProviderBridge(e,t);return o&&r.onConnect(o),r}function ce(e){const{width:t=se,height:n=V}=e,o=document.createElement("iframe");return o.src=q(e),o.width=t,o.height=n,o.style.border="0",o.setAttribute("sandbox",N),o.referrerPolicy=v,o.allow=U,o}function ue(e){return new URL(e.src).origin}function D(e,t,n,o){const r=!!o,i=B(n),u=M(n).toString(),{theme:f,hooks:l,...s}=n;d.postMessageToWindow(e,O.UPDATE_PARAMS,{urlParams:{pathname:i,search:u},appParams:s,hasProvider:r},t)}function Ee(e,t,n){return d.listenToMessageFromWindow(window,e,c.ACTIVATE,()=>{d.postMessageToWindow(e,O.UPDATE_APP_DATA,{metaData:n?{appCode:n}:void 0},t)},t)}function pe(e,t,n){let o=!1;return d.listenToMessageFromWindow(window,e,c.READY,()=>{o||(o=!0,n())},t)}function fe(e,t){return d.listenToMessageFromWindow(window,t,c.INTERCEPT_WINDOW_OPEN,({href:n,rel:o,target:r})=>{const i=_e(n.toString(),e);i&&we(i)&&window.open(i,r,o)},e)}function _e(e,t){const n=e.trim();if(!n)return null;try{return new URL(n,t).toString()}catch{return null}}function we(e){try{const t=new URL(e).protocol;return t==="http:"||t==="https:"}catch{return!1}}function Re(e,t,n=V,o){return e.contentWindow?[d.listenToMessageFromWindow(window,e.contentWindow,c.UPDATE_HEIGHT,r=>{const i=r.height?r.height+ae:void 0;e.style.height=i?`${o?Math.min(i,o):i}px`:n},t),d.listenToMessageFromWindow(window,e.contentWindow,c.SET_FULL_HEIGHT,({isUpToSmall:r})=>{e.style.height=r?n:`${o||document.body.offsetHeight}px`},t)]:[]}const Oe={[p.ON_BEFORE_APPROVAL]:(e,t)=>t?.onBeforeApproval?t.onBeforeApproval(e):!0,[p.ON_BEFORE_TRADE]:(e,t)=>t?.onBeforeTrade?t.onBeforeTrade(e):!0,[p.ON_BEFORE_WRAP_UNWRAP]:(e,t)=>t?.onBeforeWrapOrUnwrap?t.onBeforeWrapOrUnwrap(e):!0,[p.ON_BEFORE_ORDER_CANCEL]:(e,t)=>t?.onBeforeOrderCancel?t.onBeforeOrderCancel(e):!0,[p.ON_BEFORE_ORDERS_CANCEL]:(e,t)=>t?.onBeforeOrdersCancel?t.onBeforeOrdersCancel(e):!0};function Te(e,t){return Oe[e.event](e.payload,t)}function Ae(e,t,n){return d.listenToMessageFromWindow(window,e,c.PROCESS_HOOK,async o=>{let r=!1;try{r=await Te(o,n)}catch{}d.postMessageToWindow(e,O.HOOK_RESULT,{id:o.id,result:r},t)},t)}const he=Object.values(h);function Pe(e,t,n){if(w(e)){const o=e[n];return R(o)?o[t]:o}if(R(e)){const o=e[t];return w(o)?o[n]:o}return e}function w(e){return typeof e!="object"?!1:Object.keys(e).every(t=>he.includes(t))}const ge=/^\d+$/;function R(e){return typeof e!="object"?!1:Object.keys(e).every(t=>ge.test(t))}function Le(e){return w(e)?Object.values(e).flatMap(t=>R(t)?Object.values(t):[t]):R(e)?Object.values(e).flatMap(t=>w(t)?Object.values(t):[t]):[e]}exports.SHOULD_THROW_IF_INVALID_URL=H;exports.TradeType=h;exports.WIDGET_IFRAME_ALLOW=U;exports.WIDGET_IFRAME_REFERRER_POLICY=v;exports.WIDGET_IFRAME_SANDBOX=N;exports.WIDGET_PALETTE_COLORS=$;exports.WidgetHookEvents=p;exports.WidgetMethodsEmit=c;exports.WidgetMethodsListen=O;exports.createCowSwapWidget=le;exports.isCowSwapWidgetPalette=b;exports.isPerNetworkConfig=R;exports.isPerTradeTypeConfig=w;exports.resolveFlexibleConfig=Pe;exports.resolveFlexibleConfigValues=Le;exports.sanitizeWidgetBaseUrl=y;exports.widgetIframeTransport=d;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const y=require("@cowprotocol/iframe-transport"),K=require("@cowprotocol/events"),Q=new Set(["wc:","metamask:","imtokenv2:","trustassetapp:","okex:","ledgerlive:","rainbow:","argent:","exodus:","zerion:","okxwallet:","uniswap:","robinhood-wallet:","krakenwallet:","bitpay:","oneinch:","safe:","backpack:","tangem:","mathwallet:","keplrwallet:","coin98:","tpoutside:","bncus:","bnc:"]),Y=new Set(["http:","https:"]);function z(e){try{const t=new URL(e).protocol;return Y.has(t)||Q.has(t)}catch{return!1}}const U="allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox",F="strict-origin-when-cross-origin",B="clipboard-read; clipboard-write";var f=(e=>(e.ACTIVATE="ACTIVATE",e.READY="READY",e.UPDATE_HEIGHT="UPDATE_HEIGHT",e.SET_FULL_HEIGHT="SET_FULL_HEIGHT",e.EMIT_COW_EVENT="EMIT_COW_EVENT",e.PROVIDER_RPC_REQUEST="PROVIDER_RPC_REQUEST",e.INTERCEPT_WINDOW_OPEN="INTERCEPT_WINDOW_OPEN",e.PROCESS_HOOK="PROCESS_HOOK",e))(f||{}),g=(e=>(e.UPDATE_PARAMS="UPDATE_PARAMS",e.UPDATE_APP_DATA="UPDATE_APP_DATA",e.PROVIDER_RPC_RESPONSE="PROVIDER_RPC_RESPONSE",e.PROVIDER_ON_EVENT="PROVIDER_ON_EVENT",e.HOOK_RESULT="HOOK_RESULT",e))(g||{}),_=(e=>(e.ON_BEFORE_APPROVAL="ON_BEFORE_APPROVAL",e.ON_BEFORE_TRADE="ON_BEFORE_TRADE",e.ON_BEFORE_WRAP_UNWRAP="ON_BEFORE_WRAP_UNWRAP",e.ON_BEFORE_ORDER_CANCEL="ON_BEFORE_ORDER_CANCEL",e.ON_BEFORE_ORDERS_CANCEL="ON_BEFORE_ORDERS_CANCEL",e))(_||{}),P=(e=>(e.SWAP="swap",e.LIMIT="limit",e.ADVANCED="advanced",e.YIELD="yield",e))(P||{});const X=["primary","background","paper","text","danger","warning","alert","info","success"],c=new y.IframeTransport("cowSwapWidget");class J{constructor(t,n,o,r=[]){this.contentWindow=t,this.updateListeners(r),this.widgetListener=c.listenToMessageFromWindow(this.contentWindow,o,f.EMIT_COW_EVENT,i=>this.eventEmitter.emit(i.event,i.payload),n)}eventEmitter=new K.SimpleCowEventEmitter;listeners=[];widgetListener;stopListeningIframe(){c.stopListeningWindowListener(this.contentWindow,this.widgetListener)}updateListeners(t){for(const n of this.listeners)this.eventEmitter.off(n);this.listeners=t||[];for(const n of this.listeners)this.eventEmitter.on(n)}}class Z{constructor(t,n){this.appWindow=t,this.iframeWidow=n,this.forwardSdkMessage=o=>{q(o.data)&&(typeof window<"u"&&o.origin===window.location.origin||(ee(o.data)?this.appWindow.parent.postMessage(o.data,"*"):te(o.data)&&this.iframeWidow.postMessage(o.data,"*")))},this.startListening()}forwardSdkMessage;startListening(){this.appWindow.addEventListener("message",this.forwardSdkMessage)}stopListening(){this.appWindow.removeEventListener("message",this.forwardSdkMessage)}}function q(e){return typeof e=="object"&&e!==null&&"id"in e&&typeof e.id=="string"}function ee(e){return"method"in e&&typeof e.method=="string"&&"params"in e&&"env"in e&&typeof e.env=="object"&&e.env!==null&&"sdkVersion"in e.env}function te(e){return"success"in e&&typeof e.success=="boolean"&&"version"in e&&typeof e.version=="string"}function ne(e="Default",t="#1c5dbf",...n){console.debug(`%c [COW][${e}]`,`font-weight: bold; color: ${t}`,...n)}function oe(...e){process.env.NODE_ENV!=="test"&&ne("Widget","#47aba8",...e)}const H="https://swap.cow.fi";function k(e){return!!(e&&typeof e=="object")}const v="_",re="CoW Swap widget: invalid baseUrl.",M=!1;function ie(e){return e==="localhost"||e==="127.0.0.1"||e==="::1"||e.endsWith(".localhost")}function C(e,t){const n=`${re} ${e}`;if(t)throw new Error(n);return console.error("[CoW Widget]",n),H}function x(e,t=M){const n=typeof e=="string"?e.trim():"";if(!n)return H;let o;try{o=new URL(n)}catch{return C(`Not a valid URL: ${JSON.stringify(n)}`,t)}if(o.username||o.password)return C("Userinfo (username/password) in URL is not allowed.",t);const r=o.protocol==="https:",i=o.protocol==="http:"&&ie(o.hostname);if(!r&&!i)return C(`Use https, or http only on localhost / 127.0.0.1 / ::1 / *.localhost (got ${o.protocol}//${o.hostname}).`,t);const u=o.pathname==="/"||o.pathname===""?"":o.pathname.replace(/\/+$/,"");return`${o.origin}${u}`}function se(e){const t=x(e.baseUrl),n=V(e);return t+"/#"+n+"?"+$(e)}function V(e){const{chainId:t=1,sell:n,buy:o,tradeType:r=P.SWAP}=e,i=[n?.asset||v,o?.asset||v].map(encodeURIComponent).join("/");return`/${t}/widget/${r}/${i}`}function $(e){const t=new URLSearchParams;return ue(ce(le(de(ae(t,e),e),e),e),e)}function ae(e,t){const{sell:n,buy:o}=t;return n?.amount&&e.append("sellAmount",n.amount),o?.amount&&e.append("buyAmount",o.amount),e}function de(e,t){const n=t.theme;return n?(k(n)?(e.append("palette",encodeURIComponent(JSON.stringify(n))),e.append("theme",n.baseTheme)):(e.append("palette","null"),e.append("theme",n)),e):(e.append("palette","null"),e)}function le(e,t){return t.targetChainId&&e.append("targetChainId",t.targetChainId.toString()),e}function ce(e,t){return t.locale&&e.append("lng",t.locale),e}function ue(e,t){return pe(t.hooks)?e.append("hooksEnabled","true"):e.delete("hooksEnabled"),e}function pe(e){return!!e&&Object.values(e).some(Boolean)}const fe=3e4,m="coWWidgetContentReloadButton";function Ee(e,t,n){const o=e.src;let r=!1,i=!1,u;function E(){e.srcdoc=we,t?.()}function p(){clearTimeout(u),u=setTimeout(()=>{r||i||E()},fe)}function s(){r||i||(e.removeAttribute("srcdoc"),e.src=o,p())}function a(){if(r)return;const d=e.contentDocument,T=d?.querySelector(`.${m}`);if(!(!d||!T)&&(T.addEventListener("click",s),n)){const h=d.createElement("style");h.textContent=n,d.head.appendChild(h)}}return e.addEventListener("error",d=>{r||(console.error("Could not load iframe",d),E())}),e.addEventListener("load",a),p(),{cancelWidgetLoading(){r=!0,clearTimeout(u),e.removeEventListener("load",a)},onWidgetReady(){i=!0,clearTimeout(u)}}}const we=`<!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <style>
5
+ html, body { margin: 0; padding: 0; width: 100%; height: 100%; }
6
+ .errorContent {
7
+ display: flex;
8
+ flex-direction: column;
9
+ gap: 16px;
10
+ align-items: center;
11
+ justify-content: center;
12
+ text-align: center;
13
+
14
+ width: 100%;
15
+ height: 100%;
16
+
17
+ padding: 24px;
18
+ box-sizing: border-box;
19
+
20
+ background: #fff5f5;
21
+ color: #d32f2f;
22
+
23
+ border: 1px solid #f5c2c7;
24
+ border-radius: 12px;
25
+
26
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
27
+ font-size: 14px;
28
+ line-height: 1.5;
29
+ font-weight: 500;
30
+ }
31
+ .${m} {
32
+ padding: 8px 24px;
33
+ border: 1px solid #d32f2f;
34
+ border-radius: 8px;
35
+ background: transparent;
36
+ color: #d32f2f;
37
+ font: inherit;
38
+ cursor: pointer;
39
+ }
40
+ .${m}:hover {
41
+ background: #d32f2f;
42
+ color: #fff5f5;
43
+ }
44
+ </style>
45
+ </head>
46
+ <body>
47
+ <div class="errorContent">
48
+ <span>Couldn't load the widget. Please try again later.</span>
49
+
50
+ <button class="${m}">Retry</button>
51
+ </div>
52
+ </body>
53
+ </html>`,G="640px",_e="450px",Oe=20,Re={iframe:null,updateParams:()=>{},updateListeners:()=>{},updateProvider:()=>{},destroy:()=>{}};function ge(e,t){const{params:n,provider:o,listeners:r,onReady:i,enableSafeSdkBridge:u=!0}=t;let E=o,p=n;if(typeof window>"u")return Re;const s=Te(n),a=he(s);oe("Resolved trusted iframe origin",{iframeOrigin:a});const d=[];e.innerHTML="",e.appendChild(s);const{cancelWidgetLoading:T,onWidgetReady:h}=Ee(s,t.onLoadingError,t.loadingErrorStyles),{contentWindow:l}=s;if(!l)throw console.error("Iframe does not contain a window",s),new Error("Iframe does not contain a window!");d.push(Ae(l,a,()=>{i?.(),h()})),d.push(Le(l,a,n.appCode)),d.push(...Ie(s,a,n.height,n.maxHeight));let L=null;function W(){l&&(L&&window.removeEventListener("message",L),!p.disableWindowOpen&&(L=me(a,l),d.push(L)))}let A=null;function S(){l&&(A&&window.removeEventListener("message",A),A=Se(l,a,p.hooks),d.push(A))}W(),S();const D=new J(window,a,l,r);let I=b(l,a,null,E);s.addEventListener("load",()=>{N(l,a,p,E)});const j=u?new Z(window,l):null;return{iframe:s,updateParams:w=>{p=w,N(l,a,p,E),W(),S()},updateListeners:w=>D.updateListeners(w),updateProvider:w=>{E=w,I=b(l,a,I,w)},destroy:()=>{I.disconnect(),D.stopListeningIframe(),d.forEach(w=>window.removeEventListener("message",w)),j?.stopListening(),s&&s.parentNode===e&&e.removeChild(s),T()}}}function b(e,t,n,o){n&&n.disconnect();const r=n||new y.IframeRpcProviderBridge(e,t);return o&&r.onConnect(o),r}function Te(e){const{width:t=_e,height:n=G}=e,o=document.createElement("iframe");return o.src=se(e),o.width=t,o.height=n,o.style.border="0",o.setAttribute("sandbox",U),o.referrerPolicy=F,o.allow=B,o}function he(e){return new URL(e.src).origin}function N(e,t,n,o){const r=!!o,i=V(n),u=$(n).toString(),{theme:E,hooks:p,...s}=n;c.postMessageToWindow(e,g.UPDATE_PARAMS,{urlParams:{pathname:i,search:u},appParams:s,hasProvider:r},t)}function Le(e,t,n){return c.listenToMessageFromWindow(window,e,f.ACTIVATE,()=>{c.postMessageToWindow(e,g.UPDATE_APP_DATA,{metaData:n?{appCode:n}:void 0},t)},t)}function Ae(e,t,n){let o=!1;return c.listenToMessageFromWindow(window,e,f.READY,()=>{o||(o=!0,n())},t)}function me(e,t){return c.listenToMessageFromWindow(window,t,f.INTERCEPT_WINDOW_OPEN,({href:n,rel:o,target:r})=>{const i=Pe(n.toString(),e);i&&z(i)&&window.open(i,r,o)},e)}function Pe(e,t){const n=e.trim();if(!n)return null;try{return new URL(n,t).toString()}catch{return null}}function Ie(e,t,n=G,o){return e.contentWindow?[c.listenToMessageFromWindow(window,e.contentWindow,f.UPDATE_HEIGHT,r=>{const i=r.height?r.height+Oe:void 0;e.style.height=i?`${o?Math.min(i,o):i}px`:n},t),c.listenToMessageFromWindow(window,e.contentWindow,f.SET_FULL_HEIGHT,({isUpToSmall:r})=>{e.style.height=r?n:`${o||document.body.offsetHeight}px`},t)]:[]}const Ce={[_.ON_BEFORE_APPROVAL]:(e,t)=>t?.onBeforeApproval?t.onBeforeApproval(e):!0,[_.ON_BEFORE_TRADE]:(e,t)=>t?.onBeforeTrade?t.onBeforeTrade(e):!0,[_.ON_BEFORE_WRAP_UNWRAP]:(e,t)=>t?.onBeforeWrapOrUnwrap?t.onBeforeWrapOrUnwrap(e):!0,[_.ON_BEFORE_ORDER_CANCEL]:(e,t)=>t?.onBeforeOrderCancel?t.onBeforeOrderCancel(e):!0,[_.ON_BEFORE_ORDERS_CANCEL]:(e,t)=>t?.onBeforeOrdersCancel?t.onBeforeOrdersCancel(e):!0};function We(e,t){return Ce[e.event](e.payload,t)}function Se(e,t,n){return c.listenToMessageFromWindow(window,e,f.PROCESS_HOOK,async o=>{let r=!1;try{r=await We(o,n)}catch{}c.postMessageToWindow(e,g.HOOK_RESULT,{id:o.id,result:r},t)},t)}const De=Object.values(P);function ve(e,t,n){if(O(e)){const o=e[n];return R(o)?o[t]:o}if(R(e)){const o=e[t];return O(o)?o[n]:o}return e}function O(e){return typeof e!="object"?!1:Object.keys(e).every(t=>De.includes(t))}const be=/^\d+$/;function R(e){return typeof e!="object"?!1:Object.keys(e).every(t=>be.test(t))}function Ne(e){return O(e)?Object.values(e).flatMap(t=>R(t)?Object.values(t):[t]):R(e)?Object.values(e).flatMap(t=>O(t)?Object.values(t):[t]):[e]}exports.SHOULD_THROW_IF_INVALID_URL=M;exports.TradeType=P;exports.WIDGET_IFRAME_ALLOW=B;exports.WIDGET_IFRAME_REFERRER_POLICY=F;exports.WIDGET_IFRAME_SANDBOX=U;exports.WIDGET_PALETTE_COLORS=X;exports.WidgetHookEvents=_;exports.WidgetMethodsEmit=f;exports.WidgetMethodsListen=g;exports.createCowSwapWidget=ge;exports.isCowSwapWidgetPalette=k;exports.isPerNetworkConfig=R;exports.isPerTradeTypeConfig=O;exports.resolveFlexibleConfig=ve;exports.resolveFlexibleConfigValues=Ne;exports.sanitizeWidgetBaseUrl=x;exports.widgetIframeTransport=c;
package/index.js CHANGED
@@ -1,17 +1,53 @@
1
- import { IframeTransport as b, IframeRpcProviderBridge as F } from "@cowprotocol/iframe-transport";
2
- import { SimpleCowEventEmitter as y } from "@cowprotocol/events";
3
- const B = "allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox", M = "strict-origin-when-cross-origin", V = "clipboard-read; clipboard-write";
4
- var p = /* @__PURE__ */ ((e) => (e.ACTIVATE = "ACTIVATE", e.READY = "READY", e.UPDATE_HEIGHT = "UPDATE_HEIGHT", e.SET_FULL_HEIGHT = "SET_FULL_HEIGHT", e.EMIT_COW_EVENT = "EMIT_COW_EVENT", e.PROVIDER_RPC_REQUEST = "PROVIDER_RPC_REQUEST", e.INTERCEPT_WINDOW_OPEN = "INTERCEPT_WINDOW_OPEN", e.PROCESS_HOOK = "PROCESS_HOOK", e))(p || {}), h = /* @__PURE__ */ ((e) => (e.UPDATE_PARAMS = "UPDATE_PARAMS", e.UPDATE_APP_DATA = "UPDATE_APP_DATA", e.PROVIDER_RPC_RESPONSE = "PROVIDER_RPC_RESPONSE", e.PROVIDER_ON_EVENT = "PROVIDER_ON_EVENT", e.HOOK_RESULT = "HOOK_RESULT", e))(h || {}), w = /* @__PURE__ */ ((e) => (e.ON_BEFORE_APPROVAL = "ON_BEFORE_APPROVAL", e.ON_BEFORE_TRADE = "ON_BEFORE_TRADE", e.ON_BEFORE_WRAP_UNWRAP = "ON_BEFORE_WRAP_UNWRAP", e.ON_BEFORE_ORDER_CANCEL = "ON_BEFORE_ORDER_CANCEL", e.ON_BEFORE_ORDERS_CANCEL = "ON_BEFORE_ORDERS_CANCEL", e))(w || {}), m = /* @__PURE__ */ ((e) => (e.SWAP = "swap", e.LIMIT = "limit", e.ADVANCED = "advanced", e.YIELD = "yield", e))(m || {});
5
- const ge = ["primary", "background", "paper", "text", "danger", "warning", "alert", "info", "success"], d = new b("cowSwapWidget");
6
- class k {
1
+ import { IframeTransport as k, IframeRpcProviderBridge as x } from "@cowprotocol/iframe-transport";
2
+ import { SimpleCowEventEmitter as M } from "@cowprotocol/events";
3
+ const V = /* @__PURE__ */ new Set([
4
+ "wc:",
5
+ // default Wallet-connect protocol
6
+ "metamask:",
7
+ "imtokenv2:",
8
+ "trustassetapp:",
9
+ "okex:",
10
+ "ledgerlive:",
11
+ "rainbow:",
12
+ "argent:",
13
+ "exodus:",
14
+ "zerion:",
15
+ "okxwallet:",
16
+ "uniswap:",
17
+ "robinhood-wallet:",
18
+ "krakenwallet:",
19
+ "bitpay:",
20
+ "oneinch:",
21
+ "safe:",
22
+ "backpack:",
23
+ "tangem:",
24
+ "mathwallet:",
25
+ "keplrwallet:",
26
+ "coin98:",
27
+ "tpoutside:",
28
+ "bncus:",
29
+ "bnc:"
30
+ ]), $ = /* @__PURE__ */ new Set(["http:", "https:"]);
31
+ function G(e) {
32
+ try {
33
+ const t = new URL(e).protocol;
34
+ return $.has(t) || V.has(t);
35
+ } catch {
36
+ return !1;
37
+ }
38
+ }
39
+ const j = "allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox", K = "strict-origin-when-cross-origin", Q = "clipboard-read; clipboard-write";
40
+ var w = /* @__PURE__ */ ((e) => (e.ACTIVATE = "ACTIVATE", e.READY = "READY", e.UPDATE_HEIGHT = "UPDATE_HEIGHT", e.SET_FULL_HEIGHT = "SET_FULL_HEIGHT", e.EMIT_COW_EVENT = "EMIT_COW_EVENT", e.PROVIDER_RPC_REQUEST = "PROVIDER_RPC_REQUEST", e.INTERCEPT_WINDOW_OPEN = "INTERCEPT_WINDOW_OPEN", e.PROCESS_HOOK = "PROCESS_HOOK", e))(w || {}), A = /* @__PURE__ */ ((e) => (e.UPDATE_PARAMS = "UPDATE_PARAMS", e.UPDATE_APP_DATA = "UPDATE_APP_DATA", e.PROVIDER_RPC_RESPONSE = "PROVIDER_RPC_RESPONSE", e.PROVIDER_ON_EVENT = "PROVIDER_ON_EVENT", e.HOOK_RESULT = "HOOK_RESULT", e))(A || {}), _ = /* @__PURE__ */ ((e) => (e.ON_BEFORE_APPROVAL = "ON_BEFORE_APPROVAL", e.ON_BEFORE_TRADE = "ON_BEFORE_TRADE", e.ON_BEFORE_WRAP_UNWRAP = "ON_BEFORE_WRAP_UNWRAP", e.ON_BEFORE_ORDER_CANCEL = "ON_BEFORE_ORDER_CANCEL", e.ON_BEFORE_ORDERS_CANCEL = "ON_BEFORE_ORDERS_CANCEL", e))(_ || {}), I = /* @__PURE__ */ ((e) => (e.SWAP = "swap", e.LIMIT = "limit", e.ADVANCED = "advanced", e.YIELD = "yield", e))(I || {});
41
+ const Ne = ["primary", "background", "paper", "text", "danger", "warning", "alert", "info", "success"], c = new k("cowSwapWidget");
42
+ class Y {
7
43
  constructor(t, n, o, r = []) {
8
- this.contentWindow = t, this.updateListeners(r), this.widgetListener = d.listenToMessageFromWindow(this.contentWindow, o, p.EMIT_COW_EVENT, (i) => this.eventEmitter.emit(i.event, i.payload), n);
44
+ this.contentWindow = t, this.updateListeners(r), this.widgetListener = c.listenToMessageFromWindow(this.contentWindow, o, w.EMIT_COW_EVENT, (i) => this.eventEmitter.emit(i.event, i.payload), n);
9
45
  }
10
- eventEmitter = new y();
46
+ eventEmitter = new M();
11
47
  listeners = [];
12
48
  widgetListener;
13
49
  stopListeningIframe() {
14
- d.stopListeningWindowListener(this.contentWindow, this.widgetListener);
50
+ c.stopListeningWindowListener(this.contentWindow, this.widgetListener);
15
51
  }
16
52
  updateListeners(t) {
17
53
  for (const n of this.listeners)
@@ -21,10 +57,10 @@ class k {
21
57
  this.eventEmitter.on(n);
22
58
  }
23
59
  }
24
- class $ {
60
+ class z {
25
61
  constructor(t, n) {
26
62
  this.appWindow = t, this.iframeWidow = n, this.forwardSdkMessage = (o) => {
27
- G(o.data) && (typeof window < "u" && o.origin === window.location.origin || (j(o.data) ? this.appWindow.parent.postMessage(o.data, "*") : x(o.data) && this.iframeWidow.postMessage(o.data, "*")));
63
+ X(o.data) && (typeof window < "u" && o.origin === window.location.origin || (J(o.data) ? this.appWindow.parent.postMessage(o.data, "*") : Z(o.data) && this.iframeWidow.postMessage(o.data, "*")));
28
64
  }, this.startListening();
29
65
  }
30
66
  forwardSdkMessage;
@@ -35,94 +71,180 @@ class $ {
35
71
  this.appWindow.removeEventListener("message", this.forwardSdkMessage);
36
72
  }
37
73
  }
38
- function G(e) {
74
+ function X(e) {
39
75
  return typeof e == "object" && e !== null && "id" in e && typeof e.id == "string";
40
76
  }
41
- function j(e) {
77
+ function J(e) {
42
78
  return "method" in e && typeof e.method == "string" && "params" in e && "env" in e && typeof e.env == "object" && e.env !== null && "sdkVersion" in e.env;
43
79
  }
44
- function x(e) {
80
+ function Z(e) {
45
81
  return "success" in e && typeof e.success == "boolean" && "version" in e && typeof e.version == "string";
46
82
  }
47
- function Q(e = "Default", t = "#1c5dbf", ...n) {
83
+ function q(e = "Default", t = "#1c5dbf", ...n) {
48
84
  console.debug(`%c [COW][${e}]`, `font-weight: bold; color: ${t}`, ...n);
49
85
  }
50
- function K(...e) {
51
- process.env.NODE_ENV !== "test" && Q("Widget", "#47aba8", ...e);
86
+ function ee(...e) {
87
+ process.env.NODE_ENV !== "test" && q("Widget", "#47aba8", ...e);
52
88
  }
53
- const S = "https://swap.cow.fi";
54
- function Y(e) {
89
+ const y = "https://swap.cow.fi";
90
+ function te(e) {
55
91
  return !!(e && typeof e == "object");
56
92
  }
57
- const C = "_", X = "CoW Swap widget: invalid baseUrl.", J = !1;
58
- function z(e) {
93
+ const v = "_", ne = "CoW Swap widget: invalid baseUrl.", oe = !1;
94
+ function re(e) {
59
95
  return e === "localhost" || e === "127.0.0.1" || e === "::1" || e.endsWith(".localhost");
60
96
  }
61
- function P(e, t) {
62
- const n = `${X} ${e}`;
97
+ function C(e, t) {
98
+ const n = `${ne} ${e}`;
63
99
  if (t)
64
100
  throw new Error(n);
65
- return console.error("[CoW Widget]", n), S;
101
+ return console.error("[CoW Widget]", n), y;
66
102
  }
67
- function Z(e, t = J) {
103
+ function ie(e, t = oe) {
68
104
  const n = typeof e == "string" ? e.trim() : "";
69
105
  if (!n)
70
- return S;
106
+ return y;
71
107
  let o;
72
108
  try {
73
109
  o = new URL(n);
74
110
  } catch {
75
- return P(`Not a valid URL: ${JSON.stringify(n)}`, t);
111
+ return C(`Not a valid URL: ${JSON.stringify(n)}`, t);
76
112
  }
77
113
  if (o.username || o.password)
78
- return P("Userinfo (username/password) in URL is not allowed.", t);
79
- const r = o.protocol === "https:", i = o.protocol === "http:" && z(o.hostname);
114
+ return C("Userinfo (username/password) in URL is not allowed.", t);
115
+ const r = o.protocol === "https:", i = o.protocol === "http:" && re(o.hostname);
80
116
  if (!r && !i)
81
- return P(`Use https, or http only on localhost / 127.0.0.1 / ::1 / *.localhost (got ${o.protocol}//${o.hostname}).`, t);
82
- const l = o.pathname === "/" || o.pathname === "" ? "" : o.pathname.replace(/\/+$/, "");
83
- return `${o.origin}${l}`;
117
+ return C(`Use https, or http only on localhost / 127.0.0.1 / ::1 / *.localhost (got ${o.protocol}//${o.hostname}).`, t);
118
+ const u = o.pathname === "/" || o.pathname === "" ? "" : o.pathname.replace(/\/+$/, "");
119
+ return `${o.origin}${u}`;
84
120
  }
85
- function q(e) {
86
- const t = Z(e.baseUrl), n = N(e);
87
- return t + "/#" + n + "?" + v(e);
121
+ function se(e) {
122
+ const t = ie(e.baseUrl), n = U(e);
123
+ return t + "/#" + n + "?" + B(e);
88
124
  }
89
- function N(e) {
125
+ function U(e) {
90
126
  const {
91
127
  chainId: t = 1,
92
128
  sell: n,
93
129
  buy: o,
94
- tradeType: r = m.SWAP
95
- } = e, i = [n?.asset || C, o?.asset || C].map(encodeURIComponent).join("/");
130
+ tradeType: r = I.SWAP
131
+ } = e, i = [n?.asset || v, o?.asset || v].map(encodeURIComponent).join("/");
96
132
  return `/${t}/widget/${r}/${i}`;
97
133
  }
98
- function v(e) {
134
+ function B(e) {
99
135
  const t = new URLSearchParams();
100
- return re(oe(ne(te(ee(t, e), e), e), e), e);
136
+ return ue(ce(le(de(ae(t, e), e), e), e), e);
101
137
  }
102
- function ee(e, t) {
138
+ function ae(e, t) {
103
139
  const {
104
140
  sell: n,
105
141
  buy: o
106
142
  } = t;
107
143
  return n?.amount && e.append("sellAmount", n.amount), o?.amount && e.append("buyAmount", o.amount), e;
108
144
  }
109
- function te(e, t) {
145
+ function de(e, t) {
110
146
  const n = t.theme;
111
- return n ? (Y(n) ? (e.append("palette", encodeURIComponent(JSON.stringify(n))), e.append("theme", n.baseTheme)) : (e.append("palette", "null"), e.append("theme", n)), e) : (e.append("palette", "null"), e);
147
+ return n ? (te(n) ? (e.append("palette", encodeURIComponent(JSON.stringify(n))), e.append("theme", n.baseTheme)) : (e.append("palette", "null"), e.append("theme", n)), e) : (e.append("palette", "null"), e);
112
148
  }
113
- function ne(e, t) {
149
+ function le(e, t) {
114
150
  return t.targetChainId && e.append("targetChainId", t.targetChainId.toString()), e;
115
151
  }
116
- function oe(e, t) {
152
+ function ce(e, t) {
117
153
  return t.locale && e.append("lng", t.locale), e;
118
154
  }
119
- function re(e, t) {
120
- return ie(t.hooks) ? e.append("hooksEnabled", "true") : e.delete("hooksEnabled"), e;
155
+ function ue(e, t) {
156
+ return pe(t.hooks) ? e.append("hooksEnabled", "true") : e.delete("hooksEnabled"), e;
121
157
  }
122
- function ie(e) {
158
+ function pe(e) {
123
159
  return !!e && Object.values(e).some(Boolean);
124
160
  }
125
- const U = "640px", se = "450px", ae = 20, de = {
161
+ const fe = 3e4, T = "coWWidgetContentReloadButton";
162
+ function Ee(e, t, n) {
163
+ const o = e.src;
164
+ let r = !1, i = !1, u;
165
+ function f() {
166
+ e.srcdoc = we, t?.();
167
+ }
168
+ function p() {
169
+ clearTimeout(u), u = setTimeout(() => {
170
+ r || i || f();
171
+ }, fe);
172
+ }
173
+ function s() {
174
+ r || i || (e.removeAttribute("srcdoc"), e.src = o, p());
175
+ }
176
+ function a() {
177
+ if (r) return;
178
+ const d = e.contentDocument, O = d?.querySelector(`.${T}`);
179
+ if (!(!d || !O) && (O.addEventListener("click", s), n)) {
180
+ const R = d.createElement("style");
181
+ R.textContent = n, d.head.appendChild(R);
182
+ }
183
+ }
184
+ return e.addEventListener("error", (d) => {
185
+ r || (console.error("Could not load iframe", d), f());
186
+ }), e.addEventListener("load", a), p(), {
187
+ cancelWidgetLoading() {
188
+ r = !0, clearTimeout(u), e.removeEventListener("load", a);
189
+ },
190
+ onWidgetReady() {
191
+ i = !0, clearTimeout(u);
192
+ }
193
+ };
194
+ }
195
+ const we = `<!DOCTYPE html>
196
+ <html lang="en">
197
+ <head>
198
+ <style>
199
+ html, body { margin: 0; padding: 0; width: 100%; height: 100%; }
200
+ .errorContent {
201
+ display: flex;
202
+ flex-direction: column;
203
+ gap: 16px;
204
+ align-items: center;
205
+ justify-content: center;
206
+ text-align: center;
207
+
208
+ width: 100%;
209
+ height: 100%;
210
+
211
+ padding: 24px;
212
+ box-sizing: border-box;
213
+
214
+ background: #fff5f5;
215
+ color: #d32f2f;
216
+
217
+ border: 1px solid #f5c2c7;
218
+ border-radius: 12px;
219
+
220
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
221
+ font-size: 14px;
222
+ line-height: 1.5;
223
+ font-weight: 500;
224
+ }
225
+ .${T} {
226
+ padding: 8px 24px;
227
+ border: 1px solid #d32f2f;
228
+ border-radius: 8px;
229
+ background: transparent;
230
+ color: #d32f2f;
231
+ font: inherit;
232
+ cursor: pointer;
233
+ }
234
+ .${T}:hover {
235
+ background: #d32f2f;
236
+ color: #fff5f5;
237
+ }
238
+ </style>
239
+ </head>
240
+ <body>
241
+ <div class="errorContent">
242
+ <span>Couldn't load the widget. Please try again later.</span>
243
+
244
+ <button class="${T}">Retry</button>
245
+ </div>
246
+ </body>
247
+ </html>`, F = "640px", _e = "450px", Oe = 20, Re = {
126
248
  iframe: null,
127
249
  updateParams: () => {
128
250
  },
@@ -133,112 +255,118 @@ const U = "640px", se = "450px", ae = 20, de = {
133
255
  destroy: () => {
134
256
  }
135
257
  };
136
- function Le(e, t) {
258
+ function ye(e, t) {
137
259
  const {
138
260
  params: n,
139
261
  provider: o,
140
262
  listeners: r,
141
- onReady: i
263
+ onReady: i,
264
+ enableSafeSdkBridge: u = !0
142
265
  } = t;
143
- let l = o, E = n;
144
- if (typeof window > "u") return de;
145
- const c = ce(n), s = le(c);
146
- K("Resolved trusted iframe origin", {
147
- iframeOrigin: s
266
+ let f = o, p = n;
267
+ if (typeof window > "u") return Re;
268
+ const s = he(n), a = ge(s);
269
+ ee("Resolved trusted iframe origin", {
270
+ iframeOrigin: a
148
271
  });
149
- const f = [];
150
- e.innerHTML = "", e.appendChild(c);
272
+ const d = [];
273
+ e.innerHTML = "", e.appendChild(s);
151
274
  const {
152
- contentWindow: a
153
- } = c;
154
- if (!a)
155
- throw console.error("Iframe does not contain a window", c), new Error("Iframe does not contain a window!");
156
- i && f.push(pe(a, s, i)), f.push(ue(a, s, n.appCode)), f.push(..._e(c, s, n.height, n.maxHeight));
157
- let _ = null;
158
- function g() {
159
- a && (_ && window.removeEventListener("message", _), !E.disableWindowOpen && (_ = Ee(s, a), f.push(_)));
275
+ cancelWidgetLoading: O,
276
+ onWidgetReady: R
277
+ } = Ee(s, t.onLoadingError, t.loadingErrorStyles), {
278
+ contentWindow: l
279
+ } = s;
280
+ if (!l)
281
+ throw console.error("Iframe does not contain a window", s), new Error("Iframe does not contain a window!");
282
+ d.push(me(l, a, () => {
283
+ i?.(), R();
284
+ })), d.push(Te(l, a, n.appCode)), d.push(...Pe(s, a, n.height, n.maxHeight));
285
+ let h = null;
286
+ function S() {
287
+ l && (h && window.removeEventListener("message", h), !p.disableWindowOpen && (h = Le(a, l), d.push(h)));
160
288
  }
161
- let O = null;
162
- function L() {
163
- a && (O && window.removeEventListener("message", O), O = Te(a, s, E.hooks), f.push(O));
289
+ let g = null;
290
+ function W() {
291
+ l && (g && window.removeEventListener("message", g), g = Se(l, a, p.hooks), d.push(g));
164
292
  }
165
- g(), L();
166
- const I = new k(window, s, a, r);
167
- let A = D(a, s, null, l);
168
- c.addEventListener("load", () => {
169
- W(a, s, E, l);
293
+ S(), W();
294
+ const D = new Y(window, a, l, r);
295
+ let P = b(l, a, null, f);
296
+ s.addEventListener("load", () => {
297
+ N(l, a, p, f);
170
298
  });
171
- const H = new $(window, a);
299
+ const H = u ? new z(window, l) : null;
172
300
  return {
173
- iframe: c,
174
- updateParams: (u) => {
175
- E = u, W(a, s, E, l), g(), L();
301
+ iframe: s,
302
+ updateParams: (E) => {
303
+ p = E, N(l, a, p, f), S(), W();
176
304
  },
177
- updateListeners: (u) => I.updateListeners(u),
178
- updateProvider: (u) => {
179
- l = u, A = D(a, s, A, u);
305
+ updateListeners: (E) => D.updateListeners(E),
306
+ updateProvider: (E) => {
307
+ f = E, P = b(l, a, P, E);
180
308
  },
181
309
  destroy: () => {
182
- A.disconnect(), I.stopListeningIframe(), f.forEach((u) => window.removeEventListener("message", u)), H.stopListening(), e.removeChild(c);
310
+ P.disconnect(), D.stopListeningIframe(), d.forEach((E) => window.removeEventListener("message", E)), H?.stopListening(), s && s.parentNode === e && e.removeChild(s), O();
183
311
  }
184
312
  };
185
313
  }
186
- function D(e, t, n, o) {
314
+ function b(e, t, n, o) {
187
315
  n && n.disconnect();
188
- const r = n || new F(e, t);
316
+ const r = n || new x(e, t);
189
317
  return o && r.onConnect(o), r;
190
318
  }
191
- function ce(e) {
319
+ function he(e) {
192
320
  const {
193
- width: t = se,
194
- height: n = U
321
+ width: t = _e,
322
+ height: n = F
195
323
  } = e, o = document.createElement("iframe");
196
- return o.src = q(e), o.width = t, o.height = n, o.style.border = "0", o.setAttribute("sandbox", B), o.referrerPolicy = M, o.allow = V, o;
324
+ return o.src = se(e), o.width = t, o.height = n, o.style.border = "0", o.setAttribute("sandbox", j), o.referrerPolicy = K, o.allow = Q, o;
197
325
  }
198
- function le(e) {
326
+ function ge(e) {
199
327
  return new URL(e.src).origin;
200
328
  }
201
- function W(e, t, n, o) {
202
- const r = !!o, i = N(n), l = v(n).toString(), {
203
- theme: E,
204
- hooks: c,
329
+ function N(e, t, n, o) {
330
+ const r = !!o, i = U(n), u = B(n).toString(), {
331
+ theme: f,
332
+ hooks: p,
205
333
  ...s
206
334
  } = n;
207
- d.postMessageToWindow(e, h.UPDATE_PARAMS, {
335
+ c.postMessageToWindow(e, A.UPDATE_PARAMS, {
208
336
  urlParams: {
209
337
  pathname: i,
210
- search: l
338
+ search: u
211
339
  },
212
340
  appParams: s,
213
341
  hasProvider: r
214
342
  }, t);
215
343
  }
216
- function ue(e, t, n) {
217
- return d.listenToMessageFromWindow(window, e, p.ACTIVATE, () => {
218
- d.postMessageToWindow(e, h.UPDATE_APP_DATA, {
344
+ function Te(e, t, n) {
345
+ return c.listenToMessageFromWindow(window, e, w.ACTIVATE, () => {
346
+ c.postMessageToWindow(e, A.UPDATE_APP_DATA, {
219
347
  metaData: n ? {
220
348
  appCode: n
221
349
  } : void 0
222
350
  }, t);
223
351
  }, t);
224
352
  }
225
- function pe(e, t, n) {
353
+ function me(e, t, n) {
226
354
  let o = !1;
227
- return d.listenToMessageFromWindow(window, e, p.READY, () => {
355
+ return c.listenToMessageFromWindow(window, e, w.READY, () => {
228
356
  o || (o = !0, n());
229
357
  }, t);
230
358
  }
231
- function Ee(e, t) {
232
- return d.listenToMessageFromWindow(window, t, p.INTERCEPT_WINDOW_OPEN, ({
359
+ function Le(e, t) {
360
+ return c.listenToMessageFromWindow(window, t, w.INTERCEPT_WINDOW_OPEN, ({
233
361
  href: n,
234
362
  rel: o,
235
363
  target: r
236
364
  }) => {
237
- const i = fe(n.toString(), e);
238
- i && we(i) && window.open(i, r, o);
365
+ const i = Ae(n.toString(), e);
366
+ i && G(i) && window.open(i, r, o);
239
367
  }, e);
240
368
  }
241
- function fe(e, t) {
369
+ function Ae(e, t) {
242
370
  const n = e.trim();
243
371
  if (!n)
244
372
  return null;
@@ -248,85 +376,77 @@ function fe(e, t) {
248
376
  return null;
249
377
  }
250
378
  }
251
- function we(e) {
252
- try {
253
- const t = new URL(e).protocol;
254
- return t === "http:" || t === "https:";
255
- } catch {
256
- return !1;
257
- }
258
- }
259
- function _e(e, t, n = U, o) {
260
- return e.contentWindow ? [d.listenToMessageFromWindow(window, e.contentWindow, p.UPDATE_HEIGHT, (r) => {
261
- const i = r.height ? r.height + ae : void 0;
379
+ function Pe(e, t, n = F, o) {
380
+ return e.contentWindow ? [c.listenToMessageFromWindow(window, e.contentWindow, w.UPDATE_HEIGHT, (r) => {
381
+ const i = r.height ? r.height + Oe : void 0;
262
382
  e.style.height = i ? `${o ? Math.min(i, o) : i}px` : n;
263
- }, t), d.listenToMessageFromWindow(window, e.contentWindow, p.SET_FULL_HEIGHT, ({
383
+ }, t), c.listenToMessageFromWindow(window, e.contentWindow, w.SET_FULL_HEIGHT, ({
264
384
  isUpToSmall: r
265
385
  }) => {
266
386
  e.style.height = r ? n : `${o || document.body.offsetHeight}px`;
267
387
  }, t)] : [];
268
388
  }
269
- const Oe = {
270
- [w.ON_BEFORE_APPROVAL]: (e, t) => t?.onBeforeApproval ? t.onBeforeApproval(e) : !0,
271
- [w.ON_BEFORE_TRADE]: (e, t) => t?.onBeforeTrade ? t.onBeforeTrade(e) : !0,
272
- [w.ON_BEFORE_WRAP_UNWRAP]: (e, t) => t?.onBeforeWrapOrUnwrap ? t.onBeforeWrapOrUnwrap(e) : !0,
273
- [w.ON_BEFORE_ORDER_CANCEL]: (e, t) => t?.onBeforeOrderCancel ? t.onBeforeOrderCancel(e) : !0,
274
- [w.ON_BEFORE_ORDERS_CANCEL]: (e, t) => t?.onBeforeOrdersCancel ? t.onBeforeOrdersCancel(e) : !0
389
+ const Ce = {
390
+ [_.ON_BEFORE_APPROVAL]: (e, t) => t?.onBeforeApproval ? t.onBeforeApproval(e) : !0,
391
+ [_.ON_BEFORE_TRADE]: (e, t) => t?.onBeforeTrade ? t.onBeforeTrade(e) : !0,
392
+ [_.ON_BEFORE_WRAP_UNWRAP]: (e, t) => t?.onBeforeWrapOrUnwrap ? t.onBeforeWrapOrUnwrap(e) : !0,
393
+ [_.ON_BEFORE_ORDER_CANCEL]: (e, t) => t?.onBeforeOrderCancel ? t.onBeforeOrderCancel(e) : !0,
394
+ [_.ON_BEFORE_ORDERS_CANCEL]: (e, t) => t?.onBeforeOrdersCancel ? t.onBeforeOrdersCancel(e) : !0
275
395
  };
276
- function Re(e, t) {
277
- return Oe[e.event](e.payload, t);
396
+ function Ie(e, t) {
397
+ return Ce[e.event](e.payload, t);
278
398
  }
279
- function Te(e, t, n) {
280
- return d.listenToMessageFromWindow(window, e, p.PROCESS_HOOK, async (o) => {
399
+ function Se(e, t, n) {
400
+ return c.listenToMessageFromWindow(window, e, w.PROCESS_HOOK, async (o) => {
281
401
  let r = !1;
282
402
  try {
283
- r = await Re(o, n);
403
+ r = await Ie(o, n);
284
404
  } catch {
285
405
  }
286
- d.postMessageToWindow(e, h.HOOK_RESULT, {
406
+ c.postMessageToWindow(e, A.HOOK_RESULT, {
287
407
  id: o.id,
288
408
  result: r
289
409
  }, t);
290
410
  }, t);
291
411
  }
292
- const he = Object.values(m);
293
- function Ie(e, t, n) {
294
- if (R(e)) {
412
+ const We = Object.values(I);
413
+ function Ue(e, t, n) {
414
+ if (m(e)) {
295
415
  const o = e[n];
296
- return T(o) ? o[t] : o;
416
+ return L(o) ? o[t] : o;
297
417
  }
298
- if (T(e)) {
418
+ if (L(e)) {
299
419
  const o = e[t];
300
- return R(o) ? o[n] : o;
420
+ return m(o) ? o[n] : o;
301
421
  }
302
422
  return e;
303
423
  }
304
- function R(e) {
305
- return typeof e != "object" ? !1 : Object.keys(e).every((t) => he.includes(t));
424
+ function m(e) {
425
+ return typeof e != "object" ? !1 : Object.keys(e).every((t) => We.includes(t));
306
426
  }
307
- const Ae = /^\d+$/;
308
- function T(e) {
309
- return typeof e != "object" ? !1 : Object.keys(e).every((t) => Ae.test(t));
427
+ const De = /^\d+$/;
428
+ function L(e) {
429
+ return typeof e != "object" ? !1 : Object.keys(e).every((t) => De.test(t));
310
430
  }
311
- function Ce(e) {
312
- return R(e) ? Object.values(e).flatMap((t) => T(t) ? Object.values(t) : [t]) : T(e) ? Object.values(e).flatMap((t) => R(t) ? Object.values(t) : [t]) : [e];
431
+ function Be(e) {
432
+ return m(e) ? Object.values(e).flatMap((t) => L(t) ? Object.values(t) : [t]) : L(e) ? Object.values(e).flatMap((t) => m(t) ? Object.values(t) : [t]) : [e];
313
433
  }
314
434
  export {
315
- J as SHOULD_THROW_IF_INVALID_URL,
316
- m as TradeType,
317
- V as WIDGET_IFRAME_ALLOW,
318
- M as WIDGET_IFRAME_REFERRER_POLICY,
319
- B as WIDGET_IFRAME_SANDBOX,
320
- ge as WIDGET_PALETTE_COLORS,
321
- w as WidgetHookEvents,
322
- p as WidgetMethodsEmit,
323
- h as WidgetMethodsListen,
324
- Le as createCowSwapWidget,
325
- Y as isCowSwapWidgetPalette,
326
- T as isPerNetworkConfig,
327
- R as isPerTradeTypeConfig,
328
- Ie as resolveFlexibleConfig,
329
- Ce as resolveFlexibleConfigValues,
330
- Z as sanitizeWidgetBaseUrl,
331
- d as widgetIframeTransport
435
+ oe as SHOULD_THROW_IF_INVALID_URL,
436
+ I as TradeType,
437
+ Q as WIDGET_IFRAME_ALLOW,
438
+ K as WIDGET_IFRAME_REFERRER_POLICY,
439
+ j as WIDGET_IFRAME_SANDBOX,
440
+ Ne as WIDGET_PALETTE_COLORS,
441
+ _ as WidgetHookEvents,
442
+ w as WidgetMethodsEmit,
443
+ A as WidgetMethodsListen,
444
+ ye as createCowSwapWidget,
445
+ te as isCowSwapWidgetPalette,
446
+ L as isPerNetworkConfig,
447
+ m as isPerTradeTypeConfig,
448
+ Ue as resolveFlexibleConfig,
449
+ Be as resolveFlexibleConfigValues,
450
+ ie as sanitizeWidgetBaseUrl,
451
+ c as widgetIframeTransport
332
452
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cowprotocol/widget-lib",
3
- "version": "4.0.5",
3
+ "version": "4.2.0",
4
4
  "description": "CoW Swap Widget Library. Allows you to easily embed a CoW Swap widget on your website.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -15,9 +15,9 @@
15
15
  "access": "public"
16
16
  },
17
17
  "dependencies": {
18
- "@cowprotocol/cow-sdk": "9.1.1",
19
- "@cowprotocol/events": "^4.4.1",
20
- "@cowprotocol/iframe-transport": "^2.2.6"
18
+ "@cowprotocol/cow-sdk": "9.1.2",
19
+ "@cowprotocol/events": "^4.6.0",
20
+ "@cowprotocol/iframe-transport": "^2.3.0"
21
21
  },
22
22
  "exports": {
23
23
  ".": {
package/types.d.ts CHANGED
@@ -75,6 +75,13 @@ export interface CowSwapWidgetProps {
75
75
  provider?: EthereumProvider;
76
76
  listeners?: CowWidgetEventListeners;
77
77
  onReady?(): void;
78
+ onLoadingError?(): void;
79
+ /**
80
+ * Custom CSS appended to the error document displayed inside the iframe when the widget fails to load.
81
+ * Use it to override the default look (`.errorContent` and `.reloadButton` classes).
82
+ */
83
+ loadingErrorStyles?: string;
84
+ enableSafeSdkBridge?: boolean;
78
85
  }
79
86
  export interface JsonRpcRequest {
80
87
  id: number;
@@ -304,11 +311,33 @@ export interface CowSwapWidgetParams {
304
311
  * Defaults to false.
305
312
  */
306
313
  disableCrossChainSwap?: boolean;
314
+ /**
315
+ * Disable setting custom recipient for all trading widgets (swap,limit,twap)
316
+ * Important! Cross-chain swaps are based on custom recipient functionality!
317
+ * If you want always having recipient === order owner, then set disableCrossChainSwap=true as well
318
+ */
319
+ disableCustomRecipient?: boolean;
307
320
  /**
308
321
  * Disables adding custom tokens and custom token lists.
309
322
  * Defaults to false.
310
323
  */
311
324
  disableTokenImport?: boolean;
325
+ /**
326
+ * Disables the EIP-2612 permit signing flow. When `true`, the widget will
327
+ * never sign an off-chain permit and will always send an on-chain approval
328
+ * transaction — even for tokens that support permit.
329
+ *
330
+ * Defaults to false.
331
+ */
332
+ disableEIP2612Permits?: boolean;
333
+ /**
334
+ * Disables infinite (MAX_UINT256) ERC-20 approvals. When `true`, every
335
+ * approval transaction approves only the exact trade-size amount, and the
336
+ * "Partial approval" toggle in Settings is shown but locked on.
337
+ *
338
+ * Defaults to false.
339
+ */
340
+ disableInfiniteApprove?: boolean;
312
341
  /**
313
342
  * Disables showing the confirmation modal you get after posting an order.
314
343
  * Defaults to false.
@@ -0,0 +1,6 @@
1
+ type IframeLoadingState = {
2
+ cancelWidgetLoading: () => void;
3
+ onWidgetReady: () => void;
4
+ };
5
+ export declare function widgetIframeLoading(iframe: HTMLIFrameElement, onWidgetLoadingError?: () => void, customErrorStyles?: string): IframeLoadingState;
6
+ export {};