Skip to content

Commit

Permalink
Merge pull request #269 from enkryptcom/develop
Browse files Browse the repository at this point in the history
Release: v1.16.0
  • Loading branch information
kvhnuke authored Apr 4, 2023
2 parents 22700f1 + bb7762a commit af22390
Show file tree
Hide file tree
Showing 183 changed files with 5,720 additions and 2,931 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Enkrypt is a web3 wallet built from the ground up to support the multi-chain fut
* Edgeware
* Acala
* Karura
* TomoChain
* More coming soon!

Looking to add your project? [Contact us!](https://mewwallet.typeform.com/enkrypt-inquiry?typeform-source=www.enkrypt.com)
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"packages/storage",
"packages/request",
"packages/hw-wallets",
"packages/swap",
"packages/name-resolution"
],
"scripts": {
Expand Down
17 changes: 9 additions & 8 deletions packages/extension/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@enkryptcom/extension",
"version": "1.15.0",
"version": "1.16.0",
"private": true,
"scripts": {
"zip": "cd dist; zip -r release.zip *;",
Expand All @@ -19,13 +19,14 @@
},
"dependencies": {
"@acala-network/api": "^4.1.8-2.3",
"@enkryptcom/extension-bridge": "^0.0.2",
"@enkryptcom/hw-wallets": "^0.0.2",
"@enkryptcom/keyring": "^0.0.2",
"@enkryptcom/request": "^0.0.1",
"@enkryptcom/storage": "^0.0.2",
"@enkryptcom/types": "^0.0.1",
"@enkryptcom/utils": "^0.0.3",
"@enkryptcom/extension-bridge": "workspace:^",
"@enkryptcom/hw-wallets": "workspace:^",
"@enkryptcom/keyring": "workspace:^",
"@enkryptcom/request": "workspace:^",
"@enkryptcom/storage": "workspace:^",
"@enkryptcom/swap": "workspace:^",
"@enkryptcom/types": "workspace:^",
"@enkryptcom/utils": "workspace:^",
"@ethereumjs/common": "^3.1.1",
"@ethereumjs/tx": "^4.1.1",
"@ledgerhq/hw-transport-webusb": "^6.27.12",
Expand Down
7 changes: 6 additions & 1 deletion packages/extension/src/libs/activity-state/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ class ActivityState {
const cleanArr: Activity[] = [];
const currentTime = new Date().getTime();
const minedNonces = cleanArr
.filter((item) => item.status === ActivityStatus.success && item.nonce)
.filter(
(item) =>
(item.status === ActivityStatus.success ||
item.status === ActivityStatus.failed) &&
item.nonce
)
.map((item) => item.nonce);
for (let i = 0; i < combined.length; i++) {
if (!existingHashes.includes(combined[i].transactionHash)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { ActivityStatus } from "@/types/activity";
import ActivityState from ".";
import { ActivityHandlerType } from "./types";
const CACHE_TTL = 1000 * 60 * 5; // 5 mins
Expand All @@ -20,17 +19,7 @@ export default (activityHandler: ActivityHandlerType): ActivityHandlerType => {
await activityState.setCacheTime(options);
return liveActivities;
} else {
const pendingActivities = activities.filter(
(act) => act.status === ActivityStatus.pending
);
const liveActivityHashes = liveActivities.map(
(act) => act.transactionHash
);
const stillPendingActivities = pendingActivities.filter(
(act) => !liveActivityHashes.includes(act.transactionHash)
);
const newSet = stillPendingActivities.concat(liveActivities);
await activityState.addActivities(newSet, options);
await activityState.addActivities(liveActivities, options);
await activityState.setCacheTime(options);
return activityState.getAllActivities(options);
}
Expand Down
12 changes: 12 additions & 0 deletions packages/extension/src/libs/dapp-list/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@ const lists: Partial<Record<NetworkNames, string>> = {
"https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/zksync.json",
[NetworkNames.Rootstock]:
"https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/rootstock.json",
[NetworkNames.TomoChain]:
"https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/tomo.json",
[NetworkNames.Arbitrum]:
"https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/arb.json",
[NetworkNames.Avalanche]:
"https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/avax.json",
[NetworkNames.Fantom]:
"https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/ftm.json",
[NetworkNames.Klaytn]:
"https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/klay.json",
[NetworkNames.Aurora]:
"https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/aurora.json",
};

export default lists;
80 changes: 80 additions & 0 deletions packages/extension/src/libs/market-data/ethvm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import {
CoinGeckoToken,
CoinGeckoTokenMarket,
CoingeckPlatforms,
} from "./types";

interface getCoinGeckoTokenInfoAllType {
data: {
getCoinGeckoTokenInfoAll: {
id: string;
symbol: string;
name: string;
platforms: {
platform: string;
address: string;
}[];
}[];
};
}
const ETHVM_BASE = `https://api-v2.ethvm.dev/`;

const ethvmPost = (requestData: string): Promise<any> => {
return fetch(ETHVM_BASE, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: requestData,
}).then((res) => res.json());
};

export const getAllPlatformData = (): Promise<CoinGeckoToken[]> => {
return ethvmPost(
'{"operationName":null,"variables":{},"query":"{\\n getCoinGeckoTokenInfoAll {\\n id\\n symbol\\n name\\n platforms {\\n platform\\n address\\n }\\n }\\n}\\n"}'
).then((json: getCoinGeckoTokenInfoAllType) => {
const retResponse: CoinGeckoToken[] = [];
json.data.getCoinGeckoTokenInfoAll.forEach((item) => {
const { id, name, symbol, platforms } = item;
const cgPlatforms: CoingeckPlatforms = {};
platforms.forEach((p) => {
cgPlatforms[p.platform] = p.address;
});
const token: CoinGeckoToken = {
id,
name,
symbol,
platforms: cgPlatforms,
};
retResponse.push(token);
});
return retResponse;
});
};

export const getUSDPriceById = (id: string): Promise<string | null> => {
return ethvmPost(
'{"operationName":null,"variables":{},"query":"{\\n getCoinGeckoTokenMarketDataByIds(coinGeckoTokenIds: [\\"' +
id +
'\\"]) {\\n current_price\\n }\\n}\\n"}'
)
.then((json) => {
return json.data.getCoinGeckoTokenMarketDataByIds[0]
? json.data.getCoinGeckoTokenMarketDataByIds[0].current_price.toString()
: null;
})
.catch(() => null);
};

export const getMarketInfoByIDs = (
ids: string[]
): Promise<Array<CoinGeckoTokenMarket | null>> => {
const params = ids.map((i) => '\\"' + i + '\\"').join(", ");
return ethvmPost(
'{"operationName":null,"variables":{},"query":"{\\n getCoinGeckoTokenMarketDataByIds(coinGeckoTokenIds: [' +
params +
']) {\\n id\\n symbol\\n name\\n image\\n market_cap\\n market_cap_rank\\n high_24h\\n low_24h\\n price_change_24h\\n price_change_percentage_24h\\n sparkline_in_7d {\\n price\\n }\\n price_change_percentage_7d_in_currency\\n current_price\\n }\\n}\\n"}'
).then((json) => {
return json.data.getCoinGeckoTokenMarketDataByIds as CoinGeckoTokenMarket[];
});
};
67 changes: 19 additions & 48 deletions packages/extension/src/libs/market-data/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ import {
FiatMarket,
} from "./types";
import BigNumber from "bignumber.js";
import cacheFetch from "../cache-fetch";
import { CoingeckoPlatform } from "@enkryptcom/types";
const COINGECKO_ENDPOINT = "https://partners.mewapi.io/coingecko/api/v3/";
import {
getAllPlatformData,
getMarketInfoByIDs,
getUSDPriceById,
} from "./ethvm";
const FIAT_EXCHANGE_RATE_ENDPOINT =
"https://mainnet.mewwallet.dev/v2/prices/exchange-rates";
const REFRESH_DELAY = 1000 * 60 * 5;
Expand All @@ -36,25 +39,8 @@ class MarketData {
}
return "0";
}
async getTokenPrice(
coingeckoID: string,
currency = "usd"
): Promise<string | null> {
const urlParams = new URLSearchParams();
urlParams.append("ids", coingeckoID);
urlParams.append("vs_currencies", currency);

return cacheFetch(
{
url: `${COINGECKO_ENDPOINT}simple/price?include_market_cap=false&include_24hr_vol=false&include_24hr_change=false&include_last_updated_at=false&${urlParams.toString()}`,
},
REFRESH_DELAY
).then((json) => {
if (json[coingeckoID] && json[coingeckoID][currency] !== undefined) {
return json[coingeckoID][currency].toString();
}
return null;
});
async getTokenPrice(coingeckoID: string): Promise<string | null> {
return getUSDPriceById(coingeckoID);
}
async getMarketInfoByContracts(
contracts: string[],
Expand All @@ -77,6 +63,7 @@ class MarketData {
return false;
})
.map((token) => token.id);
if (!tokenIds.length) return requested;
const marketData = await this.getMarketData(tokenIds);
Object.keys(contractTokenMap).forEach((contract) => {
if (contractTokenMap[contract]) {
Expand All @@ -92,21 +79,9 @@ class MarketData {
async getMarketData(
coingeckoIDs: string[]
): Promise<Array<CoinGeckoTokenMarket | null>> {
return await cacheFetch(
{
url: `${COINGECKO_ENDPOINT}coins/markets?vs_currency=usd&order=market_cap_desc&price_change_percentage=7d&per_page=250&page=1&sparkline=true&ids=${coingeckoIDs.join(
","
)}`,
},
REFRESH_DELAY
).then((json) => {
const markets = json as CoinGeckoTokenMarket[];
const retMarkets: Array<CoinGeckoTokenMarket | null> = [];
coingeckoIDs.forEach((id) => {
retMarkets.push(markets.find((m) => m.id === id) || null);
});
return retMarkets;
});
return getMarketInfoByIDs(coingeckoIDs).catch(() =>
coingeckoIDs.map(() => null)
);
}
async getFiatValue(symbol: string): Promise<FiatMarket | null> {
await this.setMarketInfo();
Expand Down Expand Up @@ -137,19 +112,15 @@ class MarketData {
const lastTimestamp = await this.#getLastTimestamp();
if (lastTimestamp && lastTimestamp >= new Date().getTime() - REFRESH_DELAY)
return;
const allCoins = await fetch(
`${COINGECKO_ENDPOINT}coins/list?include_platform=true`
)
.then((res) => res.json())
.then((json) => {
console.log(json);
const allTokens = json as CoinGeckoToken[];
const tokens: Record<string, CoinGeckoToken> = {};
allTokens.forEach((token) => {
tokens[token.id] = token;
});
return tokens;

const allCoins = await getAllPlatformData().then((json) => {
const allTokens = json as CoinGeckoToken[];
const tokens: Record<string, CoinGeckoToken> = {};
allTokens.forEach((token) => {
tokens[token.id] = token;
});
return tokens;
});
await this.#setAllTokens(allCoins);
const fiatMarketData = await fetch(`${FIAT_EXCHANGE_RATE_ENDPOINT}`)
.then((res) => res.json())
Expand Down
3 changes: 3 additions & 0 deletions packages/extension/src/libs/nft-handlers/simplehash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ export default async (
const supportedNetworks = {
[NetworkNames.Optimism]: "optimism",
[NetworkNames.Binance]: "bsc",
[NetworkNames.Arbitrum]: "arbitrum",
[NetworkNames.Gnosis]: "gnosis",
[NetworkNames.Avalanche]: "avalanche",
};
if (!Object.keys(supportedNetworks).includes(network.name))
throw new Error("Simplehash: network not supported");
Expand Down
2 changes: 1 addition & 1 deletion packages/extension/src/providers/bitcoin/libs/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class API implements ProviderAPIInterface {
});
}
async getUTXOs(pubkey: string): Promise<HaskoinUnspentType[]> {
const address = this.getAddress(pubkey);
const address = pubkey.length < 64 ? pubkey : this.getAddress(pubkey);
return fetch(`${this.node}address/${address}/unspent`)
.then((res) => res.json())
.then((utxos: HaskoinUnspentType[]) => {
Expand Down
22 changes: 22 additions & 0 deletions packages/extension/src/providers/bitcoin/libs/btc-fee-handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { GasPriceTypes } from "@/providers/common/types";

const BTCFeeHandler = async (): Promise<Record<GasPriceTypes, number>> => {
return fetch(`https://bitcoiner.live/api/fees/estimates/latest`)
.then((res) => res.json())
.then((json) => {
return {
[GasPriceTypes.FASTEST]: Math.ceil(json.estimates["30"].sat_per_vbyte),
[GasPriceTypes.FAST]: Math.ceil(json.estimates["60"].sat_per_vbyte),
[GasPriceTypes.REGULAR]: Math.ceil(json.estimates["120"].sat_per_vbyte),
[GasPriceTypes.ECONOMY]: Math.ceil(json.estimates["180"].sat_per_vbyte),
};
})
.catch(() => ({
[GasPriceTypes.FASTEST]: 25,
[GasPriceTypes.FAST]: 20,
[GasPriceTypes.REGULAR]: 10,
[GasPriceTypes.ECONOMY]: 5,
}));
};

export default BTCFeeHandler;
15 changes: 9 additions & 6 deletions packages/extension/src/providers/bitcoin/libs/utils.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { BitcoinNetworkInfo } from "../types";
import { address as BTCAddress } from "bitcoinjs-lib";
import { GasPriceTypes } from "@/providers/common/types";
import { fromBase } from "@/libs/utils/units";
import { fromBase } from "@enkryptcom/utils";
import BigNumber from "bignumber.js";
import { BitcoinNetwork } from "../types/bitcoin-network";

const isAddress = (address: string, network: BitcoinNetworkInfo): boolean => {
try {
Expand All @@ -12,17 +13,19 @@ const isAddress = (address: string, network: BitcoinNetworkInfo): boolean => {
return false;
}
};
const getGasCostValues = (
const getGasCostValues = async (
network: BitcoinNetwork,
byteSize: number,
nativeVal = "0",
decimals: number,
currencyName: string
) => {
const fees = await network.feeHandler();
const gasVals = {
[GasPriceTypes.FASTEST]: (byteSize * 25).toString(),
[GasPriceTypes.FAST]: (byteSize * 20).toString(),
[GasPriceTypes.REGULAR]: (byteSize * 10).toString(),
[GasPriceTypes.ECONOMY]: (byteSize * 5).toString(),
[GasPriceTypes.FASTEST]: (byteSize * fees.FASTEST).toString(),
[GasPriceTypes.FAST]: (byteSize * fees.FAST).toString(),
[GasPriceTypes.REGULAR]: (byteSize * fees.REGULAR).toString(),
[GasPriceTypes.ECONOMY]: (byteSize * fees.ECONOMY).toString(),
};
const getConvertedVal = (type: GasPriceTypes) =>
fromBase(gasVals[type], decimals);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
} from "../types/bitcoin-network";
import { haskoinHandler } from "../libs/activity-handlers";
import wrapActivityHandler from "@/libs/activity-state/wrap-activity-handler";
import { GasPriceTypes } from "@/providers/common/types";

const bitcoinOptions: BitcoinNetworkOptions = {
name: NetworkNames.BitcoinTest,
Expand All @@ -23,6 +24,13 @@ const bitcoinOptions: BitcoinNetworkOptions = {
activityHandler: wrapActivityHandler(haskoinHandler),
basePath: "m/49'/1'/0'/0",
coingeckoID: "bitcoin",
feeHandler: () =>
Promise.resolve({
[GasPriceTypes.FASTEST]: 25,
[GasPriceTypes.FAST]: 20,
[GasPriceTypes.REGULAR]: 10,
[GasPriceTypes.ECONOMY]: 5,
}),
networkInfo: {
messagePrefix: "\x18Bitcoin Signed Message:\n",
bech32: "tb",
Expand Down
Loading

2 comments on commit af22390

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.