@cowprotocol/widget-lib 2.0.2 → 2.1.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.
@@ -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,r=[]){this.contentWindow=t,this.updateListeners(r),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 r of this.listeners)this.eventEmitter.off(r);this.listeners=t||[];for(const r of this.listeners)this.eventEmitter.on(r)}}class y{constructor(t,r){this.appWindow=t,this.iframeWidow=r,this.forwardSdkMessage=n=>{F(n.data)&&(typeof window<"u"&&n.origin===window.location.origin||(U(n.data)?this.appWindow.parent.postMessage(n.data,"*"):b(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 F(e){return typeof e=="object"&&e!==null&&"id"in e&&typeof e.id=="string"}function U(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 b(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 h="_";function B(e){const t=typeof e.baseUrl=="string"?e.baseUrl:"https://swap.cow.fi",r=L(e);return t+"/#"+r+"?"+I(e)}function L(e){const{chainId:t=1,sell:r,buy:n,tradeType:s=T.SWAP}=e,a=[r?.asset||h,n?.asset||h].map(encodeURIComponent).join("/");return`/${t}/widget/${s}/${a}`}function I(e){const t=new URLSearchParams;return j(k(V(M(t,e),e),e),e)}function M(e,t){const{sell:r,buy:n}=t;return r?.amount&&e.append("sellAmount",r.amount),n?.amount&&e.append("buyAmount",n.amount),e}function V(e,t){const r=t.theme;return r?(S(r)?(e.append("palette",encodeURIComponent(JSON.stringify(r))),e.append("theme",r.baseTheme)):(e.append("palette","null"),e.append("theme",r)),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}const N="640px",G="450px",x=20,K={updateParams:()=>{},updateListeners:()=>{},updateProvider:()=>{},destroy:()=>{}};function Q(e,t){const{params:r,provider:n,listeners:s}=t;let a=n,l=r;if(typeof window>"u")return K;const u=$(r);e.innerHTML="",e.appendChild(u);const{contentWindow:o}=u;if(!o)throw console.error("Iframe does not contain a window",u),new Error("Iframe does not contain a window!");const p=[];p.push(Y(o,r.appCode)),p.push(...J(u,r.height,r.maxHeight)),p.push(z());let O=null;function P(){o&&(O&&window.removeEventListener("message",O),O=q(o,l.hooks),p.push(O))}P();const A=new H(window,s);let R=C(o,null,a);u.addEventListener("load",()=>{g(o,l,a)});const v=new y(window,o);return{updateParams:d=>{l=d,g(o,l,a),P()},updateListeners:d=>A.updateListeners(d),updateProvider:d=>{a=d,R=C(o,R,d)},destroy:()=>{R.disconnect(),A.stopListeningIframe(),p.forEach(d=>window.removeEventListener("message",d)),v.stopListening(),e.removeChild(u)}}}function C(e,t,r){t&&t.disconnect();const n=t||new m.IframeRpcProviderBridge(e);return r&&n.onConnect(r),n}function $(e){const{width:t=G,height:r=N}=e,n=document.createElement("iframe");return n.src=B(e),n.width=t,n.height=r,n.style.border="0",n.allow="clipboard-read; clipboard-write",n}function g(e,t,r){const n=!!r,s=L(t),a=I(t).toString(),{theme:l,hooks:u,...o}=t;i.postMessageToWindow(e,w.UPDATE_PARAMS,{urlParams:{pathname:s,search:a},appParams:o,hasProvider:n})}function Y(e,t){return i.listenToMessageFromWindow(window,E.ACTIVATE,()=>{i.postMessageToWindow(e,w.UPDATE_APP_DATA,{metaData:t?{appCode:t}:void 0})})}function z(){return i.listenToMessageFromWindow(window,E.INTERCEPT_WINDOW_OPEN,({href:e,rel:t,target:r})=>{const n=e.toString();if(!n.startsWith("http")&&n.match(/^[a-zA-Z0-9]+:\/\//)){window.open(n,r,t);return}})}function J(e,t=N,r){return[i.listenToMessageFromWindow(window,E.UPDATE_HEIGHT,n=>{const s=n.height?n.height+x:void 0;e.style.height=s?`${r?Math.min(s,r):s}px`:t}),i.listenToMessageFromWindow(window,E.SET_FULL_HEIGHT,({isUpToSmall:n})=>{e.style.height=n?t:`${r||document.body.offsetHeight}px`})]}const X={[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 Z(e,t){return X[e.event](e.payload,t)}function q(e,t){return i.listenToMessageFromWindow(window,E.PROCESS_HOOK,async r=>{let n=!1;try{n=await Z(r,t)}catch{}i.postMessageToWindow(e,w.HOOK_RESULT,{id:r.id,result:n})})}const ee=Object.values(T);function te(e,t,r){if(f(e)){const n=e[r];return _(n)?n[t]:n}if(_(e)){const n=e[t];return f(n)?n[r]:n}return e}function f(e){return typeof e!="object"?!1:Object.keys(e).every(t=>ee.includes(t))}const ne=/^\d+$/;function _(e){return typeof e!="object"?!1:Object.keys(e).every(t=>ne.test(t))}function re(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=Q;exports.isCowSwapWidgetPalette=S;exports.isPerNetworkConfig=_;exports.isPerTradeTypeConfig=f;exports.resolveFlexibleConfig=te;exports.resolveFlexibleConfigValues=re;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 re = ["primary", "background", "paper", "text", "danger", "warning", "alert", "info", "success"], i = new N("cowSwapWidget");
5
+ class W {
6
+ constructor(t, r = []) {
7
+ this.contentWindow = t, this.updateListeners(r), 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 r of this.listeners)
17
+ this.eventEmitter.off(r);
18
18
  this.listeners = t || [];
19
- for (const i of this.listeners)
20
- this.eventEmitter.on(i);
19
+ for (const r of this.listeners)
20
+ this.eventEmitter.on(r);
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, r) {
25
+ this.appWindow = t, this.iframeWidow = r, this.forwardSdkMessage = (n) => {
26
+ U(n.data) && (typeof window < "u" && n.origin === window.location.origin || (B(n.data) ? this.appWindow.parent.postMessage(n.data, "*") : F(n.data) && this.iframeWidow.postMessage(n.data, "*")));
27
27
  }, this.startListening();
28
28
  }
29
29
  forwardSdkMessage;
@@ -34,51 +34,54 @@ 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 F(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 y(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 b(e) {
51
+ const t = typeof e.baseUrl == "string" ? e.baseUrl : "https://swap.cow.fi", r = L(e);
52
+ return t + "/#" + r + "?" + 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: r,
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 = [r?.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 j(k(V(M(t, e), e), e), e);
66
66
  }
67
- function N(e, t) {
67
+ function M(e, t) {
68
68
  const {
69
- sell: i,
69
+ sell: r,
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 r?.amount && e.append("sellAmount", r.amount), n?.amount && e.append("buyAmount", n.amount), e;
77
73
  }
78
74
  function V(e, t) {
75
+ const r = t.theme;
76
+ return r ? (y(r) ? (e.append("palette", encodeURIComponent(JSON.stringify(r))), e.append("theme", r.baseTheme)) : (e.append("palette", "null"), e.append("theme", r)), 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
+ const I = "640px", G = "450px", x = 20, K = {
82
85
  updateParams: () => {
83
86
  },
84
87
  updateListeners: () => {
@@ -88,130 +91,162 @@ const v = "640px", F = "450px", k = 20, j = {
88
91
  destroy: () => {
89
92
  }
90
93
  };
91
- function X(e, t) {
94
+ function oe(e, t) {
92
95
  const {
93
- params: i,
96
+ params: r,
94
97
  provider: n,
95
- listeners: o
98
+ listeners: s
96
99
  } = 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);
100
+ let a = n, p = r;
101
+ if (typeof window > "u") return K;
102
+ const E = Q(r);
103
+ e.innerHTML = "", e.appendChild(E);
101
104
  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!");
105
+ contentWindow: o
106
+ } = E;
107
+ if (!o)
108
+ throw console.error("Iframe does not contain a window", E), new Error("Iframe does not contain a window!");
106
109
  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);
110
+ f.push($(o, r.appCode)), f.push(...z(E, r.height, r.maxHeight)), f.push(Y());
111
+ let l = null;
112
+ function P() {
113
+ o && (l && window.removeEventListener("message", l), l = Z(o, p.hooks), f.push(l));
114
+ }
115
+ P();
116
+ const A = new W(window, s);
117
+ let T = m(o, null, a);
118
+ E.addEventListener("load", () => {
119
+ C(o, p, a);
120
+ });
121
+ const g = new H(window, o);
112
122
  return {
113
- updateParams: (a) => {
114
- p = a, I(c, p, r);
123
+ updateParams: (d) => {
124
+ p = d, C(o, p, a), P();
115
125
  },
116
- updateListeners: (a) => P.updateListeners(a),
117
- updateProvider: (a) => {
118
- r = a, w = _(c, w, a);
126
+ updateListeners: (d) => A.updateListeners(d),
127
+ updateProvider: (d) => {
128
+ a = d, T = m(o, T, d);
119
129
  },
120
130
  destroy: () => {
121
- w.disconnect(), P.stopListeningIframe(), f.forEach((a) => window.removeEventListener("message", a)), S.stopListening(), e.removeChild(s);
131
+ T.disconnect(), A.stopListeningIframe(), f.forEach((d) => window.removeEventListener("message", d)), g.stopListening(), e.removeChild(E);
122
132
  }
123
133
  };
124
134
  }
125
- function _(e, t, i) {
135
+ function m(e, t, r) {
126
136
  t && t.disconnect();
127
- const n = t || new L(e);
128
- return i && n.onConnect(i), n;
137
+ const n = t || new v(e);
138
+ return r && n.onConnect(r), n;
129
139
  }
130
- function G(e) {
140
+ function Q(e) {
131
141
  const {
132
- width: t = F,
133
- height: i = v
142
+ width: t = G,
143
+ height: r = I
134
144
  } = 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;
145
+ return n.src = b(e), n.width = t, n.height = r, n.style.border = "0", n.allow = "clipboard-read; clipboard-write", n;
136
146
  }
137
- function I(e, t, i) {
138
- const n = !!i, o = A(t), r = g(t).toString(), {
147
+ function C(e, t, r) {
148
+ const n = !!r, s = L(t), a = S(t).toString(), {
139
149
  theme: p,
140
- ...s
150
+ hooks: E,
151
+ ...o
141
152
  } = t;
142
- d.postMessageToWindow(e, T.UPDATE_PARAMS, {
153
+ i.postMessageToWindow(e, w.UPDATE_PARAMS, {
143
154
  urlParams: {
144
- pathname: o,
145
- search: r
155
+ pathname: s,
156
+ search: a
146
157
  },
147
- appParams: s,
158
+ appParams: o,
148
159
  hasProvider: n
149
160
  });
150
161
  }
151
- function x(e, t) {
152
- return d.listenToMessageFromWindow(window, u.ACTIVATE, () => {
153
- d.postMessageToWindow(e, T.UPDATE_APP_DATA, {
162
+ function $(e, t) {
163
+ return i.listenToMessageFromWindow(window, u.ACTIVATE, () => {
164
+ i.postMessageToWindow(e, w.UPDATE_APP_DATA, {
154
165
  metaData: t ? {
155
166
  appCode: t
156
167
  } : void 0
157
168
  });
158
169
  });
159
170
  }
160
- function Q() {
161
- return d.listenToMessageFromWindow(window, u.INTERCEPT_WINDOW_OPEN, ({
171
+ function Y() {
172
+ return i.listenToMessageFromWindow(window, u.INTERCEPT_WINDOW_OPEN, ({
162
173
  href: e,
163
174
  rel: t,
164
- target: i
175
+ target: r
165
176
  }) => {
166
177
  const n = e.toString();
167
178
  if (!n.startsWith("http") && n.match(/^[a-zA-Z0-9]+:\/\//)) {
168
- window.open(n, i, t);
179
+ window.open(n, r, t);
169
180
  return;
170
181
  }
171
182
  });
172
183
  }
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, ({
184
+ function z(e, t = I, r) {
185
+ return [i.listenToMessageFromWindow(window, u.UPDATE_HEIGHT, (n) => {
186
+ const s = n.height ? n.height + x : void 0;
187
+ e.style.height = s ? `${r ? Math.min(s, r) : s}px` : t;
188
+ }), i.listenToMessageFromWindow(window, u.SET_FULL_HEIGHT, ({
178
189
  isUpToSmall: n
179
190
  }) => {
180
- e.style.height = n ? t : `${i || document.body.offsetHeight}px`;
191
+ e.style.height = n ? t : `${r || document.body.offsetHeight}px`;
181
192
  })];
182
193
  }
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;
194
+ const J = {
195
+ [c.ON_BEFORE_APPROVAL]: (e, t) => t?.onBeforeApproval ? t.onBeforeApproval(e) : !0,
196
+ [c.ON_BEFORE_TRADE]: (e, t) => t?.onBeforeTrade ? t.onBeforeTrade(e) : !0,
197
+ [c.ON_BEFORE_WRAP_UNWRAP]: (e, t) => t?.onBeforeWrapOrUnwrap ? t.onBeforeWrapOrUnwrap(e) : !0,
198
+ [c.ON_BEFORE_ORDER_CANCEL]: (e, t) => t?.onBeforeOrderCancel ? t.onBeforeOrderCancel(e) : !0,
199
+ [c.ON_BEFORE_ORDERS_CANCEL]: (e, t) => t?.onBeforeOrdersCancel ? t.onBeforeOrdersCancel(e) : !0
200
+ };
201
+ function X(e, t) {
202
+ return J[e.event](e.payload, t);
203
+ }
204
+ function Z(e, t) {
205
+ return i.listenToMessageFromWindow(window, u.PROCESS_HOOK, async (r) => {
206
+ let n = !1;
207
+ try {
208
+ n = await X(r, t);
209
+ } catch {
210
+ }
211
+ i.postMessageToWindow(e, w.HOOK_RESULT, {
212
+ id: r.id,
213
+ result: n
214
+ });
215
+ });
216
+ }
217
+ const q = Object.values(R);
218
+ function ie(e, t, r) {
219
+ if (_(e)) {
220
+ const n = e[r];
221
+ return O(n) ? n[t] : n;
188
222
  }
189
- if (E(e)) {
223
+ if (O(e)) {
190
224
  const n = e[t];
191
- return l(n) ? n[i] : n;
225
+ return _(n) ? n[r] : n;
192
226
  }
193
227
  return e;
194
228
  }
195
- function l(e) {
196
- return typeof e != "object" ? !1 : Object.keys(e).every((t) => B.includes(t));
229
+ function _(e) {
230
+ return typeof e != "object" ? !1 : Object.keys(e).every((t) => q.includes(t));
197
231
  }
198
- const Y = /^\d+$/;
199
- function E(e) {
200
- return typeof e != "object" ? !1 : Object.keys(e).every((t) => Y.test(t));
232
+ const ee = /^\d+$/;
233
+ function O(e) {
234
+ return typeof e != "object" ? !1 : Object.keys(e).every((t) => ee.test(t));
201
235
  }
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];
236
+ function se(e) {
237
+ 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
238
  }
205
239
  export {
206
- h as TradeType,
207
- K as WIDGET_PALETTE_COLORS,
240
+ R as TradeType,
241
+ re as WIDGET_PALETTE_COLORS,
242
+ c as WidgetHookEvents,
208
243
  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
244
+ w as WidgetMethodsListen,
245
+ oe as createCowSwapWidget,
246
+ y as isCowSwapWidgetPalette,
247
+ O as isPerNetworkConfig,
248
+ _ as isPerTradeTypeConfig,
249
+ ie as resolveFlexibleConfig,
250
+ se as resolveFlexibleConfigValues,
251
+ i as widgetIframeTransport
217
252
  };
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.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",
@@ -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];