@cowprotocol/widget-lib 2.0.2 → 2.1.1

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.
@@ -12,7 +12,7 @@ export interface CowSwapWidgetHandler {
12
12
  /**
13
13
  * Generates and injects a CoW Swap Widget into the provided container.
14
14
  * @param container - The HTML element to inject the widget into.
15
- * @param params - Parameters for configuring the widget.
15
+ * @param props - Parameters for configuring the widget.
16
16
  * @returns A callback function to update the widget with new settings.
17
17
  */
18
18
  export declare function createCowSwapWidget(container: HTMLElement, props: CowSwapWidgetProps): CowSwapWidgetHandler;
package/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const I=require("@cowprotocol/iframe-transport"),W=require("@cowprotocol/events");var c=(e=>(e.ACTIVATE="ACTIVATE",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))(c||{}),E=(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))(E||{}),T=(e=>(e.SWAP="swap",e.LIMIT="limit",e.ADVANCED="advanced",e.YIELD="yield",e))(T||{});const O=["primary","background","paper","text","danger","warning","alert","info","success"],r=new I.IframeTransport("cowSwapWidget");class R{constructor(t,i=[]){this.contentWindow=t,this.updateListeners(i),this.widgetListener=r.listenToMessageFromWindow(this.contentWindow,c.EMIT_COW_EVENT,n=>this.eventEmitter.emit(n.event,n.payload))}eventEmitter=new W.SimpleCowEventEmitter;listeners=[];widgetListener;stopListeningIframe(){r.stopListeningWindowListener(this.contentWindow,this.widgetListener)}updateListeners(t){for(const i of this.listeners)this.eventEmitter.off(i);this.listeners=t||[];for(const i of this.listeners)this.eventEmitter.on(i)}}class D{constructor(t,i){this.appWindow=t,this.iframeWidow=i,this.forwardSdkMessage=n=>{b(n.data)&&(typeof window<"u"&&n.origin===window.location.origin||(y(n.data)?this.appWindow.parent.postMessage(n.data,"*"):M(n.data)&&this.iframeWidow.postMessage(n.data,"*")))},this.startListening()}forwardSdkMessage;startListening(){this.appWindow.addEventListener("message",this.forwardSdkMessage)}stopListening(){this.appWindow.removeEventListener("message",this.forwardSdkMessage)}}function b(e){return typeof e=="object"&&e!==null&&"id"in e&&typeof e.id=="string"}function y(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 M(e){return"success"in e&&typeof e.success=="boolean"&&"version"in e&&typeof e.version=="string"}function A(e){return!!(e&&typeof e=="object")}const g="_";function N(e){const t=typeof e.baseUrl=="string"?e.baseUrl:"https://swap.cow.fi",i=v(e);return t+"/#"+i+"?"+C(e)}function v(e){const{chainId:t=1,sell:i,buy:n,tradeType:o=T.SWAP}=e,s=[i?.asset||g,n?.asset||g].map(encodeURIComponent).join("/");return`/${t}/widget/${o}/${s}`}function C(e){const t=new URLSearchParams;return V(H(U(t,e),e),e)}function U(e,t){const{sell:i,buy:n}=t;return i?.amount&&e.append("sellAmount",i.amount),n?.amount&&e.append("buyAmount",n.amount),e}function H(e,t){const i=t.theme;return i?(A(i)?(e.append("palette",encodeURIComponent(JSON.stringify(i))),e.append("theme",i.baseTheme)):(e.append("palette","null"),e.append("theme",i)),e):(e.append("palette","null"),e)}function V(e,t){return t.targetChainId&&e.append("targetChainId",t.targetChainId.toString()),e}const S="640px",F="450px",k=20,j={updateParams:()=>{},updateListeners:()=>{},updateProvider:()=>{},destroy:()=>{}};function G(e,t){const{params:i,provider:n,listeners:o}=t;let s=n,l=i;if(typeof window>"u")return j;const a=x(i);e.innerHTML="",e.appendChild(a);const{contentWindow:u}=a;if(!u)throw console.error("Iframe does not contain a window",a),new Error("Iframe does not contain a window!");const w=[];w.push(Q(u,i.appCode)),w.push(...B(a,i.height,i.maxHeight)),w.push($());const P=new R(window,o);let h=m(u,null,s);a.addEventListener("load",()=>_(u,l,s));const L=new D(window,u);return{updateParams:d=>{l=d,_(u,l,s)},updateListeners:d=>P.updateListeners(d),updateProvider:d=>{s=d,h=m(u,h,d)},destroy:()=>{h.disconnect(),P.stopListeningIframe(),w.forEach(d=>window.removeEventListener("message",d)),L.stopListening(),e.removeChild(a)}}}function m(e,t,i){t&&t.disconnect();const n=t||new I.IframeRpcProviderBridge(e);return i&&n.onConnect(i),n}function x(e){const{width:t=F,height:i=S}=e,n=document.createElement("iframe");return n.src=N(e),n.width=t,n.height=i,n.style.border="0",n.allow="clipboard-read; clipboard-write",n}function _(e,t,i){const n=!!i,o=v(t),s=C(t).toString(),{theme:l,...a}=t;r.postMessageToWindow(e,E.UPDATE_PARAMS,{urlParams:{pathname:o,search:s},appParams:a,hasProvider:n})}function Q(e,t){return r.listenToMessageFromWindow(window,c.ACTIVATE,()=>{r.postMessageToWindow(e,E.UPDATE_APP_DATA,{metaData:t?{appCode:t}:void 0})})}function $(){return r.listenToMessageFromWindow(window,c.INTERCEPT_WINDOW_OPEN,({href:e,rel:t,target:i})=>{const n=e.toString();if(!n.startsWith("http")&&n.match(/^[a-zA-Z0-9]+:\/\//)){window.open(n,i,t);return}})}function B(e,t=S,i){return[r.listenToMessageFromWindow(window,c.UPDATE_HEIGHT,n=>{const o=n.height?n.height+k:void 0;e.style.height=o?`${i?Math.min(o,i):o}px`:t}),r.listenToMessageFromWindow(window,c.SET_FULL_HEIGHT,({isUpToSmall:n})=>{e.style.height=n?t:`${i||document.body.offsetHeight}px`})]}const Y=Object.values(T);function z(e,t,i){if(p(e)){const n=e[i];return f(n)?n[t]:n}if(f(e)){const n=e[t];return p(n)?n[i]:n}return e}function p(e){return typeof e!="object"?!1:Object.keys(e).every(t=>Y.includes(t))}const J=/^\d+$/;function f(e){return typeof e!="object"?!1:Object.keys(e).every(t=>J.test(t))}function K(e){return p(e)?Object.values(e).flatMap(t=>f(t)?Object.values(t):[t]):f(e)?Object.values(e).flatMap(t=>p(t)?Object.values(t):[t]):[e]}exports.TradeType=T;exports.WIDGET_PALETTE_COLORS=O;exports.WidgetMethodsEmit=c;exports.WidgetMethodsListen=E;exports.createCowSwapWidget=G;exports.isCowSwapWidgetPalette=A;exports.isPerNetworkConfig=f;exports.isPerTradeTypeConfig=p;exports.resolveFlexibleConfig=z;exports.resolveFlexibleConfigValues=K;exports.widgetIframeTransport=r;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const m=require("@cowprotocol/iframe-transport"),W=require("@cowprotocol/events");var E=(e=>(e.ACTIVATE="ACTIVATE",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))(E||{}),w=(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))(w||{}),c=(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))(c||{}),T=(e=>(e.SWAP="swap",e.LIMIT="limit",e.ADVANCED="advanced",e.YIELD="yield",e))(T||{});const D=["primary","background","paper","text","danger","warning","alert","info","success"],i=new m.IframeTransport("cowSwapWidget");class H{constructor(t,o=[]){this.contentWindow=t,this.updateListeners(o),this.widgetListener=i.listenToMessageFromWindow(this.contentWindow,E.EMIT_COW_EVENT,n=>this.eventEmitter.emit(n.event,n.payload))}eventEmitter=new W.SimpleCowEventEmitter;listeners=[];widgetListener;stopListeningIframe(){i.stopListeningWindowListener(this.contentWindow,this.widgetListener)}updateListeners(t){for(const o of this.listeners)this.eventEmitter.off(o);this.listeners=t||[];for(const o of this.listeners)this.eventEmitter.on(o)}}class b{constructor(t,o){this.appWindow=t,this.iframeWidow=o,this.forwardSdkMessage=n=>{y(n.data)&&(typeof window<"u"&&n.origin===window.location.origin||(F(n.data)?this.appWindow.parent.postMessage(n.data,"*"):U(n.data)&&this.iframeWidow.postMessage(n.data,"*")))},this.startListening()}forwardSdkMessage;startListening(){this.appWindow.addEventListener("message",this.forwardSdkMessage)}stopListening(){this.appWindow.removeEventListener("message",this.forwardSdkMessage)}}function y(e){return typeof e=="object"&&e!==null&&"id"in e&&typeof e.id=="string"}function F(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 U(e){return"success"in e&&typeof e.success=="boolean"&&"version"in e&&typeof e.version=="string"}function S(e){return!!(e&&typeof e=="object")}const A="_";function B(e){const t=typeof e.baseUrl=="string"?e.baseUrl:"https://swap.cow.fi",o=L(e);return t+"/#"+o+"?"+I(e)}function L(e){const{chainId:t=1,sell:o,buy:n,tradeType:s=T.SWAP}=e,a=[o?.asset||A,n?.asset||A].map(encodeURIComponent).join("/");return`/${t}/widget/${s}/${a}`}function I(e){const t=new URLSearchParams;return G(j(k(V(M(t,e),e),e),e),e)}function M(e,t){const{sell:o,buy:n}=t;return o?.amount&&e.append("sellAmount",o.amount),n?.amount&&e.append("buyAmount",n.amount),e}function V(e,t){const o=t.theme;return o?(S(o)?(e.append("palette",encodeURIComponent(JSON.stringify(o))),e.append("theme",o.baseTheme)):(e.append("palette","null"),e.append("theme",o)),e):(e.append("palette","null"),e)}function k(e,t){return t.targetChainId&&e.append("targetChainId",t.targetChainId.toString()),e}function j(e,t){return t.locale&&e.append("lng",t.locale),e}function G(e,t){return x(t.hooks)&&e.append("hooksEnabled","true"),e}function x(e){return!!e&&Object.values(e).some(Boolean)}const v="640px",Q="450px",K=20,$={updateParams:()=>{},updateListeners:()=>{},updateProvider:()=>{},destroy:()=>{}};function Y(e,t){const{params:o,provider:n,listeners:s}=t;let a=n,l=o;if(typeof window>"u")return $;const u=z(o);e.innerHTML="",e.appendChild(u);const{contentWindow:r}=u;if(!r)throw console.error("Iframe does not contain a window",u),new Error("Iframe does not contain a window!");const p=[];p.push(J(r,o.appCode)),p.push(...Z(u,o.height,o.maxHeight)),p.push(X());let O=null;function P(){r&&(O&&window.removeEventListener("message",O),O=te(r,l.hooks),p.push(O))}P();const h=new H(window,s);let R=C(r,null,a);u.addEventListener("load",()=>{g(r,l,a)});const N=new b(window,r);return{updateParams:d=>{l=d,g(r,l,a),P()},updateListeners:d=>h.updateListeners(d),updateProvider:d=>{a=d,R=C(r,R,d)},destroy:()=>{R.disconnect(),h.stopListeningIframe(),p.forEach(d=>window.removeEventListener("message",d)),N.stopListening(),e.removeChild(u)}}}function C(e,t,o){t&&t.disconnect();const n=t||new m.IframeRpcProviderBridge(e);return o&&n.onConnect(o),n}function z(e){const{width:t=Q,height:o=v}=e,n=document.createElement("iframe");return n.src=B(e),n.width=t,n.height=o,n.style.border="0",n.allow="clipboard-read; clipboard-write",n}function g(e,t,o){const n=!!o,s=L(t),a=I(t).toString(),{theme:l,hooks:u,...r}=t;i.postMessageToWindow(e,w.UPDATE_PARAMS,{urlParams:{pathname:s,search:a},appParams:r,hasProvider:n})}function J(e,t){return i.listenToMessageFromWindow(window,E.ACTIVATE,()=>{i.postMessageToWindow(e,w.UPDATE_APP_DATA,{metaData:t?{appCode:t}:void 0})})}function X(){return i.listenToMessageFromWindow(window,E.INTERCEPT_WINDOW_OPEN,({href:e,rel:t,target:o})=>{const n=e.toString();if(!n.startsWith("http")&&n.match(/^[a-zA-Z0-9]+:\/\//)){window.open(n,o,t);return}})}function Z(e,t=v,o){return[i.listenToMessageFromWindow(window,E.UPDATE_HEIGHT,n=>{const s=n.height?n.height+K:void 0;e.style.height=s?`${o?Math.min(s,o):s}px`:t}),i.listenToMessageFromWindow(window,E.SET_FULL_HEIGHT,({isUpToSmall:n})=>{e.style.height=n?t:`${o||document.body.offsetHeight}px`})]}const q={[c.ON_BEFORE_APPROVAL]:(e,t)=>t?.onBeforeApproval?t.onBeforeApproval(e):!0,[c.ON_BEFORE_TRADE]:(e,t)=>t?.onBeforeTrade?t.onBeforeTrade(e):!0,[c.ON_BEFORE_WRAP_UNWRAP]:(e,t)=>t?.onBeforeWrapOrUnwrap?t.onBeforeWrapOrUnwrap(e):!0,[c.ON_BEFORE_ORDER_CANCEL]:(e,t)=>t?.onBeforeOrderCancel?t.onBeforeOrderCancel(e):!0,[c.ON_BEFORE_ORDERS_CANCEL]:(e,t)=>t?.onBeforeOrdersCancel?t.onBeforeOrdersCancel(e):!0};function ee(e,t){return q[e.event](e.payload,t)}function te(e,t){return i.listenToMessageFromWindow(window,E.PROCESS_HOOK,async o=>{let n=!1;try{n=await ee(o,t)}catch{}i.postMessageToWindow(e,w.HOOK_RESULT,{id:o.id,result:n})})}const ne=Object.values(T);function oe(e,t,o){if(f(e)){const n=e[o];return _(n)?n[t]:n}if(_(e)){const n=e[t];return f(n)?n[o]:n}return e}function f(e){return typeof e!="object"?!1:Object.keys(e).every(t=>ne.includes(t))}const re=/^\d+$/;function _(e){return typeof e!="object"?!1:Object.keys(e).every(t=>re.test(t))}function ie(e){return f(e)?Object.values(e).flatMap(t=>_(t)?Object.values(t):[t]):_(e)?Object.values(e).flatMap(t=>f(t)?Object.values(t):[t]):[e]}exports.TradeType=T;exports.WIDGET_PALETTE_COLORS=D;exports.WidgetHookEvents=c;exports.WidgetMethodsEmit=E;exports.WidgetMethodsListen=w;exports.createCowSwapWidget=Y;exports.isCowSwapWidgetPalette=S;exports.isPerNetworkConfig=_;exports.isPerTradeTypeConfig=f;exports.resolveFlexibleConfig=oe;exports.resolveFlexibleConfigValues=ie;exports.widgetIframeTransport=i;
package/index.js CHANGED
@@ -1,29 +1,29 @@
1
- import { IframeTransport as C, IframeRpcProviderBridge as L } from "@cowprotocol/iframe-transport";
2
- import { SimpleCowEventEmitter as R } from "@cowprotocol/events";
3
- var u = /* @__PURE__ */ ((e) => (e.ACTIVATE = "ACTIVATE", 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))(u || {}), T = /* @__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))(T || {}), h = /* @__PURE__ */ ((e) => (e.SWAP = "swap", e.LIMIT = "limit", e.ADVANCED = "advanced", e.YIELD = "yield", e))(h || {});
4
- const K = ["primary", "background", "paper", "text", "danger", "warning", "alert", "info", "success"], d = new C("cowSwapWidget");
5
- class D {
6
- constructor(t, i = []) {
7
- this.contentWindow = t, this.updateListeners(i), this.widgetListener = d.listenToMessageFromWindow(this.contentWindow, u.EMIT_COW_EVENT, (n) => this.eventEmitter.emit(n.event, n.payload));
1
+ import { IframeTransport as N, IframeRpcProviderBridge as v } from "@cowprotocol/iframe-transport";
2
+ import { SimpleCowEventEmitter as D } from "@cowprotocol/events";
3
+ var u = /* @__PURE__ */ ((e) => (e.ACTIVATE = "ACTIVATE", 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))(u || {}), w = /* @__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))(w || {}), c = /* @__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))(c || {}), R = /* @__PURE__ */ ((e) => (e.SWAP = "swap", e.LIMIT = "limit", e.ADVANCED = "advanced", e.YIELD = "yield", e))(R || {});
4
+ const ie = ["primary", "background", "paper", "text", "danger", "warning", "alert", "info", "success"], i = new N("cowSwapWidget");
5
+ class W {
6
+ constructor(t, o = []) {
7
+ this.contentWindow = t, this.updateListeners(o), this.widgetListener = i.listenToMessageFromWindow(this.contentWindow, u.EMIT_COW_EVENT, (n) => this.eventEmitter.emit(n.event, n.payload));
8
8
  }
9
- eventEmitter = new R();
9
+ eventEmitter = new D();
10
10
  listeners = [];
11
11
  widgetListener;
12
12
  stopListeningIframe() {
13
- d.stopListeningWindowListener(this.contentWindow, this.widgetListener);
13
+ i.stopListeningWindowListener(this.contentWindow, this.widgetListener);
14
14
  }
15
15
  updateListeners(t) {
16
- for (const i of this.listeners)
17
- this.eventEmitter.off(i);
16
+ for (const o of this.listeners)
17
+ this.eventEmitter.off(o);
18
18
  this.listeners = t || [];
19
- for (const i of this.listeners)
20
- this.eventEmitter.on(i);
19
+ for (const o of this.listeners)
20
+ this.eventEmitter.on(o);
21
21
  }
22
22
  }
23
- class O {
24
- constructor(t, i) {
25
- this.appWindow = t, this.iframeWidow = i, this.forwardSdkMessage = (n) => {
26
- W(n.data) && (typeof window < "u" && n.origin === window.location.origin || (b(n.data) ? this.appWindow.parent.postMessage(n.data, "*") : y(n.data) && this.iframeWidow.postMessage(n.data, "*")));
23
+ class H {
24
+ constructor(t, o) {
25
+ this.appWindow = t, this.iframeWidow = o, this.forwardSdkMessage = (n) => {
26
+ U(n.data) && (typeof window < "u" && n.origin === window.location.origin || (B(n.data) ? this.appWindow.parent.postMessage(n.data, "*") : b(n.data) && this.iframeWidow.postMessage(n.data, "*")));
27
27
  }, this.startListening();
28
28
  }
29
29
  forwardSdkMessage;
@@ -34,51 +34,60 @@ class O {
34
34
  this.appWindow.removeEventListener("message", this.forwardSdkMessage);
35
35
  }
36
36
  }
37
- function W(e) {
37
+ function U(e) {
38
38
  return typeof e == "object" && e !== null && "id" in e && typeof e.id == "string";
39
39
  }
40
- function b(e) {
40
+ function B(e) {
41
41
  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;
42
42
  }
43
- function y(e) {
43
+ function b(e) {
44
44
  return "success" in e && typeof e.success == "boolean" && "version" in e && typeof e.version == "string";
45
45
  }
46
- function U(e) {
46
+ function F(e) {
47
47
  return !!(e && typeof e == "object");
48
48
  }
49
- const m = "_";
50
- function H(e) {
51
- const t = typeof e.baseUrl == "string" ? e.baseUrl : "https://swap.cow.fi", i = A(e);
52
- return t + "/#" + i + "?" + g(e);
49
+ const h = "_";
50
+ function y(e) {
51
+ const t = typeof e.baseUrl == "string" ? e.baseUrl : "https://swap.cow.fi", o = L(e);
52
+ return t + "/#" + o + "?" + S(e);
53
53
  }
54
- function A(e) {
54
+ function L(e) {
55
55
  const {
56
56
  chainId: t = 1,
57
- sell: i,
57
+ sell: o,
58
58
  buy: n,
59
- tradeType: o = h.SWAP
60
- } = e, r = [i?.asset || m, n?.asset || m].map(encodeURIComponent).join("/");
61
- return `/${t}/widget/${o}/${r}`;
59
+ tradeType: s = R.SWAP
60
+ } = e, a = [o?.asset || h, n?.asset || h].map(encodeURIComponent).join("/");
61
+ return `/${t}/widget/${s}/${a}`;
62
62
  }
63
- function g(e) {
63
+ function S(e) {
64
64
  const t = new URLSearchParams();
65
- return V(M(N(t, e), e), e);
65
+ return G(j(k(V(M(t, e), e), e), e), e);
66
66
  }
67
- function N(e, t) {
67
+ function M(e, t) {
68
68
  const {
69
- sell: i,
69
+ sell: o,
70
70
  buy: n
71
71
  } = t;
72
- return i?.amount && e.append("sellAmount", i.amount), n?.amount && e.append("buyAmount", n.amount), e;
73
- }
74
- function M(e, t) {
75
- const i = t.theme;
76
- return i ? (U(i) ? (e.append("palette", encodeURIComponent(JSON.stringify(i))), e.append("theme", i.baseTheme)) : (e.append("palette", "null"), e.append("theme", i)), e) : (e.append("palette", "null"), e);
72
+ return o?.amount && e.append("sellAmount", o.amount), n?.amount && e.append("buyAmount", n.amount), e;
77
73
  }
78
74
  function V(e, t) {
75
+ const o = t.theme;
76
+ return o ? (F(o) ? (e.append("palette", encodeURIComponent(JSON.stringify(o))), e.append("theme", o.baseTheme)) : (e.append("palette", "null"), e.append("theme", o)), e) : (e.append("palette", "null"), e);
77
+ }
78
+ function k(e, t) {
79
79
  return t.targetChainId && e.append("targetChainId", t.targetChainId.toString()), e;
80
80
  }
81
- const v = "640px", F = "450px", k = 20, j = {
81
+ function j(e, t) {
82
+ return t.locale && e.append("lng", t.locale), e;
83
+ }
84
+ function G(e, t) {
85
+ return x(t.hooks) && e.append("hooksEnabled", "true"), e;
86
+ }
87
+ function x(e) {
88
+ return !!e && Object.values(e).some(Boolean);
89
+ }
90
+ const I = "640px", Q = "450px", K = 20, $ = {
82
91
  updateParams: () => {
83
92
  },
84
93
  updateListeners: () => {
@@ -88,130 +97,162 @@ const v = "640px", F = "450px", k = 20, j = {
88
97
  destroy: () => {
89
98
  }
90
99
  };
91
- function X(e, t) {
100
+ function se(e, t) {
92
101
  const {
93
- params: i,
102
+ params: o,
94
103
  provider: n,
95
- listeners: o
104
+ listeners: s
96
105
  } = t;
97
- let r = n, p = i;
98
- if (typeof window > "u") return j;
99
- const s = G(i);
100
- e.innerHTML = "", e.appendChild(s);
106
+ let a = n, p = o;
107
+ if (typeof window > "u") return $;
108
+ const E = Y(o);
109
+ e.innerHTML = "", e.appendChild(E);
101
110
  const {
102
- contentWindow: c
103
- } = s;
104
- if (!c)
105
- throw console.error("Iframe does not contain a window", s), new Error("Iframe does not contain a window!");
111
+ contentWindow: r
112
+ } = E;
113
+ if (!r)
114
+ throw console.error("Iframe does not contain a window", E), new Error("Iframe does not contain a window!");
106
115
  const f = [];
107
- f.push(x(c, i.appCode)), f.push(...$(s, i.height, i.maxHeight)), f.push(Q());
108
- const P = new D(window, o);
109
- let w = _(c, null, r);
110
- s.addEventListener("load", () => I(c, p, r));
111
- const S = new O(window, c);
116
+ f.push(z(r, o.appCode)), f.push(...X(E, o.height, o.maxHeight)), f.push(J());
117
+ let l = null;
118
+ function P() {
119
+ r && (l && window.removeEventListener("message", l), l = ee(r, p.hooks), f.push(l));
120
+ }
121
+ P();
122
+ const A = new W(window, s);
123
+ let T = m(r, null, a);
124
+ E.addEventListener("load", () => {
125
+ C(r, p, a);
126
+ });
127
+ const g = new H(window, r);
112
128
  return {
113
- updateParams: (a) => {
114
- p = a, I(c, p, r);
129
+ updateParams: (d) => {
130
+ p = d, C(r, p, a), P();
115
131
  },
116
- updateListeners: (a) => P.updateListeners(a),
117
- updateProvider: (a) => {
118
- r = a, w = _(c, w, a);
132
+ updateListeners: (d) => A.updateListeners(d),
133
+ updateProvider: (d) => {
134
+ a = d, T = m(r, T, d);
119
135
  },
120
136
  destroy: () => {
121
- w.disconnect(), P.stopListeningIframe(), f.forEach((a) => window.removeEventListener("message", a)), S.stopListening(), e.removeChild(s);
137
+ T.disconnect(), A.stopListeningIframe(), f.forEach((d) => window.removeEventListener("message", d)), g.stopListening(), e.removeChild(E);
122
138
  }
123
139
  };
124
140
  }
125
- function _(e, t, i) {
141
+ function m(e, t, o) {
126
142
  t && t.disconnect();
127
- const n = t || new L(e);
128
- return i && n.onConnect(i), n;
143
+ const n = t || new v(e);
144
+ return o && n.onConnect(o), n;
129
145
  }
130
- function G(e) {
146
+ function Y(e) {
131
147
  const {
132
- width: t = F,
133
- height: i = v
148
+ width: t = Q,
149
+ height: o = I
134
150
  } = e, n = document.createElement("iframe");
135
- return n.src = H(e), n.width = t, n.height = i, n.style.border = "0", n.allow = "clipboard-read; clipboard-write", n;
151
+ return n.src = y(e), n.width = t, n.height = o, n.style.border = "0", n.allow = "clipboard-read; clipboard-write", n;
136
152
  }
137
- function I(e, t, i) {
138
- const n = !!i, o = A(t), r = g(t).toString(), {
153
+ function C(e, t, o) {
154
+ const n = !!o, s = L(t), a = S(t).toString(), {
139
155
  theme: p,
140
- ...s
156
+ hooks: E,
157
+ ...r
141
158
  } = t;
142
- d.postMessageToWindow(e, T.UPDATE_PARAMS, {
159
+ i.postMessageToWindow(e, w.UPDATE_PARAMS, {
143
160
  urlParams: {
144
- pathname: o,
145
- search: r
161
+ pathname: s,
162
+ search: a
146
163
  },
147
- appParams: s,
164
+ appParams: r,
148
165
  hasProvider: n
149
166
  });
150
167
  }
151
- function x(e, t) {
152
- return d.listenToMessageFromWindow(window, u.ACTIVATE, () => {
153
- d.postMessageToWindow(e, T.UPDATE_APP_DATA, {
168
+ function z(e, t) {
169
+ return i.listenToMessageFromWindow(window, u.ACTIVATE, () => {
170
+ i.postMessageToWindow(e, w.UPDATE_APP_DATA, {
154
171
  metaData: t ? {
155
172
  appCode: t
156
173
  } : void 0
157
174
  });
158
175
  });
159
176
  }
160
- function Q() {
161
- return d.listenToMessageFromWindow(window, u.INTERCEPT_WINDOW_OPEN, ({
177
+ function J() {
178
+ return i.listenToMessageFromWindow(window, u.INTERCEPT_WINDOW_OPEN, ({
162
179
  href: e,
163
180
  rel: t,
164
- target: i
181
+ target: o
165
182
  }) => {
166
183
  const n = e.toString();
167
184
  if (!n.startsWith("http") && n.match(/^[a-zA-Z0-9]+:\/\//)) {
168
- window.open(n, i, t);
185
+ window.open(n, o, t);
169
186
  return;
170
187
  }
171
188
  });
172
189
  }
173
- function $(e, t = v, i) {
174
- return [d.listenToMessageFromWindow(window, u.UPDATE_HEIGHT, (n) => {
175
- const o = n.height ? n.height + k : void 0;
176
- e.style.height = o ? `${i ? Math.min(o, i) : o}px` : t;
177
- }), d.listenToMessageFromWindow(window, u.SET_FULL_HEIGHT, ({
190
+ function X(e, t = I, o) {
191
+ return [i.listenToMessageFromWindow(window, u.UPDATE_HEIGHT, (n) => {
192
+ const s = n.height ? n.height + K : void 0;
193
+ e.style.height = s ? `${o ? Math.min(s, o) : s}px` : t;
194
+ }), i.listenToMessageFromWindow(window, u.SET_FULL_HEIGHT, ({
178
195
  isUpToSmall: n
179
196
  }) => {
180
- e.style.height = n ? t : `${i || document.body.offsetHeight}px`;
197
+ e.style.height = n ? t : `${o || document.body.offsetHeight}px`;
181
198
  })];
182
199
  }
183
- const B = Object.values(h);
184
- function Z(e, t, i) {
185
- if (l(e)) {
186
- const n = e[i];
187
- return E(n) ? n[t] : n;
200
+ const Z = {
201
+ [c.ON_BEFORE_APPROVAL]: (e, t) => t?.onBeforeApproval ? t.onBeforeApproval(e) : !0,
202
+ [c.ON_BEFORE_TRADE]: (e, t) => t?.onBeforeTrade ? t.onBeforeTrade(e) : !0,
203
+ [c.ON_BEFORE_WRAP_UNWRAP]: (e, t) => t?.onBeforeWrapOrUnwrap ? t.onBeforeWrapOrUnwrap(e) : !0,
204
+ [c.ON_BEFORE_ORDER_CANCEL]: (e, t) => t?.onBeforeOrderCancel ? t.onBeforeOrderCancel(e) : !0,
205
+ [c.ON_BEFORE_ORDERS_CANCEL]: (e, t) => t?.onBeforeOrdersCancel ? t.onBeforeOrdersCancel(e) : !0
206
+ };
207
+ function q(e, t) {
208
+ return Z[e.event](e.payload, t);
209
+ }
210
+ function ee(e, t) {
211
+ return i.listenToMessageFromWindow(window, u.PROCESS_HOOK, async (o) => {
212
+ let n = !1;
213
+ try {
214
+ n = await q(o, t);
215
+ } catch {
216
+ }
217
+ i.postMessageToWindow(e, w.HOOK_RESULT, {
218
+ id: o.id,
219
+ result: n
220
+ });
221
+ });
222
+ }
223
+ const te = Object.values(R);
224
+ function ae(e, t, o) {
225
+ if (_(e)) {
226
+ const n = e[o];
227
+ return O(n) ? n[t] : n;
188
228
  }
189
- if (E(e)) {
229
+ if (O(e)) {
190
230
  const n = e[t];
191
- return l(n) ? n[i] : n;
231
+ return _(n) ? n[o] : n;
192
232
  }
193
233
  return e;
194
234
  }
195
- function l(e) {
196
- return typeof e != "object" ? !1 : Object.keys(e).every((t) => B.includes(t));
235
+ function _(e) {
236
+ return typeof e != "object" ? !1 : Object.keys(e).every((t) => te.includes(t));
197
237
  }
198
- const Y = /^\d+$/;
199
- function E(e) {
200
- return typeof e != "object" ? !1 : Object.keys(e).every((t) => Y.test(t));
238
+ const ne = /^\d+$/;
239
+ function O(e) {
240
+ return typeof e != "object" ? !1 : Object.keys(e).every((t) => ne.test(t));
201
241
  }
202
- function q(e) {
203
- return l(e) ? Object.values(e).flatMap((t) => E(t) ? Object.values(t) : [t]) : E(e) ? Object.values(e).flatMap((t) => l(t) ? Object.values(t) : [t]) : [e];
242
+ function de(e) {
243
+ return _(e) ? Object.values(e).flatMap((t) => O(t) ? Object.values(t) : [t]) : O(e) ? Object.values(e).flatMap((t) => _(t) ? Object.values(t) : [t]) : [e];
204
244
  }
205
245
  export {
206
- h as TradeType,
207
- K as WIDGET_PALETTE_COLORS,
246
+ R as TradeType,
247
+ ie as WIDGET_PALETTE_COLORS,
248
+ c as WidgetHookEvents,
208
249
  u as WidgetMethodsEmit,
209
- T as WidgetMethodsListen,
210
- X as createCowSwapWidget,
211
- U as isCowSwapWidgetPalette,
212
- E as isPerNetworkConfig,
213
- l as isPerTradeTypeConfig,
214
- Z as resolveFlexibleConfig,
215
- q as resolveFlexibleConfigValues,
216
- d as widgetIframeTransport
250
+ w as WidgetMethodsListen,
251
+ se as createCowSwapWidget,
252
+ F as isCowSwapWidgetPalette,
253
+ O as isPerNetworkConfig,
254
+ _ as isPerTradeTypeConfig,
255
+ ae as resolveFlexibleConfig,
256
+ de as resolveFlexibleConfigValues,
257
+ i as widgetIframeTransport
217
258
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cowprotocol/widget-lib",
3
- "version": "2.0.2",
3
+ "version": "2.1.1",
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",
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "dependencies": {
18
18
  "@cowprotocol/cow-sdk": "8.0.3",
19
- "@cowprotocol/events": "^4.0.2",
19
+ "@cowprotocol/events": "^4.1.0",
20
20
  "@cowprotocol/iframe-transport": "^2.0.10"
21
21
  },
22
22
  "exports": {
package/types.d.ts CHANGED
@@ -1,6 +1,7 @@
1
- import { SupportedChainId } from '@cowprotocol/cow-sdk';
2
- import { CowWidgetEventListeners, CowWidgetEventPayloadMap, CowWidgetEvents } from '@cowprotocol/events';
1
+ import { EnrichedOrder, SupportedChainId } from '@cowprotocol/cow-sdk';
2
+ import { CowWidgetEventListeners, CowWidgetEventPayloadMap, CowWidgetEvents, OnTradeParamsPayload } from '@cowprotocol/events';
3
3
  export type { SupportedChainId } from '@cowprotocol/cow-sdk';
4
+ export type { OnTradeParamsPayload } from '@cowprotocol/events';
4
5
  export type PerTradeTypeConfig<T> = Partial<Record<TradeType, T>>;
5
6
  export type PerNetworkConfig<T> = Partial<Record<SupportedChainId, T>>;
6
7
  export type FlexibleConfig<T> = T | PerNetworkConfig<T> | PerTradeTypeConfig<T> | PerTradeTypeConfig<PerNetworkConfig<T>> | PerNetworkConfig<PerTradeTypeConfig<T>>;
@@ -10,13 +11,30 @@ export declare enum WidgetMethodsEmit {
10
11
  SET_FULL_HEIGHT = "SET_FULL_HEIGHT",
11
12
  EMIT_COW_EVENT = "EMIT_COW_EVENT",
12
13
  PROVIDER_RPC_REQUEST = "PROVIDER_RPC_REQUEST",
13
- INTERCEPT_WINDOW_OPEN = "INTERCEPT_WINDOW_OPEN"
14
+ INTERCEPT_WINDOW_OPEN = "INTERCEPT_WINDOW_OPEN",
15
+ PROCESS_HOOK = "PROCESS_HOOK"
14
16
  }
15
17
  export declare enum WidgetMethodsListen {
16
18
  UPDATE_PARAMS = "UPDATE_PARAMS",
17
19
  UPDATE_APP_DATA = "UPDATE_APP_DATA",
18
20
  PROVIDER_RPC_RESPONSE = "PROVIDER_RPC_RESPONSE",
19
- PROVIDER_ON_EVENT = "PROVIDER_ON_EVENT"
21
+ PROVIDER_ON_EVENT = "PROVIDER_ON_EVENT",
22
+ HOOK_RESULT = "HOOK_RESULT"
23
+ }
24
+ export declare enum WidgetHookEvents {
25
+ ON_BEFORE_APPROVAL = "ON_BEFORE_APPROVAL",
26
+ ON_BEFORE_TRADE = "ON_BEFORE_TRADE",
27
+ ON_BEFORE_WRAP_UNWRAP = "ON_BEFORE_WRAP_UNWRAP",
28
+ ON_BEFORE_ORDER_CANCEL = "ON_BEFORE_ORDER_CANCEL",
29
+ ON_BEFORE_ORDERS_CANCEL = "ON_BEFORE_ORDERS_CANCEL"
30
+ }
31
+ export type WidgetHookResult = Promise<boolean> | boolean;
32
+ export interface OnApprovalPayload {
33
+ chainId: SupportedChainId;
34
+ sellToken: TokenInfo;
35
+ sellAmount: string;
36
+ walletAddress: string;
37
+ spenderAddress: string;
20
38
  }
21
39
  export interface CowSwapWidgetProps {
22
40
  params: CowSwapWidgetParams;
@@ -100,6 +118,11 @@ export type CowSwapWidgetPaletteParams = {
100
118
  };
101
119
  export type CowSwapWidgetPalette = {
102
120
  baseTheme: CowSwapTheme;
121
+ /**
122
+ * Overrides the main widget card shadow.
123
+ * Accepts any valid CSS box-shadow value, for example `none` or `0 12px 24px rgba(0, 0, 0, 0.12)`.
124
+ */
125
+ boxShadow?: string;
103
126
  } & CowSwapWidgetPaletteParams;
104
127
  export interface CowSwapWidgetSounds {
105
128
  /**
@@ -165,9 +188,36 @@ export interface CowSwapWidgetParams {
165
188
  */
166
189
  targetChainId?: number;
167
190
  /**
168
- * The token lists urls to use in the widget
191
+ * The token lists (as urls) enabled for the widget.
192
+ * These lists are available to both sell and buy selectors.
169
193
  */
170
194
  tokenLists?: string[];
195
+ /**
196
+ * The token lists (as urls) to use in the sell selector.
197
+ * Note: these lists also contribute to the widget's globally enabled list set.
198
+ * If omitted, the sell selector falls back to the globally enabled lists.
199
+ */
200
+ sellTokenLists?: string[];
201
+ /**
202
+ * The token lists (as urls) to use in the buy selector.
203
+ * Note: these lists also contribute to the widget's globally enabled list set.
204
+ * If omitted, the buy selector falls back to the globally enabled lists.
205
+ */
206
+ buyTokenLists?: string[];
207
+ /**
208
+ * Forces the widget locale.
209
+ * Serialized as the `lng` query param used by the frontend locale resolver.
210
+ * Accepts supported locales like `en-US` and fuzzy values like `en`.
211
+ */
212
+ locale?: string;
213
+ /**
214
+ * Control the "Recent tokens" section displaying in the token selector
215
+ */
216
+ hideRecentTokens?: boolean;
217
+ /**
218
+ * Control the "Favorite tokens" section displaying in the token selector
219
+ */
220
+ hideFavoriteTokens?: boolean;
171
221
  /**
172
222
  * Swap, Limit or Advanced (Twap).
173
223
  */
@@ -209,6 +259,11 @@ export interface CowSwapWidgetParams {
209
259
  * Defaults to false.
210
260
  */
211
261
  disableCrossChainSwap?: boolean;
262
+ /**
263
+ * Disables adding custom tokens and custom token lists.
264
+ * Defaults to false.
265
+ */
266
+ disableTokenImport?: boolean;
212
267
  /**
213
268
  * Disables showing the confirmation modal you get after posting an order.
214
269
  * Defaults to false.
@@ -278,6 +333,20 @@ export interface CowSwapWidgetParams {
278
333
  * Customizable slippage settings for the widget.
279
334
  */
280
335
  slippage?: FlexibleSlippageConfig;
336
+ /**
337
+ * Conditions to control the ability to trade
338
+ */
339
+ disableTrade?: {
340
+ whenPriceImpactIsUnknown?: boolean;
341
+ whenPriceImpactIsHigherThan?: number;
342
+ };
343
+ hooks?: Partial<{
344
+ onBeforeApproval(payload: OnApprovalPayload): WidgetHookResult;
345
+ onBeforeWrapOrUnwrap(payload: OnTradeParamsPayload): WidgetHookResult;
346
+ onBeforeTrade(payload: OnTradeParamsPayload): WidgetHookResult;
347
+ onBeforeOrderCancel(payload: EnrichedOrder): WidgetHookResult;
348
+ onBeforeOrdersCancel(payload: EnrichedOrder[]): WidgetHookResult;
349
+ }>;
281
350
  }
282
351
  export interface WidgetMethodsEmitPayloadMap {
283
352
  [WidgetMethodsEmit.ACTIVATE]: void;
@@ -286,17 +355,19 @@ export interface WidgetMethodsEmitPayloadMap {
286
355
  [WidgetMethodsEmit.SET_FULL_HEIGHT]: SetWidgetFullHeightPayload;
287
356
  [WidgetMethodsEmit.PROVIDER_RPC_REQUEST]: ProviderRpcRequestPayload;
288
357
  [WidgetMethodsEmit.INTERCEPT_WINDOW_OPEN]: WindowOpenPayload;
358
+ [WidgetMethodsEmit.PROCESS_HOOK]: WidgetHookPayload<WidgetHookEvents>;
289
359
  }
290
360
  export interface WidgetMethodsListenPayloadMap {
291
361
  [WidgetMethodsListen.UPDATE_APP_DATA]: UpdateAppDataPayload;
292
362
  [WidgetMethodsListen.UPDATE_PARAMS]: UpdateParamsPayload;
293
363
  [WidgetMethodsListen.PROVIDER_RPC_RESPONSE]: ProviderRpcResponsePayload;
294
364
  [WidgetMethodsListen.PROVIDER_ON_EVENT]: ProviderOnEventPayload;
365
+ [WidgetMethodsListen.HOOK_RESULT]: WidgetHookResultPayload;
295
366
  }
296
367
  export type WidgetEventsPayloadMap = WidgetMethodsEmitPayloadMap & WidgetMethodsListenPayloadMap;
297
368
  export type WidgetMethodsEmitPayloads = WidgetMethodsEmitPayloadMap[WidgetMethodsEmit];
298
369
  export type WidgetMethodsListenPayloads = WidgetMethodsListenPayloadMap[WidgetMethodsListen];
299
- export type CowSwapWidgetAppParams = Omit<CowSwapWidgetParams, 'theme'>;
370
+ export type CowSwapWidgetAppParams = Omit<CowSwapWidgetParams, 'theme' | 'hooks'>;
300
371
  export interface UpdateParamsPayload {
301
372
  urlParams: {
302
373
  pathname: string;
@@ -316,6 +387,23 @@ export interface UpdateWidgetHeightPayload {
316
387
  export interface SetWidgetFullHeightPayload {
317
388
  isUpToSmall?: boolean;
318
389
  }
390
+ export type WidgetHookId = string;
391
+ export interface WidgetHookPayload<T extends WidgetHookEvents> {
392
+ id: WidgetHookId;
393
+ event: T;
394
+ payload: WidgetHookPayloadMap[T];
395
+ }
396
+ export interface WidgetHookResultPayload {
397
+ id: WidgetHookId;
398
+ result: boolean;
399
+ }
400
+ export interface WidgetHookPayloadMap {
401
+ [WidgetHookEvents.ON_BEFORE_APPROVAL]: OnApprovalPayload;
402
+ [WidgetHookEvents.ON_BEFORE_TRADE]: OnTradeParamsPayload;
403
+ [WidgetHookEvents.ON_BEFORE_WRAP_UNWRAP]: OnTradeParamsPayload;
404
+ [WidgetHookEvents.ON_BEFORE_ORDER_CANCEL]: EnrichedOrder;
405
+ [WidgetHookEvents.ON_BEFORE_ORDERS_CANCEL]: EnrichedOrder[];
406
+ }
319
407
  export interface EmitCowEventPayload<T extends CowWidgetEvents> {
320
408
  event: T;
321
409
  payload: CowWidgetEventPayloadMap[T];