@cowprotocol/widget-lib 1.3.0 → 2.0.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.
Files changed (48) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/package.json +28 -5
  3. package/src/IframeCowEventEmitter.d.ts +10 -0
  4. package/src/IframeCowEventEmitter.js +35 -0
  5. package/src/IframeCowEventEmitter.js.map +1 -0
  6. package/src/IframeSafeSdkBridge.d.ts +8 -0
  7. package/src/IframeSafeSdkBridge.js +53 -0
  8. package/src/IframeSafeSdkBridge.js.map +1 -0
  9. package/src/cowSwapWidget.d.ts +18 -0
  10. package/src/cowSwapWidget.js +189 -0
  11. package/src/cowSwapWidget.js.map +1 -0
  12. package/src/flexibleConfig.d.ts +5 -0
  13. package/src/flexibleConfig.js +30 -0
  14. package/src/flexibleConfig.js.map +1 -0
  15. package/src/index.d.ts +7 -0
  16. package/src/index.js +14 -0
  17. package/src/index.js.map +1 -0
  18. package/src/resolveFlexibleConfigValues.d.ts +2 -0
  19. package/src/resolveFlexibleConfigValues.js +14 -0
  20. package/src/resolveFlexibleConfigValues.js.map +1 -0
  21. package/src/themeUtils.d.ts +2 -0
  22. package/src/themeUtils.js +7 -0
  23. package/src/themeUtils.js.map +1 -0
  24. package/src/types.d.ts +365 -0
  25. package/src/types.js +42 -0
  26. package/src/types.js.map +1 -0
  27. package/src/urlUtils.d.ts +4 -0
  28. package/src/urlUtils.js +55 -0
  29. package/src/urlUtils.js.map +1 -0
  30. package/src/widgetIframeTransport.d.ts +3 -0
  31. package/src/widgetIframeTransport.js +6 -0
  32. package/src/widgetIframeTransport.js.map +1 -0
  33. package/jest.config.ts +0 -10
  34. package/project.json +0 -51
  35. package/src/IframeCowEventEmitter.ts +0 -47
  36. package/src/IframeSafeSdkBridge.ts +0 -77
  37. package/src/cowSwapWidget.ts +0 -259
  38. package/src/flexibleConfig.ts +0 -39
  39. package/src/index.ts +0 -7
  40. package/src/resolveFlexibleConfigValues.ts +0 -14
  41. package/src/themeUtils.ts +0 -7
  42. package/src/types.ts +0 -458
  43. package/src/urlUtils.spec.ts +0 -88
  44. package/src/urlUtils.ts +0 -66
  45. package/src/widgetIframeTransport.ts +0 -5
  46. package/tsconfig.json +0 -22
  47. package/tsconfig.lib.json +0 -10
  48. package/tsconfig.spec.json +0 -9
package/src/types.d.ts ADDED
@@ -0,0 +1,365 @@
1
+ import type { SupportedChainId } from '@cowprotocol/cow-sdk';
2
+ import { CowWidgetEventListeners, CowWidgetEventPayloadMap, CowWidgetEvents } from '@cowprotocol/events';
3
+ export type { SupportedChainId } from '@cowprotocol/cow-sdk';
4
+ export type PerTradeTypeConfig<T> = Partial<Record<TradeType, T>>;
5
+ export type PerNetworkConfig<T> = Partial<Record<SupportedChainId, T>>;
6
+ export type FlexibleConfig<T> = T | PerNetworkConfig<T> | PerTradeTypeConfig<T> | PerTradeTypeConfig<PerNetworkConfig<T>> | PerNetworkConfig<PerTradeTypeConfig<T>>;
7
+ export declare enum WidgetMethodsEmit {
8
+ ACTIVATE = "ACTIVATE",
9
+ UPDATE_HEIGHT = "UPDATE_HEIGHT",
10
+ SET_FULL_HEIGHT = "SET_FULL_HEIGHT",
11
+ EMIT_COW_EVENT = "EMIT_COW_EVENT",
12
+ PROVIDER_RPC_REQUEST = "PROVIDER_RPC_REQUEST",
13
+ INTERCEPT_WINDOW_OPEN = "INTERCEPT_WINDOW_OPEN"
14
+ }
15
+ export declare enum WidgetMethodsListen {
16
+ UPDATE_PARAMS = "UPDATE_PARAMS",
17
+ UPDATE_APP_DATA = "UPDATE_APP_DATA",
18
+ PROVIDER_RPC_RESPONSE = "PROVIDER_RPC_RESPONSE",
19
+ PROVIDER_ON_EVENT = "PROVIDER_ON_EVENT"
20
+ }
21
+ export interface CowSwapWidgetProps {
22
+ params: CowSwapWidgetParams;
23
+ provider?: EthereumProvider;
24
+ listeners?: CowWidgetEventListeners;
25
+ }
26
+ export interface JsonRpcRequest {
27
+ id: number;
28
+ method: string;
29
+ params: unknown[];
30
+ }
31
+ export interface EthereumProvider {
32
+ /**
33
+ * Subscribes to Ethereum-related events.
34
+ * @param event - The event to subscribe to.
35
+ * @param args - Arguments for the event.
36
+ */
37
+ on(event: string, args: unknown): void;
38
+ /**
39
+ * Sends a JSON-RPC request to the Ethereum provider and returns the response.
40
+ * @param params - JSON-RPC request parameters.
41
+ * @returns A promise that resolves with the response.
42
+ */
43
+ request<T>(params: JsonRpcRequest): Promise<T>;
44
+ }
45
+ export type CowSwapTheme = 'dark' | 'light';
46
+ /**
47
+ *Trade asset parameters, for example:
48
+ * { asset: 'WBTC', amount: 12 }
49
+ * or
50
+ * { asset: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48' } // USDC
51
+ */
52
+ interface TradeAsset {
53
+ /** The asset symbol or identifier. */
54
+ asset: string;
55
+ /**
56
+ * The amount of the asset (optional).
57
+ * If specified, represents the quantity or value of the asset.
58
+ */
59
+ amount?: string;
60
+ }
61
+ export type ForcedOrderDeadline = FlexibleConfig<number>;
62
+ export declare enum TradeType {
63
+ SWAP = "swap",
64
+ LIMIT = "limit",
65
+ /**
66
+ * Currently it means only TWAP orders.
67
+ * But in the future it can be extended to support other order types.
68
+ */
69
+ ADVANCED = "advanced",
70
+ YIELD = "yield"
71
+ }
72
+ /**
73
+ * The partner fee
74
+ */
75
+ export interface PartnerFee {
76
+ /**
77
+ * The fee in basis points (BPS). One basis point is equivalent to 0.01% (1/100th of a percent)
78
+ */
79
+ bps: FlexibleConfig<number>;
80
+ /**
81
+ * The Ethereum address of the partner to receive the fee.
82
+ */
83
+ recipient: FlexibleConfig<string>;
84
+ }
85
+ /**
86
+ * ERC-20 token information
87
+ */
88
+ export type TokenInfo = {
89
+ chainId: number;
90
+ address: string;
91
+ name: string;
92
+ decimals: number;
93
+ symbol: string;
94
+ logoURI?: string;
95
+ };
96
+ export declare const WIDGET_PALETTE_COLORS: readonly ["primary", "background", "paper", "text", "danger", "warning", "alert", "info", "success"];
97
+ export type CowSwapWidgetPaletteColors = (typeof WIDGET_PALETTE_COLORS)[number];
98
+ export type CowSwapWidgetPaletteParams = {
99
+ [K in CowSwapWidgetPaletteColors]: string;
100
+ };
101
+ export type CowSwapWidgetPalette = {
102
+ baseTheme: CowSwapTheme;
103
+ } & CowSwapWidgetPaletteParams;
104
+ export interface CowSwapWidgetSounds {
105
+ /**
106
+ * The sound to play when the order is executed. Defaults to world wide famous CoW Swap moooooooooo!
107
+ * Alternatively, you can use a URL to a custom sound file, or set to null to disable the sound.
108
+ */
109
+ postOrder?: string | null;
110
+ /**
111
+ * The sound to play when the order is executed. Defaults to world wide famous CoW Swap happy moooooooooo!
112
+ * Alternatively, you can use a URL to a custom sound file, or set to null to disable the sound.
113
+ */
114
+ orderExecuted?: string | null;
115
+ /**
116
+ * The sound to play when the order is executed. Defaults to world wide famous CoW Swap unhappy moooooooooo!
117
+ * Alternatively, you can use a URL to a custom sound file, or set to null to disable the sound.
118
+ */
119
+ orderError?: string | null;
120
+ }
121
+ export interface CowSwapWidgetImages {
122
+ /**
123
+ * The image to display when the orders table is empty (no orders yet). It defaults to "Yoga CoW" image.
124
+ * Alternatively, you can use a URL to a custom image file, or set to null to disable the image.
125
+ */
126
+ emptyOrders?: string | null;
127
+ }
128
+ export interface CowSwapWidgetContent {
129
+ feeLabel?: string;
130
+ feeTooltipMarkdown?: string;
131
+ }
132
+ export interface SlippageConfig {
133
+ /** Minimum slippage in basis points (e.g., 10 = 0.1%) */
134
+ min?: number;
135
+ /** Maximum slippage in basis points (e.g., 5000 = 50%) - 5000 is max value for dApp */
136
+ max?: number;
137
+ /** Default slippage value in basis points (e.g., 50 = 0.5%) - min <= defaultValue <= max */
138
+ defaultValue?: number;
139
+ }
140
+ export type FlexibleSlippageConfig = FlexibleConfig<SlippageConfig>;
141
+ export interface CowSwapWidgetParams {
142
+ /**
143
+ * The unique identifier of the widget consumer.
144
+ * Please fill the for to let us know a little about you: https://cowprotocol.typeform.com/to/rONXaxHV
145
+ */
146
+ appCode: string;
147
+ /**
148
+ * The width of the widget in pixels. Default: 400px
149
+ */
150
+ width?: string;
151
+ /**
152
+ * The height of the widget in pixels. Default: 600px
153
+ */
154
+ height?: string;
155
+ /**
156
+ * The maximum height of the widget in pixels. Default: body.offsetHeight
157
+ */
158
+ maxHeight?: number;
159
+ /**
160
+ * Network ID.
161
+ */
162
+ chainId?: SupportedChainId;
163
+ /**
164
+ * An id of a network to bridge the output token.
165
+ */
166
+ targetChainId?: number;
167
+ /**
168
+ * The token lists urls to use in the widget
169
+ */
170
+ tokenLists?: string[];
171
+ /**
172
+ * Swap, Limit or Advanced (Twap).
173
+ */
174
+ tradeType?: TradeType;
175
+ /**
176
+ * The base url of the widget implementation
177
+ * The parameter can have the URL directly, or an object with the environment property,
178
+ * The base URL will default to the production environment if not specified, so it will use https://swap.cow.fi by default.
179
+ */
180
+ baseUrl?: string;
181
+ /**
182
+ * Sell token, and optionally the amount.
183
+ */
184
+ sell?: TradeAsset;
185
+ /**
186
+ * Buy token, and optionally the amount.
187
+ */
188
+ buy?: TradeAsset;
189
+ /**
190
+ * Forced order deadline in minutes. When set, user's won't be able to edit the deadline.
191
+ *
192
+ * Either a single value applied to each individual order type accordingly or an optional individual value per order type.
193
+ *
194
+ * The app will use the appropriated min/max value per order type.
195
+ */
196
+ forcedOrderDeadline?: ForcedOrderDeadline;
197
+ /**
198
+ * Enables the ability to switch between trade types in the widget.
199
+ */
200
+ enabledTradeTypes?: TradeType[];
201
+ /**
202
+ * The partner fee
203
+ *
204
+ * Please contact https://cowprotocol.typeform.com/to/rONXaxHV
205
+ */
206
+ partnerFee?: PartnerFee;
207
+ /**
208
+ * Disables cross-chain swaps (bridging)
209
+ * Defaults to false.
210
+ */
211
+ disableCrossChainSwap?: boolean;
212
+ /**
213
+ * Disables showing the confirmation modal you get after posting an order.
214
+ * Defaults to false.
215
+ */
216
+ disablePostedOrderConfirmationModal?: boolean;
217
+ /**
218
+ * Disables showing the progress bar after a SWAP order is placed.
219
+ * The SWAP progress bar offers a transparent view into CoW Protocol's unique solution finding mechanism.
220
+ * If you wish to not show it, set `disableProgressBar` to `true`.
221
+ *
222
+ * Defaults to false.
223
+ */
224
+ disableProgressBar?: boolean;
225
+ /**
226
+ * Disables showing the toast messages.
227
+ * Some UI might want to disable it and subscribe to WidgetMethodsEmit.ON_TOAST_MESSAGE event to handle the toast messages itself.
228
+ * Defaults to false.
229
+ */
230
+ disableToastMessages?: boolean;
231
+ /**
232
+ * Option to hide the logo in the widget.
233
+ */
234
+ hideLogo?: boolean;
235
+ /**
236
+ * Option to hide the network selector in the widget.
237
+ */
238
+ hideNetworkSelector?: boolean;
239
+ /**
240
+ * Option to hide bridge info
241
+ */
242
+ hideBridgeInfo?: boolean;
243
+ /**
244
+ * Option to hide orders table on LIMIT and TWAP forms.
245
+ *
246
+ * Warning! When `true`, users won't be able to see their LIMIT/TWAP order status or history, neither they'll be able to cancel active orders.
247
+ */
248
+ hideOrdersTable?: boolean;
249
+ /**
250
+ * Defines the widget mode.
251
+ * - `true` (standalone mode): The widget is standalone, so it will use its own Ethereum provider. The user can connect from within the widget.
252
+ * - `false` (dapp mode): The widget is embedded in a dapp which is responsible for providing the Ethereum provider. Therefore, there won't be a connect button in the widget as this should happen in the host app.
253
+ *
254
+ * Defaults to standalone.
255
+ */
256
+ standaloneMode?: boolean;
257
+ /**
258
+ * The theme of the widget UI.
259
+ */
260
+ theme?: CowSwapTheme | CowSwapWidgetPalette;
261
+ /**
262
+ * Customizable images for the widget.
263
+ */
264
+ images?: CowSwapWidgetImages;
265
+ /**
266
+ * Sounds configuration for the app.
267
+ */
268
+ sounds?: CowSwapWidgetSounds;
269
+ /**
270
+ * In case when widget does not support some tokens, you can provide a list of tokens to be used in the widget
271
+ */
272
+ customTokens?: TokenInfo[];
273
+ /**
274
+ * Customizable labels and content for the widget.
275
+ */
276
+ content?: CowSwapWidgetContent;
277
+ /**
278
+ * Customizable slippage settings for the widget.
279
+ */
280
+ slippage?: FlexibleSlippageConfig;
281
+ }
282
+ export interface WidgetMethodsEmitPayloadMap {
283
+ [WidgetMethodsEmit.ACTIVATE]: void;
284
+ [WidgetMethodsEmit.EMIT_COW_EVENT]: EmitCowEventPayload<CowWidgetEvents>;
285
+ [WidgetMethodsEmit.UPDATE_HEIGHT]: UpdateWidgetHeightPayload;
286
+ [WidgetMethodsEmit.SET_FULL_HEIGHT]: SetWidgetFullHeightPayload;
287
+ [WidgetMethodsEmit.PROVIDER_RPC_REQUEST]: ProviderRpcRequestPayload;
288
+ [WidgetMethodsEmit.INTERCEPT_WINDOW_OPEN]: WindowOpenPayload;
289
+ }
290
+ export interface WidgetMethodsListenPayloadMap {
291
+ [WidgetMethodsListen.UPDATE_APP_DATA]: UpdateAppDataPayload;
292
+ [WidgetMethodsListen.UPDATE_PARAMS]: UpdateParamsPayload;
293
+ [WidgetMethodsListen.PROVIDER_RPC_RESPONSE]: ProviderRpcResponsePayload;
294
+ [WidgetMethodsListen.PROVIDER_ON_EVENT]: ProviderOnEventPayload;
295
+ }
296
+ export type WidgetEventsPayloadMap = WidgetMethodsEmitPayloadMap & WidgetMethodsListenPayloadMap;
297
+ export type WidgetMethodsEmitPayloads = WidgetMethodsEmitPayloadMap[WidgetMethodsEmit];
298
+ export type WidgetMethodsListenPayloads = WidgetMethodsListenPayloadMap[WidgetMethodsListen];
299
+ export type CowSwapWidgetAppParams = Omit<CowSwapWidgetParams, 'theme'>;
300
+ export interface UpdateParamsPayload {
301
+ urlParams: {
302
+ pathname: string;
303
+ search: string;
304
+ };
305
+ appParams: CowSwapWidgetAppParams;
306
+ hasProvider: boolean;
307
+ }
308
+ export interface UpdateAppDataPayload {
309
+ metaData?: {
310
+ appCode: string;
311
+ };
312
+ }
313
+ export interface UpdateWidgetHeightPayload {
314
+ height?: number;
315
+ }
316
+ export interface SetWidgetFullHeightPayload {
317
+ isUpToSmall?: boolean;
318
+ }
319
+ export interface EmitCowEventPayload<T extends CowWidgetEvents> {
320
+ event: T;
321
+ payload: CowWidgetEventPayloadMap[T];
322
+ }
323
+ export type WidgetMethodsEmitListener<T extends WidgetMethodsEmit> = T extends WidgetMethodsEmit ? {
324
+ event: T;
325
+ handler: WidgetMethodHandler<T>;
326
+ } : never;
327
+ export type WidgetMethodHandler<T extends WidgetMethodsEmit> = (payload: WidgetMethodsEmitPayloadMap[T]) => void;
328
+ export interface ProviderRpcRequestPayload {
329
+ rpcRequest: JsonRpcRequestMessage;
330
+ }
331
+ export interface WindowOpenPayload {
332
+ href: string | URL;
333
+ target: string;
334
+ rel: string;
335
+ }
336
+ export interface JsonRpcRequestMessage {
337
+ jsonrpc: '2.0';
338
+ id?: number;
339
+ method: string;
340
+ params: unknown[];
341
+ }
342
+ export interface BaseJsonRpcResponseMessage {
343
+ id: number;
344
+ jsonrpc: '2.0';
345
+ }
346
+ export interface JsonRpcSucessfulResponseMessage<TResult = unknown> extends BaseJsonRpcResponseMessage {
347
+ result: TResult;
348
+ }
349
+ export interface JsonRpcError<TData = unknown> {
350
+ code: number;
351
+ message: string;
352
+ data?: TData;
353
+ }
354
+ export interface JsonRpcErrorResponseMessage<TErrorData = unknown> extends BaseJsonRpcResponseMessage {
355
+ error: JsonRpcError<TErrorData>;
356
+ }
357
+ export type ProviderRpcResponsePayload = {
358
+ rpcResponse: JsonRpcResponse;
359
+ };
360
+ export type JsonRpcResponse = JsonRpcRequestMessage | JsonRpcErrorResponseMessage | JsonRpcSucessfulResponseMessage;
361
+ export interface ProviderOnEventPayload {
362
+ event: string;
363
+ params: unknown;
364
+ }
365
+ export type WindowListener = (event: MessageEvent<unknown>) => void;
package/src/types.js ADDED
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WIDGET_PALETTE_COLORS = exports.TradeType = exports.WidgetMethodsListen = exports.WidgetMethodsEmit = void 0;
4
+ var WidgetMethodsEmit;
5
+ (function (WidgetMethodsEmit) {
6
+ WidgetMethodsEmit["ACTIVATE"] = "ACTIVATE";
7
+ WidgetMethodsEmit["UPDATE_HEIGHT"] = "UPDATE_HEIGHT";
8
+ WidgetMethodsEmit["SET_FULL_HEIGHT"] = "SET_FULL_HEIGHT";
9
+ WidgetMethodsEmit["EMIT_COW_EVENT"] = "EMIT_COW_EVENT";
10
+ WidgetMethodsEmit["PROVIDER_RPC_REQUEST"] = "PROVIDER_RPC_REQUEST";
11
+ WidgetMethodsEmit["INTERCEPT_WINDOW_OPEN"] = "INTERCEPT_WINDOW_OPEN";
12
+ })(WidgetMethodsEmit || (exports.WidgetMethodsEmit = WidgetMethodsEmit = {}));
13
+ var WidgetMethodsListen;
14
+ (function (WidgetMethodsListen) {
15
+ WidgetMethodsListen["UPDATE_PARAMS"] = "UPDATE_PARAMS";
16
+ WidgetMethodsListen["UPDATE_APP_DATA"] = "UPDATE_APP_DATA";
17
+ WidgetMethodsListen["PROVIDER_RPC_RESPONSE"] = "PROVIDER_RPC_RESPONSE";
18
+ WidgetMethodsListen["PROVIDER_ON_EVENT"] = "PROVIDER_ON_EVENT";
19
+ })(WidgetMethodsListen || (exports.WidgetMethodsListen = WidgetMethodsListen = {}));
20
+ var TradeType;
21
+ (function (TradeType) {
22
+ TradeType["SWAP"] = "swap";
23
+ TradeType["LIMIT"] = "limit";
24
+ /**
25
+ * Currently it means only TWAP orders.
26
+ * But in the future it can be extended to support other order types.
27
+ */
28
+ TradeType["ADVANCED"] = "advanced";
29
+ TradeType["YIELD"] = "yield";
30
+ })(TradeType || (exports.TradeType = TradeType = {}));
31
+ exports.WIDGET_PALETTE_COLORS = [
32
+ 'primary',
33
+ 'background',
34
+ 'paper',
35
+ 'text',
36
+ 'danger',
37
+ 'warning',
38
+ 'alert',
39
+ 'info',
40
+ 'success',
41
+ ];
42
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../libs/widget-lib/src/types.ts"],"names":[],"mappings":";;;AAgBA,IAAY,iBAOX;AAPD,WAAY,iBAAiB;IAC3B,0CAAqB,CAAA;IACrB,oDAA+B,CAAA;IAC/B,wDAAmC,CAAA;IACnC,sDAAiC,CAAA;IACjC,kEAA6C,CAAA;IAC7C,oEAA+C,CAAA;AACjD,CAAC,EAPW,iBAAiB,iCAAjB,iBAAiB,QAO5B;AAED,IAAY,mBAKX;AALD,WAAY,mBAAmB;IAC7B,sDAA+B,CAAA;IAC/B,0DAAmC,CAAA;IACnC,sEAA+C,CAAA;IAC/C,8DAAuC,CAAA;AACzC,CAAC,EALW,mBAAmB,mCAAnB,mBAAmB,QAK9B;AAmDD,IAAY,SASX;AATD,WAAY,SAAS;IACnB,0BAAa,CAAA;IACb,4BAAe,CAAA;IACf;;;OAGG;IACH,kCAAqB,CAAA;IACrB,4BAAe,CAAA;AACjB,CAAC,EATW,SAAS,yBAAT,SAAS,QASpB;AA6BY,QAAA,qBAAqB,GAAG;IACnC,SAAS;IACT,YAAY;IACZ,OAAO;IACP,MAAM;IACN,QAAQ;IACR,SAAS;IACT,OAAO;IACP,MAAM;IACN,SAAS;CACD,CAAA"}
@@ -0,0 +1,4 @@
1
+ import { CowSwapWidgetParams } from './types';
2
+ export declare function buildWidgetUrl(params: Partial<CowSwapWidgetParams>): string;
3
+ export declare function buildWidgetPath(params: Partial<CowSwapWidgetParams>): string;
4
+ export declare function buildWidgetUrlQuery(params: Partial<CowSwapWidgetParams>): URLSearchParams;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildWidgetUrl = buildWidgetUrl;
4
+ exports.buildWidgetPath = buildWidgetPath;
5
+ exports.buildWidgetUrlQuery = buildWidgetUrlQuery;
6
+ const themeUtils_1 = require("./themeUtils");
7
+ const types_1 = require("./types");
8
+ const EMPTY_TOKEN = '_';
9
+ function buildWidgetUrl(params) {
10
+ const host = typeof params.baseUrl === 'string' ? params.baseUrl : 'https://swap.cow.fi';
11
+ const path = buildWidgetPath(params);
12
+ return host + '/#' + path + '?' + buildWidgetUrlQuery(params);
13
+ }
14
+ function buildWidgetPath(params) {
15
+ const { chainId = 1, sell, buy, tradeType = types_1.TradeType.SWAP } = params;
16
+ const assetsPath = [sell?.asset || EMPTY_TOKEN, buy?.asset || EMPTY_TOKEN].map(encodeURIComponent).join('/');
17
+ return `/${chainId}/widget/${tradeType}/${assetsPath}`;
18
+ }
19
+ function buildWidgetUrlQuery(params) {
20
+ const query = new URLSearchParams();
21
+ return addTargetChainIdToQuery(addThemePaletteToQuery(addTradeAmountsToQuery(query, params), params), params);
22
+ }
23
+ function addTradeAmountsToQuery(query, params) {
24
+ const { sell, buy } = params;
25
+ if (sell?.amount) {
26
+ query.append('sellAmount', sell.amount);
27
+ }
28
+ if (buy?.amount) {
29
+ query.append('buyAmount', buy.amount);
30
+ }
31
+ return query;
32
+ }
33
+ function addThemePaletteToQuery(query, params) {
34
+ const theme = params.theme;
35
+ if (!theme) {
36
+ query.append('palette', 'null');
37
+ return query;
38
+ }
39
+ if ((0, themeUtils_1.isCowSwapWidgetPalette)(theme)) {
40
+ query.append('palette', encodeURIComponent(JSON.stringify(theme)));
41
+ query.append('theme', theme.baseTheme);
42
+ }
43
+ else {
44
+ query.append('palette', 'null');
45
+ query.append('theme', theme);
46
+ }
47
+ return query;
48
+ }
49
+ function addTargetChainIdToQuery(query, params) {
50
+ if (params.targetChainId) {
51
+ query.append('targetChainId', params.targetChainId.toString());
52
+ }
53
+ return query;
54
+ }
55
+ //# sourceMappingURL=urlUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"urlUtils.js","sourceRoot":"","sources":["../../../../libs/widget-lib/src/urlUtils.ts"],"names":[],"mappings":";;AAKA,wCAKC;AAED,0CAMC;AAED,kDAIC;AAxBD,6CAAqD;AACrD,mCAAwD;AAExD,MAAM,WAAW,GAAG,GAAG,CAAA;AAEvB,SAAgB,cAAc,CAAC,MAAoC;IACjE,MAAM,IAAI,GAAG,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAA;IACxF,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,CAAC,CAAA;IAEpC,OAAO,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAA;AAC/D,CAAC;AAED,SAAgB,eAAe,CAAC,MAAoC;IAClE,MAAM,EAAE,OAAO,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,GAAG,iBAAS,CAAC,IAAI,EAAE,GAAG,MAAM,CAAA;IAErE,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,KAAK,IAAI,WAAW,EAAE,GAAG,EAAE,KAAK,IAAI,WAAW,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAE5G,OAAO,IAAI,OAAO,WAAW,SAAS,IAAI,UAAU,EAAE,CAAA;AACxD,CAAC;AAED,SAAgB,mBAAmB,CAAC,MAAoC;IACtE,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAA;IAEnC,OAAO,uBAAuB,CAAC,sBAAsB,CAAC,sBAAsB,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAA;AAC/G,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAsB,EAAE,MAAoC;IAC1F,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,CAAA;IAE5B,IAAI,IAAI,EAAE,MAAM,EAAE,CAAC;QACjB,KAAK,CAAC,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IACzC,CAAC;IAED,IAAI,GAAG,EAAE,MAAM,EAAE,CAAC;QAChB,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACvC,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAsB,EAAE,MAAoC;IAC1F,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAA;IAE1B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;QAC/B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,IAAA,mCAAsB,EAAC,KAAK,CAAC,EAAE,CAAC;QAClC,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAClE,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,CAAA;IACxC,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;QAC/B,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IAC9B,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,uBAAuB,CAAC,KAAsB,EAAE,MAAoC;IAC3F,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;QACzB,KAAK,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC,CAAA;IAChE,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { IframeTransport } from '@cowprotocol/iframe-transport';
2
+ import { WidgetEventsPayloadMap } from './types';
3
+ export declare const widgetIframeTransport: IframeTransport<WidgetEventsPayloadMap>;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.widgetIframeTransport = void 0;
4
+ const iframe_transport_1 = require("@cowprotocol/iframe-transport");
5
+ exports.widgetIframeTransport = new iframe_transport_1.IframeTransport('cowSwapWidget');
6
+ //# sourceMappingURL=widgetIframeTransport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widgetIframeTransport.js","sourceRoot":"","sources":["../../../../libs/widget-lib/src/widgetIframeTransport.ts"],"names":[],"mappings":";;;AAAA,oEAA+D;AAIlD,QAAA,qBAAqB,GAAG,IAAI,kCAAe,CAAyB,eAAe,CAAC,CAAA"}
package/jest.config.ts DELETED
@@ -1,10 +0,0 @@
1
- export default {
2
- displayName: 'widget-lib',
3
- preset: '../../jest.preset.js',
4
- transform: {
5
- '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
6
- },
7
- setupFilesAfterEnv: ['../../jest.setup.ts'],
8
- moduleFileExtensions: ['ts', 'js', 'html'],
9
- coverageDirectory: '../../../coverage/libs/widget-lib',
10
- }
package/project.json DELETED
@@ -1,51 +0,0 @@
1
- {
2
- "name": "widget-lib",
3
- "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
- "sourceRoot": "libs/widget-lib/src",
5
- "projectType": "library",
6
- "targets": {
7
- "build": {
8
- "executor": "@nx/js:tsc",
9
- "outputs": ["{options.outputPath}"],
10
- "options": {
11
- "outputPath": "dist/libs/widget-lib",
12
- "main": "libs/widget-lib/src/index.ts",
13
- "tsConfig": "libs/widget-lib/tsconfig.lib.json",
14
- "assets": ["libs/widget-lib/*.md"],
15
- "updateBuildableProjectDepsInPackageJson": true,
16
- "buildableProjectDepsInPackageJsonType": "dependencies"
17
- }
18
- },
19
- "serve": {
20
- "executor": "@nx/vite:dev-server",
21
- "defaultConfiguration": "development",
22
- "options": {
23
- "buildTarget": "widget-lib:build",
24
- "port": 3012
25
- },
26
- "configurations": {}
27
- },
28
- "lint": {
29
- "executor": "@nx/eslint:lint",
30
- "outputs": ["{options.outputFile}"],
31
- "options": {
32
- "lintFilePatterns": ["libs/widget-lib/**/*.ts"]
33
- }
34
- },
35
- "test": {
36
- "executor": "@nx/jest:jest",
37
- "outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
38
- "options": {
39
- "jestConfig": "libs/widget-lib/jest.config.ts",
40
- "passWithNoTests": true
41
- },
42
- "configurations": {
43
- "ci": {
44
- "ci": true,
45
- "codeCoverage": true
46
- }
47
- }
48
- }
49
- },
50
- "tags": []
51
- }
@@ -1,47 +0,0 @@
1
- import {
2
- SimpleCowEventEmitter,
3
- CowWidgetEventListeners,
4
- CowWidgetEvents,
5
- CowWidgetEventPayloadMap,
6
- } from '@cowprotocol/events'
7
-
8
- import { WindowListener, WidgetMethodsEmit } from './types'
9
- import { widgetIframeTransport } from './widgetIframeTransport'
10
-
11
- export class IframeCowEventEmitter {
12
- private eventEmitter = new SimpleCowEventEmitter<CowWidgetEventPayloadMap, CowWidgetEvents>()
13
- private listeners: CowWidgetEventListeners = []
14
- private widgetListener: WindowListener
15
-
16
- constructor(
17
- private contentWindow: Window,
18
- listeners: CowWidgetEventListeners = [],
19
- ) {
20
- // Subscribe listeners to local event emitter
21
- this.updateListeners(listeners)
22
-
23
- // Listen to iFrame, and forward to local event emitter
24
- this.widgetListener = widgetIframeTransport.listenToMessageFromWindow(
25
- this.contentWindow,
26
- WidgetMethodsEmit.EMIT_COW_EVENT,
27
- (cowEvent) => this.eventEmitter.emit(cowEvent.event, cowEvent.payload),
28
- )
29
- }
30
-
31
- public stopListeningIframe(): void {
32
- widgetIframeTransport.stopListeningWindowListener(this.contentWindow, this.widgetListener)
33
- }
34
-
35
- public updateListeners(listeners?: CowWidgetEventListeners): void {
36
- // Unsubscribe from previous listeners
37
- for (const listener of this.listeners) {
38
- this.eventEmitter.off(listener)
39
- }
40
-
41
- // Subscribe to events
42
- this.listeners = listeners || []
43
- for (const listener of this.listeners) {
44
- this.eventEmitter.on(listener)
45
- }
46
- }
47
- }
@@ -1,77 +0,0 @@
1
- export class IframeSafeSdkBridge {
2
- forwardSdkMessage: (event: MessageEvent<unknown>) => void
3
-
4
- constructor(
5
- private appWindow: Window,
6
- private iframeWidow: Window,
7
- ) {
8
- this.forwardSdkMessage = (event: MessageEvent<unknown>) => {
9
- if (!isSafeMessage(event.data)) {
10
- return
11
- }
12
-
13
- if (typeof window !== 'undefined' && event.origin === window.location.origin) {
14
- return
15
- }
16
-
17
- if (isSafeMessageRequest(event.data)) {
18
- this.appWindow.parent.postMessage(event.data, '*')
19
- } else if (isSafeMessageResponse(event.data)) {
20
- this.iframeWidow.postMessage(event.data, '*')
21
- }
22
- }
23
-
24
- this.startListening()
25
- }
26
-
27
- private startListening(): void {
28
- this.appWindow.addEventListener('message', this.forwardSdkMessage)
29
- }
30
-
31
- public stopListening(): void {
32
- this.appWindow.removeEventListener('message', this.forwardSdkMessage)
33
- }
34
- }
35
-
36
- function isSafeMessage(obj: unknown): obj is SafeMessage {
37
- return typeof obj === 'object' && obj !== null && 'id' in obj && typeof obj.id === 'string'
38
- }
39
-
40
- function isSafeMessageRequest(message: SafeMessage): message is SafeMessageRequest {
41
- return (
42
- 'method' in message &&
43
- typeof message.method === 'string' &&
44
- 'params' in message &&
45
- 'env' in message &&
46
- typeof message.env === 'object' &&
47
- message.env !== null &&
48
- 'sdkVersion' in message.env
49
- )
50
- }
51
-
52
- function isSafeMessageResponse(message: SafeMessage): message is SafeMessageResponse {
53
- return (
54
- 'success' in message &&
55
- typeof message.success === 'boolean' &&
56
- 'version' in message &&
57
- typeof message.version === 'string'
58
- )
59
- }
60
-
61
- interface SafeMessage {
62
- id: string
63
- }
64
-
65
- interface SafeMessageRequest extends SafeMessage {
66
- method: string
67
- params: unknown
68
- env: {
69
- sdkVersion: string
70
- }
71
- }
72
-
73
- interface SafeMessageResponse extends SafeMessage {
74
- id: string
75
- success: boolean
76
- version: string
77
- }