From d96bd26d256d467ec1fb049a36276cfa13bf9263 Mon Sep 17 00:00:00 2001 From: kvhnuke <10602065+kvhnuke@users.noreply.github.com> Date: Wed, 13 Sep 2023 16:45:56 -0700 Subject: [PATCH 01/12] feat: add litecoin --- .../src/libs/keyring/public-keyring.ts | 10 ++ .../bitcoin/libs/activity-handlers/index.ts | 4 +- .../activity-handlers/providers/ss/index.ts | 105 +++++++++++++++ .../src/providers/bitcoin/libs/api-ss.ts | 125 ++++++++++++++++++ .../providers/bitcoin/libs/ss-fee-handler.ts | 31 +++++ .../bitcoin/networks/bitcoin-testnet.ts | 2 + .../src/providers/bitcoin/networks/bitcoin.ts | 2 + .../providers/bitcoin/networks/icons/ltc.svg | 1 + .../src/providers/bitcoin/networks/index.ts | 2 + .../providers/bitcoin/networks/litecoin.ts | 46 +++++++ .../bitcoin/types/bitcoin-network.ts | 7 +- .../src/providers/bitcoin/types/index.ts | 28 ++++ packages/types/src/networks.ts | 1 + 13 files changed, 360 insertions(+), 4 deletions(-) create mode 100644 packages/extension/src/providers/bitcoin/libs/activity-handlers/providers/ss/index.ts create mode 100644 packages/extension/src/providers/bitcoin/libs/api-ss.ts create mode 100644 packages/extension/src/providers/bitcoin/libs/ss-fee-handler.ts create mode 100644 packages/extension/src/providers/bitcoin/networks/icons/ltc.svg create mode 100644 packages/extension/src/providers/bitcoin/networks/litecoin.ts diff --git a/packages/extension/src/libs/keyring/public-keyring.ts b/packages/extension/src/libs/keyring/public-keyring.ts index 3ad208cec..87fbc4349 100644 --- a/packages/extension/src/libs/keyring/public-keyring.ts +++ b/packages/extension/src/libs/keyring/public-keyring.ts @@ -64,6 +64,16 @@ class PublicKeyRing { walletType: WalletType.mnemonic, isHardware: false, }; + allKeys["ltc1qccf4af6j3xm9v3r6ujt7dlmvazywzq82hnuwgx"] = { + address: "ltc1qccf4af6j3xm9v3r6ujt7dlmvazywzq82hnuwgx", + basePath: "m/49'/2'/0'/1", + name: "fake ltc account #4", + pathIndex: 0, + publicKey: "0x0", + signerType: SignerType.secp256k1btc, + walletType: WalletType.mnemonic, + isHardware: false, + }; } return allKeys; } diff --git a/packages/extension/src/providers/bitcoin/libs/activity-handlers/index.ts b/packages/extension/src/providers/bitcoin/libs/activity-handlers/index.ts index 03e77198c..dc0e381ea 100644 --- a/packages/extension/src/providers/bitcoin/libs/activity-handlers/index.ts +++ b/packages/extension/src/providers/bitcoin/libs/activity-handlers/index.ts @@ -1,3 +1,3 @@ import haskoinHandler from "./providers/haskoin"; - -export { haskoinHandler }; +import ssHandler from "./providers/ss"; +export { haskoinHandler, ssHandler }; diff --git a/packages/extension/src/providers/bitcoin/libs/activity-handlers/providers/ss/index.ts b/packages/extension/src/providers/bitcoin/libs/activity-handlers/providers/ss/index.ts new file mode 100644 index 000000000..636fcc197 --- /dev/null +++ b/packages/extension/src/providers/bitcoin/libs/activity-handlers/providers/ss/index.ts @@ -0,0 +1,105 @@ +import MarketData from "@/libs/market-data"; +import { SSTxType } from "@/providers/bitcoin/types"; +import { + Activity, + ActivityStatus, + ActivityType, + BTCRawInfo, +} from "@/types/activity"; +import { BaseNetwork } from "@/types/base-network"; +export default async ( + network: BaseNetwork, + pubkey: string +): Promise => { + return fetch( + `${network.node}/api/v1/account/${network.displayAddress( + pubkey + )}/txs?pageSize=40` + ) + .then((res) => res.json()) + .then(async (txs: { txs: SSTxType[] }) => { + if ((txs as any).message) return []; + let tokenPrice = "0"; + if (network.coingeckoID) { + const marketData = new MarketData(); + await marketData + .getTokenPrice(network.coingeckoID) + .then((mdata) => (tokenPrice = mdata || "0")); + } + + const address = network.displayAddress(pubkey); + const cleanedTxs = txs.txs.map((tx) => { + return { + ...tx, + vin: tx.vin.filter((vi) => vi.addresses), + vout: tx.vout.filter((vo) => vo.addresses), + }; + }); + return cleanedTxs.map((tx) => { + const isIncoming = !tx.vin.find((i) => i.addresses![0] === address); + + let toAddress = ""; + let value = 0; + + if (isIncoming) { + const relevantOut = tx.vout.find( + (tx) => tx.addresses![0] === address + ); + if (relevantOut) { + toAddress = relevantOut.addresses![0]; + value = Number(relevantOut.value); + } + } else { + const relevantOut = tx.vout.find( + (tx) => tx.addresses![0] !== address + ); + if (relevantOut) { + toAddress = relevantOut.addresses![0]; + value = Number(relevantOut.value); + } + } + + const rawInfo: BTCRawInfo = { + blockNumber: tx.blockHeight!, + fee: Number(tx.fee), + inputs: tx.vin.map((input) => ({ + address: input.addresses![0], + value: Number(input.value), + })), + outputs: tx.vout.map((output) => ({ + address: output.addresses![0], + value: Number(output.value), + })), + transactionHash: tx.txid, + timestamp: tx.timestamp * 1000, + }; + const act: Activity = { + from: tx.vin[0].addresses![0], + isIncoming, + network: network.name, + status: + tx.blockHeight > 0 + ? ActivityStatus.success + : ActivityStatus.pending, + timestamp: tx.timestamp * 1000, + to: toAddress, + token: { + decimals: network.decimals, + icon: network.icon, + name: network.name_long, + symbol: network.currencyName, + coingeckoID: network.coingeckoID, + price: tokenPrice, + }, + transactionHash: tx.txid, + type: ActivityType.transaction, + value: value.toString(), + rawInfo: rawInfo, + }; + return act; + }); + }) + .catch(() => { + return []; + }); +}; diff --git a/packages/extension/src/providers/bitcoin/libs/api-ss.ts b/packages/extension/src/providers/bitcoin/libs/api-ss.ts new file mode 100644 index 000000000..4113a1651 --- /dev/null +++ b/packages/extension/src/providers/bitcoin/libs/api-ss.ts @@ -0,0 +1,125 @@ +import { BTCRawInfo } from "@/types/activity"; +import { ProviderAPIInterface } from "@/types/provider"; +import { hexToBuffer } from "@enkryptcom/utils"; +import { + BitcoinNetworkInfo, + HaskoinUnspentType, + SSTxType, + SSUnspentType, +} from "../types"; +import { payments } from "bitcoinjs-lib"; +import { toBN } from "web3-utils"; +import cacheFetch from "@/libs/cache-fetch"; + +class API implements ProviderAPIInterface { + node: string; + networkInfo: BitcoinNetworkInfo; + + constructor(node: string, networkInfo: BitcoinNetworkInfo) { + this.node = node; + this.networkInfo = networkInfo; + } + + public get api() { + return this; + } + private getAddress(pubkey: string) { + const { address } = payments.p2wpkh({ + pubkey: hexToBuffer(pubkey), + network: this.networkInfo, + }); + return address as string; + } + // eslint-disable-next-line @typescript-eslint/no-empty-function + async init(): Promise {} + async getTransactionStatus(hash: string): Promise { + return fetch(`${this.node}/api/v1/tx/${hash}`) + .then((res) => res.json()) + .then((tx: SSTxType) => { + if ((tx as any).message) return null; + if (tx.blockHeight < 0) return null; + const rawInfo: BTCRawInfo = { + blockNumber: tx.blockHeight, + fee: Number(tx.fee), + inputs: tx.vin + .filter((t) => t.addresses && t.addresses.length) + .map((input) => ({ + address: input.addresses![0], + value: Number(input.value), + })), + outputs: tx.vout + .filter((t) => t.addresses && t.addresses.length) + .map((output) => ({ + address: output.addresses![0], + value: Number(output.value), + })), + transactionHash: tx.txid, + timestamp: tx.timestamp * 1000, + }; + return rawInfo; + }); + } + async getBalance(pubkey: string): Promise { + const address = pubkey.length < 64 ? pubkey : this.getAddress(pubkey); + return fetch(`${this.node}/api/v1/account/${address}`) + .then((res) => res.json()) + .then((balance: { balance: string }) => { + if ((balance as any).message) return "0"; + return toBN(balance.balance).toString(); + }); + } + async broadcastTx(rawtx: string): Promise { + return fetch(`${this.node}/api/v1/send`, { + method: "POST", + headers: { + Accept: "application/json", + "Content-Type": "application/json", + }, + body: JSON.stringify({ hex: rawtx }), + }) + .then((res) => res.json()) + .then((response) => { + if (response.error) { + return Promise.reject(response.message); + } + return true; + }); + } + async SSToHaskoinUTXOs( + SSUTXOs: SSUnspentType[], + address: string + ): Promise { + const ret: HaskoinUnspentType[] = []; + for (const utx of SSUTXOs) { + const res = (await cacheFetch({ + url: `${this.node}/api/v1/tx/${utx.txid}`, + })) as SSTxType; + ret.push({ + address, + block: { + height: utx.height, + position: 0, + }, + index: utx.vout, + pkscript: res.vout[utx.vout].scriptPubKey.hex, + txid: utx.txid, + value: Number(utx.value), + }); + } + ret.sort((a, b) => { + return a.value - b.value; + }); + return ret; + } + + async getUTXOs(pubkey: string): Promise { + const address = pubkey.length < 64 ? pubkey : this.getAddress(pubkey); + return fetch(`${this.node}/api/v1/account/${address}/utxos`) + .then((res) => res.json()) + .then((utxos: SSUnspentType[]) => { + if ((utxos as any).message || !utxos.length) return []; + return this.SSToHaskoinUTXOs(utxos, address); + }); + } +} +export default API; diff --git a/packages/extension/src/providers/bitcoin/libs/ss-fee-handler.ts b/packages/extension/src/providers/bitcoin/libs/ss-fee-handler.ts new file mode 100644 index 000000000..8a56be8fb --- /dev/null +++ b/packages/extension/src/providers/bitcoin/libs/ss-fee-handler.ts @@ -0,0 +1,31 @@ +import { GasPriceTypes } from "@/providers/common/types"; + +interface FeeType { + fast: { + satsPerKiloByte: number; + }; + average: { + satsPerKiloByte: number; + }; + slow: { + satsPerKiloByte: number; + }; +} +const SSFeeHandler = async ( + url: string +): Promise> => { + return fetch(url) + .then((res) => res.json()) + .then((json: FeeType) => { + if (json.fast.satsPerKiloByte < 0) + json.fast.satsPerKiloByte = json.average.satsPerKiloByte; + return { + [GasPriceTypes.FASTEST]: Math.ceil(json.fast.satsPerKiloByte / 1024), + [GasPriceTypes.FAST]: Math.ceil(json.fast.satsPerKiloByte / 1024), + [GasPriceTypes.REGULAR]: Math.ceil(json.average.satsPerKiloByte / 1024), + [GasPriceTypes.ECONOMY]: Math.ceil(json.slow.satsPerKiloByte / 1024), + }; + }); +}; + +export default SSFeeHandler; diff --git a/packages/extension/src/providers/bitcoin/networks/bitcoin-testnet.ts b/packages/extension/src/providers/bitcoin/networks/bitcoin-testnet.ts index 1093e9357..6c9f03120 100644 --- a/packages/extension/src/providers/bitcoin/networks/bitcoin-testnet.ts +++ b/packages/extension/src/providers/bitcoin/networks/bitcoin-testnet.ts @@ -6,6 +6,7 @@ import { import { haskoinHandler } from "../libs/activity-handlers"; import wrapActivityHandler from "@/libs/activity-state/wrap-activity-handler"; import { GasPriceTypes } from "@/providers/common/types"; +import HaskoinAPI from "../libs/api"; const bitcoinOptions: BitcoinNetworkOptions = { name: NetworkNames.BitcoinTest, @@ -23,6 +24,7 @@ const bitcoinOptions: BitcoinNetworkOptions = { activityHandler: wrapActivityHandler(haskoinHandler), basePath: "m/49'/1'/0'/0", coingeckoID: "bitcoin", + apiType: HaskoinAPI, feeHandler: () => Promise.resolve({ [GasPriceTypes.FASTEST]: 25, diff --git a/packages/extension/src/providers/bitcoin/networks/bitcoin.ts b/packages/extension/src/providers/bitcoin/networks/bitcoin.ts index d895acae0..c1e97a37f 100644 --- a/packages/extension/src/providers/bitcoin/networks/bitcoin.ts +++ b/packages/extension/src/providers/bitcoin/networks/bitcoin.ts @@ -6,6 +6,7 @@ import { import { haskoinHandler } from "../libs/activity-handlers"; import wrapActivityHandler from "@/libs/activity-state/wrap-activity-handler"; import BTCFeeHandler from "../libs/btc-fee-handler"; +import HaskoinAPI from "../libs/api"; const bitcoinOptions: BitcoinNetworkOptions = { name: NetworkNames.Bitcoin, @@ -23,6 +24,7 @@ const bitcoinOptions: BitcoinNetworkOptions = { activityHandler: wrapActivityHandler(haskoinHandler), basePath: "m/49'/0'/0'/0", feeHandler: BTCFeeHandler, + apiType: HaskoinAPI, networkInfo: { messagePrefix: "\x18Bitcoin Signed Message:\n", bech32: "bc", diff --git a/packages/extension/src/providers/bitcoin/networks/icons/ltc.svg b/packages/extension/src/providers/bitcoin/networks/icons/ltc.svg new file mode 100644 index 000000000..13e76a40e --- /dev/null +++ b/packages/extension/src/providers/bitcoin/networks/icons/ltc.svg @@ -0,0 +1 @@ +litecoin-ltc-logo \ No newline at end of file diff --git a/packages/extension/src/providers/bitcoin/networks/index.ts b/packages/extension/src/providers/bitcoin/networks/index.ts index 9d0dee744..09b7d0764 100644 --- a/packages/extension/src/providers/bitcoin/networks/index.ts +++ b/packages/extension/src/providers/bitcoin/networks/index.ts @@ -1,7 +1,9 @@ import btcNode from "./bitcoin"; import btcTestNode from "./bitcoin-testnet"; +import ltcNode from "./litecoin"; export default { bitcoin: btcNode, bitcoinTest: btcTestNode, + litecoin: ltcNode, }; diff --git a/packages/extension/src/providers/bitcoin/networks/litecoin.ts b/packages/extension/src/providers/bitcoin/networks/litecoin.ts new file mode 100644 index 000000000..a149025e9 --- /dev/null +++ b/packages/extension/src/providers/bitcoin/networks/litecoin.ts @@ -0,0 +1,46 @@ +import { NetworkNames } from "@enkryptcom/types"; +import { + BitcoinNetwork, + BitcoinNetworkOptions, +} from "../types/bitcoin-network"; +import { ssHandler } from "../libs/activity-handlers"; +import wrapActivityHandler from "@/libs/activity-state/wrap-activity-handler"; +import SSFeeHandler from "../libs/ss-fee-handler"; +import SSApi from "../libs/api-ss"; + +const litecoinOptions: BitcoinNetworkOptions = { + name: NetworkNames.Litecoin, + name_long: "Litecoin", + homePage: "https://litecoin.org/", + blockExplorerTX: "https://explorer.btc.com/ltc/transaction/[[txHash]]", + blockExplorerAddr: "https://explorer.btc.com/ltc/address/[[address]]", + isTestNetwork: false, + currencyName: "LTC", + currencyNameLong: "Litecoin", + icon: require("./icons/ltc.svg"), + decimals: 8, + node: "https://partners.mewapi.io/nodes/ss/ltc", + coingeckoID: "litecoin", + apiType: SSApi, + activityHandler: wrapActivityHandler(ssHandler), + basePath: "m/49'/2'/0'/0", + feeHandler: () => { + return SSFeeHandler("https://partners.mewapi.io/nodes/ss/ltc/api/v1/fees"); + }, + networkInfo: { + messagePrefix: "\x19Litecoin Signed Message:\n", + bech32: "ltc", + bip32: { + public: 0x019da462, + private: 0x019d9cfe, + }, + pubKeyHash: 0x30, + scriptHash: 0x32, + wif: 0xb0, + dustThreshold: null, + }, +}; + +const litecoin = new BitcoinNetwork(litecoinOptions); + +export default litecoin; diff --git a/packages/extension/src/providers/bitcoin/types/bitcoin-network.ts b/packages/extension/src/providers/bitcoin/types/bitcoin-network.ts index 7867c650c..0b77cf175 100644 --- a/packages/extension/src/providers/bitcoin/types/bitcoin-network.ts +++ b/packages/extension/src/providers/bitcoin/types/bitcoin-network.ts @@ -19,6 +19,8 @@ import { CoinGeckoTokenMarket } from "@/libs/market-data/types"; import Sparkline from "@/libs/sparkline"; import { BTCToken } from "./btc-token"; import { GasPriceTypes } from "@/providers/common/types"; +import type HaskoinAPI from "@/providers/bitcoin/libs/api"; +import type SSAPI from "@/providers/bitcoin/libs/api-ss"; export interface BitcoinNetworkOptions { name: NetworkNames; @@ -40,6 +42,7 @@ export interface BitcoinNetworkOptions { network: BaseNetwork, address: string ) => Promise; + apiType: typeof HaskoinAPI | typeof SSAPI; } export class BitcoinNetwork extends BaseNetwork { @@ -52,9 +55,9 @@ export class BitcoinNetwork extends BaseNetwork { feeHandler: () => Promise>; constructor(options: BitcoinNetworkOptions) { const api = async () => { - const api = new BitcoinAPI(options.node, options.networkInfo); + const api = new options.apiType(options.node, options.networkInfo); await api.init(); - return api; + return api as BitcoinAPI; }; const baseOptions: BaseNetworkOptions = { diff --git a/packages/extension/src/providers/bitcoin/types/index.ts b/packages/extension/src/providers/bitcoin/types/index.ts index c6ba23bd2..609727630 100644 --- a/packages/extension/src/providers/bitcoin/types/index.ts +++ b/packages/extension/src/providers/bitcoin/types/index.ts @@ -38,6 +38,13 @@ export interface HaskoinUnspentType { pkscript: string; value: number; } +export interface SSUnspentType { + txid: string; + vout: number; + value: string; + height: number; + confirmations: number; +} export interface HaskoinTxType { txid: string; size: number; @@ -63,6 +70,27 @@ export interface HaskoinTxType { time: number; } +export interface SSTxType { + txid: string; + blockHash: string; + blockHeight: number; + timestamp: number; + confirmations: number; + fee: string; + vin: { + txid: string; + addresses?: string[]; + value: string; + }[]; + vout: { + addresses?: string[]; + value: string; + scriptPubKey: { + hex: string; + }; + }[]; +} + export interface RPCTxType { to: string; value: number; diff --git a/packages/types/src/networks.ts b/packages/types/src/networks.ts index 477cf6b03..b489d7993 100644 --- a/packages/types/src/networks.ts +++ b/packages/types/src/networks.ts @@ -58,6 +58,7 @@ export enum NetworkNames { Vara = "VARA", Base = "BASE", Celo = "CELO", + Litecoin = "LTC", } export enum CoingeckoPlatform { From c94fcf89f70bc388cdeaf86f30cb96d6d4203374 Mon Sep 17 00:00:00 2001 From: kvhnuke <10602065+kvhnuke@users.noreply.github.com> Date: Thu, 14 Sep 2023 14:01:31 -0700 Subject: [PATCH 02/12] feat: dogecoin --- .../src/providers/bitcoin/libs/api-ss.ts | 16 +++-- .../src/providers/bitcoin/libs/api.ts | 9 +-- .../providers/bitcoin/libs/ss-fee-handler.ts | 8 ++- .../bitcoin/networks/bitcoin-testnet.ts | 2 + .../src/providers/bitcoin/networks/bitcoin.ts | 2 + .../providers/bitcoin/networks/dogecoin.ts | 48 +++++++++++++++ .../providers/bitcoin/networks/icons/doge.svg | 1 + .../src/providers/bitcoin/networks/index.ts | 2 + .../providers/bitcoin/networks/litecoin.ts | 2 + .../bitcoin/types/bitcoin-network.ts | 22 ++++--- .../src/providers/bitcoin/types/index.ts | 4 ++ .../bitcoin/ui/btc-verify-transaction.vue | 14 ++--- .../src/providers/bitcoin/ui/libs/signer.ts | 29 +++++++--- .../src/providers/bitcoin/ui/libs/tx-size.ts | 58 +++++++++++++------ .../bitcoin/ui/send-transaction/index.vue | 14 ++--- .../action/views/swap/libs/bitcoin-gasvals.ts | 13 ++--- packages/types/src/networks.ts | 1 + 17 files changed, 169 insertions(+), 76 deletions(-) create mode 100644 packages/extension/src/providers/bitcoin/networks/dogecoin.ts create mode 100644 packages/extension/src/providers/bitcoin/networks/icons/doge.svg diff --git a/packages/extension/src/providers/bitcoin/libs/api-ss.ts b/packages/extension/src/providers/bitcoin/libs/api-ss.ts index 4113a1651..42671d7c5 100644 --- a/packages/extension/src/providers/bitcoin/libs/api-ss.ts +++ b/packages/extension/src/providers/bitcoin/libs/api-ss.ts @@ -1,15 +1,14 @@ import { BTCRawInfo } from "@/types/activity"; import { ProviderAPIInterface } from "@/types/provider"; -import { hexToBuffer } from "@enkryptcom/utils"; import { BitcoinNetworkInfo, HaskoinUnspentType, SSTxType, SSUnspentType, } from "../types"; -import { payments } from "bitcoinjs-lib"; import { toBN } from "web3-utils"; import cacheFetch from "@/libs/cache-fetch"; +import { getAddress as getBitcoinAddress } from "../types/bitcoin-network"; class API implements ProviderAPIInterface { node: string; @@ -24,11 +23,7 @@ class API implements ProviderAPIInterface { return this; } private getAddress(pubkey: string) { - const { address } = payments.p2wpkh({ - pubkey: hexToBuffer(pubkey), - network: this.networkInfo, - }); - return address as string; + return getBitcoinAddress(pubkey, this.networkInfo); } // eslint-disable-next-line @typescript-eslint/no-empty-function async init(): Promise {} @@ -63,9 +58,11 @@ class API implements ProviderAPIInterface { const address = pubkey.length < 64 ? pubkey : this.getAddress(pubkey); return fetch(`${this.node}/api/v1/account/${address}`) .then((res) => res.json()) - .then((balance: { balance: string }) => { + .then((balance: { balance: string; unconfirmedBalance: string }) => { if ((balance as any).message) return "0"; - return toBN(balance.balance).toString(); + return toBN(balance.balance) + .add(toBN(balance.unconfirmedBalance)) + .toString(); }); } async broadcastTx(rawtx: string): Promise { @@ -104,6 +101,7 @@ class API implements ProviderAPIInterface { pkscript: res.vout[utx.vout].scriptPubKey.hex, txid: utx.txid, value: Number(utx.value), + raw: res.hex, }); } ret.sort((a, b) => { diff --git a/packages/extension/src/providers/bitcoin/libs/api.ts b/packages/extension/src/providers/bitcoin/libs/api.ts index 924f37df1..1ee289e6f 100644 --- a/packages/extension/src/providers/bitcoin/libs/api.ts +++ b/packages/extension/src/providers/bitcoin/libs/api.ts @@ -1,14 +1,13 @@ import { BTCRawInfo } from "@/types/activity"; import { ProviderAPIInterface } from "@/types/provider"; -import { hexToBuffer } from "@enkryptcom/utils"; import { BitcoinNetworkInfo, HaskoinBalanceType, HaskoinTxType, HaskoinUnspentType, } from "../types"; -import { payments } from "bitcoinjs-lib"; import { toBN } from "web3-utils"; +import { getAddress as getBitcoinAddress } from "../types/bitcoin-network"; class API implements ProviderAPIInterface { node: string; @@ -23,11 +22,7 @@ class API implements ProviderAPIInterface { return this; } private getAddress(pubkey: string) { - const { address } = payments.p2wpkh({ - pubkey: hexToBuffer(pubkey), - network: this.networkInfo, - }); - return address as string; + return getBitcoinAddress(pubkey, this.networkInfo); } // eslint-disable-next-line @typescript-eslint/no-empty-function async init(): Promise {} diff --git a/packages/extension/src/providers/bitcoin/libs/ss-fee-handler.ts b/packages/extension/src/providers/bitcoin/libs/ss-fee-handler.ts index 8a56be8fb..1cc641602 100644 --- a/packages/extension/src/providers/bitcoin/libs/ss-fee-handler.ts +++ b/packages/extension/src/providers/bitcoin/libs/ss-fee-handler.ts @@ -20,9 +20,11 @@ const SSFeeHandler = async ( if (json.fast.satsPerKiloByte < 0) json.fast.satsPerKiloByte = json.average.satsPerKiloByte; return { - [GasPriceTypes.FASTEST]: Math.ceil(json.fast.satsPerKiloByte / 1024), - [GasPriceTypes.FAST]: Math.ceil(json.fast.satsPerKiloByte / 1024), - [GasPriceTypes.REGULAR]: Math.ceil(json.average.satsPerKiloByte / 1024), + [GasPriceTypes.FASTEST]: + Math.ceil(json.fast.satsPerKiloByte / 1024) + 5, + [GasPriceTypes.FAST]: Math.ceil(json.fast.satsPerKiloByte / 1024) + 3, + [GasPriceTypes.REGULAR]: + Math.ceil(json.average.satsPerKiloByte / 1024) + 2, [GasPriceTypes.ECONOMY]: Math.ceil(json.slow.satsPerKiloByte / 1024), }; }); diff --git a/packages/extension/src/providers/bitcoin/networks/bitcoin-testnet.ts b/packages/extension/src/providers/bitcoin/networks/bitcoin-testnet.ts index 6c9f03120..0a1572a7e 100644 --- a/packages/extension/src/providers/bitcoin/networks/bitcoin-testnet.ts +++ b/packages/extension/src/providers/bitcoin/networks/bitcoin-testnet.ts @@ -2,6 +2,7 @@ import { NetworkNames } from "@enkryptcom/types"; import { BitcoinNetwork, BitcoinNetworkOptions, + PaymentType, } from "../types/bitcoin-network"; import { haskoinHandler } from "../libs/activity-handlers"; import wrapActivityHandler from "@/libs/activity-state/wrap-activity-handler"; @@ -43,6 +44,7 @@ const bitcoinOptions: BitcoinNetworkOptions = { scriptHash: 0xc4, wif: 0xef, dustThreshold: null, + paymentType: PaymentType.P2WPKH, }, }; diff --git a/packages/extension/src/providers/bitcoin/networks/bitcoin.ts b/packages/extension/src/providers/bitcoin/networks/bitcoin.ts index c1e97a37f..ae19fe97d 100644 --- a/packages/extension/src/providers/bitcoin/networks/bitcoin.ts +++ b/packages/extension/src/providers/bitcoin/networks/bitcoin.ts @@ -2,6 +2,7 @@ import { NetworkNames } from "@enkryptcom/types"; import { BitcoinNetwork, BitcoinNetworkOptions, + PaymentType, } from "../types/bitcoin-network"; import { haskoinHandler } from "../libs/activity-handlers"; import wrapActivityHandler from "@/libs/activity-state/wrap-activity-handler"; @@ -36,6 +37,7 @@ const bitcoinOptions: BitcoinNetworkOptions = { scriptHash: 0x05, wif: 0x80, dustThreshold: null, + paymentType: PaymentType.P2WPKH, }, }; diff --git a/packages/extension/src/providers/bitcoin/networks/dogecoin.ts b/packages/extension/src/providers/bitcoin/networks/dogecoin.ts new file mode 100644 index 000000000..e0552c517 --- /dev/null +++ b/packages/extension/src/providers/bitcoin/networks/dogecoin.ts @@ -0,0 +1,48 @@ +import { NetworkNames } from "@enkryptcom/types"; +import { + BitcoinNetwork, + BitcoinNetworkOptions, + PaymentType, +} from "../types/bitcoin-network"; +import { ssHandler } from "../libs/activity-handlers"; +import wrapActivityHandler from "@/libs/activity-state/wrap-activity-handler"; +import SSFeeHandler from "../libs/ss-fee-handler"; +import SSApi from "../libs/api-ss"; + +const dogeOptions: BitcoinNetworkOptions = { + name: NetworkNames.Dogecoin, + name_long: "Dogecoin", + homePage: "https://dogecoin.com/", + blockExplorerTX: "https://dogechain.info/tx/[[txHash]]", + blockExplorerAddr: "https://dogechain.info/address/[[address]]", + isTestNetwork: false, + currencyName: "Doge", + currencyNameLong: "Dogecoin", + icon: require("./icons/doge.svg"), + decimals: 8, + node: "https://partners.mewapi.io/nodes/ss/doge", + coingeckoID: "dogecoin", + apiType: SSApi, + activityHandler: wrapActivityHandler(ssHandler), + basePath: "m/44'/3'/0'/0", + feeHandler: () => { + return SSFeeHandler("https://partners.mewapi.io/nodes/ss/doge/api/v1/fees"); + }, + networkInfo: { + messagePrefix: "\x19Dogecoin Signed Message:\n", + bech32: "dc", + bip32: { + public: 0x02facafd, + private: 0x02fac398, + }, + pubKeyHash: 0x1e, + scriptHash: 0x16, + wif: 0x9e, + dustThreshold: null, + paymentType: PaymentType.P2PKH, + }, +}; + +const dogecoin = new BitcoinNetwork(dogeOptions); + +export default dogecoin; diff --git a/packages/extension/src/providers/bitcoin/networks/icons/doge.svg b/packages/extension/src/providers/bitcoin/networks/icons/doge.svg new file mode 100644 index 000000000..c435731dc --- /dev/null +++ b/packages/extension/src/providers/bitcoin/networks/icons/doge.svg @@ -0,0 +1 @@ +Dogecoin (DOGE) \ No newline at end of file diff --git a/packages/extension/src/providers/bitcoin/networks/index.ts b/packages/extension/src/providers/bitcoin/networks/index.ts index 09b7d0764..2cf52f449 100644 --- a/packages/extension/src/providers/bitcoin/networks/index.ts +++ b/packages/extension/src/providers/bitcoin/networks/index.ts @@ -1,9 +1,11 @@ import btcNode from "./bitcoin"; import btcTestNode from "./bitcoin-testnet"; import ltcNode from "./litecoin"; +import dogeNode from "./dogecoin"; export default { bitcoin: btcNode, bitcoinTest: btcTestNode, litecoin: ltcNode, + dogecoin: dogeNode, }; diff --git a/packages/extension/src/providers/bitcoin/networks/litecoin.ts b/packages/extension/src/providers/bitcoin/networks/litecoin.ts index a149025e9..856fe7d77 100644 --- a/packages/extension/src/providers/bitcoin/networks/litecoin.ts +++ b/packages/extension/src/providers/bitcoin/networks/litecoin.ts @@ -2,6 +2,7 @@ import { NetworkNames } from "@enkryptcom/types"; import { BitcoinNetwork, BitcoinNetworkOptions, + PaymentType, } from "../types/bitcoin-network"; import { ssHandler } from "../libs/activity-handlers"; import wrapActivityHandler from "@/libs/activity-state/wrap-activity-handler"; @@ -38,6 +39,7 @@ const litecoinOptions: BitcoinNetworkOptions = { scriptHash: 0x32, wif: 0xb0, dustThreshold: null, + paymentType: PaymentType.P2WPKH, }, }; diff --git a/packages/extension/src/providers/bitcoin/types/bitcoin-network.ts b/packages/extension/src/providers/bitcoin/types/bitcoin-network.ts index 0b77cf175..19f3b78cd 100644 --- a/packages/extension/src/providers/bitcoin/types/bitcoin-network.ts +++ b/packages/extension/src/providers/bitcoin/types/bitcoin-network.ts @@ -22,6 +22,10 @@ import { GasPriceTypes } from "@/providers/common/types"; import type HaskoinAPI from "@/providers/bitcoin/libs/api"; import type SSAPI from "@/providers/bitcoin/libs/api-ss"; +export enum PaymentType { + P2PKH = "p2pkh", + P2WPKH = "p2wpkh", +} export interface BitcoinNetworkOptions { name: NetworkNames; name_long: string; @@ -45,6 +49,14 @@ export interface BitcoinNetworkOptions { apiType: typeof HaskoinAPI | typeof SSAPI; } +export const getAddress = (pubkey: string, network: BitcoinNetworkInfo) => { + if (pubkey.length < 64) return pubkey; + const { address } = payments[network.paymentType]({ + network, + pubkey: hexToBuffer(pubkey), + }); + return address as string; +}; export class BitcoinNetwork extends BaseNetwork { public assets: BaseToken[] = []; public networkInfo: BitcoinNetworkInfo; @@ -64,14 +76,8 @@ export class BitcoinNetwork extends BaseNetwork { identicon: createIcon, signer: [SignerType.secp256k1btc], provider: ProviderName.bitcoin, - displayAddress: (pubkey: string) => { - if (pubkey.length < 64) return pubkey; - const { address } = payments.p2wpkh({ - pubkey: hexToBuffer(pubkey), - network: options.networkInfo, - }); - return address as string; - }, + displayAddress: (pubkey: string) => + getAddress(pubkey, options.networkInfo), api, ...options, }; diff --git a/packages/extension/src/providers/bitcoin/types/index.ts b/packages/extension/src/providers/bitcoin/types/index.ts index 609727630..d5c965487 100644 --- a/packages/extension/src/providers/bitcoin/types/index.ts +++ b/packages/extension/src/providers/bitcoin/types/index.ts @@ -1,5 +1,6 @@ import { NetworkNames } from "@enkryptcom/types"; import type { Provider as InjectedProvider } from "../inject"; +import { PaymentType } from "./bitcoin-network"; export const BitcoinNetworks = { BTC: NetworkNames.Bitcoin, @@ -17,6 +18,7 @@ export interface BitcoinNetworkInfo { scriptHash: number; wif: number; dustThreshold: null; + paymentType: PaymentType; } export interface HaskoinBalanceType { @@ -37,6 +39,7 @@ export interface HaskoinUnspentType { index: number; pkscript: string; value: number; + raw?: string; } export interface SSUnspentType { txid: string; @@ -77,6 +80,7 @@ export interface SSTxType { timestamp: number; confirmations: number; fee: string; + hex: string; vin: { txid: string; addresses?: string[]; diff --git a/packages/extension/src/providers/bitcoin/ui/btc-verify-transaction.vue b/packages/extension/src/providers/bitcoin/ui/btc-verify-transaction.vue index b7a3a248b..78f5d2ce1 100644 --- a/packages/extension/src/providers/bitcoin/ui/btc-verify-transaction.vue +++ b/packages/extension/src/providers/bitcoin/ui/btc-verify-transaction.vue @@ -144,7 +144,7 @@ import { GasPriceTypes } from "@/providers/common/types"; import { RPCTxType } from "../types"; import BitcoinAPI from "@/providers/bitcoin/libs/api"; import { HaskoinUnspentType } from "../types"; -import { calculateSize } from "./libs/tx-size"; +import { calculateSizeBasedOnType } from "./libs/tx-size"; import { getGasCostValues } from "../libs/utils"; import { computed } from "@vue/reactivity"; import { toBN } from "web3-utils"; @@ -233,13 +233,10 @@ const updateUTXOs = async () => { const api = (await network.value.api()) as BitcoinAPI; return api.getUTXOs(account.value.address).then((utxos) => { accountUTXOs.value = utxos; - const txSize = calculateSize( - { - input_count: accountUTXOs.value.length, - }, - { - p2wpkh_output_count: 2, - } + const txSize = calculateSizeBasedOnType( + accountUTXOs.value.length, + 2, + (network.value as BitcoinNetwork).networkInfo.paymentType ); setTransactionFees(Math.ceil(txSize.txVBytes)); }); @@ -254,6 +251,7 @@ const getTxInfo = () => { txInfo.inputs.push({ hash: u.txid, index: u.index, + raw: u.raw, witnessUtxo: { script: u.pkscript, value: u.value, diff --git a/packages/extension/src/providers/bitcoin/ui/libs/signer.ts b/packages/extension/src/providers/bitcoin/ui/libs/signer.ts index a7a38b5e5..afe2e7098 100644 --- a/packages/extension/src/providers/bitcoin/ui/libs/signer.ts +++ b/packages/extension/src/providers/bitcoin/ui/libs/signer.ts @@ -5,6 +5,7 @@ import sendUsingInternalMessengers from "@/libs/messenger/internal-messenger"; import { hexToBuffer } from "@enkryptcom/utils"; import { Psbt } from "bitcoinjs-lib"; import { signAsync } from "bitcoinjs-message"; +import { PaymentType } from "../../types/bitcoin-network"; const TransactionSigner = ( options: SignerTransactionOptions @@ -33,14 +34,26 @@ const TransactionSigner = ( }; const tx = new Psbt({ network: network.networkInfo }); payload.inputs - .map((u) => ({ - hash: u.hash, - index: u.index, - witnessUtxo: { - script: Buffer.from(u.witnessUtxo.script, "hex"), - value: u.witnessUtxo.value, - }, - })) + .map((u) => { + const res: { + hash: string; + index: number; + witnessUtxo?: { script: Buffer; value: number }; + nonWitnessUtxo?: Buffer; + } = { + hash: u.hash, + index: u.index, + }; + if (network.networkInfo.paymentType === PaymentType.P2WPKH) { + res.witnessUtxo = { + script: Buffer.from(u.witnessUtxo.script, "hex"), + value: u.witnessUtxo.value, + }; + } else if (network.networkInfo.paymentType === PaymentType.P2PKH) { + res.nonWitnessUtxo = Buffer.from(u.raw, "hex"); + } + return res; + }) .forEach((input) => tx.addInput(input)); payload.outputs.forEach((output) => tx.addOutput(output)); return tx.signAllInputsAsync(signer).then(() => { diff --git a/packages/extension/src/providers/bitcoin/ui/libs/tx-size.ts b/packages/extension/src/providers/bitcoin/ui/libs/tx-size.ts index 5c276cdce..f944fd373 100644 --- a/packages/extension/src/providers/bitcoin/ui/libs/tx-size.ts +++ b/packages/extension/src/providers/bitcoin/ui/libs/tx-size.ts @@ -1,6 +1,7 @@ // https://github.com/jlopp/bitcoin-transaction-size-calculator/blob/master/index.html import { toBN } from "web3-utils"; +import { PaymentType } from "../../types/bitcoin-network"; enum InputScriptType { P2PKH = "P2PKH", @@ -104,22 +105,24 @@ const getTxOverheadVBytes = ( ); }; +interface calcInputType { + input_script?: InputScriptType; + input_n?: number; + input_m?: number; + input_count: number; +} +interface calcOutputType { + p2pkh_output_count?: number; + p2sh_output_count?: number; + p2sh_p2wpkh_output_count?: number; + p2sh_p2wsh_output_count?: number; + p2wpkh_output_count?: number; + p2wsh_output_count?: number; + p2tr_output_count?: number; +} const calculateSize = ( - inputOptions: { - input_script?: InputScriptType; - input_n?: number; - input_m?: number; - input_count: number; - }, - outputOptions: { - p2pkh_output_count?: number; - p2sh_output_count?: number; - p2sh_p2wpkh_output_count?: number; - p2sh_p2wsh_output_count?: number; - p2wpkh_output_count?: number; - p2wsh_output_count?: number; - p2tr_output_count?: number; - } + inputOptions: calcInputType, + outputOptions: calcOutputType ) => { const defaultInputOptions = { input_script: InputScriptType.P2WPKH, @@ -232,5 +235,26 @@ const calculateSize = ( txWeight, }; }; - -export { InputScriptType, calculateSize }; +const calculateSizeBasedOnType = ( + numInputs: number, + numOutputs: number, + type: PaymentType +) => { + const output: calcOutputType = {}; + if (type === PaymentType.P2PKH) { + output.p2pkh_output_count = numOutputs; + } else { + output.p2wpkh_output_count = numOutputs; + } + return calculateSize( + { + input_script: + type === PaymentType.P2PKH + ? InputScriptType.P2PKH + : InputScriptType.P2WPKH, + input_count: numInputs, + }, + output + ); +}; +export { InputScriptType, calculateSize, calculateSizeBasedOnType }; diff --git a/packages/extension/src/providers/bitcoin/ui/send-transaction/index.vue b/packages/extension/src/providers/bitcoin/ui/send-transaction/index.vue index 85bab3bfb..c5608d65c 100644 --- a/packages/extension/src/providers/bitcoin/ui/send-transaction/index.vue +++ b/packages/extension/src/providers/bitcoin/ui/send-transaction/index.vue @@ -132,7 +132,7 @@ import { BaseNetwork } from "@/types/base-network"; import { getGasCostValues, isAddress } from "../../libs/utils"; import BitcoinAPI from "@/providers/bitcoin/libs/api"; -import { calculateSize } from "../libs/tx-size"; +import { calculateSizeBasedOnType } from "../libs/tx-size"; import { HaskoinUnspentType } from "../../types"; import { VerifyTransactionParams, BTCTxInfo } from "../types"; @@ -239,13 +239,10 @@ const updateUTXOs = async () => { const api = (await props.network.api()) as BitcoinAPI; return api.getUTXOs(addressFrom.value).then((utxos) => { accountUTXOs.value = utxos; - const txSize = calculateSize( - { - input_count: accountUTXOs.value.length, - }, - { - p2wpkh_output_count: 2, - } + const txSize = calculateSizeBasedOnType( + accountUTXOs.value.length, + 2, + (props.network as BitcoinNetwork).networkInfo.paymentType ); setTransactionFees(Math.ceil(txSize.txVBytes)); }); @@ -377,6 +374,7 @@ const sendAction = async () => { txInfo.inputs.push({ hash: u.txid, index: u.index, + raw: u.raw, witnessUtxo: { script: u.pkscript, value: u.value, diff --git a/packages/extension/src/ui/action/views/swap/libs/bitcoin-gasvals.ts b/packages/extension/src/ui/action/views/swap/libs/bitcoin-gasvals.ts index 470231700..35f4e8106 100644 --- a/packages/extension/src/ui/action/views/swap/libs/bitcoin-gasvals.ts +++ b/packages/extension/src/ui/action/views/swap/libs/bitcoin-gasvals.ts @@ -1,6 +1,6 @@ import { GasFeeType } from "@/providers/common/types"; import { BaseNetwork } from "@/types/base-network"; -import { calculateSize } from "@/providers/bitcoin/ui/libs/tx-size"; +import { calculateSizeBasedOnType } from "@/providers/bitcoin/ui/libs/tx-size"; import { BTCTxInfo } from "@/providers/bitcoin/ui/types"; import { getGasCostValues } from "@/providers/bitcoin/libs/utils"; import { BitcoinNetwork } from "@/providers/bitcoin/types/bitcoin-network"; @@ -11,13 +11,10 @@ export const getBitcoinGasVals = async ( price: number ): Promise => { const tx = txs[0] as BTCTxInfo; - const txSize = calculateSize( - { - input_count: tx.inputs.length, - }, - { - p2wpkh_output_count: 2, - } + const txSize = calculateSizeBasedOnType( + tx.inputs.length, + 2, + (network as BitcoinNetwork).networkInfo.paymentType ); return getGasCostValues( network as BitcoinNetwork, diff --git a/packages/types/src/networks.ts b/packages/types/src/networks.ts index b489d7993..d0001f07d 100644 --- a/packages/types/src/networks.ts +++ b/packages/types/src/networks.ts @@ -59,6 +59,7 @@ export enum NetworkNames { Base = "BASE", Celo = "CELO", Litecoin = "LTC", + Dogecoin = "DOGE", } export enum CoingeckoPlatform { From 3ab81ddea596e63162f2d0118d28d527cd3322d8 Mon Sep 17 00:00:00 2001 From: kvhnuke <10602065+kvhnuke@users.noreply.github.com> Date: Thu, 14 Sep 2023 16:44:26 -0700 Subject: [PATCH 03/12] devop: add dogecoin litecoin swap --- packages/swap/src/common/supportedNetworks.ts | 22 +++++++++++++++++++ .../swap/src/providers/changelly/supported.ts | 6 +++++ packages/swap/src/types/index.ts | 2 ++ 3 files changed, 30 insertions(+) diff --git a/packages/swap/src/common/supportedNetworks.ts b/packages/swap/src/common/supportedNetworks.ts index c89989608..ab58b68bc 100644 --- a/packages/swap/src/common/supportedNetworks.ts +++ b/packages/swap/src/common/supportedNetworks.ts @@ -193,6 +193,28 @@ const NetworkDetails: Record = { rank: 16, symbol: "ETH", }, + [SupportedNetworkName.Litecoin]: { + id: SupportedNetworkName.Litecoin, + decimals: 8, + logoURI: "https://assets.coingecko.com/coins/images/2/thumb/litecoin.png", + name: "Litecoin", + symbol: "LTC", + cgId: "litecoin", + rank: 17, + signerType: [SignerType.secp256k1btc], + type: NetworkType.Bitcoin, + }, + [SupportedNetworkName.Dogecoin]: { + id: SupportedNetworkName.Dogecoin, + decimals: 8, + logoURI: "https://assets.coingecko.com/coins/images/5/thumb/dogecoin.png", + name: "Dogecoin", + symbol: "DOGE", + cgId: "dogecoin", + rank: 18, + signerType: [SignerType.secp256k1btc], + type: NetworkType.Bitcoin, + }, }; export const isSupportedNetwork = (networkName: SupportedNetworkName) => !!NetworkDetails[networkName]; diff --git a/packages/swap/src/providers/changelly/supported.ts b/packages/swap/src/providers/changelly/supported.ts index 05d5d7217..ac8d7fe4d 100644 --- a/packages/swap/src/providers/changelly/supported.ts +++ b/packages/swap/src/providers/changelly/supported.ts @@ -44,6 +44,12 @@ const supportedNetworks: { [SupportedNetworkName.Bitcoin]: { changellyName: "bitcoin", }, + [SupportedNetworkName.Litecoin]: { + changellyName: "litecoin", + }, + [SupportedNetworkName.Dogecoin]: { + changellyName: "doge", + }, }; export default supportedNetworks; diff --git a/packages/swap/src/types/index.ts b/packages/swap/src/types/index.ts index 13e130341..ac1e38b84 100644 --- a/packages/swap/src/types/index.ts +++ b/packages/swap/src/types/index.ts @@ -11,6 +11,8 @@ export enum Events { export enum SupportedNetworkName { Ethereum = NetworkNames.Ethereum, Binance = NetworkNames.Binance, + Litecoin = NetworkNames.Litecoin, + Dogecoin = NetworkNames.Dogecoin, Matic = NetworkNames.Matic, Optimism = NetworkNames.Optimism, Polkadot = NetworkNames.Polkadot, From e0814d3c051e5ae43636b4f54fa75bf03be7160d Mon Sep 17 00:00:00 2001 From: kvhnuke <10602065+kvhnuke@users.noreply.github.com> Date: Fri, 15 Sep 2023 12:01:02 -0700 Subject: [PATCH 04/12] devop: replace disconnect ion --- .../action/icons/header/disconnect_icon.vue | 29 ++++++------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/packages/extension/src/ui/action/icons/header/disconnect_icon.vue b/packages/extension/src/ui/action/icons/header/disconnect_icon.vue index ff76de632..e6e3e317c 100644 --- a/packages/extension/src/ui/action/icons/header/disconnect_icon.vue +++ b/packages/extension/src/ui/action/icons/header/disconnect_icon.vue @@ -1,27 +1,16 @@ From 851749b4243281cb72f5745bde1e4a8d1d017f93 Mon Sep 17 00:00:00 2001 From: kvhnuke <10602065+kvhnuke@users.noreply.github.com> Date: Fri, 15 Sep 2023 12:05:54 -0700 Subject: [PATCH 05/12] devop: bump package version --- packages/extension/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/extension/package.json b/packages/extension/package.json index ffefa2ffa..982cd59ae 100644 --- a/packages/extension/package.json +++ b/packages/extension/package.json @@ -1,6 +1,6 @@ { "name": "@enkryptcom/extension", - "version": "1.27.0", + "version": "1.28.0", "private": true, "scripts": { "zip": "cd dist; zip -r release.zip *;", From 11559c03c0f9a2a97503e3dd3f5080314f271682 Mon Sep 17 00:00:00 2001 From: kvhnuke <10602065+kvhnuke@users.noreply.github.com> Date: Fri, 15 Sep 2023 14:10:50 -0700 Subject: [PATCH 06/12] devop: set dust values for btc networks --- .../providers/bitcoin/networks/bitcoin-testnet.ts | 1 + .../src/providers/bitcoin/networks/bitcoin.ts | 1 + .../src/providers/bitcoin/networks/dogecoin.ts | 1 + .../src/providers/bitcoin/networks/litecoin.ts | 1 + .../src/providers/bitcoin/types/bitcoin-network.ts | 3 +++ .../providers/bitcoin/ui/send-transaction/index.vue | 13 ++++++++++--- 6 files changed, 17 insertions(+), 3 deletions(-) diff --git a/packages/extension/src/providers/bitcoin/networks/bitcoin-testnet.ts b/packages/extension/src/providers/bitcoin/networks/bitcoin-testnet.ts index 0a1572a7e..7193f9c83 100644 --- a/packages/extension/src/providers/bitcoin/networks/bitcoin-testnet.ts +++ b/packages/extension/src/providers/bitcoin/networks/bitcoin-testnet.ts @@ -21,6 +21,7 @@ const bitcoinOptions: BitcoinNetworkOptions = { currencyNameLong: "Test Bitcoin", icon: require("./icons/tbtc.svg"), decimals: 8, + dust: 0.00000546, node: "https://api.blockchain.info/haskoin-store/btc-testnet/", activityHandler: wrapActivityHandler(haskoinHandler), basePath: "m/49'/1'/0'/0", diff --git a/packages/extension/src/providers/bitcoin/networks/bitcoin.ts b/packages/extension/src/providers/bitcoin/networks/bitcoin.ts index ae19fe97d..f08a76e91 100644 --- a/packages/extension/src/providers/bitcoin/networks/bitcoin.ts +++ b/packages/extension/src/providers/bitcoin/networks/bitcoin.ts @@ -26,6 +26,7 @@ const bitcoinOptions: BitcoinNetworkOptions = { basePath: "m/49'/0'/0'/0", feeHandler: BTCFeeHandler, apiType: HaskoinAPI, + dust: 0.00000546, networkInfo: { messagePrefix: "\x18Bitcoin Signed Message:\n", bech32: "bc", diff --git a/packages/extension/src/providers/bitcoin/networks/dogecoin.ts b/packages/extension/src/providers/bitcoin/networks/dogecoin.ts index e0552c517..63b06beea 100644 --- a/packages/extension/src/providers/bitcoin/networks/dogecoin.ts +++ b/packages/extension/src/providers/bitcoin/networks/dogecoin.ts @@ -23,6 +23,7 @@ const dogeOptions: BitcoinNetworkOptions = { node: "https://partners.mewapi.io/nodes/ss/doge", coingeckoID: "dogecoin", apiType: SSApi, + dust: 0.01, activityHandler: wrapActivityHandler(ssHandler), basePath: "m/44'/3'/0'/0", feeHandler: () => { diff --git a/packages/extension/src/providers/bitcoin/networks/litecoin.ts b/packages/extension/src/providers/bitcoin/networks/litecoin.ts index 856fe7d77..a565d52e9 100644 --- a/packages/extension/src/providers/bitcoin/networks/litecoin.ts +++ b/packages/extension/src/providers/bitcoin/networks/litecoin.ts @@ -22,6 +22,7 @@ const litecoinOptions: BitcoinNetworkOptions = { decimals: 8, node: "https://partners.mewapi.io/nodes/ss/ltc", coingeckoID: "litecoin", + dust: 0.0001, apiType: SSApi, activityHandler: wrapActivityHandler(ssHandler), basePath: "m/49'/2'/0'/0", diff --git a/packages/extension/src/providers/bitcoin/types/bitcoin-network.ts b/packages/extension/src/providers/bitcoin/types/bitcoin-network.ts index 19f3b78cd..3258c4866 100644 --- a/packages/extension/src/providers/bitcoin/types/bitcoin-network.ts +++ b/packages/extension/src/providers/bitcoin/types/bitcoin-network.ts @@ -41,6 +41,7 @@ export interface BitcoinNetworkOptions { coingeckoID?: string; basePath: string; networkInfo: BitcoinNetworkInfo; + dust: number; feeHandler: () => Promise>; activityHandler: ( network: BaseNetwork, @@ -60,6 +61,7 @@ export const getAddress = (pubkey: string, network: BitcoinNetworkInfo) => { export class BitcoinNetwork extends BaseNetwork { public assets: BaseToken[] = []; public networkInfo: BitcoinNetworkInfo; + public dust: number; private activityHandler: ( network: BaseNetwork, address: string @@ -85,6 +87,7 @@ export class BitcoinNetwork extends BaseNetwork { this.activityHandler = options.activityHandler; this.networkInfo = options.networkInfo; this.feeHandler = options.feeHandler; + this.dust = options.dust; } public async getAllTokens(pubkey: string): Promise { diff --git a/packages/extension/src/providers/bitcoin/ui/send-transaction/index.vue b/packages/extension/src/providers/bitcoin/ui/send-transaction/index.vue index c5608d65c..80182b591 100644 --- a/packages/extension/src/providers/bitcoin/ui/send-transaction/index.vue +++ b/packages/extension/src/providers/bitcoin/ui/send-transaction/index.vue @@ -167,6 +167,9 @@ const hasEnoughBalance = computed(() => { if (!isValidDecimals(sendAmount.value, selectedAsset.value.decimals!)) { return false; } + if (Number(sendAmount.value) < (props.network as BitcoinNetwork).dust) { + return false; + } return toBN(selectedAsset.value.balance ?? "0").gte( toBN(toBase(sendAmount.value ?? "0", selectedAsset.value.decimals!)).add( toBN( @@ -211,8 +214,10 @@ onMounted(async () => { }); const nativeBalanceAfterTransaction = computed(() => { - if (nativeBalance.value && amount.value !== "") { - const rawAmount = toBN(toBase(amount.value, selectedAsset.value.decimals!)); + if (nativeBalance.value) { + const rawAmount = toBN( + toBase(sendAmount.value, selectedAsset.value.decimals!) + ); return toBN(nativeBalance.value).sub(rawAmount); } return toBN(0); @@ -276,6 +281,8 @@ const isInputsValid = computed(() => { if (!isValidDecimals(sendAmount.value, selectedAsset.value.decimals!)) { return false; } + if (Number(sendAmount.value) < (props.network as BitcoinNetwork).dust) + return false; if (new BigNumber(sendAmount.value).gt(assetMaxValue.value)) return false; return true; }); @@ -382,7 +389,7 @@ const sendAction = async () => { }); }); const balance = toBN(selectedAsset.value.balance!); - const toAmount = toBN(toBase(amount.value, selectedAsset.value.decimals)); + const toAmount = toBN(toBase(sendAmount.value, selectedAsset.value.decimals)); const currentFee = toBN( toBase( gasCostValues.value[selectedFee.value].nativeValue, From 74ab2b8efccdc891ac23d8d2e58af4ad2a41f257 Mon Sep 17 00:00:00 2001 From: kvhnuke <10602065+kvhnuke@users.noreply.github.com> Date: Wed, 20 Sep 2023 12:57:02 -0700 Subject: [PATCH 07/12] fix: multiple bugs --- .../providers/haskoin/index.ts | 3 +++ .../activity-handlers/providers/ss/index.ts | 5 ++++- .../src/providers/ethereum/networks/rsk.ts | 12 +++++++++--- .../src/ui/action/composables/account-info.ts | 19 +++++++++++++------ .../components/custom-evm-token.vue | 4 ++-- .../components/network-assets-item.vue | 2 +- 6 files changed, 32 insertions(+), 13 deletions(-) diff --git a/packages/extension/src/providers/bitcoin/libs/activity-handlers/providers/haskoin/index.ts b/packages/extension/src/providers/bitcoin/libs/activity-handlers/providers/haskoin/index.ts index 7dd9c5f51..5d4837d30 100644 --- a/packages/extension/src/providers/bitcoin/libs/activity-handlers/providers/haskoin/index.ts +++ b/packages/extension/src/providers/bitcoin/libs/activity-handlers/providers/haskoin/index.ts @@ -43,6 +43,9 @@ export default async ( if (relevantOut) { toAddress = relevantOut.address; value = relevantOut.value; + } else { + toAddress = tx.outputs[0].address; + value = Number(tx.outputs[0].value); } } diff --git a/packages/extension/src/providers/bitcoin/libs/activity-handlers/providers/ss/index.ts b/packages/extension/src/providers/bitcoin/libs/activity-handlers/providers/ss/index.ts index 636fcc197..1a0af2958 100644 --- a/packages/extension/src/providers/bitcoin/libs/activity-handlers/providers/ss/index.ts +++ b/packages/extension/src/providers/bitcoin/libs/activity-handlers/providers/ss/index.ts @@ -37,7 +37,7 @@ export default async ( }); return cleanedTxs.map((tx) => { const isIncoming = !tx.vin.find((i) => i.addresses![0] === address); - + console.log(isIncoming, tx.vin, tx.vout, address); let toAddress = ""; let value = 0; @@ -56,6 +56,9 @@ export default async ( if (relevantOut) { toAddress = relevantOut.addresses![0]; value = Number(relevantOut.value); + } else { + toAddress = tx.vout[0].addresses![0]; + value = Number(tx.vout[0].value); } } diff --git a/packages/extension/src/providers/ethereum/networks/rsk.ts b/packages/extension/src/providers/ethereum/networks/rsk.ts index c07c52fcf..3661eea3f 100644 --- a/packages/extension/src/providers/ethereum/networks/rsk.ts +++ b/packages/extension/src/providers/ethereum/networks/rsk.ts @@ -2,8 +2,11 @@ import { CoingeckoPlatform, 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"; -import { toChecksumAddress } from "ethereumjs-util"; -import { isAddress } from "web3-utils"; +import { + toChecksumAddress, + isValidChecksumAddress, + isValidAddress, +} from "ethereumjs-util"; import assetsInfoHandler from "@/providers/ethereum/libs/assets-handlers/assetinfo-mew"; const rootstockOptions: EvmNetworkOptions = { @@ -29,7 +32,10 @@ rootstockOptions.displayAddress = (address: string) => { return toChecksumAddress(address, rootstockOptions.chainID); }; rootstockOptions.isAddress = (address: string) => { - return isAddress(address, parseInt(rootstockOptions.chainID)); + return ( + isValidAddress(address) || + isValidChecksumAddress(address, rootstockOptions.chainID) + ); }; const rootstock = new EvmNetwork(rootstockOptions); diff --git a/packages/extension/src/ui/action/composables/account-info.ts b/packages/extension/src/ui/action/composables/account-info.ts index cd6581796..467654c0c 100644 --- a/packages/extension/src/ui/action/composables/account-info.ts +++ b/packages/extension/src/ui/action/composables/account-info.ts @@ -10,24 +10,31 @@ export default ( ) => { const marketData = new MarketData(); const fiatAmount = ref(defaultFiatVal); - const cryptoAmount = computed(() => { + + const cryptoAmountRaw = computed(() => { const selectedAccountIdx = accountInfo.value.activeAccounts.findIndex( (acc) => acc.address === accountInfo.value.selectedAccount?.address ); - let balance = "0"; if (selectedAccountIdx > -1) { - balance = accountInfo.value.activeBalances[selectedAccountIdx]; + const balance = accountInfo.value.activeBalances[selectedAccountIdx]; + return balance; } - return balance !== "~" ? formatFloatingPointValue(balance).value : balance; + return "0"; + }); + + const cryptoAmount = computed(() => { + return cryptoAmountRaw.value !== "~" + ? formatFloatingPointValue(cryptoAmountRaw.value).value + : cryptoAmountRaw.value; }); const updateFiatValues = async () => { fiatAmount.value = defaultFiatVal; - if (network.value.coingeckoID && cryptoAmount.value != "~") { + if (network.value.coingeckoID && cryptoAmountRaw.value != "~") { fiatAmount.value = `${ formatFiatValue( await marketData.getTokenValue( - cryptoAmount.value, + cryptoAmountRaw.value, network.value.coingeckoID, "USD" ) diff --git a/packages/extension/src/ui/action/views/network-assets/components/custom-evm-token.vue b/packages/extension/src/ui/action/views/network-assets/components/custom-evm-token.vue index 160a774e2..142332884 100644 --- a/packages/extension/src/ui/action/views/network-assets/components/custom-evm-token.vue +++ b/packages/extension/src/ui/action/views/network-assets/components/custom-evm-token.vue @@ -141,7 +141,7 @@ watch([contractAddress, props], async () => { if (isValidAddress.value) { const api = (await props.network.api()) as API; - const info = await api.getTokenInfo(contractAddress.value!); + const info = await api.getTokenInfo(contractAddress.value!.toLowerCase()); if (info.name !== "Unknown") { let icon = props.network.icon; @@ -168,7 +168,7 @@ watch([contractAddress, props], async () => { symbol: info.symbol, decimals: info.decimals, icon, - contract: contractAddress.value!, + contract: contractAddress.value!.toLowerCase(), coingeckoID, }); diff --git a/packages/extension/src/ui/action/views/network-assets/components/network-assets-item.vue b/packages/extension/src/ui/action/views/network-assets/components/network-assets-item.vue index e64b24695..c0e831e84 100644 --- a/packages/extension/src/ui/action/views/network-assets/components/network-assets-item.vue +++ b/packages/extension/src/ui/action/views/network-assets/components/network-assets-item.vue @@ -43,7 +43,7 @@
-

{{ token.balanceUSDf }}

+

${{ token.balanceUSDf }}

@{{ token.valuef }}

From 6f2b6c95e6f19066a679a7673ea6d4376f1e56c7 Mon Sep 17 00:00:00 2001 From: kvhnuke <10602065+kvhnuke@users.noreply.github.com> Date: Fri, 22 Sep 2023 11:22:41 -0700 Subject: [PATCH 08/12] fix: doge swap and add minimum amount --- .../src/providers/bitcoin/libs/utils.ts | 25 +++++- .../bitcoin/ui/btc-verify-transaction.vue | 18 +---- .../bitcoin/ui/send-transaction/index.vue | 81 ++++++------------- .../common/ui/send-transaction/send-alert.vue | 6 +- .../src/ui/action/views/swap/libs/swap-txs.ts | 15 +--- 5 files changed, 58 insertions(+), 87 deletions(-) diff --git a/packages/extension/src/providers/bitcoin/libs/utils.ts b/packages/extension/src/providers/bitcoin/libs/utils.ts index 0c72aee8b..42f61c600 100644 --- a/packages/extension/src/providers/bitcoin/libs/utils.ts +++ b/packages/extension/src/providers/bitcoin/libs/utils.ts @@ -1,9 +1,10 @@ -import { BitcoinNetworkInfo } from "../types"; +import { BitcoinNetworkInfo, HaskoinUnspentType } from "../types"; import { address as BTCAddress } from "bitcoinjs-lib"; import { GasPriceTypes } from "@/providers/common/types"; import { fromBase } from "@enkryptcom/utils"; import BigNumber from "bignumber.js"; import { BitcoinNetwork } from "../types/bitcoin-network"; +import { BTCTxInfo } from "../ui/types"; const isAddress = (address: string, network: BitcoinNetworkInfo): boolean => { try { @@ -13,6 +14,26 @@ const isAddress = (address: string, network: BitcoinNetworkInfo): boolean => { return false; } }; + +const getTxInfo = (utxos: HaskoinUnspentType[]): BTCTxInfo => { + const txInfo: BTCTxInfo = { + inputs: [], + outputs: [], + }; + utxos.forEach((u) => { + txInfo.inputs.push({ + hash: u.txid, + index: u.index, + raw: u.raw, + witnessUtxo: { + script: u.pkscript, + value: u.value, + }, + }); + }); + return txInfo; +}; + const getGasCostValues = async ( network: BitcoinNetwork, byteSize: number, @@ -66,4 +87,4 @@ const getGasCostValues = async ( }; return gasCostValues; }; -export { isAddress, getGasCostValues }; +export { isAddress, getGasCostValues, getTxInfo }; diff --git a/packages/extension/src/providers/bitcoin/ui/btc-verify-transaction.vue b/packages/extension/src/providers/bitcoin/ui/btc-verify-transaction.vue index 78f5d2ce1..dfaca4d4c 100644 --- a/packages/extension/src/providers/bitcoin/ui/btc-verify-transaction.vue +++ b/packages/extension/src/providers/bitcoin/ui/btc-verify-transaction.vue @@ -148,7 +148,7 @@ import { calculateSizeBasedOnType } from "./libs/tx-size"; import { getGasCostValues } from "../libs/utils"; import { computed } from "@vue/reactivity"; import { toBN } from "web3-utils"; -import { BTCTxInfo } from "./types"; +import { getTxInfo as getBTCTxInfo } from "../libs/utils"; const isProcessing = ref(false); const isOpenSelectFee = ref(false); @@ -243,21 +243,7 @@ const updateUTXOs = async () => { }; const getTxInfo = () => { - const txInfo: BTCTxInfo = { - inputs: [], - outputs: [], - }; - accountUTXOs.value.forEach((u) => { - txInfo.inputs.push({ - hash: u.txid, - index: u.index, - raw: u.raw, - witnessUtxo: { - script: u.pkscript, - value: u.value, - }, - }); - }); + const txInfo = getBTCTxInfo(accountUTXOs.value); const balance = toBN(TokenBalance.value); const toAmount = toBN(tx.value.value.toString()); const currentFee = toBN( diff --git a/packages/extension/src/providers/bitcoin/ui/send-transaction/index.vue b/packages/extension/src/providers/bitcoin/ui/send-transaction/index.vue index 80182b591..0772a5d98 100644 --- a/packages/extension/src/providers/bitcoin/ui/send-transaction/index.vue +++ b/packages/extension/src/providers/bitcoin/ui/send-transaction/index.vue @@ -51,11 +51,10 @@ v-if="isSendToken" :amount="amount" :fiat-value="selectedAsset.price" - :has-enough-balance="hasEnoughBalance" + :has-enough-balance="!nativeBalanceAfterTransaction.isNeg()" @update:input-amount="inputAmount" @update:input-set-max="setMaxValue" /> -
@@ -134,7 +136,8 @@ import { getGasCostValues, isAddress } from "../../libs/utils"; import BitcoinAPI from "@/providers/bitcoin/libs/api"; import { calculateSizeBasedOnType } from "../libs/tx-size"; import { HaskoinUnspentType } from "../../types"; -import { VerifyTransactionParams, BTCTxInfo } from "../types"; +import { VerifyTransactionParams } from "../types"; +import { getTxInfo as getBTCTxInfo } from "@/providers/bitcoin/libs/utils"; const props = defineProps({ network: { @@ -163,25 +166,6 @@ const selectedAsset = ref(loadingAsset); const amount = ref(""); const accountUTXOs = ref([]); -const hasEnoughBalance = computed(() => { - if (!isValidDecimals(sendAmount.value, selectedAsset.value.decimals!)) { - return false; - } - if (Number(sendAmount.value) < (props.network as BitcoinNetwork).dust) { - return false; - } - return toBN(selectedAsset.value.balance ?? "0").gte( - toBN(toBase(sendAmount.value ?? "0", selectedAsset.value.decimals!)).add( - toBN( - toBase( - gasCostValues.value[selectedFee.value].nativeValue, - selectedAsset.value.decimals! - ) - ) - ) - ); -}); - const sendAmount = computed(() => { if (amount.value && amount.value !== "") return amount.value; return "0"; @@ -196,29 +180,22 @@ const addressFrom = ref( const addressTo = ref(""); const isLoadingAssets = ref(true); -const nativeBalance = computed(() => { - const accountIndex = props.accountInfo.activeAccounts.findIndex( - (acc) => acc.address === addressFrom.value - ); - if (accountIndex !== -1) { - const balance = props.accountInfo.activeBalances[accountIndex]; - if (balance !== "~") { - return toBase(balance, props.network.decimals); - } - } - return "0"; -}); - onMounted(async () => { fetchAssets().then(setBaseCosts); }); const nativeBalanceAfterTransaction = computed(() => { - if (nativeBalance.value) { - const rawAmount = toBN( - toBase(sendAmount.value, selectedAsset.value.decimals!) + if (selectedAsset.value) { + return toBN(selectedAsset.value.balance ?? "0").sub( + toBN(toBase(sendAmount.value ?? "0", selectedAsset.value.decimals!)).add( + toBN( + toBase( + gasCostValues.value[selectedFee.value].nativeValue, + selectedAsset.value.decimals! + ) + ) + ) ); - return toBN(nativeBalance.value).sub(rawAmount); } return toBN(0); }); @@ -373,21 +350,7 @@ const selectFee = (type: GasPriceTypes) => { const sendAction = async () => { const keyring = new PublicKeyRing(); const fromAccountInfo = await keyring.getAccount(addressFrom.value); - const txInfo: BTCTxInfo = { - inputs: [], - outputs: [], - }; - accountUTXOs.value.forEach((u) => { - txInfo.inputs.push({ - hash: u.txid, - index: u.index, - raw: u.raw, - witnessUtxo: { - script: u.pkscript, - value: u.value, - }, - }); - }); + const txInfo = getBTCTxInfo(accountUTXOs.value); const balance = toBN(selectedAsset.value.balance!); const toAmount = toBN(toBase(sendAmount.value, selectedAsset.value.decimals)); const currentFee = toBN( @@ -504,4 +467,12 @@ const toggleSelector = (isTokenSend: boolean) => { } } } +p { + font-weight: 400; + font-size: 14px; + line-height: 20px; + letter-spacing: 0.25px; + color: @error; + margin: 0; +} diff --git a/packages/extension/src/providers/common/ui/send-transaction/send-alert.vue b/packages/extension/src/providers/common/ui/send-transaction/send-alert.vue index f115c963b..5c223ca3b 100644 --- a/packages/extension/src/providers/common/ui/send-transaction/send-alert.vue +++ b/packages/extension/src/providers/common/ui/send-transaction/send-alert.vue @@ -1,7 +1,7 @@ @@ -21,6 +22,9 @@ interface IProps { nativeSymbol: string; nativeValue: string; price?: string; + notEnough: boolean; + belowDust: boolean; + dust: string; } const props = defineProps(); diff --git a/packages/extension/src/ui/action/views/swap/libs/swap-txs.ts b/packages/extension/src/ui/action/views/swap/libs/swap-txs.ts index 8119f259d..eebadf263 100644 --- a/packages/extension/src/ui/action/views/swap/libs/swap-txs.ts +++ b/packages/extension/src/ui/action/views/swap/libs/swap-txs.ts @@ -17,7 +17,7 @@ import { ApiPromise } from "@polkadot/api"; import { TransactionType } from "../types"; import { BitcoinNetwork } from "@/providers/bitcoin/types/bitcoin-network"; import BitcoinAPI from "@/providers/bitcoin/libs/api"; -import { BTCTxInfo } from "@/providers/bitcoin/ui/types"; +import { getTxInfo as getBTCTxInfo } from "@/providers/bitcoin/libs/utils"; import { toBN } from "web3-utils"; export const getSubstrateNativeTransation = async ( @@ -45,21 +45,10 @@ export const getBitcoinNativeTransaction = async ( ) => { const api = (await network.api()) as BitcoinAPI; const utxos = await api.getUTXOs(tx.from); - const txInfo: BTCTxInfo = { - inputs: [], - outputs: [], - }; + const txInfo = getBTCTxInfo(utxos); let balance = 0; utxos.forEach((u) => { balance += u.value; - txInfo.inputs.push({ - hash: u.txid, - index: u.index, - witnessUtxo: { - script: u.pkscript, - value: u.value, - }, - }); }); const toAmount = toBN(tx.value); const remainder = balance - toAmount.toNumber(); From bbb55d51559a41136bdc9e79c3ee1dfbf5e8abaf Mon Sep 17 00:00:00 2001 From: kvhnuke <10602065+kvhnuke@users.noreply.github.com> Date: Mon, 25 Sep 2023 13:29:52 -0700 Subject: [PATCH 09/12] fix: utxo size calculation --- .../src/providers/bitcoin/ui/btc-verify-transaction.vue | 2 +- packages/extension/src/providers/bitcoin/ui/libs/tx-size.ts | 6 +++--- .../src/providers/bitcoin/ui/send-transaction/index.vue | 2 +- .../src/ui/action/views/swap/libs/bitcoin-gasvals.ts | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/extension/src/providers/bitcoin/ui/btc-verify-transaction.vue b/packages/extension/src/providers/bitcoin/ui/btc-verify-transaction.vue index dfaca4d4c..7cffa490c 100644 --- a/packages/extension/src/providers/bitcoin/ui/btc-verify-transaction.vue +++ b/packages/extension/src/providers/bitcoin/ui/btc-verify-transaction.vue @@ -238,7 +238,7 @@ const updateUTXOs = async () => { 2, (network.value as BitcoinNetwork).networkInfo.paymentType ); - setTransactionFees(Math.ceil(txSize.txVBytes)); + setTransactionFees(Math.ceil(txSize)); }); }; diff --git a/packages/extension/src/providers/bitcoin/ui/libs/tx-size.ts b/packages/extension/src/providers/bitcoin/ui/libs/tx-size.ts index f944fd373..4dcb707eb 100644 --- a/packages/extension/src/providers/bitcoin/ui/libs/tx-size.ts +++ b/packages/extension/src/providers/bitcoin/ui/libs/tx-size.ts @@ -228,7 +228,6 @@ const calculateSize = ( txVBytes + (inputWitnessSize * input_count * 3) / 4; const txWeight = txVBytes * 4; - return { txVBytes, txBytes, @@ -239,14 +238,14 @@ const calculateSizeBasedOnType = ( numInputs: number, numOutputs: number, type: PaymentType -) => { +): number => { const output: calcOutputType = {}; if (type === PaymentType.P2PKH) { output.p2pkh_output_count = numOutputs; } else { output.p2wpkh_output_count = numOutputs; } - return calculateSize( + const size = calculateSize( { input_script: type === PaymentType.P2PKH @@ -256,5 +255,6 @@ const calculateSizeBasedOnType = ( }, output ); + return type === PaymentType.P2PKH ? size.txBytes : size.txVBytes; }; export { InputScriptType, calculateSize, calculateSizeBasedOnType }; diff --git a/packages/extension/src/providers/bitcoin/ui/send-transaction/index.vue b/packages/extension/src/providers/bitcoin/ui/send-transaction/index.vue index 0772a5d98..6d5e72fd8 100644 --- a/packages/extension/src/providers/bitcoin/ui/send-transaction/index.vue +++ b/packages/extension/src/providers/bitcoin/ui/send-transaction/index.vue @@ -226,7 +226,7 @@ const updateUTXOs = async () => { 2, (props.network as BitcoinNetwork).networkInfo.paymentType ); - setTransactionFees(Math.ceil(txSize.txVBytes)); + setTransactionFees(Math.ceil(txSize)); }); }; diff --git a/packages/extension/src/ui/action/views/swap/libs/bitcoin-gasvals.ts b/packages/extension/src/ui/action/views/swap/libs/bitcoin-gasvals.ts index 35f4e8106..303eeb8a6 100644 --- a/packages/extension/src/ui/action/views/swap/libs/bitcoin-gasvals.ts +++ b/packages/extension/src/ui/action/views/swap/libs/bitcoin-gasvals.ts @@ -18,7 +18,7 @@ export const getBitcoinGasVals = async ( ); return getGasCostValues( network as BitcoinNetwork, - Math.ceil(txSize.txVBytes), + Math.ceil(txSize), price.toString(), network.decimals, network.currencyName From ef5c830490bf342074a61887448ee47520ed514f Mon Sep 17 00:00:00 2001 From: kvhnuke <10602065+kvhnuke@users.noreply.github.com> Date: Tue, 26 Sep 2023 15:00:41 -0700 Subject: [PATCH 10/12] fix: ui bugs and switch btc nodes --- .../bitcoin/networks/bitcoin-testnet.ts | 2 +- .../src/providers/bitcoin/networks/bitcoin.ts | 2 +- .../components/send-alert.vue | 72 +++++++++++++++++++ .../bitcoin/ui/send-transaction/index.vue | 2 +- .../common/ui/send-transaction/send-alert.vue | 6 +- .../libs/assets-handlers/assetinfo-mew.ts | 4 ++ .../libs/assets-handlers/token-lists.ts | 21 +++--- .../assets-handlers/types/tokenbalance-mew.ts | 1 + .../src/providers/ethereum/networks/shib.ts | 2 + packages/types/src/networks.ts | 2 +- 10 files changed, 96 insertions(+), 18 deletions(-) create mode 100644 packages/extension/src/providers/bitcoin/ui/send-transaction/components/send-alert.vue diff --git a/packages/extension/src/providers/bitcoin/networks/bitcoin-testnet.ts b/packages/extension/src/providers/bitcoin/networks/bitcoin-testnet.ts index 7193f9c83..fe2c96906 100644 --- a/packages/extension/src/providers/bitcoin/networks/bitcoin-testnet.ts +++ b/packages/extension/src/providers/bitcoin/networks/bitcoin-testnet.ts @@ -22,7 +22,7 @@ const bitcoinOptions: BitcoinNetworkOptions = { icon: require("./icons/tbtc.svg"), decimals: 8, dust: 0.00000546, - node: "https://api.blockchain.info/haskoin-store/btc-testnet/", + node: "https://partners.mewapi.io/nodes/hk/btct/", activityHandler: wrapActivityHandler(haskoinHandler), basePath: "m/49'/1'/0'/0", coingeckoID: "bitcoin", diff --git a/packages/extension/src/providers/bitcoin/networks/bitcoin.ts b/packages/extension/src/providers/bitcoin/networks/bitcoin.ts index f08a76e91..8e17d7db0 100644 --- a/packages/extension/src/providers/bitcoin/networks/bitcoin.ts +++ b/packages/extension/src/providers/bitcoin/networks/bitcoin.ts @@ -20,7 +20,7 @@ const bitcoinOptions: BitcoinNetworkOptions = { currencyNameLong: "Bitcoin", icon: require("./icons/btc.svg"), decimals: 8, - node: "https://api.blockchain.info/haskoin-store/btc/", + node: "https://partners.mewapi.io/nodes/hk/btc/", coingeckoID: "bitcoin", activityHandler: wrapActivityHandler(haskoinHandler), basePath: "m/49'/0'/0'/0", diff --git a/packages/extension/src/providers/bitcoin/ui/send-transaction/components/send-alert.vue b/packages/extension/src/providers/bitcoin/ui/send-transaction/components/send-alert.vue new file mode 100644 index 000000000..9f33862f8 --- /dev/null +++ b/packages/extension/src/providers/bitcoin/ui/send-transaction/components/send-alert.vue @@ -0,0 +1,72 @@ + + + + + diff --git a/packages/extension/src/providers/bitcoin/ui/send-transaction/index.vue b/packages/extension/src/providers/bitcoin/ui/send-transaction/index.vue index 6d5e72fd8..b30e0dc2d 100644 --- a/packages/extension/src/providers/bitcoin/ui/send-transaction/index.vue +++ b/packages/extension/src/providers/bitcoin/ui/send-transaction/index.vue @@ -111,7 +111,7 @@ import SendAddressInput from "./components/send-address-input.vue"; import SendFromContactsList from "@/providers/common/ui/send-transaction/send-from-contacts-list.vue"; import SendContactsList from "@/providers/common/ui/send-transaction/send-contacts-list.vue"; import SendTokenSelect from "./components/send-token-select.vue"; -import SendAlert from "@/providers/common/ui/send-transaction/send-alert.vue"; +import SendAlert from "@/providers/bitcoin/ui/send-transaction/components/send-alert.vue"; import SendInputAmount from "@/providers/common/ui/send-transaction/send-input-amount.vue"; import SendFeeSelect from "@/providers/common/ui/send-transaction/send-fee-select.vue"; import TransactionFeeView from "@action/views/transaction-fee/index.vue"; diff --git a/packages/extension/src/providers/common/ui/send-transaction/send-alert.vue b/packages/extension/src/providers/common/ui/send-transaction/send-alert.vue index 5c223ca3b..f115c963b 100644 --- a/packages/extension/src/providers/common/ui/send-transaction/send-alert.vue +++ b/packages/extension/src/providers/common/ui/send-transaction/send-alert.vue @@ -1,7 +1,7 @@ @@ -22,9 +21,6 @@ interface IProps { nativeSymbol: string; nativeValue: string; price?: string; - notEnough: boolean; - belowDust: boolean; - dust: string; } const props = defineProps(); diff --git a/packages/extension/src/providers/ethereum/libs/assets-handlers/assetinfo-mew.ts b/packages/extension/src/providers/ethereum/libs/assets-handlers/assetinfo-mew.ts index 4281a89a0..5eb13ce91 100644 --- a/packages/extension/src/providers/ethereum/libs/assets-handlers/assetinfo-mew.ts +++ b/packages/extension/src/providers/ethereum/libs/assets-handlers/assetinfo-mew.ts @@ -111,6 +111,10 @@ const supportedNetworks: Record = { tbName: "", cgPlatform: CoingeckoPlatform.TomoChain, }, + [NetworkNames.Shibarium]: { + tbName: "shib", + cgPlatform: CoingeckoPlatform.Shibarium, + }, }; const getTokens = ( diff --git a/packages/extension/src/providers/ethereum/libs/assets-handlers/token-lists.ts b/packages/extension/src/providers/ethereum/libs/assets-handlers/token-lists.ts index 49da949bd..b3dd20211 100644 --- a/packages/extension/src/providers/ethereum/libs/assets-handlers/token-lists.ts +++ b/packages/extension/src/providers/ethereum/libs/assets-handlers/token-lists.ts @@ -24,6 +24,7 @@ const TokenList: Record = { [NetworkNames.Aurora]: `https://tokens.coingecko.com/${CoingeckoPlatform.Aurora}/all.json`, [NetworkNames.Celo]: `https://tokens.coingecko.com/${CoingeckoPlatform.Celo}/all.json`, [NetworkNames.TomoChain]: `https://tokens.coingecko.com/${CoingeckoPlatform.TomoChain}/all.json`, + [NetworkNames.Shibarium]: `https://tokens.coingecko.com/${CoingeckoPlatform.Shibarium}/all.json`, }; const getKnownNetworkTokens = async ( @@ -35,14 +36,16 @@ const getKnownNetworkTokens = async ( url: TokenList[networkName as SupportedNetworkNames], }, TOKEN_FETCH_TTL - ).then((json) => { - const tokens: CGToken[] = json.tokens; - const tObject: Record = {}; - tokens.forEach((t) => { - t.address = t.address.toLowerCase(); - tObject[t.address] = t; - }); - return tObject; - }); + ) + .then((json) => { + const tokens: CGToken[] = json.tokens; + const tObject: Record = {}; + tokens.forEach((t) => { + t.address = t.address.toLowerCase(); + tObject[t.address] = t; + }); + return tObject; + }) + .catch(() => ({})); }; export { TokenList, getKnownNetworkTokens }; diff --git a/packages/extension/src/providers/ethereum/libs/assets-handlers/types/tokenbalance-mew.ts b/packages/extension/src/providers/ethereum/libs/assets-handlers/types/tokenbalance-mew.ts index 542e91097..5271ae82c 100644 --- a/packages/extension/src/providers/ethereum/libs/assets-handlers/types/tokenbalance-mew.ts +++ b/packages/extension/src/providers/ethereum/libs/assets-handlers/types/tokenbalance-mew.ts @@ -44,6 +44,7 @@ export type SupportedNetworkNames = | NetworkNames.Klaytn | NetworkNames.Aurora | NetworkNames.TomoChain + | NetworkNames.Shibarium | NetworkNames.MaticZK | NetworkNames.Celo | NetworkNames.ZkSync; diff --git a/packages/extension/src/providers/ethereum/networks/shib.ts b/packages/extension/src/providers/ethereum/networks/shib.ts index 2d4b71f52..0c2e0f432 100644 --- a/packages/extension/src/providers/ethereum/networks/shib.ts +++ b/packages/extension/src/providers/ethereum/networks/shib.ts @@ -2,6 +2,7 @@ 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"; +import assetsInfoHandler from "@/providers/ethereum/libs/assets-handlers/assetinfo-mew"; const shibOptions: EvmNetworkOptions = { name: NetworkNames.Shibarium, @@ -16,6 +17,7 @@ const shibOptions: EvmNetworkOptions = { node: "https://www.shibrpc.com", icon: require("./icons/shiba-inu.svg"), coingeckoID: "bone-shibaswap", + assetsInfoHandler, activityHandler: wrapActivityHandler(EtherscanActivity), }; diff --git a/packages/types/src/networks.ts b/packages/types/src/networks.ts index d0001f07d..2e30e99b2 100644 --- a/packages/types/src/networks.ts +++ b/packages/types/src/networks.ts @@ -90,7 +90,7 @@ export enum CoingeckoPlatform { Arbitrum = "arbitrum-one", Gnosis = "xdai", Avalanche = "avalanche", - Fantom = "avalanche", + Fantom = "fantom", Klaytn = "klay-token", Aurora = "aurora", Zksync = "zksync", From ae67a47adf78561ad344f7edaf32c2b6cfdd3cbd Mon Sep 17 00:00:00 2001 From: kvhnuke <10602065+kvhnuke@users.noreply.github.com> Date: Wed, 27 Sep 2023 12:30:04 -0700 Subject: [PATCH 11/12] fix: swap identicon --- .../src/ui/action/views/swap/components/send-address-item.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/extension/src/ui/action/views/swap/components/send-address-item.vue b/packages/extension/src/ui/action/views/swap/components/send-address-item.vue index ad3d88621..0968fab32 100644 --- a/packages/extension/src/ui/action/views/swap/components/send-address-item.vue +++ b/packages/extension/src/ui/action/views/swap/components/send-address-item.vue @@ -4,7 +4,7 @@ @click="emit('selected:account', account.address)" >
- +

{{ account.name }}

From 2ce957b066c8387191458ff8d9237de686b3b0eb Mon Sep 17 00:00:00 2001 From: kvhnuke <10602065+kvhnuke@users.noreply.github.com> Date: Thu, 28 Sep 2023 11:39:22 -0700 Subject: [PATCH 12/12] fix: swap identicon --- .../views/swap/components/send-address-input.vue | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/extension/src/ui/action/views/swap/components/send-address-input.vue b/packages/extension/src/ui/action/views/swap/components/send-address-input.vue index d065b1d44..818fcdb7f 100644 --- a/packages/extension/src/ui/action/views/swap/components/send-address-input.vue +++ b/packages/extension/src/ui/action/views/swap/components/send-address-input.vue @@ -1,7 +1,7 @@