@rabby-wallet/rabby-swap 0.0.87 → 0.0.88-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/abi.d.ts CHANGED
@@ -335,3 +335,29 @@ export declare const SushiABI: ({
335
335
  stateMutability: string;
336
336
  type: string;
337
337
  })[];
338
+ export declare const UniABI: {
339
+ inputs: {
340
+ internalType: string;
341
+ name: string;
342
+ type: string;
343
+ }[];
344
+ name: string;
345
+ outputs: never[];
346
+ stateMutability: string;
347
+ type: string;
348
+ }[];
349
+ export declare const MagpieABI: {
350
+ inputs: {
351
+ internalType: string;
352
+ name: string;
353
+ type: string;
354
+ }[];
355
+ name: string;
356
+ outputs: {
357
+ internalType: string;
358
+ name: string;
359
+ type: string;
360
+ }[];
361
+ stateMutability: string;
362
+ type: string;
363
+ }[];
package/dist/abi.js CHANGED
@@ -1652,3 +1652,53 @@ export const ZeroXABIV2 = [
1652
1652
  { stateMutability: "payable", type: "fallback" },
1653
1653
  ];
1654
1654
  export const SushiABI = [{ "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, { "inputs": [{ "internalType": "address", "name": "tokenOut", "type": "address" }, { "internalType": "uint256", "name": "amountOut", "type": "uint256" }], "name": "MinimalOutputBalanceViolation", "type": "error" }, { "inputs": [], "name": "safeExecutor", "outputs": [{ "internalType": "contract SafeExecutor", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "contract IERC20", "name": "tokenIn", "type": "address" }, { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "contract IERC20", "name": "tokenOut", "type": "address" }, { "internalType": "uint256", "name": "amountOutMin", "type": "uint256" }, { "internalType": "address", "name": "executor", "type": "address" }, { "internalType": "bytes", "name": "executorData", "type": "bytes" }], "name": "snwap", "outputs": [{ "internalType": "uint256", "name": "amountOut", "type": "uint256" }], "stateMutability": "payable", "type": "function" }, { "inputs": [{ "components": [{ "internalType": "contract IERC20", "name": "token", "type": "address" }, { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, { "internalType": "address", "name": "transferTo", "type": "address" }], "internalType": "struct InputToken[]", "name": "inputTokens", "type": "tuple[]" }, { "components": [{ "internalType": "contract IERC20", "name": "token", "type": "address" }, { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amountOutMin", "type": "uint256" }], "internalType": "struct OutputToken[]", "name": "outputTokens", "type": "tuple[]" }, { "components": [{ "internalType": "address", "name": "executor", "type": "address" }, { "internalType": "uint256", "name": "value", "type": "uint256" }, { "internalType": "bytes", "name": "data", "type": "bytes" }], "internalType": "struct Executor[]", "name": "executors", "type": "tuple[]" }], "name": "snwapMultiple", "outputs": [{ "internalType": "uint256[]", "name": "amountOut", "type": "uint256[]" }], "stateMutability": "payable", "type": "function" }];
1655
+ export const UniABI = [
1656
+ {
1657
+ inputs: [
1658
+ { internalType: "bytes", name: "commands", type: "bytes" },
1659
+ { internalType: "bytes[]", name: "inputs", type: "bytes[]" },
1660
+ ],
1661
+ name: "execute",
1662
+ outputs: [],
1663
+ stateMutability: "payable",
1664
+ type: "function",
1665
+ },
1666
+ {
1667
+ inputs: [
1668
+ { internalType: "bytes", name: "commands", type: "bytes" },
1669
+ { internalType: "bytes[]", name: "inputs", type: "bytes[]" },
1670
+ { internalType: "uint256", name: "deadline", type: "uint256" },
1671
+ ],
1672
+ name: "execute",
1673
+ outputs: [],
1674
+ stateMutability: "payable",
1675
+ type: "function",
1676
+ },
1677
+ {
1678
+ inputs: [
1679
+ {
1680
+ internalType: "contract IUniversalRouter",
1681
+ name: "router",
1682
+ type: "address",
1683
+ },
1684
+ { internalType: "address", name: "token", type: "address" },
1685
+ { internalType: "uint256", name: "amount", type: "uint256" },
1686
+ { internalType: "bytes", name: "commands", type: "bytes" },
1687
+ { internalType: "bytes[]", name: "inputs", type: "bytes[]" },
1688
+ { internalType: "uint256", name: "deadline", type: "uint256" },
1689
+ ],
1690
+ name: "execute",
1691
+ outputs: [],
1692
+ stateMutability: "nonpayable",
1693
+ type: "function",
1694
+ },
1695
+ ];
1696
+ export const MagpieABI = [
1697
+ {
1698
+ inputs: [{ internalType: "bytes", name: "swapData", type: "bytes" }],
1699
+ name: "swapWithMagpieSignature",
1700
+ outputs: [{ internalType: "uint256", name: "amountOut", type: "uint256" }],
1701
+ stateMutability: "payable",
1702
+ type: "function",
1703
+ },
1704
+ ];
@@ -1,5 +1,8 @@
1
- import { CHAINS_ENUM } from "@debank/common";
2
- import { generateGetQuote } from "../utils";
1
+ import { CHAINS, CHAINS_ENUM } from "@debank/common";
2
+ import { Interface } from "@ethersproject/abi";
3
+ import BigNumber from "bignumber.js";
4
+ import { MagpieABI } from "../abi";
5
+ import { generateGetQuote, isSameAddress, NULL_ADDRESS, resolveToTokenReceiver, } from "../utils";
3
6
  import { DEX_ENUM } from "../consts";
4
7
  export const SUPPORT_CHAINS = [
5
8
  CHAINS_ENUM.ETH,
@@ -37,6 +40,55 @@ export const getQuote = generateGetQuote({
37
40
  id: "magpie",
38
41
  dex: DEX_ENUM.MAGPIE,
39
42
  });
43
+ const magpieInterface = new Interface(MagpieABI);
44
+ // MagpieRouterV3 LibRouter.getData() 用绝对 calldata 偏移,不是 ABI tuple。
45
+ // swapWithMagpieSignature(bytes) 标准编码下 bytes 从第 68 字节开始。
46
+ const Packed = {
47
+ toAddress: 72,
48
+ fromAsset: 92,
49
+ toAsset: 112,
50
+ amountOutMin: { shift: 135, ptr: 136 },
51
+ amountIn: { shift: 141, ptr: 142 },
52
+ };
53
+ const readCompactUint = (hex, field) => {
54
+ const shiftBits = hex.slice(field.shift * 2, field.shift * 2 + 2);
55
+ const wordOffset = hex.slice(field.ptr * 2, field.ptr * 2 + 4);
56
+ if (shiftBits.length !== 2 || wordOffset.length !== 4)
57
+ return null;
58
+ const word = hex.slice(parseInt(wordOffset, 16) * 2, parseInt(wordOffset, 16) * 2 + 64);
59
+ if (word.length !== 64)
60
+ return null;
61
+ return new BigNumber(word, 16)
62
+ .idiv(new BigNumber(2).pow(parseInt(shiftBits, 16)))
63
+ .toFixed(0);
64
+ };
40
65
  export const decodeCalldata = (tx) => {
41
- return null;
66
+ const chain = Object.values(CHAINS).find((item) => item.id === tx.chainId);
67
+ if (!chain)
68
+ return null;
69
+ const result = magpieInterface.parseTransaction({ data: tx.data });
70
+ if (result.name !== "swapWithMagpieSignature")
71
+ return null;
72
+ const hex = tx.data.replace(/^0x/i, "").toLowerCase();
73
+ if (hex.length < (Packed.toAsset + 20) * 2)
74
+ return null;
75
+ const toAddress = `0x${hex.slice(Packed.toAddress * 2, (Packed.toAddress + 20) * 2)}`;
76
+ const fromAsset = `0x${hex.slice(Packed.fromAsset * 2, (Packed.fromAsset + 20) * 2)}`;
77
+ const toAsset = `0x${hex.slice(Packed.toAsset * 2, (Packed.toAsset + 20) * 2)}`;
78
+ const amountOutMin = readCompactUint(hex, Packed.amountOutMin);
79
+ const amountIn = readCompactUint(hex, Packed.amountIn);
80
+ if (!amountOutMin || !amountIn) {
81
+ return null;
82
+ }
83
+ return {
84
+ fromToken: isSameAddress(fromAsset, NULL_ADDRESS)
85
+ ? chain.nativeTokenAddress
86
+ : fromAsset,
87
+ fromTokenAmount: amountIn,
88
+ toToken: isSameAddress(toAsset, NULL_ADDRESS)
89
+ ? chain.nativeTokenAddress
90
+ : toAsset,
91
+ minReceiveToTokenAmount: amountOutMin,
92
+ toTokenReceiver: resolveToTokenReceiver(toAddress, tx.from),
93
+ };
42
94
  };
@@ -1,5 +1,5 @@
1
1
  import { CHAINS_ENUM } from "@debank/common";
2
- import { TxWithChainId, DecodeCalldataResult } from "../quote";
2
+ import { DecodeCalldataResult, TxWithChainId } from "../quote";
3
3
  export declare const SUPPORT_CHAINS: CHAINS_ENUM[];
4
4
  export declare const UNI_NATIVE_TO_ADDRESSES: Record<CHAINS_ENUM, string>;
5
5
  export declare const getQuote: (options: import("../quote").QuoteParams, api: import("@rabby-wallet/rabby-api").OpenApiService) => Promise<import("../quote").QuoteResult>;
package/dist/dexs/uni.js CHANGED
@@ -1,5 +1,8 @@
1
- import { CHAINS_ENUM } from "@debank/common";
2
- import { generateGetQuote } from "../utils";
1
+ import { CHAINS, CHAINS_ENUM } from "@debank/common";
2
+ import { defaultAbiCoder, Interface } from "@ethersproject/abi";
3
+ import BigNumber from "bignumber.js";
4
+ import { UniABI } from "../abi";
5
+ import { generateGetQuote, isSameAddress, NULL_ADDRESS } from "../utils";
3
6
  import { DEX_ENUM } from "../consts";
4
7
  export const SUPPORT_CHAINS = [
5
8
  CHAINS_ENUM.ETH,
@@ -40,6 +43,299 @@ export const getQuote = generateGetQuote({
40
43
  id: "uni",
41
44
  dex: DEX_ENUM.UNI,
42
45
  });
43
- export const decodeCalldata = (tx) => {
46
+ const uniInterface = new Interface(UniABI);
47
+ const MSG_SENDER = "0x0000000000000000000000000000000000000001";
48
+ const ROUTER = "0x0000000000000000000000000000000000000002";
49
+ const EETH = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
50
+ const CONTRACT_BALANCE = new BigNumber(2).pow(255);
51
+ const COMMAND_MASK = 0x7f;
52
+ const Command = {
53
+ V3_EXACT_IN: 0x00,
54
+ V3_EXACT_OUT: 0x01,
55
+ SWEEP: 0x04,
56
+ TRANSFER: 0x05,
57
+ V2_EXACT_IN: 0x08,
58
+ V2_EXACT_OUT: 0x09,
59
+ WRAP_ETH: 0x0b,
60
+ UNWRAP_WETH: 0x0c,
61
+ UNWRAP_WETH_EXACT: 0x0f,
62
+ V4_SWAP: 0x10,
63
+ SUB_PLAN: 0x21,
64
+ };
65
+ const V4 = {
66
+ EXACT_IN_SINGLE: 0x06,
67
+ EXACT_IN: 0x07,
68
+ EXACT_OUT_SINGLE: 0x08,
69
+ EXACT_OUT: 0x09,
70
+ TAKE: 0x0e,
71
+ TAKE_ALL: 0x0f,
72
+ TAKE_PAIR: 0x11,
73
+ SWEEP: 0x14,
74
+ WRAP: 0x15,
75
+ UNWRAP: 0x16,
76
+ };
77
+ const POOL_KEY = "tuple(address,address,uint24,int24,address)";
78
+ const PATH_HOP = "tuple(address,uint24,int24,address,bytes)";
79
+ const decode = (types, data) => {
80
+ try {
81
+ return defaultAbiCoder.decode(types, data);
82
+ }
83
+ catch (_a) {
84
+ return null;
85
+ }
86
+ };
87
+ const decodeAny = (variants, data) => {
88
+ for (const types of variants) {
89
+ const result = decode(types, data);
90
+ if (result)
91
+ return result;
92
+ }
44
93
  return null;
45
94
  };
95
+ const chainToken = (token, native) => isSameAddress(token, NULL_ADDRESS) || isSameAddress(token, EETH)
96
+ ? native
97
+ : token;
98
+ const realAmount = (amount, fallback) => CONTRACT_BALANCE.eq(amount) && fallback ? fallback : amount;
99
+ const setSwap = (swap, ctx, fromToken, toToken, amountA, amountB, exactOut) => {
100
+ if (exactOut || !swap.wrappedNativeIn) {
101
+ swap.fromToken = chainToken(fromToken, ctx.native);
102
+ }
103
+ swap.toToken = chainToken(toToken, ctx.native);
104
+ swap.fromTokenAmount = exactOut
105
+ ? amountB
106
+ : realAmount(amountA, swap.fromTokenAmount || ctx.proxyAmount || ctx.txValue);
107
+ swap.minReceive = exactOut ? amountA : amountB;
108
+ };
109
+ const setReceiver = (swap, recipient, txFrom) => {
110
+ if (isSameAddress(recipient, ROUTER))
111
+ return;
112
+ const receiver = isSameAddress(recipient, MSG_SENDER) ? txFrom : recipient;
113
+ if (receiver)
114
+ swap.receiver = receiver;
115
+ };
116
+ const applyAmmSwap = (swap, ctx, input, exactOut, v3) => {
117
+ const result = decode(["address", "uint256", "uint256", v3 ? "bytes" : "address[]", "bool"], input);
118
+ if (!result)
119
+ return;
120
+ const [recipient, amountA, amountB, path] = result;
121
+ let tokens;
122
+ if (v3) {
123
+ // V3 path 是紧凑编码的 token + fee + token,不能按 address[] 解码。
124
+ const hex = path.replace(/^0x/i, "");
125
+ if (hex.length < 86)
126
+ return;
127
+ tokens = [`0x${hex.slice(0, 40)}`, `0x${hex.slice(-40)}`];
128
+ }
129
+ else {
130
+ tokens = path;
131
+ if (!(tokens === null || tokens === void 0 ? void 0 : tokens.length))
132
+ return;
133
+ }
134
+ const first = tokens[0];
135
+ const last = tokens[tokens.length - 1];
136
+ setSwap(swap, ctx, exactOut ? last : first, exactOut ? first : last, amountA.toString(), amountB.toString(), exactOut);
137
+ setReceiver(swap, recipient, ctx.txFrom);
138
+ };
139
+ const wrapNative = (swap, ctx, amount) => {
140
+ swap.wrappedNativeIn = true;
141
+ swap.fromToken = ctx.native;
142
+ swap.fromTokenAmount = realAmount(amount, ctx.txValue);
143
+ };
144
+ const unwrapNative = (swap, ctx, recipient, minOut) => {
145
+ swap.toToken = ctx.native;
146
+ swap.minReceive = minOut;
147
+ setReceiver(swap, recipient, ctx.txFrom);
148
+ };
149
+ const readV4Single = (params) => {
150
+ const decoded = decodeAny([
151
+ [POOL_KEY, "bool", "uint128", "uint128", "uint256", "bytes"],
152
+ [POOL_KEY, "bool", "uint128", "uint128", "bytes"],
153
+ ], params);
154
+ if (!decoded)
155
+ return null;
156
+ const pool = decoded[0];
157
+ const zeroForOne = Boolean(decoded[1]);
158
+ return {
159
+ fromToken: zeroForOne ? pool[0] : pool[1],
160
+ toToken: zeroForOne ? pool[1] : pool[0],
161
+ amountA: decoded[2].toString(),
162
+ amountB: decoded[3].toString(),
163
+ };
164
+ };
165
+ const readV4Path = (params, exactOut) => {
166
+ const decoded = decodeAny([
167
+ ["address", `${PATH_HOP}[]`, "uint256[]", "uint128", "uint128"],
168
+ ["address", `${PATH_HOP}[]`, "uint128", "uint128"],
169
+ ], params);
170
+ if (!decoded)
171
+ return null;
172
+ const path = decoded[1];
173
+ const lastHop = path[path.length - 1];
174
+ const end = (lastHop === null || lastHop === void 0 ? void 0 : lastHop.intermediateCurrency) || (lastHop === null || lastHop === void 0 ? void 0 : lastHop[0]);
175
+ if (!end)
176
+ return null;
177
+ const hasHopPrices = decoded.length === 5;
178
+ const amountA = (hasHopPrices ? decoded[3] : decoded[2]).toString();
179
+ const amountB = (hasHopPrices ? decoded[4] : decoded[3]).toString();
180
+ return exactOut
181
+ ? { fromToken: end, toToken: decoded[0], amountA, amountB }
182
+ : { fromToken: decoded[0], toToken: end, amountA, amountB };
183
+ };
184
+ const walkV4 = (swap, ctx, input) => {
185
+ const decoded = decode(["bytes", "bytes[]"], input);
186
+ if (!decoded)
187
+ return;
188
+ const actions = decoded[0].replace(/^0x/i, "");
189
+ const params = decoded[1];
190
+ for (let i = 0; i < actions.length / 2; i++) {
191
+ const action = parseInt(actions.slice(i * 2, i * 2 + 2), 16);
192
+ const data = params[i];
193
+ if (!data)
194
+ continue;
195
+ if (action === V4.EXACT_IN_SINGLE || action === V4.EXACT_IN ||
196
+ action === V4.EXACT_OUT_SINGLE || action === V4.EXACT_OUT) {
197
+ const exactOut = action === V4.EXACT_OUT_SINGLE || action === V4.EXACT_OUT;
198
+ const single = action === V4.EXACT_IN_SINGLE || action === V4.EXACT_OUT_SINGLE;
199
+ const parsed = single ? readV4Single(data) : readV4Path(data, exactOut);
200
+ if (parsed) {
201
+ setSwap(swap, ctx, parsed.fromToken, parsed.toToken, parsed.amountA, parsed.amountB, exactOut);
202
+ }
203
+ }
204
+ else if (action === V4.TAKE) {
205
+ const take = decode(["address", "address", "uint256"], data);
206
+ if (!take)
207
+ continue;
208
+ swap.toToken = chainToken(take[0], ctx.native);
209
+ setReceiver(swap, take[1], ctx.txFrom);
210
+ }
211
+ else if (action === V4.TAKE_ALL) {
212
+ const take = decode(["address", "uint256"], data);
213
+ if (!take)
214
+ continue;
215
+ swap.toToken = chainToken(take[0], ctx.native);
216
+ swap.minReceive = take[1].toString();
217
+ swap.receiver = ctx.txFrom;
218
+ }
219
+ else if (action === V4.TAKE_PAIR) {
220
+ const take = decode(["address", "address", "address"], data);
221
+ if (take)
222
+ setReceiver(swap, take[2], ctx.txFrom);
223
+ }
224
+ else if (action === V4.SWEEP) {
225
+ const sweep = decode(["address", "address", "uint256"], data);
226
+ if (!sweep)
227
+ continue;
228
+ swap.toToken = chainToken(sweep[0], ctx.native);
229
+ swap.minReceive = sweep[2].toString();
230
+ setReceiver(swap, sweep[1], ctx.txFrom);
231
+ }
232
+ else if (action === V4.WRAP) {
233
+ const wrap = decode(["address", "uint256"], data);
234
+ if (wrap)
235
+ wrapNative(swap, ctx, wrap[1].toString());
236
+ }
237
+ else if (action === V4.UNWRAP) {
238
+ const unwrap = decode(["address", "uint256"], data);
239
+ if (unwrap)
240
+ unwrapNative(swap, ctx, unwrap[0], unwrap[1].toString());
241
+ }
242
+ }
243
+ };
244
+ const walkCommands = (commands, inputs, ctx) => {
245
+ const swap = {};
246
+ if (ctx.proxyToken && !isSameAddress(ctx.proxyToken, NULL_ADDRESS)) {
247
+ swap.fromToken = ctx.proxyToken;
248
+ }
249
+ if (ctx.proxyAmount && ctx.proxyAmount !== "0") {
250
+ swap.fromTokenAmount = ctx.proxyAmount;
251
+ }
252
+ const cmdHex = (commands || "").replace(/^0x/i, "");
253
+ for (let i = 0; i < cmdHex.length / 2; i++) {
254
+ const command = parseInt(cmdHex.slice(i * 2, i * 2 + 2), 16) & COMMAND_MASK;
255
+ const input = inputs[i];
256
+ if (!input)
257
+ continue;
258
+ switch (command) {
259
+ case Command.V3_EXACT_IN:
260
+ applyAmmSwap(swap, ctx, input, false, true);
261
+ break;
262
+ case Command.V3_EXACT_OUT:
263
+ applyAmmSwap(swap, ctx, input, true, true);
264
+ break;
265
+ case Command.V2_EXACT_IN:
266
+ applyAmmSwap(swap, ctx, input, false, false);
267
+ break;
268
+ case Command.V2_EXACT_OUT:
269
+ applyAmmSwap(swap, ctx, input, true, false);
270
+ break;
271
+ case Command.WRAP_ETH: {
272
+ const wrap = decode(["address", "uint256"], input);
273
+ if (wrap)
274
+ wrapNative(swap, ctx, wrap[1].toString());
275
+ break;
276
+ }
277
+ case Command.UNWRAP_WETH:
278
+ case Command.UNWRAP_WETH_EXACT: {
279
+ const unwrap = decode(["address", "uint256"], input);
280
+ if (unwrap)
281
+ unwrapNative(swap, ctx, unwrap[0], unwrap[1].toString());
282
+ break;
283
+ }
284
+ case Command.SWEEP:
285
+ case Command.TRANSFER: {
286
+ const pay = decode(["address", "address", "uint256"], input);
287
+ if (!pay)
288
+ break;
289
+ swap.toToken = chainToken(pay[0], ctx.native);
290
+ if (command === Command.SWEEP)
291
+ swap.minReceive = pay[2].toString();
292
+ setReceiver(swap, pay[1], ctx.txFrom);
293
+ break;
294
+ }
295
+ case Command.V4_SWAP:
296
+ walkV4(swap, ctx, input);
297
+ break;
298
+ case Command.SUB_PLAN: {
299
+ const nested = decode(["bytes", "bytes[]"], input);
300
+ if (!nested)
301
+ break;
302
+ Object.assign(swap, walkCommands(nested[0], nested[1], ctx));
303
+ break;
304
+ }
305
+ default:
306
+ break;
307
+ }
308
+ }
309
+ return swap;
310
+ };
311
+ export const decodeCalldata = (tx) => {
312
+ var _a;
313
+ const chain = Object.values(CHAINS).find((item) => item.id === tx.chainId);
314
+ if (!chain)
315
+ return null;
316
+ const result = uniInterface.parseTransaction({ data: tx.data });
317
+ if (result.name !== "execute")
318
+ return null;
319
+ const { commands, inputs, token, amount } = result.args;
320
+ const swap = walkCommands(commands, inputs, {
321
+ native: chain.nativeTokenAddress,
322
+ txFrom: tx.from,
323
+ proxyToken: token,
324
+ proxyAmount: amount === null || amount === void 0 ? void 0 : amount.toString(),
325
+ txValue: (_a = tx.value) === null || _a === void 0 ? void 0 : _a.toString(),
326
+ });
327
+ if (!swap.fromToken ||
328
+ !swap.fromTokenAmount ||
329
+ !swap.toToken ||
330
+ !swap.minReceive ||
331
+ !swap.receiver) {
332
+ return null;
333
+ }
334
+ return {
335
+ fromToken: swap.fromToken,
336
+ fromTokenAmount: swap.fromTokenAmount,
337
+ toToken: swap.toToken,
338
+ minReceiveToTokenAmount: swap.minReceive,
339
+ toTokenReceiver: swap.receiver,
340
+ };
341
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rabby-wallet/rabby-swap",
3
- "version": "0.0.87",
3
+ "version": "0.0.88-alpha.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {