From 921cb4992f2e0c675c8931176af898fc34cf9ab2 Mon Sep 17 00:00:00 2001 From: alexei Date: Thu, 13 Apr 2023 20:30:19 +0200 Subject: [PATCH 01/14] Added Interlay and Kintsugi networks --- .../polkadot/networks/icons/interlay.svg | 104 ++++++++++++ .../polkadot/networks/icons/kintsugi.svg | 23 +++ .../networks/interlay/assets/icons/DOT.png | Bin 0 -> 47197 bytes .../networks/interlay/assets/icons/IBTC.png | Bin 0 -> 3796 bytes .../networks/interlay/assets/icons/INTR.png | Bin 0 -> 2964 bytes .../networks/interlay/assets/icons/KBTC.png | Bin 0 -> 7446 bytes .../networks/interlay/assets/icons/KINT.png | Bin 0 -> 6831 bytes .../networks/interlay/assets/icons/KSM.png | Bin 0 -> 2017 bytes .../networks/interlay/assets/icons/LDOT.png | Bin 0 -> 10948 bytes .../networks/interlay/assets/icons/LKSM.png | Bin 0 -> 7981 bytes .../networks/interlay/assets/icons/USDC.png | Bin 0 -> 12625 bytes .../networks/interlay/assets/icons/USDT.png | Bin 0 -> 1171 bytes .../interlay/assets/interlay-assets.ts | 30 ++++ .../interlay/assets/kintsugi-assets.ts | 36 ++++ .../polkadot/networks/interlay/interlay.ts | 39 +++++ .../polkadot/networks/interlay/kintsugi.ts | 39 +++++ .../networks/interlay/libs/assetinfo-orml.ts | 160 ++++++++++++++++++ .../interlay/types/interlay-orml-asset.ts | 54 ++++++ packages/types/src/networks.ts | 4 + 19 files changed, 489 insertions(+) create mode 100644 packages/extension/src/providers/polkadot/networks/icons/interlay.svg create mode 100644 packages/extension/src/providers/polkadot/networks/icons/kintsugi.svg create mode 100755 packages/extension/src/providers/polkadot/networks/interlay/assets/icons/DOT.png create mode 100644 packages/extension/src/providers/polkadot/networks/interlay/assets/icons/IBTC.png create mode 100644 packages/extension/src/providers/polkadot/networks/interlay/assets/icons/INTR.png create mode 100644 packages/extension/src/providers/polkadot/networks/interlay/assets/icons/KBTC.png create mode 100644 packages/extension/src/providers/polkadot/networks/interlay/assets/icons/KINT.png create mode 100644 packages/extension/src/providers/polkadot/networks/interlay/assets/icons/KSM.png create mode 100644 packages/extension/src/providers/polkadot/networks/interlay/assets/icons/LDOT.png create mode 100644 packages/extension/src/providers/polkadot/networks/interlay/assets/icons/LKSM.png create mode 100644 packages/extension/src/providers/polkadot/networks/interlay/assets/icons/USDC.png create mode 100644 packages/extension/src/providers/polkadot/networks/interlay/assets/icons/USDT.png create mode 100644 packages/extension/src/providers/polkadot/networks/interlay/assets/interlay-assets.ts create mode 100644 packages/extension/src/providers/polkadot/networks/interlay/assets/kintsugi-assets.ts create mode 100644 packages/extension/src/providers/polkadot/networks/interlay/interlay.ts create mode 100644 packages/extension/src/providers/polkadot/networks/interlay/kintsugi.ts create mode 100644 packages/extension/src/providers/polkadot/networks/interlay/libs/assetinfo-orml.ts create mode 100644 packages/extension/src/providers/polkadot/networks/interlay/types/interlay-orml-asset.ts diff --git a/packages/extension/src/providers/polkadot/networks/icons/interlay.svg b/packages/extension/src/providers/polkadot/networks/icons/interlay.svg new file mode 100644 index 000000000..570c73cf8 --- /dev/null +++ b/packages/extension/src/providers/polkadot/networks/icons/interlay.svg @@ -0,0 +1,104 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/extension/src/providers/polkadot/networks/icons/kintsugi.svg b/packages/extension/src/providers/polkadot/networks/icons/kintsugi.svg new file mode 100644 index 000000000..10488c6e9 --- /dev/null +++ b/packages/extension/src/providers/polkadot/networks/icons/kintsugi.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/extension/src/providers/polkadot/networks/interlay/assets/icons/DOT.png b/packages/extension/src/providers/polkadot/networks/interlay/assets/icons/DOT.png new file mode 100755 index 0000000000000000000000000000000000000000..bb0e3ad3b27afd383a3c2c34dd5a47e36b7531fe GIT binary patch literal 47197 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 Iw7U5J0pJmFF#rGn literal 0 HcmV?d00001 diff --git a/packages/extension/src/providers/polkadot/networks/interlay/assets/icons/IBTC.png b/packages/extension/src/providers/polkadot/networks/interlay/assets/icons/IBTC.png new file mode 100644 index 0000000000000000000000000000000000000000..e0a9cf42823fe7c31764e9353b00df10103cf8d1 GIT binary patch literal 3796 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 MRbeWaCpKaK11?!X#{d8T literal 0 HcmV?d00001 diff --git a/packages/extension/src/providers/polkadot/networks/interlay/assets/icons/INTR.png b/packages/extension/src/providers/polkadot/networks/interlay/assets/icons/INTR.png new file mode 100644 index 0000000000000000000000000000000000000000..40d48f892b9a9e4fc30eff9154b91c0205d12c93 GIT binary patch literal 2964 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 DKg_$9 literal 0 HcmV?d00001 diff --git a/packages/extension/src/providers/polkadot/networks/interlay/assets/icons/KBTC.png b/packages/extension/src/providers/polkadot/networks/interlay/assets/icons/KBTC.png new file mode 100644 index 0000000000000000000000000000000000000000..cc8cee74288aa882bf07409b3c4e1c573dbdceb9 GIT binary patch literal 7446 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 IzZ(AfKO_oyd;kCd literal 0 HcmV?d00001 diff --git a/packages/extension/src/providers/polkadot/networks/interlay/assets/icons/KINT.png b/packages/extension/src/providers/polkadot/networks/interlay/assets/icons/KINT.png new file mode 100644 index 0000000000000000000000000000000000000000..53d1ff84d6a92a24621a5dc7184e7d05d86184e4 GIT binary patch literal 6831 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 literal 0 HcmV?d00001 diff --git a/packages/extension/src/providers/polkadot/networks/interlay/assets/icons/LDOT.png b/packages/extension/src/providers/polkadot/networks/interlay/assets/icons/LDOT.png new file mode 100644 index 0000000000000000000000000000000000000000..dff99e44d5027640441b6e6ebb593d7aaa91617f GIT binary patch literal 10948 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

_&_;#;=S1Ere5d^{RB?00on%7Xt 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 literal 0 HcmV?d00001 diff --git a/packages/extension/src/providers/polkadot/networks/interlay/assets/icons/USDC.png b/packages/extension/src/providers/polkadot/networks/interlay/assets/icons/USDC.png new file mode 100644 index 0000000000000000000000000000000000000000..3c9ea9f3243301558d7c634af5288bf5d002339b GIT binary patch literal 12625 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 T^DS1hK&6YPtDnm{r-UW|99$W4 literal 0 HcmV?d00001 diff --git a/packages/extension/src/providers/polkadot/networks/interlay/assets/interlay-assets.ts b/packages/extension/src/providers/polkadot/networks/interlay/assets/interlay-assets.ts new file mode 100644 index 000000000..460dbbd06 --- /dev/null +++ b/packages/extension/src/providers/polkadot/networks/interlay/assets/interlay-assets.ts @@ -0,0 +1,30 @@ +import { KnownTokenDisplay } from "@/providers/polkadot/types"; + +const assets: KnownTokenDisplay[] = [ + { + name: "Interlay", + symbol: "INTR", + coingeckoID: "interlay", + icon: require("./icons/INTR.png"), + }, + { + name: "Polkadot", + symbol: "DOT", + coingeckoID: "polkadot", + icon: require("../../icons/polkadot.svg"), + }, + { + name: "USDT", + symbol: "USDT", + icon: require("./icons/USDT.png"), + coingeckoID: "usdt", + }, + { + name: "IBTC", + symbol: "IBTC", + icon: require("./icons/IBTC.png"), + coingeckoID: "interbtc", + }, +]; + +export default assets; diff --git a/packages/extension/src/providers/polkadot/networks/interlay/assets/kintsugi-assets.ts b/packages/extension/src/providers/polkadot/networks/interlay/assets/kintsugi-assets.ts new file mode 100644 index 000000000..6050413fa --- /dev/null +++ b/packages/extension/src/providers/polkadot/networks/interlay/assets/kintsugi-assets.ts @@ -0,0 +1,36 @@ +import { KnownTokenDisplay } from "@/providers/polkadot/types"; + +const assets: KnownTokenDisplay[] = [ + { + name: "Interlay", + symbol: "INTR", + coingeckoID: "interlay", + icon: require("./icons/INTR.png"), + }, + { + name: "Kusama", + symbol: "KSM", + + icon: require("./icons/KSM.png"), + coingeckoID: "kusama", + }, + { + name: "Liquid KSM", + symbol: "LKSM", + icon: require("./icons/LKSM.png"), + }, + { + name: "USDT", + symbol: "USDT", + icon: require("./icons/USDT.png"), + coingeckoID: "usdt", + }, + { + name: "KBTC", + symbol: "KBTC", + icon: require("./icons/KBTC.png"), + coingeckoID: "kintsugi-btc", + }, +]; + +export default assets; diff --git a/packages/extension/src/providers/polkadot/networks/interlay/interlay.ts b/packages/extension/src/providers/polkadot/networks/interlay/interlay.ts new file mode 100644 index 000000000..15b998392 --- /dev/null +++ b/packages/extension/src/providers/polkadot/networks/interlay/interlay.ts @@ -0,0 +1,39 @@ +import assetHandler from "./libs/assetinfo-orml"; +import { CoingeckoPlatform, NetworkNames } from "@enkryptcom/types"; +import assets from "./assets/interlay-assets"; +import { + SubstrateNetwork, + SubstrateNetworkOptions, +} from "../../types/substrate-network"; +import { subscanActivity } from "../../libs/activity-handlers"; +import wrapActivityHandler from "@/libs/activity-state/wrap-activity-handler"; +import { toBN } from "web3-utils"; + +const interlayOptions: SubstrateNetworkOptions = { + name: NetworkNames.Interlay, + name_long: "Interlay", + homePage: "https://interlay.io/", + blockExplorerTX: "https://interlay.subscan.io/extrinsic/[[txHash]]", + blockExplorerAddr: "https://interlay.subscan.io/account/[[address]]", + isTestNetwork: false, + currencyName: "INTR", + currencyNameLong: "Interlay", + icon: require("../icons/interlay.svg"), + decimals: 12, + prefix: 2032, + gradient: + "linear-gradient(326.87deg, #1A0A2D 12.53%, #1A0A2D 50.89%, #1A0A2D 89.24%)", + node: "wss://api.interlay.io:443/parachain", + coingeckoID: "interlay", + coingeckoPlatform: CoingeckoPlatform.Interlay, + genesisHash: + "0xbf88efe70e9e0e916416e8bed61f2b45717f517d7f3523e33c7b001e5ffcbc72", + activityHandler: wrapActivityHandler(subscanActivity), + assetHandler: assetHandler, + knownTokens: assets, + existentialDeposit: toBN("0"), +}; + +const interlay = new SubstrateNetwork(interlayOptions); + +export default interlay; diff --git a/packages/extension/src/providers/polkadot/networks/interlay/kintsugi.ts b/packages/extension/src/providers/polkadot/networks/interlay/kintsugi.ts new file mode 100644 index 000000000..aeb1976c3 --- /dev/null +++ b/packages/extension/src/providers/polkadot/networks/interlay/kintsugi.ts @@ -0,0 +1,39 @@ +import assetHandler from "./libs/assetinfo-orml"; +import { CoingeckoPlatform, NetworkNames } from "@enkryptcom/types"; +import assets from "./assets/kintsugi-assets"; +import { + SubstrateNetwork, + SubstrateNetworkOptions, +} from "../../types/substrate-network"; +import { subscanActivity } from "../../libs/activity-handlers"; +import wrapActivityHandler from "@/libs/activity-state/wrap-activity-handler"; +import { toBN } from "web3-utils"; + +const kintsugiOptions: SubstrateNetworkOptions = { + name: NetworkNames.Kintsugi, + name_long: "Kintsugi", + homePage: "https://interlay.io/kintsugi", + blockExplorerTX: "https://kintsugi.subscan.io/extrinsic/[[txHash]]", + blockExplorerAddr: "https://kintsugi.subscan.io/account/[[address]]", + isTestNetwork: false, + currencyName: "KINT", + currencyNameLong: "Kintsugi", + icon: require("../icons/kintsugi.svg"), + decimals: 12, + prefix: 2092, + gradient: + "linear-gradient(326.87deg, #041333 12.53%, #041333 50.89%, #041333 89.24%)", + node: "wss://api-kusama.interlay.io:443/parachain", + coingeckoID: "kintsugi", + coingeckoPlatform: CoingeckoPlatform.Kintsugi, + genesisHash: + "0x9af9a64e6e4da8e3073901c3ff0cc4c3aad9563786d89daf6ad820b6e14a0b8b", + activityHandler: wrapActivityHandler(subscanActivity), + assetHandler: assetHandler, + knownTokens: assets, + existentialDeposit: toBN("0"), +}; + +const kintsugi = new SubstrateNetwork(kintsugiOptions); + +export default kintsugi; diff --git a/packages/extension/src/providers/polkadot/networks/interlay/libs/assetinfo-orml.ts b/packages/extension/src/providers/polkadot/networks/interlay/libs/assetinfo-orml.ts new file mode 100644 index 000000000..5f81774eb --- /dev/null +++ b/packages/extension/src/providers/polkadot/networks/interlay/libs/assetinfo-orml.ts @@ -0,0 +1,160 @@ +import API from "@/providers/polkadot/libs/api"; +import { SubstrateNetwork } from "@/providers/polkadot/types/substrate-network"; +import { hexToString, hexToBn } from "@polkadot/util"; +import { + InterlayOrmlAsset, + InterlayOrmlAssetOptions, + OrmlAssetType, +} from "../types/interlay-orml-asset"; +import { OrmlTokensAccountData } from "../../acala/types/acala-orml-asset"; +import { toBN } from "web3-utils"; +import { KnownTokenDisplay } from "@/providers/polkadot/types"; +import { SubstrateNativeToken } from "@/providers/polkadot/types/substrate-native-token"; + +type AssetMetadata = { + name: `0x${string}`; + symbol: `0x${string}`; + decimals: number; + minimalBalance: number | `0x${string}`; +}; + +type NativeAsset = Record; + +type ForeignAsset = string; + +type StableAsset = string; + +type Erc20 = string; + +enum AssetIds { + NATIVE_ASSET = "NativeAssetId", + FOREIGN_ASSET = "ForeignAssetId", + STABLE_ASSET = "StableAssetId", + ERC20_ASSET = "Erc20", +} + +type AssetKey = Record< + AssetIds, + NativeAsset | ForeignAsset | StableAsset | Erc20 +>; + +export default async ( + network: SubstrateNetwork, + address: string | null, + knownTokens?: KnownTokenDisplay[] +) => { + const api = (await network.api()) as API; + + const apiPromise = api.api; + + const metadata = + await apiPromise.query.assetRegistry.assetMetadatas.entries(); + + const assets = metadata + .map(([key, value]) => { + const assetKey = (key.toHuman() as [AssetKey])[0]; + const assetMetadata = value.toJSON() as AssetMetadata; + const decimals = assetMetadata.decimals; + const minimalBalance = + typeof assetMetadata.minimalBalance === "string" + ? hexToBn(assetMetadata.minimalBalance) + : toBN(assetMetadata.minimalBalance); + + let assetLookupId: OrmlAssetType | null = null; + let assetLookupValue: string | null = null; + + if (assetKey[AssetIds.FOREIGN_ASSET]) { + assetLookupId = "foreignAsset"; + assetLookupValue = assetKey[AssetIds.FOREIGN_ASSET] as string; + } else if (assetKey[AssetIds.NATIVE_ASSET]) { + assetLookupId = Object.keys( + assetKey[AssetIds.NATIVE_ASSET] + )[0] as "token"; + + assetLookupValue = (assetKey[AssetIds.NATIVE_ASSET] as NativeAsset)[ + assetLookupId + ] as string; + } else if (assetKey[AssetIds.STABLE_ASSET]) { + assetLookupId = "stableAssetPoolToken"; + assetLookupValue = assetKey[AssetIds.STABLE_ASSET] as string; + } else if (assetKey[AssetIds.ERC20_ASSET]) { + // TODO add Erc20 support, required special RPC call + } + + if (assetLookupId && assetLookupValue) { + const assetInfo = { + name: assetMetadata.name, + symbol: assetMetadata.symbol, + decimals, + minimalBalance, + assetLookupId, + assetLookupValue, + }; + + return assetInfo; + } else { + // Unhandled token types, right now just Erc20 + return null; + } + }) + .filter((asset) => asset !== null); + + const tokenOptions: InterlayOrmlAssetOptions[] = assets + .map((asset) => { + const ormlOptions: InterlayOrmlAssetOptions = { + name: hexToString(asset!.name), + symbol: hexToString(asset!.symbol), + existentialDeposit: asset!.minimalBalance, + assetType: asset!.assetLookupId, + lookupValue: asset!.assetLookupValue, + icon: network.icon, + decimals: asset!.decimals, + }; + + return ormlOptions; + }) + .map((tokenOptions) => { + if (knownTokens) { + const knownToken = knownTokens.find( + (knownToken) => + knownToken.name === tokenOptions.name && + knownToken.symbol === tokenOptions.symbol + ); + + if (knownToken) { + tokenOptions.coingeckoID = knownToken.coingeckoID; + tokenOptions.icon = knownToken.icon; + } + } + return tokenOptions; + }); + + const nativeAsset = new SubstrateNativeToken({ + name: network.currencyNameLong, + symbol: network.name, + decimals: network.decimals, + existentialDeposit: network.existentialDeposit, + icon: network.icon, + coingeckoID: network.coingeckoID, + }); + + if (address) { + await nativeAsset.getLatestUserBalance(apiPromise, address); + const queries = tokenOptions.map((asset) => { + const token = { [asset.assetType]: asset.lookupValue }; + const query = [address, token]; + + return query; + }); + + const tokenBalances = await apiPromise.query.tokens.accounts.multi(queries); + + tokenBalances.forEach((tokenData, index) => { + const data = tokenData as unknown as OrmlTokensAccountData; + + tokenOptions[index].balance = data.free.toString(); + }); + } + + return [nativeAsset, ...tokenOptions.map((o) => new InterlayOrmlAsset(o))]; +}; diff --git a/packages/extension/src/providers/polkadot/networks/interlay/types/interlay-orml-asset.ts b/packages/extension/src/providers/polkadot/networks/interlay/types/interlay-orml-asset.ts new file mode 100644 index 000000000..a48f6604f --- /dev/null +++ b/packages/extension/src/providers/polkadot/networks/interlay/types/interlay-orml-asset.ts @@ -0,0 +1,54 @@ +import { ApiPromise } from "@polkadot/api"; +import { OrmlTokensAccountData } from "../../acala/types/acala-orml-asset"; +import { SubmittableExtrinsic } from "@polkadot/api/types"; +import { ISubmittableResult } from "@polkadot/types/types"; +import { SubstrateToken } from "@/providers/polkadot/types/substrate-token"; +import { BaseTokenOptions } from "@/types/base-token"; + +export type OrmlAssetType = + | "token" + | "foreignAsset" + | "stableAssetPoolToken" + | "liquidCrowdloan"; + +export interface InterlayOrmlAssetOptions extends BaseTokenOptions { + assetType: OrmlAssetType; + lookupValue: string | number; +} + +export class InterlayOrmlAsset extends SubstrateToken { + public assetType: OrmlAssetType; + public lookupValue: string | number; + + constructor(options: InterlayOrmlAssetOptions) { + super(options); + + this.assetType = options.assetType; + this.lookupValue = options.lookupValue; + } + + public async getLatestUserBalance( + api: ApiPromise, + address: any + ): Promise { + const tokenLookup: Record = {}; + tokenLookup[this.assetType] = this.lookupValue; + + return api.query.tokens.accounts(address, tokenLookup).then((res) => { + const balance = (res as unknown as OrmlTokensAccountData).free.toString(); + this.balance = balance; + return balance; + }); + } + + public async send( + api: ApiPromise, + to: string, + amount: string + ): Promise> { + const currencyId: Record = {}; + currencyId[this.assetType] = this.lookupValue; + + return (api as ApiPromise).tx.currencies.transfer(to, currencyId, amount); + } +} diff --git a/packages/types/src/networks.ts b/packages/types/src/networks.ts index 30a1e215c..8ac7bf47c 100644 --- a/packages/types/src/networks.ts +++ b/packages/types/src/networks.ts @@ -50,6 +50,8 @@ export enum NetworkNames { Klaytn = "KLAY", Aurora = "AURORA", PuppyNet = "puppyNet", + Interlay = "INTR", + Kintsugi = "KINT", } export enum CoingeckoPlatform { @@ -82,4 +84,6 @@ export enum CoingeckoPlatform { Fantom = "avalanche", Klaytn = "klay-token", Aurora = "aurora", + Interlay = "interlay", + Kintsugi = "kintsugi", } From badf15ed59bdec0ceb8e26e69c738a2d3c125b67 Mon Sep 17 00:00:00 2001 From: ashkuc Date: Mon, 17 Apr 2023 14:36:26 +0200 Subject: [PATCH 02/14] Added Opal (Polkadot) --- .../polkadot/networks/icons/opal.svg | 1 + .../src/providers/polkadot/networks/index.ts | 2 + .../networks/unique/activity-handler.ts | 134 ++++++++++++++++++ .../polkadot/networks/unique/opal.ts | 32 +++++ packages/types/src/networks.ts | 1 + 5 files changed, 170 insertions(+) create mode 100644 packages/extension/src/providers/polkadot/networks/icons/opal.svg create mode 100644 packages/extension/src/providers/polkadot/networks/unique/activity-handler.ts create mode 100644 packages/extension/src/providers/polkadot/networks/unique/opal.ts diff --git a/packages/extension/src/providers/polkadot/networks/icons/opal.svg b/packages/extension/src/providers/polkadot/networks/icons/opal.svg new file mode 100644 index 000000000..c3d1b9357 --- /dev/null +++ b/packages/extension/src/providers/polkadot/networks/icons/opal.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/extension/src/providers/polkadot/networks/index.ts b/packages/extension/src/providers/polkadot/networks/index.ts index 198c52aa7..43704e11e 100644 --- a/packages/extension/src/providers/polkadot/networks/index.ts +++ b/packages/extension/src/providers/polkadot/networks/index.ts @@ -8,6 +8,7 @@ import sdnNode from "./astar/shiden"; import bncNode from "./bifrost/polkadot"; import bncKusamaNode from "./bifrost/kusama"; import edgNode from "./edgeware"; +import opalNode from "./unique/opal"; export default { acala: acaNode, @@ -20,4 +21,5 @@ export default { bifrost: bncNode, bifrostKusama: bncKusamaNode, edgeware: edgNode, + opal: opalNode, }; diff --git a/packages/extension/src/providers/polkadot/networks/unique/activity-handler.ts b/packages/extension/src/providers/polkadot/networks/unique/activity-handler.ts new file mode 100644 index 000000000..0b916de16 --- /dev/null +++ b/packages/extension/src/providers/polkadot/networks/unique/activity-handler.ts @@ -0,0 +1,134 @@ +import { ActivityHandlerType } from "@/libs/activity-state/types"; +import cacheFetch from "@/libs/cache-fetch"; +import { BaseNetwork } from "@/types/base-network"; +import { Activity, ActivityStatus, ActivityType } from "@/types/activity"; + +// const TTL = 30000; +const TTL = 5000; + +type ExtrinsicData = { + amount: number; + block_index: string; + block_number: string; + fee: number; + from_owner: string; + from_owner_normalized: string; + hash: string; + method: string; + section: string; + success: boolean; + timestamp: number; + to_owner: string; + to_owner_normalized: string; +}; + +const query = ` + query getLastTransfers($orderBy: ExtrinsicOrderByParams = {}, $where: ExtrinsicWhereParams = {}) { + extrinsics(limit: 50, offset: 0, order_by: $orderBy, where: $where) { + data { + block_number + block_index + amount + fee + from_owner_normalized + hash + success + timestamp + to_owner_normalized + } + timestamp + } + } +`.replace(/[\n ]+/g, " "); + +const getVariables = (address: string) => ({ + orderBy: { timestamp: "desc" }, + where: { + _and: [ + { amount: { _neq: 0 } }, + { + method: { + _in: ["transfer", "transfer_all", "transfer_keep_alive"], + }, + }, + { section: { _eq: "Balances" } }, + { + _or: [ + { from_owner_normalized: { _eq: address } }, + { to_owner_normalized: { _eq: address } }, + ], + }, + ], + }, +}); + +function getLastTransfersByAddress( + graphqlEndpoint: string, + address: string +): Promise { + const queryParams = new URLSearchParams({ + query, + variables: JSON.stringify(getVariables(address)), + }); + + const url = `${graphqlEndpoint}?${queryParams.toString()}`; + + return cacheFetch({ url }, TTL) + .then((response) => { + return response.data.extrinsics.data; + }) + .catch((reason) => { + console.error("Failed to fetch activity", reason); + + return []; + }); +} + +const transform = ( + address: string, + network: BaseNetwork, + activity: ExtrinsicData +): Activity => ({ + from: activity.from_owner_normalized, + to: activity.from_owner_normalized, + isIncoming: activity.from_owner_normalized !== address, + network: network.name, + rawInfo: { + from: activity.from_owner_normalized, + to: activity.to_owner_normalized, + success: activity.success, + hash: activity.hash, + block_num: parseInt(activity.block_number), + block_timestamp: activity.timestamp, + module: activity.section, + amount: activity.amount.toString(), + fee: activity.fee.toString(), + nonce: 0, + asset_symbol: network.currencyName, + asset_type: "", + }, + status: activity.success ? ActivityStatus.success : ActivityStatus.failed, + timestamp: activity.timestamp * 1000, + value: activity.amount + "".padStart(network.decimals, "0"), + transactionHash: activity.block_index, + type: ActivityType.transaction, + token: { + decimals: network.decimals, + icon: network.icon, + name: network.currencyNameLong, + symbol: network.currencyName, + }, +}); + +export const getActivityHandler = ( + graphqlEndpoint: string +): ActivityHandlerType => { + return async (network: BaseNetwork, address: string) => { + const activities = await getLastTransfersByAddress( + graphqlEndpoint, + address + ); + + return activities.map((activity) => transform(address, network, activity)); + }; +}; diff --git a/packages/extension/src/providers/polkadot/networks/unique/opal.ts b/packages/extension/src/providers/polkadot/networks/unique/opal.ts new file mode 100644 index 000000000..a0132bcc8 --- /dev/null +++ b/packages/extension/src/providers/polkadot/networks/unique/opal.ts @@ -0,0 +1,32 @@ +import { NetworkNames } from "@enkryptcom/types"; +import { + SubstrateNetwork, + SubstrateNetworkOptions, +} from "../../types/substrate-network"; +import { getActivityHandler } from "./activity-handler"; + +const GRAPHQL_ENDPOINT = "https://api-opal.uniquescan.io/v1/graphql"; +// const GRAPHQL_ENDPOINT = "https://scan-api.opal.uniquenetwork.dev/v1/graphql"; + +const opalOptions: SubstrateNetworkOptions = { + name: NetworkNames.Opal, + name_long: "Opal", + homePage: "https://unique.network/", + blockExplorerTX: "https://uniquescan.io/opal/extrinsic/[[txHash]]", + blockExplorerAddr: "https://uniquescan.io/opal/account/[[address]]", + isTestNetwork: true, + currencyName: "OPL", + currencyNameLong: "Opal", + icon: require("../icons/opal.svg"), + decimals: 18, + prefix: 42, + gradient: "#0CB6B8", + node: "wss://ws-opal.unique.network", + genesisHash: + "0xc87870ef90a438d574b8e320f17db372c50f62beb52e479c8ff6ee5b460670b9", + activityHandler: getActivityHandler(GRAPHQL_ENDPOINT), +}; + +const opal = new SubstrateNetwork(opalOptions); + +export default opal; diff --git a/packages/types/src/networks.ts b/packages/types/src/networks.ts index 30a1e215c..bcd646ad0 100644 --- a/packages/types/src/networks.ts +++ b/packages/types/src/networks.ts @@ -50,6 +50,7 @@ export enum NetworkNames { Klaytn = "KLAY", Aurora = "AURORA", PuppyNet = "puppyNet", + Opal = "OPL", } export enum CoingeckoPlatform { From c9deabd403036a4077b4df232e3b68bfe2a48781 Mon Sep 17 00:00:00 2001 From: ashkuc Date: Mon, 17 Apr 2023 23:04:09 +0200 Subject: [PATCH 03/14] Added Quartz and Unique (Polkadot) --- .../providers/subscan/configs.ts | 2 ++ .../polkadot/networks/icons/quartz.svg | 1 + .../polkadot/networks/icons/unique.svg | 1 + .../src/providers/polkadot/networks/index.ts | 4 +++ .../polkadot/networks/unique/quartz.ts | 32 +++++++++++++++++++ .../polkadot/networks/unique/unique.ts | 32 +++++++++++++++++++ packages/types/src/networks.ts | 4 +++ 7 files changed, 76 insertions(+) create mode 100644 packages/extension/src/providers/polkadot/networks/icons/quartz.svg create mode 100644 packages/extension/src/providers/polkadot/networks/icons/unique.svg create mode 100644 packages/extension/src/providers/polkadot/networks/unique/quartz.ts create mode 100644 packages/extension/src/providers/polkadot/networks/unique/unique.ts diff --git a/packages/extension/src/providers/polkadot/libs/activity-handlers/providers/subscan/configs.ts b/packages/extension/src/providers/polkadot/libs/activity-handlers/providers/subscan/configs.ts index 47e2a426a..78f2d0bac 100644 --- a/packages/extension/src/providers/polkadot/libs/activity-handlers/providers/subscan/configs.ts +++ b/packages/extension/src/providers/polkadot/libs/activity-handlers/providers/subscan/configs.ts @@ -11,6 +11,8 @@ const NetworkEndpoints = { [NetworkNames.Bifrost]: "https://bifrost.api.subscan.io/", [NetworkNames.BifrostKusama]: "https://bifrost-kusama.api.subscan.io/", [NetworkNames.Edgeware]: "https://edgeware.api.subscan.io/", + [NetworkNames.Quartz]: "https://quartz.api.subscan.io/", + [NetworkNames.Unique]: "https://unique.api.subscan.io/", }; export { NetworkEndpoints }; diff --git a/packages/extension/src/providers/polkadot/networks/icons/quartz.svg b/packages/extension/src/providers/polkadot/networks/icons/quartz.svg new file mode 100644 index 000000000..9b68cdde3 --- /dev/null +++ b/packages/extension/src/providers/polkadot/networks/icons/quartz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/extension/src/providers/polkadot/networks/icons/unique.svg b/packages/extension/src/providers/polkadot/networks/icons/unique.svg new file mode 100644 index 000000000..1963c5e3d --- /dev/null +++ b/packages/extension/src/providers/polkadot/networks/icons/unique.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/extension/src/providers/polkadot/networks/index.ts b/packages/extension/src/providers/polkadot/networks/index.ts index 43704e11e..a12b192c1 100644 --- a/packages/extension/src/providers/polkadot/networks/index.ts +++ b/packages/extension/src/providers/polkadot/networks/index.ts @@ -9,6 +9,8 @@ import bncNode from "./bifrost/polkadot"; import bncKusamaNode from "./bifrost/kusama"; import edgNode from "./edgeware"; import opalNode from "./unique/opal"; +import quartzNode from "./unique/quartz"; +import uniqueNode from "./unique/unique"; export default { acala: acaNode, @@ -22,4 +24,6 @@ export default { bifrostKusama: bncKusamaNode, edgeware: edgNode, opal: opalNode, + quartz: quartzNode, + unique: uniqueNode, }; diff --git a/packages/extension/src/providers/polkadot/networks/unique/quartz.ts b/packages/extension/src/providers/polkadot/networks/unique/quartz.ts new file mode 100644 index 000000000..131cad1b6 --- /dev/null +++ b/packages/extension/src/providers/polkadot/networks/unique/quartz.ts @@ -0,0 +1,32 @@ +import { CoingeckoPlatform, NetworkNames } from "@enkryptcom/types"; +import { subscanActivity } from "../../libs/activity-handlers"; +import { + SubstrateNetwork, + SubstrateNetworkOptions, +} from "../../types/substrate-network"; +import wrapActivityHandler from "@/libs/activity-state/wrap-activity-handler"; + +const quartzOptions: SubstrateNetworkOptions = { + name: NetworkNames.Quartz, + name_long: "Quartz", + homePage: "https://unique.network/", + blockExplorerTX: "https://quartz.subscan.io/extrinsic/[[txHash]]", + blockExplorerAddr: "https://quartz.subscan.io/account/[[address]]", + isTestNetwork: false, + currencyName: "QTZ", + currencyNameLong: "Quartz", + icon: require("../icons/quartz.svg"), + decimals: 18, + prefix: 255, + gradient: "#FF4D6A", + node: "wss://ws-quartz.unique.network", + coingeckoID: "quartz", + coingeckoPlatform: CoingeckoPlatform.Quartz, + genesisHash: + "0xcd4d732201ebe5d6b014edda071c4203e16867305332301dc8d092044b28e554", + activityHandler: wrapActivityHandler(subscanActivity), +}; + +const quartz = new SubstrateNetwork(quartzOptions); + +export default quartz; diff --git a/packages/extension/src/providers/polkadot/networks/unique/unique.ts b/packages/extension/src/providers/polkadot/networks/unique/unique.ts new file mode 100644 index 000000000..f7c4b0a8c --- /dev/null +++ b/packages/extension/src/providers/polkadot/networks/unique/unique.ts @@ -0,0 +1,32 @@ +import { CoingeckoPlatform, NetworkNames } from "@enkryptcom/types"; +import { subscanActivity } from "../../libs/activity-handlers"; +import { + SubstrateNetwork, + SubstrateNetworkOptions, +} from "../../types/substrate-network"; +import wrapActivityHandler from "@/libs/activity-state/wrap-activity-handler"; + +const uniqueOptions: SubstrateNetworkOptions = { + name: NetworkNames.Unique, + name_long: "Unique", + homePage: "https://unique.network/", + blockExplorerTX: "https://unique.subscan.io/extrinsic/[[txHash]]", + blockExplorerAddr: "https://unique.subscan.io/account/[[address]]", + isTestNetwork: false, + currencyName: "UNQ", + currencyNameLong: "Unique", + icon: require("../icons/unique.svg"), + decimals: 18, + prefix: 7391, + gradient: "#00BFFF", + node: "wss://ws.unique.network", + coingeckoID: "unique-network", + coingeckoPlatform: CoingeckoPlatform.Unique, + genesisHash: + "0x84322d9cddbf35088f1e54e9a85c967a41a56a4f43445768125e61af166c7d31", + activityHandler: wrapActivityHandler(subscanActivity), +}; + +const unique = new SubstrateNetwork(uniqueOptions); + +export default unique; diff --git a/packages/types/src/networks.ts b/packages/types/src/networks.ts index bcd646ad0..5c5f2d098 100644 --- a/packages/types/src/networks.ts +++ b/packages/types/src/networks.ts @@ -51,6 +51,8 @@ export enum NetworkNames { Aurora = "AURORA", PuppyNet = "puppyNet", Opal = "OPL", + Quartz = "QTZ", + Unique = "UNQ", } export enum CoingeckoPlatform { @@ -83,4 +85,6 @@ export enum CoingeckoPlatform { Fantom = "avalanche", Klaytn = "klay-token", Aurora = "aurora", + Quartz = "quartz", + Unique = "unique-network", } From 645e8a23352e3d794f73e39a1ad5e8ad255679dd Mon Sep 17 00:00:00 2001 From: ashkuc Date: Tue, 18 Apr 2023 13:01:53 +0200 Subject: [PATCH 04/14] minor fixes --- .../networks/unique/{ => libs}/activity-handler.ts | 10 +++------- .../src/providers/polkadot/networks/unique/opal.ts | 3 +-- 2 files changed, 4 insertions(+), 9 deletions(-) rename packages/extension/src/providers/polkadot/networks/unique/{ => libs}/activity-handler.ts (93%) diff --git a/packages/extension/src/providers/polkadot/networks/unique/activity-handler.ts b/packages/extension/src/providers/polkadot/networks/unique/libs/activity-handler.ts similarity index 93% rename from packages/extension/src/providers/polkadot/networks/unique/activity-handler.ts rename to packages/extension/src/providers/polkadot/networks/unique/libs/activity-handler.ts index 0b916de16..e9dd1470e 100644 --- a/packages/extension/src/providers/polkadot/networks/unique/activity-handler.ts +++ b/packages/extension/src/providers/polkadot/networks/unique/libs/activity-handler.ts @@ -3,8 +3,7 @@ import cacheFetch from "@/libs/cache-fetch"; import { BaseNetwork } from "@/types/base-network"; import { Activity, ActivityStatus, ActivityType } from "@/types/activity"; -// const TTL = 30000; -const TTL = 5000; +const TTL = 30000; type ExtrinsicData = { amount: number; @@ -124,11 +123,8 @@ export const getActivityHandler = ( graphqlEndpoint: string ): ActivityHandlerType => { return async (network: BaseNetwork, address: string) => { - const activities = await getLastTransfersByAddress( - graphqlEndpoint, - address - ); + const transfers = await getLastTransfersByAddress(graphqlEndpoint, address); - return activities.map((activity) => transform(address, network, activity)); + return transfers.map((transfer) => transform(address, network, transfer)); }; }; diff --git a/packages/extension/src/providers/polkadot/networks/unique/opal.ts b/packages/extension/src/providers/polkadot/networks/unique/opal.ts index a0132bcc8..710c542f7 100644 --- a/packages/extension/src/providers/polkadot/networks/unique/opal.ts +++ b/packages/extension/src/providers/polkadot/networks/unique/opal.ts @@ -3,10 +3,9 @@ import { SubstrateNetwork, SubstrateNetworkOptions, } from "../../types/substrate-network"; -import { getActivityHandler } from "./activity-handler"; +import { getActivityHandler } from "./libs/activity-handler"; const GRAPHQL_ENDPOINT = "https://api-opal.uniquescan.io/v1/graphql"; -// const GRAPHQL_ENDPOINT = "https://scan-api.opal.uniquenetwork.dev/v1/graphql"; const opalOptions: SubstrateNetworkOptions = { name: NetworkNames.Opal, From ed94b18ff2c79642887b399b32f085e5b5939dd9 Mon Sep 17 00:00:00 2001 From: kvhnuke <10602065+kvhnuke@users.noreply.github.com> Date: Thu, 4 May 2023 13:01:41 -0700 Subject: [PATCH 05/14] feat: add paraswap --- packages/swap/src/index.ts | 11 +- packages/swap/src/providers/paraswap/index.ts | 348 ++++++++++++++++++ packages/swap/src/providers/paraswap/types.ts | 28 ++ packages/swap/src/types/index.ts | 14 +- .../swap/tests/fixtures/mainnet/configs.ts | 26 +- packages/swap/tests/paraswap.test.ts | 84 +++++ packages/swap/tests/swap.test.ts | 11 +- 7 files changed, 510 insertions(+), 12 deletions(-) create mode 100644 packages/swap/src/providers/paraswap/index.ts create mode 100644 packages/swap/src/providers/paraswap/types.ts create mode 100644 packages/swap/tests/paraswap.test.ts diff --git a/packages/swap/src/index.ts b/packages/swap/src/index.ts index da5247e8f..77b46cf5d 100644 --- a/packages/swap/src/index.ts +++ b/packages/swap/src/index.ts @@ -3,6 +3,7 @@ import { merge } from "lodash"; import EventEmitter from "eventemitter3"; import { TOKEN_LISTS, TOP_TOKEN_INFO_LIST } from "./configs"; import OneInch from "./providers/oneInch"; +import Paraswap from "./providers/paraswap"; import Changelly from "./providers/changelly"; import NetworkDetails, { isSupportedNetwork, @@ -48,9 +49,13 @@ class Swap extends EventEmitter { initPromise: Promise; - private providerClasses: (typeof OneInch | typeof Changelly)[]; + private providerClasses: ( + | typeof OneInch + | typeof Changelly + | typeof Paraswap + )[]; - private providers: (OneInch | Changelly)[]; + private providers: (OneInch | Changelly | Paraswap)[]; private tokenList: FromTokenType; @@ -72,7 +77,7 @@ class Swap extends EventEmitter { }; this.api = options.api; this.walletId = options.walletIdentifier; - this.providerClasses = [OneInch, Changelly]; + this.providerClasses = [OneInch, Paraswap, Changelly]; this.topTokenInfo = { contractsToId: {}, topTokens: {}, diff --git a/packages/swap/src/providers/paraswap/index.ts b/packages/swap/src/providers/paraswap/index.ts new file mode 100644 index 000000000..ae1db09bf --- /dev/null +++ b/packages/swap/src/providers/paraswap/index.ts @@ -0,0 +1,348 @@ +import type Web3Eth from "web3-eth"; +import { numberToHex, toBN } from "web3-utils"; +import { + EVMTransaction, + getQuoteOptions, + MinMaxResponse, + ProviderClass, + ProviderFromTokenResponse, + ProviderName, + ProviderQuoteResponse, + ProviderSwapResponse, + ProviderToTokenResponse, + QuoteMetaOptions, + StatusOptions, + StatusOptionsResponse, + SupportedNetworkName, + SwapQuote, + TokenType, + TransactionStatus, + TransactionType, +} from "../../types"; +import { + DEFAULT_SLIPPAGE, + FEE_CONFIGS, + GAS_LIMITS, + NATIVE_TOKEN_ADDRESS, +} from "../../configs"; +import { + ParaSwapSwapResponse, + ParaswapResponseType, + ParaswpQuoteResponse, +} from "./types"; +import { + getAllowanceTransactions, + TOKEN_AMOUNT_INFINITY_AND_BEYOND, +} from "../../utils/approvals"; +import estimateGasList from "../../common/estimateGasList"; +import { isEVMAddress } from "../../utils/common"; + +export const PARASWAP_APPROVAL_ADDRESS = + "0x216b4b4ba9f3e719726886d34a177484278bfcae"; + +const supportedNetworks: { + [key in SupportedNetworkName]?: { approvalAddress: string; chainId: string }; +} = { + [SupportedNetworkName.Ethereum]: { + approvalAddress: PARASWAP_APPROVAL_ADDRESS, + chainId: "1", + }, + [SupportedNetworkName.Binance]: { + approvalAddress: PARASWAP_APPROVAL_ADDRESS, + chainId: "56", + }, + [SupportedNetworkName.Matic]: { + approvalAddress: PARASWAP_APPROVAL_ADDRESS, + chainId: "137", + }, + [SupportedNetworkName.Avalanche]: { + approvalAddress: PARASWAP_APPROVAL_ADDRESS, + chainId: "43114", + }, + [SupportedNetworkName.Fantom]: { + approvalAddress: PARASWAP_APPROVAL_ADDRESS, + chainId: "250", + }, + [SupportedNetworkName.Arbitrum]: { + approvalAddress: PARASWAP_APPROVAL_ADDRESS, + chainId: "42161", + }, +}; + +const BASE_URL = "https://apiv5.paraswap.io/"; + +class ParaSwap extends ProviderClass { + tokenList: TokenType[]; + + network: SupportedNetworkName; + + web3eth: Web3Eth; + + name: ProviderName; + + fromTokens: ProviderFromTokenResponse; + + toTokens: ProviderToTokenResponse; + + constructor(web3eth: Web3Eth, network: SupportedNetworkName) { + super(web3eth, network); + this.network = network; + this.tokenList = []; + this.web3eth = web3eth; + this.name = ProviderName.paraswap; + this.fromTokens = {}; + this.toTokens = {}; + } + + init(tokenList: TokenType[]): Promise { + if (!ParaSwap.isSupported(this.network)) return; + tokenList.forEach((t) => { + this.fromTokens[t.address] = t; + if (!this.toTokens[this.network]) this.toTokens[this.network] = {}; + this.toTokens[this.network][t.address] = { + ...t, + networkInfo: { + name: this.network, + isAddress: (address: string) => + Promise.resolve(isEVMAddress(address)), + }, + }; + }); + } + + static isSupported(network: SupportedNetworkName) { + return Object.keys(supportedNetworks).includes( + network as unknown as string + ); + } + + getFromTokens() { + return this.fromTokens; + } + + getToTokens() { + return this.toTokens; + } + + getMinMaxAmount(): Promise { + return Promise.resolve({ + minimumFrom: toBN("1"), + maximumFrom: toBN(TOKEN_AMOUNT_INFINITY_AND_BEYOND), + minimumTo: toBN("1"), + maximumTo: toBN(TOKEN_AMOUNT_INFINITY_AND_BEYOND), + }); + } + + private getParaswapSwap( + options: getQuoteOptions, + meta: QuoteMetaOptions, + accurateEstimate: boolean + ): Promise { + if ( + !ParaSwap.isSupported( + options.toToken.networkInfo.name as SupportedNetworkName + ) || + this.network !== options.toToken.networkInfo.name + ) + return Promise.resolve(null); + const feeConfig = FEE_CONFIGS[this.name][meta.walletIdentifier]; + const params = new URLSearchParams({ + ignoreChecks: "true", + ignoreGasEstimate: "true", + onlyParams: "false", + }); + const body = JSON.stringify({ + srcToken: options.fromToken.address, + srcDecimals: options.fromToken.decimals.toString(), + destToken: options.toToken.address, + destDecimals: options.toToken.decimals.toString(), + srcAmount: options.amount.toString(), + priceRoute: meta.priceRoute!, + userAddress: options.fromAddress, + txOrigin: options.fromAddress, + receiver: options.toAddress, + slippage: parseInt( + ( + parseFloat(meta.slippage ? meta.slippage : DEFAULT_SLIPPAGE) * 10 + ).toString(), + 10 + ).toString(), + deadline: Math.floor(Date.now() / 1000) + 300, + partnerAddress: feeConfig ? feeConfig.referrer : "", + partnerFeeBps: feeConfig + ? parseInt((feeConfig.fee * 10000).toString(), 10).toString() + : "0", + }); + return fetch( + `${BASE_URL}transactions/${ + supportedNetworks[this.network].chainId + }?${params.toString()}`, + { + method: "POST", + headers: { + Accept: "application/json", + "Content-Type": "application/json", + }, + body, + } + ) + .then((res) => res.json()) + .then(async (response: ParaswapResponseType) => { + if (response.error) { + console.error(response.error); + return Promise.resolve(null); + } + const transactions: EVMTransaction[] = []; + + if (options.fromToken.address !== NATIVE_TOKEN_ADDRESS) { + const approvalTxs = await getAllowanceTransactions({ + infinityApproval: meta.infiniteApproval, + spender: supportedNetworks[this.network].approvalAddress, + web3eth: this.web3eth, + amount: options.amount, + fromAddress: options.fromAddress, + fromToken: options.fromToken, + }); + transactions.push(...approvalTxs); + } + transactions.push({ + from: options.fromAddress, + gasLimit: GAS_LIMITS.swap, + to: response.to, + value: numberToHex(response.value), + data: response.data, + type: TransactionType.evm, + }); + if (accurateEstimate) { + const accurateGasEstimate = await estimateGasList( + transactions, + this.network + ); + if (accurateGasEstimate) { + if (accurateGasEstimate.isError) return null; + transactions.forEach((tx, idx) => { + tx.gasLimit = accurateGasEstimate.result[idx]; + }); + } + } + return { + transactions, + toTokenAmount: toBN( + (meta.priceRoute as ParaswpQuoteResponse).destAmount + ), + fromTokenAmount: toBN( + (meta.priceRoute as ParaswpQuoteResponse).srcAmount + ), + }; + }); + } + + getQuote( + options: getQuoteOptions, + meta: QuoteMetaOptions + ): Promise { + if ( + !ParaSwap.isSupported( + options.toToken.networkInfo.name as SupportedNetworkName + ) || + this.network !== options.toToken.networkInfo.name + ) + return Promise.resolve(null); + const feeConfig = FEE_CONFIGS[this.name][meta.walletIdentifier]; + const params = new URLSearchParams({ + srcToken: options.fromToken.address, + srcDecimals: options.fromToken.decimals.toString(), + destToken: options.toToken.address, + destDecimals: options.toToken.decimals.toString(), + amount: options.amount.toString(), + side: "SELL", + network: supportedNetworks[this.network].chainId, + userAddress: options.fromAddress, + receiver: options.toAddress, + partnerAddress: feeConfig ? feeConfig.referrer : "", + partnerFeeBps: feeConfig + ? parseInt((feeConfig.fee * 10000).toString(), 10).toString() + : "0", + }); + return fetch(`${BASE_URL}prices?${params.toString()}`) + .then((j) => j.json()) + .then(async (jsonRes) => { + if (!jsonRes) return null; + const res: ParaswpQuoteResponse = jsonRes.priceRoute; + const transactions: EVMTransaction[] = []; + if (options.fromToken.address !== NATIVE_TOKEN_ADDRESS) { + const approvalTxs = await getAllowanceTransactions({ + infinityApproval: meta.infiniteApproval, + spender: supportedNetworks[this.network].approvalAddress, + web3eth: this.web3eth, + amount: options.amount, + fromAddress: options.fromAddress, + fromToken: options.fromToken, + }); + transactions.push(...approvalTxs); + } + const response: ProviderQuoteResponse = { + fromTokenAmount: toBN(res.srcAmount), + toTokenAmount: toBN(res.destAmount), + provider: this.name, + quote: { + meta: { + ...meta, + priceRoute: res, + }, + options, + provider: this.name, + }, + totalGaslimit: + transactions.reduce( + (total: number, curVal: EVMTransaction) => + total + toBN(curVal.gasLimit).toNumber(), + 0 + ) + toBN(GAS_LIMITS.swap).toNumber(), + minMax: await this.getMinMaxAmount(), + }; + return response; + }); + } + + getSwap(quote: SwapQuote): Promise { + return this.getParaswapSwap(quote.options, quote.meta, true).then((res) => { + if (!res) return null; + const feeConfig = + FEE_CONFIGS[this.name][quote.meta.walletIdentifier].fee || 0; + const response: ProviderSwapResponse = { + fromTokenAmount: res.fromTokenAmount, + provider: this.name, + toTokenAmount: res.toTokenAmount, + transactions: res.transactions, + slippage: quote.meta.slippage || DEFAULT_SLIPPAGE, + fee: feeConfig * 100, + getStatusObject: async ( + options: StatusOptions + ): Promise => ({ + options, + provider: this.name, + }), + }; + return response; + }); + } + + getStatus(options: StatusOptions): Promise { + const promises = options.transactionHashes.map((hash) => + this.web3eth.getTransactionReceipt(hash) + ); + return Promise.all(promises).then((receipts) => { + // eslint-disable-next-line no-restricted-syntax + for (const receipt of receipts) { + if (!receipt || (receipt && !receipt.blockNumber)) { + return TransactionStatus.pending; + } + if (receipt && !receipt.status) return TransactionStatus.failed; + } + return TransactionStatus.success; + }); + } +} + +export default ParaSwap; diff --git a/packages/swap/src/providers/paraswap/types.ts b/packages/swap/src/providers/paraswap/types.ts new file mode 100644 index 000000000..9d4c1a79e --- /dev/null +++ b/packages/swap/src/providers/paraswap/types.ts @@ -0,0 +1,28 @@ +import { BN, EVMTransaction } from "../../types"; + +export interface ParaswapResponseType { + error?: string; + from: string; + to: string; + data: string; + value: string; +} +export interface ParaSwapSwapResponse { + transactions: EVMTransaction[]; + toTokenAmount: BN; + fromTokenAmount: BN; +} + +export interface ParaswpQuoteResponse { + blockNumber: number; + network: number; + srcToken: string; + srcDecimals: number; + srcAmount: string; + destToken: string; + destDecimals: number; + destAmount: string; + tokenTransferProxy: string; + contractAddress: string; + bestRoute: unknown; +} diff --git a/packages/swap/src/types/index.ts b/packages/swap/src/types/index.ts index 0696acfb2..7fe9a18ea 100644 --- a/packages/swap/src/types/index.ts +++ b/packages/swap/src/types/index.ts @@ -75,9 +75,9 @@ export interface FromTokenType { } export interface ToTokenType { - top: Record; - trending: Record; - all: Record; + top: Record | Record; + trending: Record | Record; + all: Record | Record; } export interface EvmOptions { @@ -97,6 +97,7 @@ export interface QuoteMetaOptions { walletIdentifier: WalletIdentifier; slippage?: string; changellyQuoteId?: string; + priceRoute?: unknown; } export interface SwapOptions { @@ -196,10 +197,9 @@ export interface ProviderSwapResponse { export type ProviderFromTokenResponse = Record; -export type ProviderToTokenResponse = Record< - SupportedNetworkName, - Record ->; +export type ProviderToTokenResponse = + | Record> + | Record; export interface TopTokenInfo { trendingTokens: Record; diff --git a/packages/swap/tests/fixtures/mainnet/configs.ts b/packages/swap/tests/fixtures/mainnet/configs.ts index 955c242ed..07279342b 100644 --- a/packages/swap/tests/fixtures/mainnet/configs.ts +++ b/packages/swap/tests/fixtures/mainnet/configs.ts @@ -19,6 +19,22 @@ const fromToken: TokenType = { type: NetworkType.EVM, }; +const toTokenWETH: TokenTypeTo = { + address: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", + decimals: 18, + logoURI: + "https://assets.coingecko.com/coins/images/2518/thumb/weth.png?1628852295", + name: "WETH", + symbol: "WETH", + rank: 100, + cgId: "ethereum", + type: NetworkType.EVM, + networkInfo: { + isAddress: async (address: string) => isAddress(address), + name: NetworkNames.Ethereum, + }, +}; + const toToken: TokenTypeTo = { address: "0x111111111117dc0aa78b770fa6a738034120c302", decimals: 18, @@ -35,4 +51,12 @@ const toToken: TokenTypeTo = { }, }; -export { fromToken, toToken, amount, fromAddress, toAddress, nodeURL }; +export { + fromToken, + toToken, + toTokenWETH, + amount, + fromAddress, + toAddress, + nodeURL, +}; diff --git a/packages/swap/tests/paraswap.test.ts b/packages/swap/tests/paraswap.test.ts new file mode 100644 index 000000000..141dc5319 --- /dev/null +++ b/packages/swap/tests/paraswap.test.ts @@ -0,0 +1,84 @@ +import { expect } from "chai"; +import Web3Eth from "web3-eth"; +import { numberToHex } from "web3-utils"; +import Parawap, { PARASWAP_APPROVAL_ADDRESS } from "../src/providers/paraswap"; +import { + EVMTransaction, + ProviderName, + SupportedNetworkName, + WalletIdentifier, +} from "../src/types"; +import { TOKEN_AMOUNT_INFINITY_AND_BEYOND } from "../src/utils/approvals"; +import { + fromToken, + toTokenWETH as toToken, + amount, + fromAddress, + toAddress, + nodeURL, +} from "./fixtures/mainnet/configs"; + +describe("Paraswap Provider", () => { + // @ts-ignore + const web3eth = new Web3Eth(nodeURL); + const paraSwap = new Parawap(web3eth, SupportedNetworkName.Ethereum); + it("it should return a quote infinity approval", async () => { + const quote = await paraSwap.getQuote( + { + amount, + fromAddress, + fromToken, + toToken, + toAddress, + }, + { infiniteApproval: true, walletIdentifier: WalletIdentifier.enkrypt } + ); + expect(quote?.provider).to.be.eq(ProviderName.paraswap); + expect(quote?.quote.meta.infiniteApproval).to.be.eq(true); + expect(quote?.quote.meta.walletIdentifier).to.be.eq( + WalletIdentifier.enkrypt + ); + expect(quote?.fromTokenAmount.toString()).to.be.eq(amount.toString()); + expect(quote?.toTokenAmount.gtn(0)).to.be.eq(true); + + const swap = await paraSwap.getSwap(quote!.quote); + expect(swap?.transactions.length).to.be.eq(2); + expect(swap?.transactions[0].to).to.be.eq(fromToken.address); + expect((swap?.transactions[0] as EVMTransaction).data).to.be.eq( + `0x095ea7b3000000000000000000000000${PARASWAP_APPROVAL_ADDRESS.replace( + "0x", + "" + )}${TOKEN_AMOUNT_INFINITY_AND_BEYOND.replace("0x", "")}` + ); + expect(swap?.transactions[1].to).to.be.eq( + "0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57" + ); + }).timeout(5000); + + it("it should return a quote non infinity approval", async () => { + const quote = await paraSwap.getQuote( + { + amount, + fromAddress, + fromToken, + toToken, + toAddress, + }, + { infiniteApproval: false, walletIdentifier: WalletIdentifier.enkrypt } + ); + expect(quote?.quote.meta.infiniteApproval).to.be.eq(false); + const swap = await paraSwap.getSwap(quote!.quote); + expect(swap?.transactions.length).to.be.eq(2); + expect((swap?.transactions[0] as EVMTransaction).data).to.be.eq( + `0x095ea7b3000000000000000000000000${PARASWAP_APPROVAL_ADDRESS.replace( + "0x", + "" + )}000000000000000000000000000000000000000000000000${numberToHex( + amount + ).replace("0x", "")}` + ); + expect(swap?.transactions[1].to).to.be.eq( + "0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57" + ); + }).timeout(5000); +}); diff --git a/packages/swap/tests/swap.test.ts b/packages/swap/tests/swap.test.ts index 60b4d0774..423979878 100644 --- a/packages/swap/tests/swap.test.ts +++ b/packages/swap/tests/swap.test.ts @@ -61,18 +61,27 @@ describe("Swap", () => { toToken, toAddress, }); - expect(quotes?.length).to.be.eq(2); + expect(quotes?.length).to.be.eq(3); const oneInceQuote = quotes.find( (q) => q.provider === ProviderName.oneInch ); + const paraswapQuote = quotes.find( + (q) => q.provider === ProviderName.paraswap + ); const changellyQuote = quotes.find( (q) => q.provider === ProviderName.changelly ); expect(changellyQuote!.provider).to.be.eq(ProviderName.changelly); expect(oneInceQuote!.provider).to.be.eq(ProviderName.oneInch); + expect(paraswapQuote!.provider).to.be.eq(ProviderName.paraswap); const swapOneInch = await enkryptSwap.getSwap(oneInceQuote!.quote); expect(swapOneInch?.fromTokenAmount.toString()).to.be.eq(amount.toString()); expect(swapOneInch?.transactions.length).to.be.eq(2); + const swapParaswap = await enkryptSwap.getSwap(paraswapQuote!.quote); + expect(swapParaswap?.fromTokenAmount.toString()).to.be.eq( + amount.toString() + ); + expect(swapParaswap?.transactions.length).to.be.eq(2); const swapChangelly = await enkryptSwap.getSwap(changellyQuote!.quote); if (swapChangelly) expect(swapChangelly?.transactions.length).to.be.eq(1); }).timeout(10000); From 238006f8eff2a1cb6d5b375e9f5d996a553332f5 Mon Sep 17 00:00:00 2001 From: kvhnuke <10602065+kvhnuke@users.noreply.github.com> Date: Wed, 10 May 2023 13:50:05 -0700 Subject: [PATCH 06/14] feat: add zerox support --- packages/swap/src/index.ts | 6 +- packages/swap/src/providers/zerox/index.ts | 281 +++++++++++++++++++++ packages/swap/src/providers/zerox/types.ts | 18 ++ packages/swap/tests/swap.test.ts | 30 ++- packages/swap/tests/zerox.test.ts | 81 ++++++ 5 files changed, 413 insertions(+), 3 deletions(-) create mode 100644 packages/swap/src/providers/zerox/index.ts create mode 100644 packages/swap/src/providers/zerox/types.ts create mode 100644 packages/swap/tests/zerox.test.ts diff --git a/packages/swap/src/index.ts b/packages/swap/src/index.ts index 77b46cf5d..71196c462 100644 --- a/packages/swap/src/index.ts +++ b/packages/swap/src/index.ts @@ -5,6 +5,7 @@ import { TOKEN_LISTS, TOP_TOKEN_INFO_LIST } from "./configs"; import OneInch from "./providers/oneInch"; import Paraswap from "./providers/paraswap"; import Changelly from "./providers/changelly"; +import ZeroX from "./providers/zerox"; import NetworkDetails, { isSupportedNetwork, getSupportedNetworks, @@ -53,9 +54,10 @@ class Swap extends EventEmitter { | typeof OneInch | typeof Changelly | typeof Paraswap + | typeof ZeroX )[]; - private providers: (OneInch | Changelly | Paraswap)[]; + private providers: (OneInch | Changelly | Paraswap | ZeroX)[]; private tokenList: FromTokenType; @@ -77,7 +79,7 @@ class Swap extends EventEmitter { }; this.api = options.api; this.walletId = options.walletIdentifier; - this.providerClasses = [OneInch, Paraswap, Changelly]; + this.providerClasses = [OneInch, Paraswap, Changelly, ZeroX]; this.topTokenInfo = { contractsToId: {}, topTokens: {}, diff --git a/packages/swap/src/providers/zerox/index.ts b/packages/swap/src/providers/zerox/index.ts new file mode 100644 index 000000000..39c183d95 --- /dev/null +++ b/packages/swap/src/providers/zerox/index.ts @@ -0,0 +1,281 @@ +import type Web3Eth from "web3-eth"; +import { numberToHex, toBN } from "web3-utils"; +import { + EVMTransaction, + getQuoteOptions, + MinMaxResponse, + ProviderClass, + ProviderFromTokenResponse, + ProviderName, + ProviderQuoteResponse, + ProviderSwapResponse, + ProviderToTokenResponse, + QuoteMetaOptions, + StatusOptions, + StatusOptionsResponse, + SupportedNetworkName, + SwapQuote, + TokenType, + TransactionStatus, + TransactionType, +} from "../../types"; +import { + DEFAULT_SLIPPAGE, + FEE_CONFIGS, + GAS_LIMITS, + NATIVE_TOKEN_ADDRESS, +} from "../../configs"; +import { ZeroXResponseType, ZeroXSwapResponse } from "./types"; +import { + getAllowanceTransactions, + TOKEN_AMOUNT_INFINITY_AND_BEYOND, +} from "../../utils/approvals"; +import estimateGasList from "../../common/estimateGasList"; +import { isEVMAddress } from "../../utils/common"; + +const supportedNetworks: { + [key in SupportedNetworkName]?: { approvalAddress: string; chainId: string }; +} = { + [SupportedNetworkName.Ethereum]: { + approvalAddress: "0xdef1c0ded9bec7f1a1670819833240f027b25eff", + chainId: "1", + }, + [SupportedNetworkName.Binance]: { + approvalAddress: "0xdef1c0ded9bec7f1a1670819833240f027b25eff", + chainId: "56", + }, + [SupportedNetworkName.Matic]: { + approvalAddress: "0xdef1c0ded9bec7f1a1670819833240f027b25eff", + chainId: "137", + }, + [SupportedNetworkName.Optimism]: { + approvalAddress: "0xdef1abe32c034e558cdd535791643c58a13acc10", + chainId: "10", + }, + [SupportedNetworkName.Avalanche]: { + approvalAddress: "0xdef1c0ded9bec7f1a1670819833240f027b25eff", + chainId: "43114", + }, + [SupportedNetworkName.Fantom]: { + approvalAddress: "0xdef189deaef76e379df891899eb5a00a94cbc250", + chainId: "250", + }, + [SupportedNetworkName.Arbitrum]: { + approvalAddress: "0xdef1c0ded9bec7f1a1670819833240f027b25eff", + chainId: "42161", + }, +}; + +const BASE_URL = "https://partners.mewapi.io/zerox/"; + +class ZeroX extends ProviderClass { + tokenList: TokenType[]; + + network: SupportedNetworkName; + + web3eth: Web3Eth; + + name: ProviderName; + + fromTokens: ProviderFromTokenResponse; + + toTokens: ProviderToTokenResponse; + + constructor(web3eth: Web3Eth, network: SupportedNetworkName) { + super(web3eth, network); + this.network = network; + this.tokenList = []; + this.web3eth = web3eth; + this.name = ProviderName.zerox; + this.fromTokens = {}; + this.toTokens = {}; + } + + init(tokenList: TokenType[]): Promise { + if (!ZeroX.isSupported(this.network)) return; + tokenList.forEach((t) => { + this.fromTokens[t.address] = t; + if (!this.toTokens[this.network]) this.toTokens[this.network] = {}; + this.toTokens[this.network][t.address] = { + ...t, + networkInfo: { + name: this.network, + isAddress: (address: string) => + Promise.resolve(isEVMAddress(address)), + }, + }; + }); + } + + static isSupported(network: SupportedNetworkName) { + return Object.keys(supportedNetworks).includes( + network as unknown as string + ); + } + + getFromTokens() { + return this.fromTokens; + } + + getToTokens() { + return this.toTokens; + } + + getMinMaxAmount(): Promise { + return Promise.resolve({ + minimumFrom: toBN("1"), + maximumFrom: toBN(TOKEN_AMOUNT_INFINITY_AND_BEYOND), + minimumTo: toBN("1"), + maximumTo: toBN(TOKEN_AMOUNT_INFINITY_AND_BEYOND), + }); + } + + private getZeroXSwap( + options: getQuoteOptions, + meta: QuoteMetaOptions, + accurateEstimate: boolean + ): Promise { + if ( + !ZeroX.isSupported( + options.toToken.networkInfo.name as SupportedNetworkName + ) || + this.network !== options.toToken.networkInfo.name + ) + return Promise.resolve(null); + if (options.fromAddress.toLowerCase() !== options.toAddress.toLowerCase()) + // zerox doesnt allow different to address + return Promise.resolve(null); + const feeConfig = FEE_CONFIGS[this.name][meta.walletIdentifier]; + const params = new URLSearchParams({ + sellToken: options.fromToken.address, + buyToken: options.toToken.address, + sellAmount: options.amount.toString(), + takerAddress: options.fromAddress, + slippagePercentage: ( + parseFloat(meta.slippage ? meta.slippage : DEFAULT_SLIPPAGE) / 100 + ).toString(), + buyTokenPercentageFee: feeConfig ? feeConfig.fee.toString() : "0", + feeRecipient: feeConfig ? feeConfig.referrer : "", + skipValidation: "true", + enableSlippageProtection: "false", + affiliateAddress: feeConfig ? feeConfig.referrer : "", + }); + return fetch( + `${BASE_URL}${ + supportedNetworks[this.network].chainId + }/swap/v1/quote?${params.toString()}` + ) + .then((res) => res.json()) + .then(async (response: ZeroXResponseType) => { + if (response.code) { + console.error(response.code, response.reason); + return Promise.resolve(null); + } + const transactions: EVMTransaction[] = []; + + if (options.fromToken.address !== NATIVE_TOKEN_ADDRESS) { + const approvalTxs = await getAllowanceTransactions({ + infinityApproval: meta.infiniteApproval, + spender: supportedNetworks[this.network].approvalAddress, + web3eth: this.web3eth, + amount: options.amount, + fromAddress: options.fromAddress, + fromToken: options.fromToken, + }); + transactions.push(...approvalTxs); + } + transactions.push({ + from: options.fromAddress, + gasLimit: GAS_LIMITS.swap, + to: response.to, + value: numberToHex(response.value), + data: response.data, + type: TransactionType.evm, + }); + if (accurateEstimate) { + const accurateGasEstimate = await estimateGasList( + transactions, + this.network + ); + if (accurateGasEstimate) { + if (accurateGasEstimate.isError) return null; + transactions.forEach((tx, idx) => { + tx.gasLimit = accurateGasEstimate.result[idx]; + }); + } + } + return { + transactions, + toTokenAmount: toBN(response.buyAmount), + fromTokenAmount: toBN(response.sellAmount), + }; + }); + } + + getQuote( + options: getQuoteOptions, + meta: QuoteMetaOptions + ): Promise { + return this.getZeroXSwap(options, meta, false).then(async (res) => { + if (!res) return null; + const response: ProviderQuoteResponse = { + fromTokenAmount: res.fromTokenAmount, + toTokenAmount: res.toTokenAmount, + provider: this.name, + quote: { + meta, + options, + provider: this.name, + }, + totalGaslimit: res.transactions.reduce( + (total: number, curVal: EVMTransaction) => + total + toBN(curVal.gasLimit).toNumber(), + 0 + ), + minMax: await this.getMinMaxAmount(), + }; + return response; + }); + } + + getSwap(quote: SwapQuote): Promise { + return this.getZeroXSwap(quote.options, quote.meta, true).then((res) => { + if (!res) return null; + const feeConfig = + FEE_CONFIGS[this.name][quote.meta.walletIdentifier].fee || 0; + const response: ProviderSwapResponse = { + fromTokenAmount: res.fromTokenAmount, + provider: this.name, + toTokenAmount: res.toTokenAmount, + transactions: res.transactions, + slippage: quote.meta.slippage || DEFAULT_SLIPPAGE, + fee: feeConfig * 100, + getStatusObject: async ( + options: StatusOptions + ): Promise => ({ + options, + provider: this.name, + }), + }; + return response; + }); + } + + getStatus(options: StatusOptions): Promise { + const promises = options.transactionHashes.map((hash) => + this.web3eth.getTransactionReceipt(hash) + ); + return Promise.all(promises).then((receipts) => { + // eslint-disable-next-line no-restricted-syntax + for (const receipt of receipts) { + if (!receipt || (receipt && !receipt.blockNumber)) { + return TransactionStatus.pending; + } + if (receipt && !receipt.status) return TransactionStatus.failed; + } + return TransactionStatus.success; + }); + } +} + +export default ZeroX; diff --git a/packages/swap/src/providers/zerox/types.ts b/packages/swap/src/providers/zerox/types.ts new file mode 100644 index 000000000..9bd5c7b5f --- /dev/null +++ b/packages/swap/src/providers/zerox/types.ts @@ -0,0 +1,18 @@ +import { BN, EVMTransaction } from "../../types"; + +export interface ZeroXResponseType { + code?: number; + reason?: string; + buyTokenAddress: string; + sellTokenAddress: string; + buyAmount: string; + sellAmount: string; + to: string; + data: string; + value: string; +} +export interface ZeroXSwapResponse { + transactions: EVMTransaction[]; + toTokenAmount: BN; + fromTokenAmount: BN; +} diff --git a/packages/swap/tests/swap.test.ts b/packages/swap/tests/swap.test.ts index 423979878..89935a7b6 100644 --- a/packages/swap/tests/swap.test.ts +++ b/packages/swap/tests/swap.test.ts @@ -52,7 +52,7 @@ describe("Swap", () => { ); }); - it("it should get quote and swap", async () => { + it("it should get quote and swap for different destination", async () => { await enkryptSwap.initPromise; const quotes = await enkryptSwap.getQuotes({ amount, @@ -71,6 +71,8 @@ describe("Swap", () => { const changellyQuote = quotes.find( (q) => q.provider === ProviderName.changelly ); + const zeroxQuote = quotes.find((q) => q.provider === ProviderName.zerox); + expect(zeroxQuote).to.be.eq(undefined); expect(changellyQuote!.provider).to.be.eq(ProviderName.changelly); expect(oneInceQuote!.provider).to.be.eq(ProviderName.oneInch); expect(paraswapQuote!.provider).to.be.eq(ProviderName.paraswap); @@ -85,4 +87,30 @@ describe("Swap", () => { const swapChangelly = await enkryptSwap.getSwap(changellyQuote!.quote); if (swapChangelly) expect(swapChangelly?.transactions.length).to.be.eq(1); }).timeout(10000); + + it("it should get quote and swap for same destination", async () => { + await enkryptSwap.initPromise; + const quotes = await enkryptSwap.getQuotes({ + amount, + fromAddress, + fromToken, + toToken, + toAddress: fromAddress, + }); + expect(quotes?.length).to.be.eq(4); + const oneInceQuote = quotes.find( + (q) => q.provider === ProviderName.oneInch + ); + const paraswapQuote = quotes.find( + (q) => q.provider === ProviderName.paraswap + ); + const changellyQuote = quotes.find( + (q) => q.provider === ProviderName.changelly + ); + const zeroxQuote = quotes.find((q) => q.provider === ProviderName.zerox); + expect(zeroxQuote!.provider).to.be.eq(ProviderName.zerox); + expect(changellyQuote!.provider).to.be.eq(ProviderName.changelly); + expect(oneInceQuote!.provider).to.be.eq(ProviderName.oneInch); + expect(paraswapQuote!.provider).to.be.eq(ProviderName.paraswap); + }).timeout(10000); }); diff --git a/packages/swap/tests/zerox.test.ts b/packages/swap/tests/zerox.test.ts new file mode 100644 index 000000000..8756902e5 --- /dev/null +++ b/packages/swap/tests/zerox.test.ts @@ -0,0 +1,81 @@ +import { expect } from "chai"; +import Web3Eth from "web3-eth"; +import { numberToHex } from "web3-utils"; +import Zerox from "../src/providers/zerox"; +import { + EVMTransaction, + ProviderName, + SupportedNetworkName, + WalletIdentifier, +} from "../src/types"; +import { TOKEN_AMOUNT_INFINITY_AND_BEYOND } from "../src/utils/approvals"; +import { + fromToken, + toToken, + amount, + fromAddress, + toAddress, + nodeURL, +} from "./fixtures/mainnet/configs"; + +describe("Zerox Provider", () => { + // @ts-ignore + const web3eth = new Web3Eth(nodeURL); + const zerox = new Zerox(web3eth, SupportedNetworkName.Ethereum); + const ZEROX_APPROVAL = "0xdef1c0ded9bec7f1a1670819833240f027b25eff"; + it("it should return a quote infinity approval", async () => { + const quote = await zerox.getQuote( + { + amount, + fromAddress, + fromToken, + toToken, + toAddress: fromAddress, + }, + { infiniteApproval: true, walletIdentifier: WalletIdentifier.enkrypt } + ); + expect(quote?.provider).to.be.eq(ProviderName.zerox); + expect(quote?.quote.meta.infiniteApproval).to.be.eq(true); + expect(quote?.quote.meta.walletIdentifier).to.be.eq( + WalletIdentifier.enkrypt + ); + expect(quote?.fromTokenAmount.toString()).to.be.eq(amount.toString()); + expect(quote?.toTokenAmount.gtn(0)).to.be.eq(true); + + const swap = await zerox.getSwap(quote!.quote); + expect(swap?.transactions.length).to.be.eq(2); + expect(swap?.transactions[0].to).to.be.eq(fromToken.address); + expect((swap?.transactions[0] as EVMTransaction).data).to.be.eq( + `0x095ea7b3000000000000000000000000${ZEROX_APPROVAL.replace( + "0x", + "" + )}${TOKEN_AMOUNT_INFINITY_AND_BEYOND.replace("0x", "")}` + ); + expect(swap?.transactions[1].to).to.be.eq(ZEROX_APPROVAL); + }).timeout(5000); + + it("it should return a quote non infinity approval", async () => { + const quote = await zerox.getQuote( + { + amount, + fromAddress, + fromToken, + toToken, + toAddress: fromAddress, + }, + { infiniteApproval: false, walletIdentifier: WalletIdentifier.enkrypt } + ); + expect(quote?.quote.meta.infiniteApproval).to.be.eq(false); + const swap = await zerox.getSwap(quote!.quote); + expect(swap?.transactions.length).to.be.eq(2); + expect((swap?.transactions[0] as EVMTransaction).data).to.be.eq( + `0x095ea7b3000000000000000000000000${ZEROX_APPROVAL.replace( + "0x", + "" + )}000000000000000000000000000000000000000000000000${numberToHex( + amount + ).replace("0x", "")}` + ); + expect(swap?.transactions[1].to).to.be.eq(ZEROX_APPROVAL); + }).timeout(5000); +}); From 120e1c2d3b9ebed48e6ce0310da473182818b47d Mon Sep 17 00:00:00 2001 From: kvhnuke <10602065+kvhnuke@users.noreply.github.com> Date: Wed, 10 May 2023 14:13:02 -0700 Subject: [PATCH 07/14] devop: remove console.log --- packages/extension/src/ui/action/views/swap/index.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/extension/src/ui/action/views/swap/index.vue b/packages/extension/src/ui/action/views/swap/index.vue index b49b93cca..253880540 100644 --- a/packages/extension/src/ui/action/views/swap/index.vue +++ b/packages/extension/src/ui/action/views/swap/index.vue @@ -255,7 +255,6 @@ onMounted(async () => { props.network .getAllTokenInfo(props.accountInfo.selectedAccount?.address as string) .then(async (tokens) => { - console.log(tokens); await swap.initPromise; let swapFromTokens = await swap.getFromTokens(); const tokensWithBalance: Record = {}; From 34f47db49017b89e50bb878ab20697c3767741cf Mon Sep 17 00:00:00 2001 From: kvhnuke <10602065+kvhnuke@users.noreply.github.com> Date: Wed, 10 May 2023 14:14:56 -0700 Subject: [PATCH 08/14] devop: update tests --- packages/swap/tests/zerox.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/swap/tests/zerox.test.ts b/packages/swap/tests/zerox.test.ts index 8756902e5..772cf68aa 100644 --- a/packages/swap/tests/zerox.test.ts +++ b/packages/swap/tests/zerox.test.ts @@ -14,7 +14,6 @@ import { toToken, amount, fromAddress, - toAddress, nodeURL, } from "./fixtures/mainnet/configs"; From 879e8df98f8cf202c53401c8fb2052e661384cfe Mon Sep 17 00:00:00 2001 From: kvhnuke <10602065+kvhnuke@users.noreply.github.com> Date: Wed, 10 May 2023 14:27:33 -0700 Subject: [PATCH 09/14] devop: add interlay and kintsugi --- packages/extension/src/providers/polkadot/networks/index.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/extension/src/providers/polkadot/networks/index.ts b/packages/extension/src/providers/polkadot/networks/index.ts index a12b192c1..9199b6aeb 100644 --- a/packages/extension/src/providers/polkadot/networks/index.ts +++ b/packages/extension/src/providers/polkadot/networks/index.ts @@ -11,6 +11,8 @@ import edgNode from "./edgeware"; import opalNode from "./unique/opal"; import quartzNode from "./unique/quartz"; import uniqueNode from "./unique/unique"; +import interlayNode from "./interlay/interlay"; +import kintsugiNode from "./interlay/kintsugi"; export default { acala: acaNode, @@ -26,4 +28,6 @@ export default { opal: opalNode, quartz: quartzNode, unique: uniqueNode, + interlay: interlayNode, + kintsugi: kintsugiNode, }; From 21f8cfaf4389434c7fbab7bc9b3921da3273a202 Mon Sep 17 00:00:00 2001 From: kvhnuke <10602065+kvhnuke@users.noreply.github.com> Date: Wed, 10 May 2023 14:37:15 -0700 Subject: [PATCH 10/14] fix: swap long string --- packages/extension/package.json | 2 +- .../swap-best-offer-block/components/best-offer-list.vue | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/extension/package.json b/packages/extension/package.json index 732417a01..78d50be2d 100644 --- a/packages/extension/package.json +++ b/packages/extension/package.json @@ -1,6 +1,6 @@ { "name": "@enkryptcom/extension", - "version": "1.17.0", + "version": "1.18.0", "private": true, "scripts": { "zip": "cd dist; zip -r release.zip *;", diff --git a/packages/extension/src/ui/action/views/swap/views/swap-best-offer/components/swap-best-offer-block/components/best-offer-list.vue b/packages/extension/src/ui/action/views/swap/views/swap-best-offer/components/swap-best-offer-block/components/best-offer-list.vue index 248239f96..a56f5ad56 100644 --- a/packages/extension/src/ui/action/views/swap/views/swap-best-offer/components/swap-best-offer-block/components/best-offer-list.vue +++ b/packages/extension/src/ui/action/views/swap/views/swap-best-offer/components/swap-best-offer-block/components/best-offer-list.vue @@ -26,9 +26,9 @@ interface IProps { } const getReadable = (idx: number) => { - return new SwapToken(props.toToken).toReadable( - props.trades[idx].toTokenAmount - ); + return new SwapToken(props.toToken) + .toReadable(props.trades[idx].toTokenAmount) + .substring(0, 20); }; const props = defineProps(); From 3921cf95427fafd646e4936347944dbd7be20eac Mon Sep 17 00:00:00 2001 From: kvhnuke <10602065+kvhnuke@users.noreply.github.com> Date: Wed, 10 May 2023 18:42:33 -0700 Subject: [PATCH 11/14] devop: set current year --- .../src/ui/action/views/settings/views/settings-start/index.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/extension/src/ui/action/views/settings/views/settings-start/index.vue b/packages/extension/src/ui/action/views/settings/views/settings-start/index.vue index 4e3195d57..3c75d1f87 100644 --- a/packages/extension/src/ui/action/views/settings/views/settings-start/index.vue +++ b/packages/extension/src/ui/action/views/settings/views/settings-start/index.vue @@ -36,7 +36,7 @@

Date: Fri, 12 May 2023 12:33:36 -0700 Subject: [PATCH 12/14] fix: btc addresses getting saved to evm --- .../src/providers/ethereum/libs/accounts-state/index.ts | 7 ++++++- .../extension/src/providers/polkadot/networks/index.ts | 8 ++++---- packages/extension/src/ui/action/App.vue | 8 ++++++-- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/packages/extension/src/providers/ethereum/libs/accounts-state/index.ts b/packages/extension/src/providers/ethereum/libs/accounts-state/index.ts index facf2626d..e3ca57ee8 100644 --- a/packages/extension/src/providers/ethereum/libs/accounts-state/index.ts +++ b/packages/extension/src/providers/ethereum/libs/accounts-state/index.ts @@ -30,7 +30,12 @@ class AccountState { } async getApprovedAddresses(domain: string): Promise { const state = await this.getStateByDomain(domain); - if (state.approvedAccounts) return state.approvedAccounts; + if (state.approvedAccounts) { + for (const acc of state.approvedAccounts) { + if (acc.length !== 42) await this.removeApprovedAddress(acc, domain); // remove after a while, bug due to getting btc accounts added to evm + } + return state.approvedAccounts.filter((acc) => acc.length === 42); + } return []; } async deleteState(domain: string): Promise { diff --git a/packages/extension/src/providers/polkadot/networks/index.ts b/packages/extension/src/providers/polkadot/networks/index.ts index 9199b6aeb..5d41bb54f 100644 --- a/packages/extension/src/providers/polkadot/networks/index.ts +++ b/packages/extension/src/providers/polkadot/networks/index.ts @@ -11,8 +11,8 @@ import edgNode from "./edgeware"; import opalNode from "./unique/opal"; import quartzNode from "./unique/quartz"; import uniqueNode from "./unique/unique"; -import interlayNode from "./interlay/interlay"; -import kintsugiNode from "./interlay/kintsugi"; +// import interlayNode from "./interlay/interlay"; +// import kintsugiNode from "./interlay/kintsugi"; export default { acala: acaNode, @@ -28,6 +28,6 @@ export default { opal: opalNode, quartz: quartzNode, unique: uniqueNode, - interlay: interlayNode, - kintsugi: kintsugiNode, + // interlay: interlayNode, + // kintsugi: kintsugiNode, }; diff --git a/packages/extension/src/ui/action/App.vue b/packages/extension/src/ui/action/App.vue index 4b6f887a2..adf6a4edd 100644 --- a/packages/extension/src/ui/action/App.vue +++ b/packages/extension/src/ui/action/App.vue @@ -117,6 +117,7 @@ import { fromBase } from "@enkryptcom/utils"; import { EnkryptAccount } from "@enkryptcom/types"; import Browser from "webextension-polyfill"; import EVMAccountState from "@/providers/ethereum/libs/accounts-state"; +import BTCAccountState from "@/providers/bitcoin/libs/accounts-state"; import { ProviderName } from "@/types/provider"; import { onClickOutside } from "@vueuse/core"; import RateState from "@/libs/rate-state"; @@ -304,9 +305,12 @@ const onSelectedAddressChanged = async (newAccount: EnkryptAccount) => { currentNetwork.value.provider === ProviderName.ethereum || currentNetwork.value.provider === ProviderName.bitcoin ) { - const evmAccountState = new EVMAccountState(); + const AccountState = + currentNetwork.value.provider === ProviderName.ethereum + ? new EVMAccountState() + : new BTCAccountState(); const domain = await domainState.getCurrentDomain(); - evmAccountState.addApprovedAddress(newAccount.address, domain); + AccountState.addApprovedAddress(newAccount.address, domain); } await domainState.setSelectedAddress(newAccount.address); await sendToBackgroundFromAction({ From c38fd843d87313cacd83a3be91790ffdfe82e095 Mon Sep 17 00:00:00 2001 From: kvhnuke <10602065+kvhnuke@users.noreply.github.com> Date: Fri, 12 May 2023 12:47:29 -0700 Subject: [PATCH 13/14] devop: remove rinkeby, ropsten and kovan --- .../src/providers/ethereum/networks/index.ts | 6 ----- .../src/providers/ethereum/networks/kov.ts | 24 ------------------ .../src/providers/ethereum/networks/rin.ts | 24 ------------------ .../src/providers/ethereum/networks/rop.ts | 25 ------------------- 4 files changed, 79 deletions(-) delete mode 100644 packages/extension/src/providers/ethereum/networks/kov.ts delete mode 100644 packages/extension/src/providers/ethereum/networks/rin.ts delete mode 100644 packages/extension/src/providers/ethereum/networks/rop.ts diff --git a/packages/extension/src/providers/ethereum/networks/index.ts b/packages/extension/src/providers/ethereum/networks/index.ts index aab793449..f6b4dc324 100644 --- a/packages/extension/src/providers/ethereum/networks/index.ts +++ b/packages/extension/src/providers/ethereum/networks/index.ts @@ -1,8 +1,5 @@ import ethNode from "./eth"; import goerliNode from "./goerli"; -import kovanNode from "./kov"; -import ropstenNode from "./rop"; -import rinkebyNode from "./rin"; import etcNode from "./etc"; import maticNode from "./matic"; import bscNode from "./bsc"; @@ -32,9 +29,6 @@ import puppyNode from "./puppy"; export default { goerli: goerliNode, ethereum: ethNode, - kovan: kovanNode, - ropsten: ropstenNode, - rinkeby: rinkebyNode, etc: etcNode, matic: maticNode, bsc: bscNode, diff --git a/packages/extension/src/providers/ethereum/networks/kov.ts b/packages/extension/src/providers/ethereum/networks/kov.ts deleted file mode 100644 index 3d123379c..000000000 --- a/packages/extension/src/providers/ethereum/networks/kov.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { NetworkNames } from "@enkryptcom/types"; -import { EvmNetwork, EvmNetworkOptions } from "../types/evm-network"; -import { EtherscanActivity } from "../libs/activity-handlers"; -import wrapActivityHandler from "@/libs/activity-state/wrap-activity-handler"; - -const kovOptions: EvmNetworkOptions = { - name: NetworkNames.Kovan, - name_long: "Kovan", - homePage: "https://github.com/kovan-testnet", - blockExplorerTX: "https://kovan.etherscan.io/tx/[[txHash]]", - blockExplorerAddr: "https://kovan.etherscan.io/address/[[address]]", - chainID: "0x2a", - isTestNetwork: true, - currencyName: "KOV", - currencyNameLong: "Kovan", - node: "wss://nodes.mewapi.io/ws/kovan", - icon: require("./icons/eth.svg"), - gradient: "linear-gradient(180deg, #C549FF 0%, #684CFF 100%)", - activityHandler: wrapActivityHandler(EtherscanActivity), -}; - -const kov = new EvmNetwork(kovOptions); - -export default kov; diff --git a/packages/extension/src/providers/ethereum/networks/rin.ts b/packages/extension/src/providers/ethereum/networks/rin.ts deleted file mode 100644 index 47a96dcf8..000000000 --- a/packages/extension/src/providers/ethereum/networks/rin.ts +++ /dev/null @@ -1,24 +0,0 @@ -import wrapActivityHandler from "@/libs/activity-state/wrap-activity-handler"; -import { NetworkNames } from "@enkryptcom/types"; -import { RivetActivity } from "../libs/activity-handlers"; -import { EvmNetwork, EvmNetworkOptions } from "../types/evm-network"; - -const rinOptions: EvmNetworkOptions = { - name: NetworkNames.Rinkeby, - name_long: "Rinkeby", - homePage: "https://www.rinkeby.io/", - blockExplorerTX: "https://rinkeby.etherscan.io/tx/[[txHash]]", - blockExplorerAddr: "https://rinkeby.etherscan.io/address/[[address]]", - chainID: "0x4", - isTestNetwork: true, - currencyName: "RIN", - currencyNameLong: "Rinkeby", - node: "wss://nodes.mewapi.io/ws/rinkeby", - icon: require("./icons/eth.svg"), - gradient: "linear-gradient(180deg, #C549FF 0%, #684CFF 100%)", - activityHandler: wrapActivityHandler(RivetActivity), -}; - -const rin = new EvmNetwork(rinOptions); - -export default rin; diff --git a/packages/extension/src/providers/ethereum/networks/rop.ts b/packages/extension/src/providers/ethereum/networks/rop.ts deleted file mode 100644 index bd64a3e4c..000000000 --- a/packages/extension/src/providers/ethereum/networks/rop.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { NetworkNames } from "@enkryptcom/types"; -import { EvmNetwork, EvmNetworkOptions } from "../types/evm-network"; -import { RivetActivity } from "../libs/activity-handlers"; -import wrapActivityHandler from "@/libs/activity-state/wrap-activity-handler"; - -const ropOptions: EvmNetworkOptions = { - name: NetworkNames.Ropsten, - name_long: "Ropsten", - homePage: "https://github.com/ethereum/ropsten", - blockExplorerTX: "https://ropsten.etherscan.io/tx/[[txHash]]", - blockExplorerAddr: "https://ropsten.etherscan.io/address/[[address]]", - chainID: "0x3", - isTestNetwork: true, - currencyName: "ROP", - currencyNameLong: "Ropsten", - node: "wss://nodes.mewapi.io/ws/rop", - icon: require("./icons/eth.svg"), - basePath: "m/44'/1'/0'/0", - gradient: "linear-gradient(180deg, #C549FF 0%, #684CFF 100%)", - activityHandler: wrapActivityHandler(RivetActivity), -}; - -const rop = new EvmNetwork(ropOptions); - -export default rop; From 09e221aa4ef44a4c3f05a3b8127ee8752250cc75 Mon Sep 17 00:00:00 2001 From: kvhnuke <10602065+kvhnuke@users.noreply.github.com> Date: Mon, 15 May 2023 11:05:18 -0700 Subject: [PATCH 14/14] devop: update tests --- packages/swap/tests/swap.test.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/swap/tests/swap.test.ts b/packages/swap/tests/swap.test.ts index 89935a7b6..426b7cddf 100644 --- a/packages/swap/tests/swap.test.ts +++ b/packages/swap/tests/swap.test.ts @@ -79,11 +79,6 @@ describe("Swap", () => { const swapOneInch = await enkryptSwap.getSwap(oneInceQuote!.quote); expect(swapOneInch?.fromTokenAmount.toString()).to.be.eq(amount.toString()); expect(swapOneInch?.transactions.length).to.be.eq(2); - const swapParaswap = await enkryptSwap.getSwap(paraswapQuote!.quote); - expect(swapParaswap?.fromTokenAmount.toString()).to.be.eq( - amount.toString() - ); - expect(swapParaswap?.transactions.length).to.be.eq(2); const swapChangelly = await enkryptSwap.getSwap(changellyQuote!.quote); if (swapChangelly) expect(swapChangelly?.transactions.length).to.be.eq(1); }).timeout(10000);