@shapeshiftoss/swapper 15.7.0 → 16.0.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/api.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Asset } from '@shapeshiftoss/asset-service';
2
2
  import { AssetId, ChainId } from '@shapeshiftoss/caip';
3
- import { avalanche, cosmos, ethereum, osmosis } from '@shapeshiftoss/chain-adapters';
3
+ import { avalanche, cosmos, ethereum, optimism, osmosis } from '@shapeshiftoss/chain-adapters';
4
4
  import { HDWallet } from '@shapeshiftoss/hdwallet-core';
5
5
  import { ChainSpecific, KnownChainIds, UtxoAccountType } from '@shapeshiftoss/types';
6
6
  export declare const SwapError: {
@@ -73,9 +73,15 @@ export declare type ByPairInput = {
73
73
  sellAssetId: AssetId;
74
74
  buyAssetId: AssetId;
75
75
  };
76
- export declare type GetBestSwapperArgs = GetTradeQuoteInput & {
76
+ export declare type GetSwappersWithQuoteMetadataArgs = GetTradeQuoteInput & {
77
77
  feeAsset: Asset;
78
78
  };
79
+ export declare type SwapperWithQuoteMetadata = {
80
+ swapper: Swapper<ChainId>;
81
+ quote: TradeQuote<ChainId>;
82
+ inputOutputRatio: number | undefined;
83
+ };
84
+ export declare type GetSwappersWithQuoteMetadataReturn = SwapperWithQuoteMetadata[];
79
85
  export declare type BuyAssetBySellIdInput = {
80
86
  sellAssetId: AssetId;
81
87
  assetIds: AssetId[];
@@ -91,9 +97,9 @@ declare type CommonTradeInput = {
91
97
  receiveAddress: string;
92
98
  accountNumber: number;
93
99
  };
94
- export declare type EvmSupportedChainIds = KnownChainIds.EthereumMainnet | KnownChainIds.AvalancheMainnet;
100
+ export declare type EvmSupportedChainIds = KnownChainIds.EthereumMainnet | KnownChainIds.AvalancheMainnet | KnownChainIds.OptimismMainnet;
95
101
  export declare type CosmosSdkSupportedChainIds = KnownChainIds.CosmosMainnet | KnownChainIds.OsmosisMainnet | KnownChainIds.ThorchainMainnet;
96
- export declare type EvmSupportedChainAdapter = ethereum.ChainAdapter | avalanche.ChainAdapter;
102
+ export declare type EvmSupportedChainAdapter = ethereum.ChainAdapter | avalanche.ChainAdapter | optimism.ChainAdapter;
97
103
  export declare type CosmosSdkSupportedChainAdapters = cosmos.ChainAdapter | osmosis.ChainAdapter;
98
104
  export declare type UtxoSupportedChainIds = KnownChainIds.BitcoinMainnet | KnownChainIds.DogecoinMainnet | KnownChainIds.LitecoinMainnet | KnownChainIds.BitcoinCashMainnet;
99
105
  export declare type GetEvmTradeQuoteInput = CommonTradeInput & {
@@ -174,6 +180,7 @@ export declare enum SwapperName {
174
180
  export declare enum SwapperType {
175
181
  ZrxEthereum = "0xEthereum",
176
182
  ZrxAvalanche = "0xAvalanche",
183
+ ZrxOptimism = "0xOptimism",
177
184
  Thorchain = "Thorchain",
178
185
  Osmosis = "Osmosis",
179
186
  CowSwap = "CoW Swap",
package/dist/api.js CHANGED
@@ -16,6 +16,7 @@ var SwapperType;
16
16
  (function (SwapperType) {
17
17
  SwapperType["ZrxEthereum"] = "0xEthereum";
18
18
  SwapperType["ZrxAvalanche"] = "0xAvalanche";
19
+ SwapperType["ZrxOptimism"] = "0xOptimism";
19
20
  SwapperType["Thorchain"] = "Thorchain";
20
21
  SwapperType["Osmosis"] = "Osmosis";
21
22
  SwapperType["CowSwap"] = "CoW Swap";
@@ -1,5 +1,5 @@
1
1
  import { ChainId } from '@shapeshiftoss/caip';
2
- import { BuyAssetBySellIdInput, ByPairInput, GetBestSwapperArgs, SupportedSellAssetsInput, Swapper } from '..';
2
+ import { BuyAssetBySellIdInput, ByPairInput, GetSwappersWithQuoteMetadataArgs, GetSwappersWithQuoteMetadataReturn, SupportedSellAssetsInput, Swapper } from '..';
3
3
  import { SwapperType } from '../api';
4
4
  export declare class SwapperManager {
5
5
  swappers: Map<SwapperType, Swapper<ChainId>>;
@@ -24,10 +24,12 @@ export declare class SwapperManager {
24
24
  removeSwapper(swapperType: SwapperType): this;
25
25
  /**
26
26
  *
27
- * @param args {GetBestSwapperArgs}
28
- * @returns {Promise<Swapper<ChainId> | undefined>}
27
+ * Returns an ordered list of SwapperWithQuoteMetadata objects, descending from best to worst input output ratios
28
+ *
29
+ * @param args {GetSwappersWithQuoteMetadataArgs}
30
+ * @returns {Promise<GetSwappersWithQuoteMetadataReturn>}
29
31
  */
30
- getBestSwapper(args: GetBestSwapperArgs): Promise<Swapper<ChainId> | undefined>;
32
+ getSwappersWithQuoteMetadata(args: GetSwappersWithQuoteMetadataArgs): Promise<GetSwappersWithQuoteMetadataReturn>;
31
33
  /**
32
34
  *
33
35
  * @param pair type {GetQuoteInput}
@@ -62,47 +62,32 @@ class SwapperManager {
62
62
  }
63
63
  /**
64
64
  *
65
- * @param args {GetBestSwapperArgs}
66
- * @returns {Promise<Swapper<ChainId> | undefined>}
65
+ * Returns an ordered list of SwapperWithQuoteMetadata objects, descending from best to worst input output ratios
66
+ *
67
+ * @param args {GetSwappersWithQuoteMetadataArgs}
68
+ * @returns {Promise<GetSwappersWithQuoteMetadataReturn>}
67
69
  */
68
- async getBestSwapper(args) {
70
+ async getSwappersWithQuoteMetadata(args) {
69
71
  const { sellAsset, buyAsset, feeAsset } = args;
70
72
  // Get all swappers that support the pair
71
73
  const supportedSwappers = this.getSwappersByPair({
72
74
  sellAssetId: sellAsset.assetId,
73
75
  buyAssetId: buyAsset.assetId,
74
76
  });
75
- // Get quotes from all swappers that support the pair
76
- const quotePromises = supportedSwappers.map(async (swapper) => [swapper, await swapper.getTradeQuote(args)]);
77
- const settledQuoteRequests = await Promise.allSettled(quotePromises);
78
- // For each swapper, get receive amount/(input amount + gas fee), where all values are in fiat
79
- const fulfilledQuoteTuples = settledQuoteRequests
77
+ const settledSwapperDetailRequests = await Promise.allSettled(supportedSwappers.map(async (swapper) => {
78
+ const quote = await swapper.getTradeQuote(args);
79
+ const ratio = await (0, utils_1.getRatioFromQuote)(quote, swapper, feeAsset);
80
+ return {
81
+ swapper,
82
+ quote,
83
+ inputOutputRatio: ratio,
84
+ };
85
+ }));
86
+ // Swappers with quote and ratio details, sorted by descending input output ratio (best to worst)
87
+ const swappersWithDetail = (0, lodash_1.sortBy)(settledSwapperDetailRequests
80
88
  .filter(typeGuards_1.isFulfilled)
81
- .map((quoteRequest) => quoteRequest.value);
82
- // The best swapper is the one with the highest ratio
83
- const bestQuoteTuple = await fulfilledQuoteTuples.reduce(async (acc, currentQuoteTuple) => {
84
- const resolvedAcc = await acc;
85
- const [currentSwapper, currentQuote] = currentQuoteTuple;
86
- const currentRatio = await (0, utils_1.getRatioFromQuote)(currentQuote, currentSwapper, feeAsset);
87
- // It's our first iteration, so we just return the current SwapperQuoteTuple
88
- if (!resolvedAcc)
89
- return Promise.resolve([currentSwapper, currentRatio]);
90
- const [, bestRatio] = resolvedAcc;
91
- const isCurrentSwapperBestSwapper = (() => {
92
- // Happy path - no div by 0's in getRatioFromQuote evaluations so we have both ratios
93
- if (!(0, lodash_1.isUndefined)(currentRatio) && !(0, lodash_1.isUndefined)(bestRatio))
94
- return currentRatio > bestRatio;
95
- // We don't know, neither has a ratio, so we can't compare (big edge case div by 0 scenario)
96
- if ((0, lodash_1.isUndefined)(currentRatio) && (0, lodash_1.isUndefined)(bestRatio))
97
- return false;
98
- // We don't have a best, but we do have a current, so current is the new best
99
- return !(0, lodash_1.isUndefined)(currentRatio);
100
- })();
101
- const currentSwapperRatioTuple = [currentSwapper, currentRatio];
102
- return Promise.resolve(isCurrentSwapperBestSwapper ? currentSwapperRatioTuple : resolvedAcc);
103
- }, undefined);
104
- const bestSwapper = bestQuoteTuple === null || bestQuoteTuple === void 0 ? void 0 : bestQuoteTuple[0];
105
- return bestSwapper;
89
+ .map((swapperDetailRequest) => swapperDetailRequest.value), ['inputOutputRatio']).reverse();
90
+ return swappersWithDetail;
106
91
  }
107
92
  /**
108
93
  *
@@ -3,6 +3,7 @@ import { TradeQuote } from '../api';
3
3
  import { CowSwapper, ThorchainSwapper, ZrxSwapper } from '../swappers';
4
4
  export declare const getZrxEthereumSwapper: () => ZrxSwapper<import("../api").EvmSupportedChainIds>;
5
5
  export declare const getZrxAvalancheSwapper: () => ZrxSwapper<import("../api").EvmSupportedChainIds>;
6
+ export declare const getZrxOptimismSwapper: () => ZrxSwapper<import("../api").EvmSupportedChainIds>;
6
7
  export declare const getCowSwapper: () => CowSwapper;
7
8
  export declare const getThorchainSwapper: () => ThorchainSwapper;
8
9
  export declare const tradeQuote: TradeQuote<KnownChainIds.EthereumMainnet>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.badTradeQuote = exports.goodTradeQuote = exports.tradeQuote = exports.getThorchainSwapper = exports.getCowSwapper = exports.getZrxAvalancheSwapper = exports.getZrxEthereumSwapper = void 0;
3
+ exports.badTradeQuote = exports.goodTradeQuote = exports.tradeQuote = exports.getThorchainSwapper = exports.getCowSwapper = exports.getZrxOptimismSwapper = exports.getZrxAvalancheSwapper = exports.getZrxEthereumSwapper = void 0;
4
4
  const types_1 = require("@shapeshiftoss/types");
5
5
  const api_1 = require("../api");
6
6
  const swappers_1 = require("../swappers");
@@ -21,6 +21,14 @@ const zrxAvalancheSwapperDeps = {
21
21
  };
22
22
  const getZrxAvalancheSwapper = () => new swappers_1.ZrxSwapper(zrxAvalancheSwapperDeps);
23
23
  exports.getZrxAvalancheSwapper = getZrxAvalancheSwapper;
24
+ const zrxOptimismSwapperDeps = {
25
+ web3: {},
26
+ adapter: {
27
+ getChainId: () => types_1.KnownChainIds.OptimismMainnet,
28
+ },
29
+ };
30
+ const getZrxOptimismSwapper = () => new swappers_1.ZrxSwapper(zrxOptimismSwapperDeps);
31
+ exports.getZrxOptimismSwapper = getZrxOptimismSwapper;
24
32
  const cowSwapperDeps = {
25
33
  apiUrl: 'https://api.cow.fi/mainnet/api/',
26
34
  adapter: {
@@ -105,10 +105,11 @@ const main = async () => {
105
105
  explorerTxLink: 'https://etherscan.io/tx/',
106
106
  };
107
107
  const { quoteInput } = (0, setupSwapQuote_1.setupQuote)();
108
- const swapper = await swapManager.getBestSwapper({
108
+ const swappersWithQuoteMetadata = await swapManager.getSwappersWithQuoteMetadata({
109
109
  ...quoteInput,
110
110
  feeAsset: ethereumAsset,
111
111
  });
112
+ const swapper = swappersWithQuoteMetadata[0].swapper;
112
113
  console.info(`using swapper ${swapper === null || swapper === void 0 ? void 0 : swapper.getType()}`);
113
114
  if (!swapper) {
114
115
  console.warn(`no swapper found for specified assets`);
@@ -62,7 +62,7 @@ export interface BtcThorTrade<C extends ChainId> extends Trade<C> {
62
62
  txData: BTCSignTx;
63
63
  }
64
64
  export interface EvmThorTrade<C extends ChainId> extends Trade<C> {
65
- chainId: KnownChainIds.EthereumMainnet | KnownChainIds.AvalancheMainnet;
65
+ chainId: KnownChainIds.EthereumMainnet | KnownChainIds.AvalancheMainnet | KnownChainIds.OptimismMainnet;
66
66
  txData: ETHSignTx;
67
67
  }
68
68
  export interface CosmosThorTrade<C extends ChainId> extends Trade<C> {
@@ -7,4 +7,5 @@ export declare const ETH: Asset;
7
7
  export declare const UNSUPPORTED: Asset;
8
8
  export declare const USDC: Asset;
9
9
  export declare const AVAX: Asset;
10
+ export declare const OPTIMISM: Asset;
10
11
  export declare const RUNE: Asset;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RUNE = exports.AVAX = exports.USDC = exports.UNSUPPORTED = exports.ETH = exports.WBTC = exports.FOX = exports.WETH = exports.BTC = void 0;
3
+ exports.RUNE = exports.OPTIMISM = exports.AVAX = exports.USDC = exports.UNSUPPORTED = exports.ETH = exports.WBTC = exports.FOX = exports.WETH = exports.BTC = void 0;
4
4
  const caip_1 = require("@shapeshiftoss/caip");
5
5
  exports.BTC = {
6
6
  assetId: 'bip122:000000000019d6689c085ae165831e93/slip44:0',
@@ -98,6 +98,21 @@ exports.AVAX = {
98
98
  explorerAddressLink: 'https://snowtrace.io/address/',
99
99
  explorerTxLink: 'https://snowtrace.io/tx/',
100
100
  };
101
+ exports.OPTIMISM = {
102
+ assetId: caip_1.optimismAssetId,
103
+ chainId: caip_1.optimismChainId,
104
+ name: 'Ethereum',
105
+ networkName: 'Optimism',
106
+ symbol: 'ETH',
107
+ precision: 18,
108
+ color: '#5C6BC0',
109
+ networkColor: '#FC0424',
110
+ icon: 'https://assets.coincap.io/assets/icons/256/eth.png',
111
+ networkIcon: 'https://assets.coingecko.com/coins/images/25244/thumb/Optimism.png?1660904599',
112
+ explorer: 'https://optimistic.etherscan.io',
113
+ explorerAddressLink: 'https://optimistic.etherscan.io/address/',
114
+ explorerTxLink: 'https://optimistic.etherscan.io/tx/',
115
+ };
101
116
  exports.RUNE = {
102
117
  assetId: caip_1.thorchainAssetId,
103
118
  chainId: caip_1.thorchainChainId,
@@ -7,7 +7,7 @@ export declare class ZrxSwapper<T extends EvmSupportedChainIds> implements Swapp
7
7
  deps: ZrxSwapperDeps;
8
8
  chainId: ChainId;
9
9
  constructor(deps: ZrxSwapperDeps);
10
- getType(): SwapperType.ZrxEthereum | SwapperType.ZrxAvalanche;
10
+ getType(): SwapperType.ZrxEthereum | SwapperType.ZrxAvalanche | SwapperType.ZrxOptimism;
11
11
  buildTrade(args: BuildTradeInput): Promise<ZrxTrade<T>>;
12
12
  getTradeQuote(input: GetEvmTradeQuoteInput): Promise<TradeQuote<T>>;
13
13
  getUsdRate(input: Asset): Promise<string>;
@@ -23,6 +23,8 @@ class ZrxSwapper {
23
23
  return api_1.SwapperType.ZrxEthereum;
24
24
  case types_1.KnownChainIds.AvalancheMainnet:
25
25
  return api_1.SwapperType.ZrxAvalanche;
26
+ case types_1.KnownChainIds.OptimismMainnet:
27
+ return api_1.SwapperType.ZrxOptimism;
26
28
  default:
27
29
  throw new api_1.SwapError('[getType]', {
28
30
  code: api_1.SwapErrorType.UNSUPPORTED_CHAIN,
@@ -8,11 +8,12 @@ const bignumber_1 = require("../../../utils/bignumber");
8
8
  const zrxService_1 = require("../zrxService");
9
9
  const baseUrlFromChainId = (chainId) => {
10
10
  switch (chainId) {
11
- case types_1.KnownChainIds.EthereumMainnet: {
11
+ case types_1.KnownChainIds.EthereumMainnet:
12
12
  return 'https://api.0x.org/';
13
- }
14
13
  case types_1.KnownChainIds.AvalancheMainnet:
15
14
  return 'https://avalanche.api.0x.org/';
15
+ case types_1.KnownChainIds.OptimismMainnet:
16
+ return 'https://optimism.api.0x.org/';
16
17
  default:
17
18
  throw new api_1.SwapError(`baseUrlFromChainId] - Unsupported chainId: ${chainId}`, {
18
19
  code: api_1.SwapErrorType.UNSUPPORTED_CHAIN,
@@ -22,11 +23,12 @@ const baseUrlFromChainId = (chainId) => {
22
23
  exports.baseUrlFromChainId = baseUrlFromChainId;
23
24
  const usdcContractFromChainId = (chainId) => {
24
25
  switch (chainId) {
25
- case types_1.KnownChainIds.EthereumMainnet: {
26
+ case types_1.KnownChainIds.EthereumMainnet:
26
27
  return '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48';
27
- }
28
28
  case types_1.KnownChainIds.AvalancheMainnet:
29
29
  return '0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e';
30
+ case types_1.KnownChainIds.OptimismMainnet:
31
+ return '0x7f5c764cbc14f9669b88837ca1490cca17c31607';
30
32
  default:
31
33
  throw new api_1.SwapError(`usdcContractFromChainId] - Unsupported chainId: ${chainId}`, {
32
34
  code: api_1.SwapErrorType.UNSUPPORTED_CHAIN,
@@ -41,6 +43,8 @@ const isNativeEvmAsset = (assetId) => {
41
43
  return assetId === caip_1.ethAssetId;
42
44
  case types_1.KnownChainIds.AvalancheMainnet:
43
45
  return assetId === caip_1.avalancheAssetId;
46
+ case types_1.KnownChainIds.OptimismMainnet:
47
+ return assetId === caip_1.optimismAssetId;
44
48
  default:
45
49
  return false;
46
50
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapeshiftoss/swapper",
3
- "version": "15.7.0",
3
+ "version": "16.0.0",
4
4
  "description": "An interface and implementations to trade coins via various protocols",
5
5
  "repository": "https://github.com/shapeshift/lib",
6
6
  "license": "MIT",