From c197ede71019e9cc6b12a27a26c13375fce4a24f Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Mon, 21 Oct 2024 18:11:10 +0200 Subject: [PATCH] feat: eip-6963 support (#689) --- examples/sandbox/index.html | 2 - examples/sandbox/index.ts | 42 +- examples/sandbox/package.json | 38 +- integration/package.json | 20 +- integration/src/bitcoin/bitcoin.ts | 52 ++- integration/src/bitcoin/litecoin.ts | 19 +- integration/src/bitcoin/testnet.ts | 5 + integration/src/cosmos/cosmos.ts | 9 + integration/src/ethereum/ethereum.ts | 2 +- integration/src/integration.ts | 6 +- integration/src/thorchain/thorchain.ts | 13 + integration/src/wallets/metamask.ts | 67 +-- integration/src/wallets/tallyho.ts | 171 -------- integration/src/wallets/xdefi.ts | 151 ------- integration/src/xdefi.test.ts | 3 - lerna.json | 2 +- packages/hdwallet-coinbase/package.json | 4 +- packages/hdwallet-core/package.json | 2 +- packages/hdwallet-core/src/bitcoin.ts | 6 - .../hdwallet-keepkey-chromeusb/package.json | 6 +- .../hdwallet-keepkey-electron/package.json | 4 +- .../hdwallet-keepkey-nodehid/package.json | 4 +- .../hdwallet-keepkey-nodewebusb/package.json | 6 +- packages/hdwallet-keepkey-tcp/package.json | 6 +- packages/hdwallet-keepkey-webusb/package.json | 6 +- packages/hdwallet-keepkey/package.json | 4 +- packages/hdwallet-keepkey/src/bitcoin.ts | 46 --- packages/hdwallet-keepkey/src/keepkey.ts | 13 - packages/hdwallet-keplr/package.json | 4 +- packages/hdwallet-ledger-webhid/package.json | 6 +- packages/hdwallet-ledger-webusb/package.json | 6 +- packages/hdwallet-ledger/package.json | 4 +- packages/hdwallet-ledger/src/bitcoin.ts | 6 - packages/hdwallet-ledger/src/ledger.ts | 4 - .../package.json | 13 +- .../src/adapter.ts | 61 +++ .../src/bitcoin.ts | 0 .../src/bitcoincash.ts | 0 .../src/common.ts | 0 .../src/cosmos.ts | 0 .../src/dogecoin.ts | 0 .../src/ethereum.ts | 0 .../src/index.ts | 0 .../src/litecoin.ts | 0 .../src/shapeshift-multichain.test.ts | 19 +- .../src/shapeshift-multichain.ts | 49 ++- .../src/thorchain.ts | 0 .../src/utxo.ts | 0 .../tsconfig.json | 0 .../src/adapter.ts | 135 ------ packages/hdwallet-metamask/package.json | 26 -- packages/hdwallet-metamask/src/adapter.ts | 56 --- packages/hdwallet-metamask/src/ethereum.ts | 133 ------ packages/hdwallet-metamask/src/index.ts | 2 - .../hdwallet-metamask/src/metamask.test.ts | 168 -------- packages/hdwallet-metamask/src/metamask.ts | 389 ------------------ packages/hdwallet-metamask/tsconfig.json | 10 - packages/hdwallet-native-vault/package.json | 4 +- packages/hdwallet-native/package.json | 4 +- packages/hdwallet-native/src/bitcoin.test.ts | 4 - packages/hdwallet-native/src/bitcoin.ts | 6 - packages/hdwallet-native/src/native.ts | 1 - packages/hdwallet-phantom/package.json | 4 +- packages/hdwallet-phantom/src/phantom.ts | 5 - packages/hdwallet-portis/package.json | 4 +- packages/hdwallet-portis/src/portis.ts | 10 - packages/hdwallet-tallyho/package.json | 24 -- packages/hdwallet-tallyho/src/adapter.test.ts | 11 - packages/hdwallet-tallyho/src/adapter.ts | 102 ----- .../hdwallet-tallyho/src/ethereum.test.ts | 246 ----------- packages/hdwallet-tallyho/src/ethereum.ts | 132 ------ packages/hdwallet-tallyho/src/index.test.ts | 11 - packages/hdwallet-tallyho/src/index.ts | 2 - packages/hdwallet-tallyho/src/tallyho.test.ts | 203 --------- packages/hdwallet-tallyho/src/tallyho.ts | 315 -------------- packages/hdwallet-tallyho/tsconfig.json | 10 - packages/hdwallet-trezor-connect/package.json | 6 +- packages/hdwallet-trezor/package.json | 4 +- packages/hdwallet-trezor/src/bitcoin.ts | 6 - packages/hdwallet-trezor/src/trezor.ts | 8 - packages/hdwallet-walletconnect/package.json | 4 +- .../hdwallet-walletconnectV2/package.json | 4 +- packages/hdwallet-xdefi/package.json | 23 -- packages/hdwallet-xdefi/src/adapter.test.ts | 26 -- packages/hdwallet-xdefi/src/adapter.ts | 52 --- packages/hdwallet-xdefi/src/ethereum.test.ts | 255 ------------ packages/hdwallet-xdefi/src/ethereum.ts | 104 ----- packages/hdwallet-xdefi/src/index.test.ts | 11 - packages/hdwallet-xdefi/src/index.ts | 2 - packages/hdwallet-xdefi/src/xdefi.test.ts | 211 ---------- packages/hdwallet-xdefi/src/xdefi.ts | 329 --------------- packages/hdwallet-xdefi/tsconfig.json | 10 - tsconfig.json | 7 +- yarn.lock | 52 +-- 94 files changed, 299 insertions(+), 3713 deletions(-) delete mode 100644 integration/src/wallets/tallyho.ts delete mode 100644 integration/src/wallets/xdefi.ts delete mode 100644 integration/src/xdefi.test.ts rename packages/{hdwallet-metamask-shapeshift-multichain => hdwallet-metamask-multichain}/package.json (67%) create mode 100644 packages/hdwallet-metamask-multichain/src/adapter.ts rename packages/{hdwallet-metamask-shapeshift-multichain => hdwallet-metamask-multichain}/src/bitcoin.ts (100%) rename packages/{hdwallet-metamask-shapeshift-multichain => hdwallet-metamask-multichain}/src/bitcoincash.ts (100%) rename packages/{hdwallet-metamask-shapeshift-multichain => hdwallet-metamask-multichain}/src/common.ts (100%) rename packages/{hdwallet-metamask-shapeshift-multichain => hdwallet-metamask-multichain}/src/cosmos.ts (100%) rename packages/{hdwallet-metamask-shapeshift-multichain => hdwallet-metamask-multichain}/src/dogecoin.ts (100%) rename packages/{hdwallet-metamask-shapeshift-multichain => hdwallet-metamask-multichain}/src/ethereum.ts (100%) rename packages/{hdwallet-metamask-shapeshift-multichain => hdwallet-metamask-multichain}/src/index.ts (100%) rename packages/{hdwallet-metamask-shapeshift-multichain => hdwallet-metamask-multichain}/src/litecoin.ts (100%) rename packages/{hdwallet-metamask-shapeshift-multichain => hdwallet-metamask-multichain}/src/shapeshift-multichain.test.ts (91%) rename packages/{hdwallet-metamask-shapeshift-multichain => hdwallet-metamask-multichain}/src/shapeshift-multichain.ts (95%) rename packages/{hdwallet-metamask-shapeshift-multichain => hdwallet-metamask-multichain}/src/thorchain.ts (100%) rename packages/{hdwallet-metamask-shapeshift-multichain => hdwallet-metamask-multichain}/src/utxo.ts (100%) rename packages/{hdwallet-metamask-shapeshift-multichain => hdwallet-metamask-multichain}/tsconfig.json (100%) delete mode 100644 packages/hdwallet-metamask-shapeshift-multichain/src/adapter.ts delete mode 100644 packages/hdwallet-metamask/package.json delete mode 100644 packages/hdwallet-metamask/src/adapter.ts delete mode 100644 packages/hdwallet-metamask/src/ethereum.ts delete mode 100644 packages/hdwallet-metamask/src/index.ts delete mode 100644 packages/hdwallet-metamask/src/metamask.test.ts delete mode 100644 packages/hdwallet-metamask/src/metamask.ts delete mode 100644 packages/hdwallet-metamask/tsconfig.json delete mode 100644 packages/hdwallet-tallyho/package.json delete mode 100644 packages/hdwallet-tallyho/src/adapter.test.ts delete mode 100644 packages/hdwallet-tallyho/src/adapter.ts delete mode 100644 packages/hdwallet-tallyho/src/ethereum.test.ts delete mode 100644 packages/hdwallet-tallyho/src/ethereum.ts delete mode 100644 packages/hdwallet-tallyho/src/index.test.ts delete mode 100644 packages/hdwallet-tallyho/src/index.ts delete mode 100644 packages/hdwallet-tallyho/src/tallyho.test.ts delete mode 100644 packages/hdwallet-tallyho/src/tallyho.ts delete mode 100644 packages/hdwallet-tallyho/tsconfig.json delete mode 100644 packages/hdwallet-xdefi/package.json delete mode 100644 packages/hdwallet-xdefi/src/adapter.test.ts delete mode 100644 packages/hdwallet-xdefi/src/adapter.ts delete mode 100644 packages/hdwallet-xdefi/src/ethereum.test.ts delete mode 100644 packages/hdwallet-xdefi/src/ethereum.ts delete mode 100644 packages/hdwallet-xdefi/src/index.test.ts delete mode 100644 packages/hdwallet-xdefi/src/index.ts delete mode 100644 packages/hdwallet-xdefi/src/xdefi.test.ts delete mode 100644 packages/hdwallet-xdefi/src/xdefi.ts delete mode 100644 packages/hdwallet-xdefi/tsconfig.json diff --git a/examples/sandbox/index.html b/examples/sandbox/index.html index ca67657d3..af3f7d84b 100644 --- a/examples/sandbox/index.html +++ b/examples/sandbox/index.html @@ -117,9 +117,7 @@

Select

- - diff --git a/examples/sandbox/index.ts b/examples/sandbox/index.ts index 27fb843e3..afdb9be9f 100644 --- a/examples/sandbox/index.ts +++ b/examples/sandbox/index.ts @@ -9,16 +9,14 @@ import * as keepkeyWebUSB from "@shapeshiftoss/hdwallet-keepkey-webusb"; import * as keplr from "@shapeshiftoss/hdwallet-keplr"; import * as ledgerWebHID from "@shapeshiftoss/hdwallet-ledger-webhid"; import * as ledgerWebUSB from "@shapeshiftoss/hdwallet-ledger-webusb"; -import * as metaMask from "@shapeshiftoss/hdwallet-metamask"; +import * as metaMask from "@shapeshiftoss/hdwallet-metamask-multichain"; import * as native from "@shapeshiftoss/hdwallet-native"; import * as phantom from "@shapeshiftoss/hdwallet-phantom"; import * as portis from "@shapeshiftoss/hdwallet-portis"; -import * as tallyHo from "@shapeshiftoss/hdwallet-tallyho"; import * as trezorConnect from "@shapeshiftoss/hdwallet-trezor-connect"; import { WalletConnectProviderConfig } from "@shapeshiftoss/hdwallet-walletconnect"; import * as walletConnect from "@shapeshiftoss/hdwallet-walletconnect"; import * as walletConnectv2 from "@shapeshiftoss/hdwallet-walletconnectv2"; -import * as xdefi from "@shapeshiftoss/hdwallet-xdefi"; import { EthereumProviderOptions } from "@walletconnect/ethereum-provider/dist/types/EthereumProvider"; import { TypedData } from "eip-712"; import $, { noop } from "jquery"; @@ -126,12 +124,10 @@ const keepkeyAdapter = keepkeyWebUSB.WebUSBKeepKeyAdapter.useKeyring(keyring); const kkbridgeAdapter = keepkeyTcp.TCPKeepKeyAdapter.useKeyring(keyring); const kkemuAdapter = keepkeyTcp.TCPKeepKeyAdapter.useKeyring(keyring); const portisAdapter = portis.PortisAdapter.useKeyring(keyring, { portisAppId }); -const metaMaskAdapter = metaMask.MetaMaskAdapter.useKeyring(keyring); +const metaMaskAdapter = metaMask.MetaMaskAdapter.useKeyring(keyring, "io.metamask"); const phantomAdapter = phantom.PhantomAdapter.useKeyring(keyring); -const tallyHoAdapter = tallyHo.TallyHoAdapter.useKeyring(keyring); const walletConnectAdapter = walletConnect.WalletConnectAdapter.useKeyring(keyring, walletConnectOptions); const walletConnectV2Adapter = walletConnectv2.WalletConnectV2Adapter.useKeyring(keyring, walletConnectV2Options); -const xdefiAdapter = xdefi.XDEFIAdapter.useKeyring(keyring); const keplrAdapter = keplr.KeplrAdapter.useKeyring(keyring); const nativeAdapter = native.NativeAdapter.useKeyring(keyring); const trezorAdapter = trezorConnect.TrezorAdapter.useKeyring(keyring, { @@ -162,10 +158,8 @@ const $native = $("#native"); const $metaMask = $("#metaMask"); const $phantom = $("#phantom"); const $coinbase = $("#coinbase"); -const $tallyHo = $("#tallyHo"); const $walletConnect = $("#walletConnect"); const $walletConnectV2 = $("#walletConnectV2"); -const $xdefi = $("#xdefi"); const $keplr = $("#keplr"); const $keyring = $("#keyring"); @@ -284,19 +278,6 @@ $keplr.on("click", async (e) => { } }); -$tallyHo.on("click", async (e) => { - e.preventDefault(); - wallet = await tallyHoAdapter.pairDevice(); - window["wallet"] = wallet; - let deviceID = "nothing"; - try { - deviceID = await wallet.getDeviceID(); - $("#keyring select").val(deviceID); - } catch (error) { - console.error(error); - } -}); - $walletConnect.on("click", async (e) => { e.preventDefault(); try { @@ -323,19 +304,6 @@ $walletConnectV2.on("click", async (e) => { } }); -$xdefi.on("click", async (e) => { - e.preventDefault(); - wallet = await xdefiAdapter.pairDevice(); - window["wallet"] = wallet; - let deviceID = "nothing"; - try { - deviceID = await wallet.getDeviceID(); - $("#keyring select").val(deviceID); - } catch (error) { - console.error(error); - } -}); - async function deviceConnected(deviceId) { wallet = keyring.get(deviceId); if (!$keyring.find(`option[value="${deviceId}"]`).length) { @@ -426,12 +394,6 @@ async function deviceConnected(deviceId) { console.error("Could not initialize PhantomAdapter", e); } - try { - await tallyHoAdapter.initialize(); - } catch (e) { - console.error("Could not initialize TallyHoAdapter", e); - } - try { await keplrAdapter.initialize(); } catch (e) { diff --git a/examples/sandbox/package.json b/examples/sandbox/package.json index db9677a64..1b2d6f3b0 100644 --- a/examples/sandbox/package.json +++ b/examples/sandbox/package.json @@ -1,6 +1,6 @@ { "name": "@shapeshiftoss/hdwallet-sandbox", - "version": "1.55.10", + "version": "1.55.11", "license": "MIT", "private": true, "browserslist": "> 0.5%, last 2 versions, not dead", @@ -12,25 +12,23 @@ "dependencies": { "@esm2cjs/p-queue": "^7.3.0", "@metamask/eth-sig-util": "^7.0.0", - "@shapeshiftoss/hdwallet-coinbase": "1.55.10", - "@shapeshiftoss/hdwallet-core": "1.55.10", - "@shapeshiftoss/hdwallet-keepkey": "1.55.10", - "@shapeshiftoss/hdwallet-keepkey-tcp": "1.55.10", - "@shapeshiftoss/hdwallet-keepkey-webusb": "1.55.10", - "@shapeshiftoss/hdwallet-keplr": "1.55.10", - "@shapeshiftoss/hdwallet-ledger": "1.55.10", - "@shapeshiftoss/hdwallet-ledger-webhid": "1.55.10", - "@shapeshiftoss/hdwallet-ledger-webusb": "1.55.10", - "@shapeshiftoss/hdwallet-metamask": "1.55.10", - "@shapeshiftoss/hdwallet-native": "1.55.10", - "@shapeshiftoss/hdwallet-phantom": "1.55.10", - "@shapeshiftoss/hdwallet-portis": "1.55.10", - "@shapeshiftoss/hdwallet-tallyho": "1.55.10", - "@shapeshiftoss/hdwallet-trezor": "1.55.10", - "@shapeshiftoss/hdwallet-trezor-connect": "1.55.10", - "@shapeshiftoss/hdwallet-walletconnect": "1.55.10", - "@shapeshiftoss/hdwallet-walletconnectv2": "1.55.10", - "@shapeshiftoss/hdwallet-xdefi": "1.55.10", + "@shapeshiftoss/hdwallet-coinbase": "1.55.11", + "@shapeshiftoss/hdwallet-core": "1.55.11", + "@shapeshiftoss/hdwallet-keepkey": "1.55.11", + "@shapeshiftoss/hdwallet-keepkey-tcp": "1.55.11", + "@shapeshiftoss/hdwallet-keepkey-webusb": "1.55.11", + "@shapeshiftoss/hdwallet-keplr": "1.55.11", + "@shapeshiftoss/hdwallet-ledger": "1.55.11", + "@shapeshiftoss/hdwallet-ledger-webhid": "1.55.11", + "@shapeshiftoss/hdwallet-ledger-webusb": "1.55.11", + "@shapeshiftoss/hdwallet-metamask-multichain": "1.55.11", + "@shapeshiftoss/hdwallet-native": "1.55.11", + "@shapeshiftoss/hdwallet-phantom": "1.55.11", + "@shapeshiftoss/hdwallet-portis": "1.55.11", + "@shapeshiftoss/hdwallet-trezor": "1.55.11", + "@shapeshiftoss/hdwallet-trezor-connect": "1.55.11", + "@shapeshiftoss/hdwallet-walletconnect": "1.55.11", + "@shapeshiftoss/hdwallet-walletconnectv2": "1.55.11", "bip32": "^2.0.4", "eip-712": "^1.0.0", "jquery": "^3.7.1", diff --git a/integration/package.json b/integration/package.json index 3c932107f..2e9884cfb 100644 --- a/integration/package.json +++ b/integration/package.json @@ -1,6 +1,6 @@ { "name": "@shapeshiftoss/integration", - "version": "1.55.10", + "version": "1.55.11", "main": "index.js", "license": "MIT", "private": true, @@ -10,15 +10,15 @@ "dev": "lerna run test --scope integration --parallel --include-filtered-dependencies" }, "dependencies": { - "@shapeshiftoss/hdwallet-core": "1.55.10", - "@shapeshiftoss/hdwallet-keepkey": "1.55.10", - "@shapeshiftoss/hdwallet-keepkey-nodewebusb": "1.55.10", - "@shapeshiftoss/hdwallet-keepkey-tcp": "1.55.10", - "@shapeshiftoss/hdwallet-ledger": "1.55.10", - "@shapeshiftoss/hdwallet-native": "1.55.10", - "@shapeshiftoss/hdwallet-portis": "1.55.10", - "@shapeshiftoss/hdwallet-trezor": "1.55.10", - "@shapeshiftoss/hdwallet-xdefi": "1.55.10", + "@shapeshiftoss/hdwallet-core": "1.55.11", + "@shapeshiftoss/hdwallet-keepkey": "1.55.11", + "@shapeshiftoss/hdwallet-keepkey-nodewebusb": "1.55.11", + "@shapeshiftoss/hdwallet-keepkey-tcp": "1.55.11", + "@shapeshiftoss/hdwallet-ledger": "1.55.11", + "@shapeshiftoss/hdwallet-metamask-multichain": "1.55.11", + "@shapeshiftoss/hdwallet-native": "1.55.11", + "@shapeshiftoss/hdwallet-portis": "1.55.11", + "@shapeshiftoss/hdwallet-trezor": "1.55.11", "fast-json-stable-stringify": "^2.1.0", "msw": "^0.27.1", "whatwg-fetch": "^3.6.2" diff --git a/integration/src/bitcoin/bitcoin.ts b/integration/src/bitcoin/bitcoin.ts index 32810133a..d67b5ea71 100644 --- a/integration/src/bitcoin/bitcoin.ts +++ b/integration/src/bitcoin/bitcoin.ts @@ -1,5 +1,6 @@ import * as core from "@shapeshiftoss/hdwallet-core"; import * as ledger from "@shapeshiftoss/hdwallet-ledger"; +import * as metamask from "@shapeshiftoss/hdwallet-metamask-multichain"; import * as native from "@shapeshiftoss/hdwallet-native"; import * as phantom from "@shapeshiftoss/hdwallet-phantom"; import * as portis from "@shapeshiftoss/hdwallet-portis"; @@ -62,6 +63,8 @@ export function bitcoinTests(get: () => { wallet: core.HDWallet; info: core.HDWa "btcSupportsCoin()", async () => { if (!wallet || portis.isPortis(wallet)) return; + // Non-EVM things are a pain to test with snaps on test env, this wasn't tested before and still isn't + if (metamask.isMetaMask(wallet)) return; expect(wallet.btcSupportsCoin("Bitcoin")).toBeTruthy(); expect(await info.btcSupportsCoin("Bitcoin")).toBeTruthy(); }, @@ -71,7 +74,7 @@ export function bitcoinTests(get: () => { wallet: core.HDWallet; info: core.HDWa test( "btcSupportsCoin() - Testnet", async () => { - if (!wallet || portis.isPortis(wallet) || phantom.isPhantom(wallet)) return; + if (!wallet || portis.isPortis(wallet) || phantom.isPhantom(wallet) || metamask.isMetaMask(wallet)) return; expect(wallet.btcSupportsCoin("Testnet")).toBeTruthy(); expect(await info.btcSupportsCoin("Testnet")).toBeTruthy(); }, @@ -88,6 +91,9 @@ export function bitcoinTests(get: () => { wallet: core.HDWallet; info: core.HDWa ) return; + // Non-EVM things are a pain to test with snaps on test env, this wasn't tested before and still isn't + if (metamask.isMetaMask(wallet)) return; + /* FIXME: Expected failure (trezor does not use scriptType in deriving public keys and ledger's dependency bitcoinjs-lib/src/crypto.js throws a mysterious TypeError in between mock transport calls. @@ -210,10 +216,14 @@ export function bitcoinTests(get: () => { wallet: core.HDWallet; info: core.HDWa const scriptType = args[3] as core.BTCInputScriptType; const expected = args[4] as string; + // Non-EVM things are a pain to test with snaps on test env, this wasn't tested before and still isn't + if (metamask.isMetaMask(wallet)) return; + if (!(await wallet.btcSupportsCoin(coin))) return; expect(await info.btcSupportsCoin(coin)).toBeTruthy(); if (!(await wallet.btcSupportsScriptType(coin, scriptType))) return; expect(await info.btcSupportsScriptType(coin, scriptType)).toBeTruthy(); + const res = await wallet.btcGetAddress({ addressNList: core.bip32ToAddressNList(path), coin: coin, @@ -230,7 +240,7 @@ export function bitcoinTests(get: () => { wallet: core.HDWallet; info: core.HDWa test( "btcSignTx() - p2pkh", async () => { - if (!wallet || portis.isPortis(wallet) || phantom.isPhantom(wallet)) return; + if (!wallet || portis.isPortis(wallet) || phantom.isPhantom(wallet) || metamask.isMetaMask(wallet)) return; if (ledger.isLedger(wallet)) return; // FIXME: Expected failure const tx: core.BitcoinTx = { version: 1, @@ -305,7 +315,7 @@ export function bitcoinTests(get: () => { wallet: core.HDWallet; info: core.HDWa test( "btcSignTx() - thorchain swap", async () => { - if (!wallet || portis.isPortis(wallet) || phantom.isPhantom(wallet)) return; + if (!wallet || portis.isPortis(wallet) || phantom.isPhantom(wallet) || metamask.isMetaMask(wallet)) return; if (ledger.isLedger(wallet)) return; // FIXME: Expected failure if (trezor.isTrezor(wallet)) return; //TODO: Add trezor support for op return data passed at top level const tx: core.BitcoinTx = { @@ -391,6 +401,8 @@ export function bitcoinTests(get: () => { wallet: core.HDWallet; info: core.HDWa "btcSignMessage()", async () => { if (!wallet) return; + // Non-EVM things are a pain to test with snaps on test env, this wasn't tested before and still isn't + if (metamask.isMetaMask(wallet)) return; // not implemented for native if (native.isNative(wallet)) { @@ -424,6 +436,8 @@ export function bitcoinTests(get: () => { wallet: core.HDWallet; info: core.HDWa "btcVerifyMessage() - good", async () => { if (!wallet) return; + // Non-EVM things are a pain to test with snaps on test env, this wasn't tested before and still isn't + if (metamask.isMetaMask(wallet)) return; // not implemented for native if (native.isNative(wallet)) { @@ -447,6 +461,8 @@ export function bitcoinTests(get: () => { wallet: core.HDWallet; info: core.HDWa "btcVerifyMessage() - bad", async () => { if (!wallet) return; + // Non-EVM things are a pain to test with snaps on test env, this wasn't tested before and still isn't + if (metamask.isMetaMask(wallet)) return; // not implemented for native if (native.isNative(wallet)) { @@ -470,6 +486,8 @@ export function bitcoinTests(get: () => { wallet: core.HDWallet; info: core.HDWa "btcSupportsSecureTransfer()", async () => { if (!wallet) return; + // Non-EVM things are a pain to test with snaps on test env, this wasn't tested before and still isn't + if (metamask.isMetaMask(wallet)) return; expect(typeof (await wallet.btcSupportsSecureTransfer()) === typeof true).toBeTruthy(); if (await wallet.btcSupportsSecureTransfer()) { // eslint-disable-next-line jest/no-conditional-expect @@ -484,6 +502,8 @@ export function bitcoinTests(get: () => { wallet: core.HDWallet; info: core.HDWa "btcSupportsNativeShapeShift()", async () => { if (!wallet) return; + // Non-EVM things are a pain to test with snaps on test env, this wasn't tested before and still isn't + if (metamask.isMetaMask(wallet)) return; expect(typeof wallet.btcSupportsNativeShapeShift()).toBe("boolean"); if (wallet.btcSupportsNativeShapeShift()) { // eslint-disable-next-line jest/no-conditional-expect @@ -515,6 +535,8 @@ export function bitcoinTests(get: () => { wallet: core.HDWallet; info: core.HDWa const accountIdx = args[1] as number; const scriptType = args[2] as core.BTCInputScriptType; if (!wallet) return; + // Non-EVM things are a pain to test with snaps on test env, this wasn't tested before and still isn't + if (metamask.isMetaMask(wallet)) return; if (!(await wallet.btcSupportsCoin(coin))) return; expect(await info.btcSupportsCoin(coin)).toBeTruthy(); if (!(await wallet.btcSupportsScriptType(coin, scriptType))) return; @@ -537,29 +559,5 @@ export function bitcoinTests(get: () => { wallet: core.HDWallet; info: core.HDWa }, TIMEOUT ); - - test( - "btcIsSameAccount()", - async () => { - if (!wallet || phantom.isPhantom(wallet)) return; - [0, 1, 9].forEach((idx) => { - const paths = wallet.btcGetAccountPaths({ - coin: "Bitcoin", - accountIdx: idx, - }); - expect(typeof wallet.btcIsSameAccount(paths) === typeof true).toBeTruthy(); - paths.forEach((path) => { - if (wallet.getVendor() === "Portis") { - // eslint-disable-next-line jest/no-conditional-expect - expect(wallet.btcNextAccountPath(path)).toBeUndefined(); - } else { - // eslint-disable-next-line jest/no-conditional-expect - expect(wallet.btcNextAccountPath(path)).not.toBeUndefined(); - } - }); - }); - }, - TIMEOUT - ); }); } diff --git a/integration/src/bitcoin/litecoin.ts b/integration/src/bitcoin/litecoin.ts index 405f77c44..19a80ece0 100644 --- a/integration/src/bitcoin/litecoin.ts +++ b/integration/src/bitcoin/litecoin.ts @@ -1,4 +1,5 @@ import * as core from "@shapeshiftoss/hdwallet-core"; +import * as metamask from "@shapeshiftoss/hdwallet-metamask-multichain"; import { each } from "../utils"; @@ -32,6 +33,8 @@ export function litecoinTests(get: () => { wallet: core.HDWallet; info: core.HDW "btcGetAddress()", async () => { if (!wallet) return; + // Non-EVM things are a pain to test with snaps on test env, this wasn't tested before and still isn't + if (metamask.isMetaMask(wallet)) return; if (!(await wallet.btcSupportsCoin("Litecoin"))) return; await each( [ @@ -105,21 +108,5 @@ export function litecoinTests(get: () => { wallet: core.HDWallet; info: core.HDW }, TIMEOUT ); - - test( - "btcIsSameAccount()", - async () => { - if (!wallet) return; - if (!(await wallet.btcSupportsCoin("Litecoin"))) return; - [0, 1, 9].forEach((idx) => { - const paths = wallet.btcGetAccountPaths({ - coin: "Litecoin", - accountIdx: idx, - }); - expect(typeof wallet.btcIsSameAccount(paths) === typeof true).toBeTruthy(); - }); - }, - TIMEOUT - ); }); } diff --git a/integration/src/bitcoin/testnet.ts b/integration/src/bitcoin/testnet.ts index 2c1a8d658..4e21a2d9b 100644 --- a/integration/src/bitcoin/testnet.ts +++ b/integration/src/bitcoin/testnet.ts @@ -1,5 +1,6 @@ import * as core from "@shapeshiftoss/hdwallet-core"; import * as ledger from "@shapeshiftoss/hdwallet-ledger"; +import * as metamask from "@shapeshiftoss/hdwallet-metamask-multichain"; import * as portis from "@shapeshiftoss/hdwallet-portis"; const MNEMONIC12_ALLALL = "all all all all all all all all all all all all"; @@ -32,6 +33,8 @@ export function testnetTests(get: () => { wallet: core.HDWallet; info: core.HDWa "btcSignTx() - p2sh-p2wpkh", async () => { if (!wallet || portis.isPortis(wallet)) return; + // Non-EVM things are a pain to test with snaps on test env, this wasn't tested before and still isn't + if (metamask.isMetaMask(wallet)) return; if (ledger.isLedger(wallet)) return; // FIXME: Expected failure if (!(await wallet.btcSupportsCoin("Testnet"))) return; const inputs: core.BTCSignTxInputUnguarded[] = [ @@ -75,6 +78,8 @@ export function testnetTests(get: () => { wallet: core.HDWallet; info: core.HDWa test("btcSignTx() - p2wpkh", async () => { if (!wallet || portis.isPortis(wallet)) return; + // Non-EVM things are a pain to test with snaps on test env, this wasn't tested before and still isn't + if (metamask.isMetaMask(wallet)) return; if (ledger.isLedger(wallet)) return; // FIXME: Expected failure if (!(await wallet.btcSupportsCoin("Testnet"))) return; const tx: core.BitcoinTx = { diff --git a/integration/src/cosmos/cosmos.ts b/integration/src/cosmos/cosmos.ts index b9731e65e..a59aa7ca0 100644 --- a/integration/src/cosmos/cosmos.ts +++ b/integration/src/cosmos/cosmos.ts @@ -1,6 +1,7 @@ import * as core from "@shapeshiftoss/hdwallet-core"; import * as keepkey from "@shapeshiftoss/hdwallet-keepkey"; import * as ledger from "@shapeshiftoss/hdwallet-ledger"; +import * as metamask from "@shapeshiftoss/hdwallet-metamask-multichain"; // Amino-encoded transactions import tx_unsigned_delegate_cosmos_amino from "./amino/tx01.mainnet.cosmos.delegate.json"; @@ -49,6 +50,8 @@ export function cosmosTests(get: () => { wallet: core.HDWallet; info: core.HDWal beforeEach(async () => { if (!wallet) return; + // Non-EVM things are a pain to test with snaps on test env, this wasn't tested before and still isn't + if (metamask.isMetaMask(wallet)) return; await wallet.wipe(); await wallet.loadDevice({ mnemonic: MNEMONIC12_NOPIN_NOPASSPHRASE, @@ -61,6 +64,8 @@ export function cosmosTests(get: () => { wallet: core.HDWallet; info: core.HDWal "cosmosGetAccountPaths()", () => { if (!wallet) return; + // Non-EVM things are a pain to test with snaps on test env, this wasn't tested before and still isn't + if (metamask.isMetaMask(wallet)) return; const paths = wallet.cosmosGetAccountPaths({ accountIdx: 0 }); expect(paths.length > 0).toBe(true); expect(paths[0].addressNList[0] > 0x80000000).toBe(true); @@ -72,6 +77,8 @@ export function cosmosTests(get: () => { wallet: core.HDWallet; info: core.HDWal "cosmosGetAddress()", async () => { if (!wallet) return; + // Non-EVM things are a pain to test with snaps on test env, this wasn't tested before and still isn't + if (metamask.isMetaMask(wallet)) return; expect( await wallet.cosmosGetAddress({ addressNList: core.bip32ToAddressNList("m/44'/118'/0'/0/0"), @@ -131,6 +138,8 @@ export function cosmosTests(get: () => { wallet: core.HDWallet; info: core.HDWal ])( "%s", async (_, aminoTx, protoTx, signedAminoTx, signedProtoTx) => { + // Non-EVM things are a pain to test with snaps on test env, this wasn't tested before and still isn't + if (metamask.isMetaMask(wallet)) return; const tx = useAmino ? aminoTx : protoTx; const signedTx = useAmino ? signedAminoTx : signedProtoTx; if (!wallet || !tx) return; diff --git a/integration/src/ethereum/ethereum.ts b/integration/src/ethereum/ethereum.ts index 76f73d0af..5075ab95f 100644 --- a/integration/src/ethereum/ethereum.ts +++ b/integration/src/ethereum/ethereum.ts @@ -1,6 +1,6 @@ import * as core from "@shapeshiftoss/hdwallet-core"; import * as ledger from "@shapeshiftoss/hdwallet-ledger"; -import * as metamask from "@shapeshiftoss/hdwallet-metamask"; +import * as metamask from "@shapeshiftoss/hdwallet-metamask-multichain"; import * as portis from "@shapeshiftoss/hdwallet-portis"; import * as trezor from "@shapeshiftoss/hdwallet-trezor"; diff --git a/integration/src/integration.ts b/integration/src/integration.ts index a47409e1a..6aa5ee741 100644 --- a/integration/src/integration.ts +++ b/integration/src/integration.ts @@ -1,14 +1,12 @@ import * as core from "@shapeshiftoss/hdwallet-core"; import * as keepkey from "@shapeshiftoss/hdwallet-keepkey"; import * as ledger from "@shapeshiftoss/hdwallet-ledger"; -import * as metamask from "@shapeshiftoss/hdwallet-metamask"; +import * as metamask from "@shapeshiftoss/hdwallet-metamask-multichain"; import * as native from "@shapeshiftoss/hdwallet-native"; import * as phantom from "@shapeshiftoss/hdwallet-phantom"; import * as portis from "@shapeshiftoss/hdwallet-portis"; -import * as tallyHo from "@shapeshiftoss/hdwallet-tallyho"; import * as trezor from "@shapeshiftoss/hdwallet-trezor"; import * as walletconnect from "@shapeshiftoss/hdwallet-walletconnect"; -import * as xdefi from "@shapeshiftoss/hdwallet-xdefi"; import { binanceTests } from "./binance"; import { btcTests } from "./bitcoin"; @@ -57,9 +55,7 @@ export function integration(suite: WalletSuite): void { (portis.isPortis(wallet) ? 1 : 0) + (native.isNative(wallet) ? 1 : 0) + (metamask.isMetaMask(wallet) ? 1 : 0) + - (tallyHo.isTallyHo(wallet) ? 1 : 0) + (walletconnect.isWalletConnect(wallet) ? 1 : 0) + - (xdefi.isXDEFI(wallet) ? 1 : 0) + (phantom.isPhantom(wallet) ? 1 : 0) ).toEqual(1); }); diff --git a/integration/src/thorchain/thorchain.ts b/integration/src/thorchain/thorchain.ts index b95ec45a0..96c9064a2 100644 --- a/integration/src/thorchain/thorchain.ts +++ b/integration/src/thorchain/thorchain.ts @@ -1,6 +1,7 @@ import * as core from "@shapeshiftoss/hdwallet-core"; import * as keepkey from "@shapeshiftoss/hdwallet-keepkey"; import * as ledger from "@shapeshiftoss/hdwallet-ledger"; +import * as metamask from "@shapeshiftoss/hdwallet-metamask-multichain"; import tx_unsigned_swap_amino from "./tx01.mainnet.thorchain.swap.amino.json"; import tx_unsigned_swap from "./tx01.mainnet.thorchain.swap.json"; @@ -25,12 +26,16 @@ export function thorchainTests(get: () => { wallet: core.HDWallet; info: core.HD describe("Thorchain", () => { beforeAll(async () => { const { wallet: w } = get(); + // Non-EVM things are a pain to test with snaps on test env, this wasn't tested before and still isn't + if (metamask.isMetaMask(wallet)) return; if (core.supportsThorchain(w)) wallet = w; useAmino = w instanceof keepkey.KeepKeyHDWallet || w instanceof ledger.LedgerHDWallet; }); beforeEach(async () => { if (!wallet) return; + // Non-EVM things are a pain to test with snaps on test env, this wasn't tested before and still isn't + if (metamask.isMetaMask(wallet)) return; await wallet.wipe(); await wallet.loadDevice({ mnemonic: MNEMONIC12_NOPIN_NOPASSPHRASE, @@ -43,6 +48,8 @@ export function thorchainTests(get: () => { wallet: core.HDWallet; info: core.HD "thorchainGetAccountPaths()", () => { if (!wallet) return; + // Non-EVM things are a pain to test with snaps on test env, this wasn't tested before and still isn't + if (metamask.isMetaMask(wallet)) return; const paths = wallet.thorchainGetAccountPaths({ accountIdx: 0 }); expect(paths.length > 0).toBe(true); expect(paths[0].addressNList[0] > 0x80000000).toBe(true); @@ -54,6 +61,8 @@ export function thorchainTests(get: () => { wallet: core.HDWallet; info: core.HD "describePath() thorchain", async () => { if (!wallet) return; + // Non-EVM things are a pain to test with snaps on test env, this wasn't tested before and still isn't + if (metamask.isMetaMask(wallet)) return; const out = wallet.describePath({ path: core.bip32ToAddressNList("m/44'/931'/0'/0/0"), @@ -92,6 +101,8 @@ export function thorchainTests(get: () => { wallet: core.HDWallet; info: core.HD "thorchainGetAddress()", async () => { if (!wallet) return; + // Non-EVM things are a pain to test with snaps on test env, this wasn't tested before and still isn't + if (metamask.isMetaMask(wallet)) return; expect( await wallet.thorchainGetAddress({ addressNList: core.bip32ToAddressNList("m/44'/931'/0'/0/0"), @@ -126,6 +137,8 @@ export function thorchainTests(get: () => { wallet: core.HDWallet; info: core.HD const signedTx = useAmino ? signedAminoTx : signedProtoTx; if (!wallet || !tx) return; + // Non-EVM things are a pain to test with snaps on test env, this wasn't tested before and still isn't + if (metamask.isMetaMask(wallet)) return; const input: core.ThorchainSignTx = { tx, diff --git a/integration/src/wallets/metamask.ts b/integration/src/wallets/metamask.ts index 9812d4a9f..7888f73d6 100644 --- a/integration/src/wallets/metamask.ts +++ b/integration/src/wallets/metamask.ts @@ -1,12 +1,13 @@ import * as core from "@shapeshiftoss/hdwallet-core"; -import * as metamask from "@shapeshiftoss/hdwallet-metamask"; +import * as metamask from "@shapeshiftoss/hdwallet-metamask-multichain"; +import { EIP6963ProviderInfo } from "mipd"; export function name(): string { return "MetaMask"; } export function createInfo(): core.HDWalletInfo { - return new metamask.MetaMaskHDWalletInfo(); + return new metamask.MetaMaskMultiChainHDWalletInfo(); } export async function createWallet(): Promise { @@ -33,18 +34,21 @@ export async function createWallet(): Promise { } }), }; - const wallet = new metamask.MetaMaskHDWallet(provider); + const wallet = new metamask.MetaMaskMultiChainHDWallet({ + provider, + info: { rdns: "io.metamask" } as EIP6963ProviderInfo, + }); await wallet.initialize(); return wallet; } export function selfTest(get: () => core.HDWallet): void { - let wallet: metamask.MetaMaskHDWallet; + let wallet: metamask.MetaMaskMultiChainHDWallet; beforeAll(async () => { - const w = get() as metamask.MetaMaskHDWallet; + const w = get() as metamask.MetaMaskMultiChainHDWallet; - if (metamask.isMetaMask(w) && !core.supportsBTC(w) && core.supportsETH(w)) { + if (metamask.isMetaMask(w) && core.supportsBTC(w) && core.supportsETH(w)) { wallet = w; } else { throw new Error("Wallet is not a MetaMask"); @@ -56,9 +60,9 @@ export function selfTest(get: () => core.HDWallet): void { expect(await wallet.ethSupportsNetwork()).toEqual(true); }); - it("does not support BTC", async () => { + it("supports Bitcoin", async () => { if (!wallet) return; - expect(core.supportsBTC(wallet)).toBe(false); + expect(core.supportsBTC(wallet)).toBe(true); }); it("does not support Native ShapeShift", async () => { @@ -66,7 +70,7 @@ export function selfTest(get: () => core.HDWallet): void { expect(wallet.ethSupportsNativeShapeShift()).toEqual(false); }); - it("does not supports bip44 accounts", async () => { + it("does not support bip44 accounts", async () => { if (!wallet) return; expect(wallet.supportsBip44Accounts()).toEqual(false); }); @@ -83,27 +87,28 @@ export function selfTest(get: () => core.HDWallet): void { it("uses correct eth bip44 paths", () => { if (!wallet) return; - [0, 1, 3, 27].forEach((account) => { - const paths = wallet.ethGetAccountPaths({ - coin: "Ethereum", - accountIdx: account, - }); - expect(paths).toEqual([ - { - addressNList: core.bip32ToAddressNList(`m/44'/60'/${account}'/0/0`), - hardenedPath: core.bip32ToAddressNList(`m/44'/60'/${account}'`), - relPath: [0, 0], - description: "MetaMask", - }, - ]); - paths.forEach((path) => { - expect( - wallet.describePath({ - coin: "Ethereum", - path: path.addressNList, - }).isKnown - ).toBeTruthy(); - }); + // MM doesn't support multi-account *externally*, the active account is exposes should be considered account 0, + // even if internally it may not be e.g for all intents and purposes, m/44'/60'/0'/0/1 for MetaMask should be considered m/44'/60'/0'/0/0 + const accountNumber = 0; + const paths = wallet.ethGetAccountPaths({ + coin: "Ethereum", + accountIdx: accountNumber, + }); + expect(paths).toEqual([ + { + addressNList: core.bip32ToAddressNList(`m/44'/60'/${accountNumber}'/0/0`), + hardenedPath: core.bip32ToAddressNList(`m/44'/60'/${accountNumber}'`), + relPath: [0, 0], + description: "MetaMask(Shapeshift Multichain)", + }, + ]); + paths.forEach((path) => { + expect( + wallet.describePath({ + coin: "Ethereum", + path: path.addressNList, + }).isKnown + ).toBeTruthy(); }); }); @@ -120,6 +125,7 @@ export function selfTest(get: () => core.HDWallet): void { isKnown: true, accountIdx: 0, wholeAccount: true, + isPrefork: false, }); expect( @@ -133,6 +139,7 @@ export function selfTest(get: () => core.HDWallet): void { isKnown: true, accountIdx: 3, wholeAccount: true, + isPrefork: false, }); expect( diff --git a/integration/src/wallets/tallyho.ts b/integration/src/wallets/tallyho.ts deleted file mode 100644 index b2b4b133d..000000000 --- a/integration/src/wallets/tallyho.ts +++ /dev/null @@ -1,171 +0,0 @@ -import * as core from "@shapeshiftoss/hdwallet-core"; -import * as tallyHo from "@shapeshiftoss/hdwallet-tallyho"; - -export function name(): string { - return "Tally Ho"; -} - -export function createInfo(): core.HDWalletInfo { - return new tallyHo.TallyHoHDWalletInfo(); -} - -export async function createWallet(): Promise { - const provider = { - request: jest.fn(({ method, params }: any) => { - switch (method) { - case "eth_accounts": - return ["0x3f2329C9ADFbcCd9A84f52c906E936A42dA18CB8"]; - case "personal_sign": { - const [message] = params; - - if (message === "48656c6c6f20576f726c64") - return "0x29f7212ecc1c76cea81174af267b67506f754ea8c73f144afa900a0d85b24b21319621aeb062903e856352f38305710190869c3ce5a1425d65ef4fa558d0fc251b"; - - throw new Error("unknown message"); - } - case "eth_sendTransaction": { - const [{ to }] = params; - - return `txHash-${to}`; - } - default: - throw new Error(`ethereum: Unknown method ${method}`); - } - }), - }; - const wallet = new tallyHo.TallyHoHDWallet(provider); - await wallet.initialize(); - return wallet; -} - -export function selfTest(get: () => core.HDWallet): void { - let wallet: tallyHo.TallyHoHDWallet; - - beforeAll(async () => { - const w = get() as tallyHo.TallyHoHDWallet; - - if (tallyHo.isTallyHo(w) && !core.supportsBTC(w) && core.supportsETH(w)) { - wallet = w; - } else { - throw "Wallet is not a Tally"; - } - }); - - it("supports Ethereum mainnet", async () => { - if (!wallet) return; - expect(await wallet.ethSupportsNetwork()).toEqual(true); - }); - - it("does not support BTC", async () => { - if (!wallet) return; - expect(core.supportsBTC(wallet)).toBe(false); - }); - - it("does not support Native ShapeShift", async () => { - if (!wallet) return; - expect(wallet.ethSupportsNativeShapeShift()).toEqual(false); - }); - - it("does support EIP1559", async () => { - if (!wallet) return; - expect(await wallet.ethSupportsEIP1559()).toEqual(true); - }); - - it("does not support Secure Transfer", async () => { - if (!wallet) return; - expect(await wallet.ethSupportsSecureTransfer()).toEqual(false); - }); - - it("uses correct eth bip44 paths", () => { - if (!wallet) return; - [0, 1, 3, 27].forEach((account) => { - const paths = wallet.ethGetAccountPaths({ - coin: "Ethereum", - accountIdx: account, - }); - expect(paths).toEqual([ - { - addressNList: core.bip32ToAddressNList(`m/44'/60'/${account}'/0/0`), - hardenedPath: core.bip32ToAddressNList(`m/44'/60'/${account}'`), - relPath: [0, 0], - description: "TallyHo", - }, - ]); - paths.forEach((path) => { - expect( - wallet.describePath({ - coin: "Ethereum", - path: path.addressNList, - }).isKnown - ).toBeTruthy(); - }); - }); - }); - - it("can describe ETH paths", () => { - if (!wallet) return; - expect( - wallet.describePath({ - path: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - coin: "Ethereum", - }) - ).toEqual({ - verbose: "Ethereum Account #0", - coin: "Ethereum", - isKnown: true, - accountIdx: 0, - wholeAccount: true, - }); - - expect( - wallet.describePath({ - path: core.bip32ToAddressNList("m/44'/60'/3'/0/0"), - coin: "Ethereum", - }) - ).toEqual({ - verbose: "Ethereum Account #3", - coin: "Ethereum", - isKnown: true, - accountIdx: 3, - wholeAccount: true, - }); - - expect( - wallet.describePath({ - path: core.bip32ToAddressNList("m/44'/60'/0'/0/3"), - coin: "Ethereum", - }) - ).toEqual({ - verbose: "m/44'/60'/0'/0/3", - coin: "Ethereum", - isKnown: false, - }); - }); - - it("should return a valid ETH address", async () => { - if (!wallet) return; - expect( - await wallet.ethGetAddress({ - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - showDisplay: false, - }) - ).toEqual("0x3f2329C9ADFbcCd9A84f52c906E936A42dA18CB8"); - }); - - it("does not support bip44 accounts", async () => { - if (!wallet) return; - expect(wallet.supportsBip44Accounts()).toEqual(false); - }); - - it("should sign a message", async () => { - if (!wallet) return; - const res = await wallet.ethSignMessage({ - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - message: "Hello World", - }); - expect(res?.address).toEqual("0x3f2329C9ADFbcCd9A84f52c906E936A42dA18CB8"); - expect(res?.signature).toEqual( - "0x29f7212ecc1c76cea81174af267b67506f754ea8c73f144afa900a0d85b24b21319621aeb062903e856352f38305710190869c3ce5a1425d65ef4fa558d0fc251b" - ); - }); -} diff --git a/integration/src/wallets/xdefi.ts b/integration/src/wallets/xdefi.ts deleted file mode 100644 index 631b93730..000000000 --- a/integration/src/wallets/xdefi.ts +++ /dev/null @@ -1,151 +0,0 @@ -import * as core from "@shapeshiftoss/hdwallet-core"; -import * as xdefi from "@shapeshiftoss/hdwallet-xdefi"; - -const mockSignEthTxResponse = { - r: "0x122269dc9cffc02962cdaa5af54913ac3e7293c3dd2a8ba7e38da2bc638f92df", - s: "0x36334d475fc12eb62681fb2cb10f177101d5cf4c3a735c94460d92bfa2389cc8", - v: 1, - serialized: - "0x02f872018084540ae4808516854be509825ac394fc0cc6e85dff3d75e3985e0cb83b090cfd498dd1871550f7dca7000080c001a0122269dc9cffc02962cdaa5af54913ac3e7293c3dd2a8ba7e38da2bc638f92dfa036334d475fc12eb62681fb2cb10f177101d5cf4c3a735c94460d92bfa2389cc8", -}; - -const mockSignEthTxResponse1559 = { - r: "0x63db3dd3bf3e1fe7dde1969c0fc8850e34116d0b501c0483a0e08c0f77b8ce0a", - s: "0x28297d012cccf389f6332415e96ee3fc0bbf8474d05f646e029cd281a031464b", - v: 38, - serialized: - "0xf86b018501dcd650008256229412ec06288edd7ae2cc41a843fe089237fc7354f0872c68af0bb140008026a063db3dd3bf3e1fe7dde1969c0fc8850e34116d0b501c0483a0e08c0f77b8ce0aa028297d012cccf389f6332415e96ee3fc0bbf8474d05f646e029cd281a031464b", -}; - -const mockSignERC20Tx = { - r: "0x1238fd332545415f09a01470350a5a20abc784dbf875cf58f7460560e66c597f", - s: "0x10efa4dd6fdb381c317db8f815252c2ac0d2a883bd364901dee3dec5b7d3660a", - v: 37, - serialized: - "0xf8a20114149441e5560054824ea6b0732e656e3ad64e20e94e4580b844a9059cbb0000000000000000000000001d8ce9022f6284c3a5c317f8f34620107214e54500000000000000000000000000000000000000000000000000000002540be40025a01238fd332545415f09a01470350a5a20abc784dbf875cf58f7460560e66c597fa010efa4dd6fdb381c317db8f815252c2ac0d2a883bd364901dee3dec5b7d3660a", -}; - -const mockSignAVAXTx = { - r: "0x5183891ab9dc1c6813e43db1a156a2f8c9195a637c0dabe93a84281bcb1ca3c4", - s: "0x3ff9b668277c2d388bab436d209fdda1281b2b8fc4b3ad1d92464861afaa2e6f", - v: 86264, - serialized: - "0xf8b3018501dcd6500082562294dafea492d9c6733ae3d56b7ed1adb60692c98bc5872c68af0bb14000b844a9059cbb0000000000000000000000001d8ce9022f6284c3a5c317f8f34620107214e54500000000000000000000000000000000000000000000000000000002540be400830150f8a05183891ab9dc1c6813e43db1a156a2f8c9195a637c0dabe93a84281bcb1ca3c4a03ff9b668277c2d388bab436d209fdda1281b2b8fc4b3ad1d92464861afaa2e6f", -}; - -const mockSignLongContractData = { - r: "0x5ea245ddd00fdf3958d6223255e37dcb0c61fa62cfa9cfb25e507da16ec8d96a", - s: "0x6c428730776958b80fd2b2201600420bb49059f9b34ee3b960cdcce45d4a1e09", - v: 37, - serialized: - "0xf9063081ab85055ae826008305140e94def1c0ded9bec7f1a1670819833240f027b25eff80b905c8415565b0000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000c5c360b9c0000000000000000000000000000000000000000000000000000000c58cb06ec00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000c5c360b9c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000a446f646f0000000000000000000000000000000000000000000000000000000000000000000000000000000c5c360b9c0000000000000000000000000000000000000000000000000000000c58cb06ec00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000060000000000000000000000000533da777aedce766ceae696bf90f8541a4ba80eb000000000000000000000000c9f93163c99695c6526b799ebca2207fdf7d61ad0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000003000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee0000000000000000000000000000000000000000000000000000000000000000869584cd000000000000000000000000c770eefad204b5180df6a14ee197d99d808ee52d0000000000000000000000000000000000000000000000da413736cc60c8dd4e25a05ea245ddd00fdf3958d6223255e37dcb0c61fa62cfa9cfb25e507da16ec8d96aa06c428730776958b80fd2b2201600420bb49059f9b34ee3b960cdcce45d4a1e09", -}; - -export function name(): string { - return "XDEFI"; -} - -export async function createWallet(): Promise { - // mock xdefi - (globalThis as any).xfi = { - ethereum: { - request: jest.fn(({ method, params }: any) => { - switch (method) { - case "eth_accounts": - case "eth_requestAccounts": - return ["0x3f2329C9ADFbcCd9A84f52c906E936A42dA18CB8"]; - case "personal_sign": { - const [message] = params; - - if (message === "48656c6c6f20576f726c64") - return "0x29f7212ecc1c76cea81174af267b67506f754ea8c73f144afa900a0d85b24b21319621aeb062903e856352f38305710190869c3ce5a1425d65ef4fa558d0fc251b"; - - throw new Error("unknown message"); - } - case "eth_sendTransaction": { - const [{ to }] = params; - - return `txHash-${to}`; - } - default: - throw new Error(`ethereum: Unknown method ${method}`); - } - }), - }, - }; - - const adapter = xdefi.XDEFIAdapter.useKeyring(new core.Keyring()); - const wallet = await adapter.pairDevice(); - - if (!wallet) { - throw new Error("Unable to pair XDEFIWallet!"); - } - - wallet.ethSignTx = jest - .fn() - .mockReturnValueOnce(mockSignEthTxResponse) - .mockReturnValueOnce(mockSignAVAXTx) - .mockReturnValueOnce(mockSignEthTxResponse1559) - .mockReturnValueOnce(mockSignERC20Tx) - .mockReturnValueOnce(mockSignLongContractData); - - wallet.ethSignMessage = jest.fn().mockReturnValue({ - address: "0x3f2329C9ADFbcCd9A84f52c906E936A42dA18CB8", - signature: - "0x29f7212ecc1c76cea81174af267b67506f754ea8c73f144afa900a0d85b24b21319621aeb062903e856352f38305710190869c3ce5a1425d65ef4fa558d0fc251b", - }); - - wallet.ethVerifyMessage = jest.fn().mockReturnValue({ - address: "0x3f2329C9ADFbcCd9A84f52c906E936A42dA18CB8", - message: "Hello World", - signature: - "0x29f7212ecc1c76cea81174af267b67506f754ea8c73f144afa900a0d85b24b21319621aeb062903e856352f38305710190869c3ce5a1425d65ef4fa558d0fc251b", - }); - - return wallet; -} - -export function createInfo(): core.HDWalletInfo { - return new xdefi.XDEFIHDWalletInfo(); -} - -export function selfTest(get: () => core.HDWallet): void { - let wallet: xdefi.XDEFIHDWallet & core.ETHWallet & core.HDWallet; - - beforeAll(() => { - const w = get(); - if (xdefi.isXDEFI(w) && core.supportsETH(w)) { - wallet = w; - } else { - throw new Error("Wallet is not XDEFI"); - } - }); - - it("supports Ethereum mainnet", async () => { - if (!wallet) return; - expect(await wallet.ethSupportsNetwork(1)).toEqual(true); - }); - - it("prepends xDeFi: to the eth address to create the deviceId", async () => { - if (!wallet) return; - expect(await wallet.getDeviceID()).toEqual("xDeFi:0x3f2329C9ADFbcCd9A84f52c906E936A42dA18CB8"); - }); - - it("does not support bip44 accounts", async () => { - if (!wallet) return; - expect(wallet.supportsBip44Accounts()).toEqual(false); - }); - - it("does not support more than one account path", async () => { - if (!wallet) return; - const paths = core.mustBeDefined( - await wallet.ethGetAccountPaths({ - coin: "Ethereum", - accountIdx: 0, - }) - ); - expect(paths.length).toEqual(1); - const nextPath = await wallet.ethNextAccountPath(paths[0]); - expect(nextPath).toBeUndefined(); - }); -} diff --git a/integration/src/xdefi.test.ts b/integration/src/xdefi.test.ts deleted file mode 100644 index db3f9b357..000000000 --- a/integration/src/xdefi.test.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { integration } from "./integration"; -import * as XDEFI from "./wallets/xdefi"; -integration(XDEFI); diff --git a/lerna.json b/lerna.json index 00d3bec22..08b3ba343 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "5.2.0", - "version": "1.55.10", + "version": "1.55.11", "npmClient": "yarn", "useWorkspaces": true, "command": { diff --git a/packages/hdwallet-coinbase/package.json b/packages/hdwallet-coinbase/package.json index ac0b3aeec..fc2714763 100644 --- a/packages/hdwallet-coinbase/package.json +++ b/packages/hdwallet-coinbase/package.json @@ -1,6 +1,6 @@ { "name": "@shapeshiftoss/hdwallet-coinbase", - "version": "1.55.10", + "version": "1.55.11", "license": "MIT", "publishConfig": { "access": "public" @@ -15,7 +15,7 @@ }, "dependencies": { "@coinbase/wallet-sdk": "^3.6.6", - "@shapeshiftoss/hdwallet-core": "1.55.10", + "@shapeshiftoss/hdwallet-core": "1.55.11", "eth-rpc-errors": "^4.0.3", "lodash": "^4.17.21" }, diff --git a/packages/hdwallet-core/package.json b/packages/hdwallet-core/package.json index 7a2550781..e9d99f608 100644 --- a/packages/hdwallet-core/package.json +++ b/packages/hdwallet-core/package.json @@ -1,6 +1,6 @@ { "name": "@shapeshiftoss/hdwallet-core", - "version": "1.55.10", + "version": "1.55.11", "license": "MIT", "publishConfig": { "access": "public" diff --git a/packages/hdwallet-core/src/bitcoin.ts b/packages/hdwallet-core/src/bitcoin.ts index 5725d42a5..69577fa91 100644 --- a/packages/hdwallet-core/src/bitcoin.ts +++ b/packages/hdwallet-core/src/bitcoin.ts @@ -341,12 +341,6 @@ export interface BTCWalletInfo extends HDWalletInfo { */ btcGetAccountPaths(msg: BTCGetAccountPaths): Array; - /** - * Does the device support spending from the combined accounts? - * The list is assumed to contain unique entries. - */ - btcIsSameAccount(msg: Array): boolean; - /** * Returns the "next" account path, if any. */ diff --git a/packages/hdwallet-keepkey-chromeusb/package.json b/packages/hdwallet-keepkey-chromeusb/package.json index 9a2b6392a..321f48b94 100644 --- a/packages/hdwallet-keepkey-chromeusb/package.json +++ b/packages/hdwallet-keepkey-chromeusb/package.json @@ -1,6 +1,6 @@ { "name": "@shapeshiftoss/hdwallet-keepkey-chromeusb", - "version": "1.55.10", + "version": "1.55.11", "license": "MIT", "publishConfig": { "access": "public" @@ -14,7 +14,7 @@ "prepublishOnly": "yarn clean && yarn build" }, "dependencies": { - "@shapeshiftoss/hdwallet-core": "1.55.10", - "@shapeshiftoss/hdwallet-keepkey": "1.55.10" + "@shapeshiftoss/hdwallet-core": "1.55.11", + "@shapeshiftoss/hdwallet-keepkey": "1.55.11" } } diff --git a/packages/hdwallet-keepkey-electron/package.json b/packages/hdwallet-keepkey-electron/package.json index 677754346..ec22a9a08 100644 --- a/packages/hdwallet-keepkey-electron/package.json +++ b/packages/hdwallet-keepkey-electron/package.json @@ -1,6 +1,6 @@ { "name": "@shapeshiftoss/hdwallet-keepkey-electron", - "version": "1.55.10", + "version": "1.55.11", "license": "MIT", "publishConfig": { "access": "public" @@ -14,7 +14,7 @@ "prepublishOnly": "yarn clean && yarn build" }, "dependencies": { - "@shapeshiftoss/hdwallet-keepkey": "1.55.10", + "@shapeshiftoss/hdwallet-keepkey": "1.55.11", "uuid": "^8.3.2" }, "peerDependencies": { diff --git a/packages/hdwallet-keepkey-nodehid/package.json b/packages/hdwallet-keepkey-nodehid/package.json index 70b369066..a71cacb67 100644 --- a/packages/hdwallet-keepkey-nodehid/package.json +++ b/packages/hdwallet-keepkey-nodehid/package.json @@ -1,6 +1,6 @@ { "name": "@shapeshiftoss/hdwallet-keepkey-nodehid", - "version": "1.55.10", + "version": "1.55.11", "license": "MIT", "publishConfig": { "access": "public" @@ -14,7 +14,7 @@ "prepublishOnly": "yarn clean && yarn build" }, "dependencies": { - "@shapeshiftoss/hdwallet-keepkey": "1.55.10" + "@shapeshiftoss/hdwallet-keepkey": "1.55.11" }, "peerDependencies": { "node-hid": "^2.1.1" diff --git a/packages/hdwallet-keepkey-nodewebusb/package.json b/packages/hdwallet-keepkey-nodewebusb/package.json index f4c8b73b5..0bd3a89c3 100644 --- a/packages/hdwallet-keepkey-nodewebusb/package.json +++ b/packages/hdwallet-keepkey-nodewebusb/package.json @@ -1,6 +1,6 @@ { "name": "@shapeshiftoss/hdwallet-keepkey-nodewebusb", - "version": "1.55.10", + "version": "1.55.11", "license": "MIT", "publishConfig": { "access": "public" @@ -14,8 +14,8 @@ "prepublishOnly": "yarn clean && yarn build" }, "dependencies": { - "@shapeshiftoss/hdwallet-core": "1.55.10", - "@shapeshiftoss/hdwallet-keepkey": "1.55.10" + "@shapeshiftoss/hdwallet-core": "1.55.11", + "@shapeshiftoss/hdwallet-keepkey": "1.55.11" }, "peerDependencies": { "usb": "^2.3.1" diff --git a/packages/hdwallet-keepkey-tcp/package.json b/packages/hdwallet-keepkey-tcp/package.json index 77ea8676a..2dbeb3fea 100644 --- a/packages/hdwallet-keepkey-tcp/package.json +++ b/packages/hdwallet-keepkey-tcp/package.json @@ -1,6 +1,6 @@ { "name": "@shapeshiftoss/hdwallet-keepkey-tcp", - "version": "1.55.10", + "version": "1.55.11", "license": "MIT", "publishConfig": { "access": "public" @@ -14,8 +14,8 @@ "prepublishOnly": "yarn clean && yarn build" }, "dependencies": { - "@shapeshiftoss/hdwallet-core": "1.55.10", - "@shapeshiftoss/hdwallet-keepkey": "1.55.10", + "@shapeshiftoss/hdwallet-core": "1.55.11", + "@shapeshiftoss/hdwallet-keepkey": "1.55.11", "axios": "^0.21.1" } } diff --git a/packages/hdwallet-keepkey-webusb/package.json b/packages/hdwallet-keepkey-webusb/package.json index 1eebfeae1..bfb36798c 100644 --- a/packages/hdwallet-keepkey-webusb/package.json +++ b/packages/hdwallet-keepkey-webusb/package.json @@ -1,6 +1,6 @@ { "name": "@shapeshiftoss/hdwallet-keepkey-webusb", - "version": "1.55.10", + "version": "1.55.11", "license": "MIT", "publishConfig": { "access": "public" @@ -14,8 +14,8 @@ "prepublishOnly": "yarn clean && yarn build" }, "dependencies": { - "@shapeshiftoss/hdwallet-core": "1.55.10", - "@shapeshiftoss/hdwallet-keepkey": "1.55.10" + "@shapeshiftoss/hdwallet-core": "1.55.11", + "@shapeshiftoss/hdwallet-keepkey": "1.55.11" }, "devDependencies": { "@types/w3c-web-usb": "^1.0.4" diff --git a/packages/hdwallet-keepkey/package.json b/packages/hdwallet-keepkey/package.json index 634f7370b..2241b98a7 100644 --- a/packages/hdwallet-keepkey/package.json +++ b/packages/hdwallet-keepkey/package.json @@ -1,6 +1,6 @@ { "name": "@shapeshiftoss/hdwallet-keepkey", - "version": "1.55.10", + "version": "1.55.11", "license": "MIT", "publishConfig": { "access": "public" @@ -20,7 +20,7 @@ "@keepkey/device-protocol": "^7.12.2", "@metamask/eth-sig-util": "^7.0.0", "@shapeshiftoss/bitcoinjs-lib": "5.2.0-shapeshift.2", - "@shapeshiftoss/hdwallet-core": "1.55.10", + "@shapeshiftoss/hdwallet-core": "1.55.11", "@shapeshiftoss/proto-tx-builder": "^0.8.0", "bignumber.js": "^9.0.1", "bnb-javascript-sdk-nobroadcast": "^2.16.14", diff --git a/packages/hdwallet-keepkey/src/bitcoin.ts b/packages/hdwallet-keepkey/src/bitcoin.ts index e4fa48f30..1205ca6ee 100644 --- a/packages/hdwallet-keepkey/src/bitcoin.ts +++ b/packages/hdwallet-keepkey/src/bitcoin.ts @@ -559,49 +559,3 @@ export function btcGetAccountPaths(msg: core.BTCGetAccountPaths): Array): boolean { - if (msg.length < 1) return false; - - if (msg.length > 3) return false; - - const account0 = msg[0]; - if (account0.addressNList.length != 3) return false; - - // Make sure Purpose and ScriptType match - const purpose = account0.addressNList[0]; - const purposeForScriptType = { - [core.BTCInputScriptType.SpendAddress]: 0x80000000 + 44, - [core.BTCInputScriptType.SpendP2SHWitness]: 0x80000000 + 49, - [core.BTCInputScriptType.SpendWitness]: 0x80000000 + 84, - } as Partial>; - if (purposeForScriptType[account0.scriptType] !== purpose) return false; - - // Coin must be hardened - const slip44 = account0.addressNList[1]; - if (slip44 < 0x80000000) return false; - - // Account Idx must be hardened - const idx = account0.addressNList[2]; - if (idx < 0x80000000) return false; - - // Accounts must have the same SLIP44 and Account Idx, but may have differing - // purpose fields (so long as they're BIP44/BIP49/BIP84) - if ( - msg.find((path) => { - if (path.addressNList.length != 3) return true; - - if (![0x80000000 + 44, 0x80000000 + 49, 0x80000000 + 84].includes(path.addressNList[0])) return true; - - if (purposeForScriptType[path.scriptType] !== path.addressNList[0]) return true; - - if (path.addressNList[1] != slip44) return true; - - if (path.addressNList[2] != idx) return true; - }) - ) { - return false; - } - - return true; -} diff --git a/packages/hdwallet-keepkey/src/keepkey.ts b/packages/hdwallet-keepkey/src/keepkey.ts index e6e3c7a43..2959f76ca 100644 --- a/packages/hdwallet-keepkey/src/keepkey.ts +++ b/packages/hdwallet-keepkey/src/keepkey.ts @@ -445,10 +445,6 @@ export class KeepKeyHDWalletInfo return Btc.btcGetAccountPaths(msg); } - public btcIsSameAccount(msg: Array): boolean { - return Btc.btcIsSameAccount(msg); - } - public async ethSupportsNetwork(chain_id: number): Promise { return Eth.ethSupportsNetwork(chain_id); } @@ -1225,15 +1221,6 @@ export class KeepKeyHDWallet implements core.HDWallet, core.BTCWallet, core.ETHW return this.info.btcGetAccountPaths(msg); } - public btcIsSameAccount(msg: Array): boolean { - // TODO: mixed-mode segwit was added in v6.0.2 - // https://github.com/keepkey/keepkey-firmware/pull/81 - // if (firmware_version.lt('6.0.2') && msg.length > 1) - // return false - - return this.info.btcIsSameAccount(msg); - } - public async ethSignTx(msg: core.ETHSignTx): Promise { return Eth.ethSignTx(this.transport, msg); } diff --git a/packages/hdwallet-keplr/package.json b/packages/hdwallet-keplr/package.json index c3c098e5e..5402c7a4d 100644 --- a/packages/hdwallet-keplr/package.json +++ b/packages/hdwallet-keplr/package.json @@ -1,6 +1,6 @@ { "name": "@shapeshiftoss/hdwallet-keplr", - "version": "1.55.10", + "version": "1.55.11", "license": "MIT", "publishConfig": { "access": "public" @@ -15,7 +15,7 @@ }, "dependencies": { "@shapeshiftoss/caip": "8.15.0", - "@shapeshiftoss/hdwallet-core": "1.55.10", + "@shapeshiftoss/hdwallet-core": "1.55.11", "@shapeshiftoss/proto-tx-builder": "^0.8.0", "@shapeshiftoss/types": "3.1.3", "base64-js": "^1.5.1", diff --git a/packages/hdwallet-ledger-webhid/package.json b/packages/hdwallet-ledger-webhid/package.json index 9d7599a04..48c5ee32b 100644 --- a/packages/hdwallet-ledger-webhid/package.json +++ b/packages/hdwallet-ledger-webhid/package.json @@ -1,6 +1,6 @@ { "name": "@shapeshiftoss/hdwallet-ledger-webhid", - "version": "1.55.10", + "version": "1.55.11", "license": "MIT", "publishConfig": { "access": "public" @@ -19,8 +19,8 @@ "@ledgerhq/hw-transport": "^6.31.2", "@ledgerhq/hw-transport-webhid": "^6.29.2", "@ledgerhq/live-common": "^21.8.2", - "@shapeshiftoss/hdwallet-core": "1.55.10", - "@shapeshiftoss/hdwallet-ledger": "1.55.10", + "@shapeshiftoss/hdwallet-core": "1.55.11", + "@shapeshiftoss/hdwallet-ledger": "1.55.11", "@types/w3c-web-hid": "^1.0.2" }, "devDependencies": { diff --git a/packages/hdwallet-ledger-webusb/package.json b/packages/hdwallet-ledger-webusb/package.json index 6c0b6c692..9a95d29ff 100644 --- a/packages/hdwallet-ledger-webusb/package.json +++ b/packages/hdwallet-ledger-webusb/package.json @@ -1,6 +1,6 @@ { "name": "@shapeshiftoss/hdwallet-ledger-webusb", - "version": "1.55.10", + "version": "1.55.11", "license": "MIT", "publishConfig": { "access": "public" @@ -20,8 +20,8 @@ "@ledgerhq/hw-transport-webusb": "^6.29.2", "@ledgerhq/live-common": "^21.8.2", "@ledgerhq/logs": "^6.10.1", - "@shapeshiftoss/hdwallet-core": "1.55.10", - "@shapeshiftoss/hdwallet-ledger": "1.55.10", + "@shapeshiftoss/hdwallet-core": "1.55.11", + "@shapeshiftoss/hdwallet-ledger": "1.55.11", "@types/w3c-web-usb": "^1.0.4", "p-queue": "^7.4.1" }, diff --git a/packages/hdwallet-ledger/package.json b/packages/hdwallet-ledger/package.json index ac6aeacf1..3daeab7e4 100644 --- a/packages/hdwallet-ledger/package.json +++ b/packages/hdwallet-ledger/package.json @@ -1,6 +1,6 @@ { "name": "@shapeshiftoss/hdwallet-ledger", - "version": "1.55.10", + "version": "1.55.11", "license": "MIT", "publishConfig": { "access": "public" @@ -19,7 +19,7 @@ "@ethereumjs/tx": "^3.3.0", "@ledgerhq/hw-app-cosmos": "^6.29.1", "@shapeshiftoss/bitcoinjs-lib": "5.2.0-shapeshift.2", - "@shapeshiftoss/hdwallet-core": "1.55.10", + "@shapeshiftoss/hdwallet-core": "1.55.11", "base64-js": "^1.5.1", "bchaddrjs": "^0.4.4", "bitcoinjs-message": "^2.0.0", diff --git a/packages/hdwallet-ledger/src/bitcoin.ts b/packages/hdwallet-ledger/src/bitcoin.ts index 558cbd6fb..794dc2449 100644 --- a/packages/hdwallet-ledger/src/bitcoin.ts +++ b/packages/hdwallet-ledger/src/bitcoin.ts @@ -319,9 +319,3 @@ export function btcGetAccountPaths(msg: core.BTCGetAccountPaths): Array): boolean { - // TODO: There's no way this is correct. - return true; -} diff --git a/packages/hdwallet-ledger/src/ledger.ts b/packages/hdwallet-ledger/src/ledger.ts index bca083a3f..5f373efe3 100644 --- a/packages/hdwallet-ledger/src/ledger.ts +++ b/packages/hdwallet-ledger/src/ledger.ts @@ -168,10 +168,6 @@ export class LedgerHDWalletInfo return btc.btcGetAccountPaths(msg); } - public btcIsSameAccount(msg: Array): boolean { - return btc.btcIsSameAccount(msg); - } - public async ethSupportsNetwork(chain_id: number): Promise { return eth.ethSupportsNetwork(chain_id); } diff --git a/packages/hdwallet-metamask-shapeshift-multichain/package.json b/packages/hdwallet-metamask-multichain/package.json similarity index 67% rename from packages/hdwallet-metamask-shapeshift-multichain/package.json rename to packages/hdwallet-metamask-multichain/package.json index e0c6ab2a1..fb7560ed9 100644 --- a/packages/hdwallet-metamask-shapeshift-multichain/package.json +++ b/packages/hdwallet-metamask-multichain/package.json @@ -1,6 +1,6 @@ { - "name": "@shapeshiftoss/hdwallet-shapeshift-multichain", - "version": "1.55.10", + "name": "@shapeshiftoss/hdwallet-metamask-multichain", + "version": "1.55.11", "license": "MIT", "publishConfig": { "access": "public" @@ -17,11 +17,12 @@ "@metamask/detect-provider": "^1.2.0", "@metamask/onboarding": "^1.0.1", "@shapeshiftoss/common-api": "^9.3.0", - "@shapeshiftoss/hdwallet-core": "1.55.10", - "@shapeshiftoss/metamask-snaps-adapter": "^1.0.10", - "@shapeshiftoss/metamask-snaps-types": "^1.0.10", + "@shapeshiftoss/hdwallet-core": "1.55.11", + "@shapeshiftoss/metamask-snaps-adapter": "^1.0.12", + "@shapeshiftoss/metamask-snaps-types": "^1.0.12", "eth-rpc-errors": "^4.0.3", - "lodash": "^4.17.21" + "lodash": "^4.17.21", + "mipd": "^0.0.7" }, "devDependencies": { "@types/express": "^4.17.17", diff --git a/packages/hdwallet-metamask-multichain/src/adapter.ts b/packages/hdwallet-metamask-multichain/src/adapter.ts new file mode 100644 index 000000000..28211a448 --- /dev/null +++ b/packages/hdwallet-metamask-multichain/src/adapter.ts @@ -0,0 +1,61 @@ +import MetaMaskOnboarding from "@metamask/onboarding"; +import * as core from "@shapeshiftoss/hdwallet-core"; +import { createStore } from "mipd"; + +import { MetaMaskMultiChainHDWallet } from "./shapeshift-multichain"; + +export const mipdstore = createStore(); + +const METAMASK_RDNS = "io.metamask"; + +export class MetaMaskAdapter { + keyring: core.Keyring; + providerRdns: string; + + private constructor(keyring: core.Keyring, providerRdns: string) { + this.keyring = keyring; + this.providerRdns = providerRdns; + } + + public static useKeyring(keyring: core.Keyring, providerRdns: string) { + return new MetaMaskAdapter(keyring, providerRdns); + } + + public async initialize(): Promise { + return Object.keys(this.keyring.wallets).length; + } + + public async pairDevice(): Promise { + const maybeEip6963Provider = mipdstore.findProvider({ rdns: this.providerRdns }); + if (!maybeEip6963Provider && this.providerRdns === METAMASK_RDNS) { + const onboarding = new MetaMaskOnboarding(); + onboarding.startOnboarding(); + console.error("Please install MetaMask!"); + throw new Error("MetaMask provider not found"); + } + // If we were only dealing with *detected* rdns, this would never happen, however + // web contains a static list of rdns we want to display at all times to indicate support to users + // Meaning we may hit this without the wallet actually being installed + if (!maybeEip6963Provider) throw new Error("EIP-6963 provider not found"); + const eip1193Provider = maybeEip6963Provider.provider; + + try { + await eip1193Provider.request?.({ method: "eth_requestAccounts" }).catch(() => + eip1193Provider.request?.({ + method: "wallet_requestPermissions", + params: [{ eth_accounts: {} }], + }) + ); + } catch (error) { + console.error("Could not get MetaMask accounts. "); + throw error; + } + const wallet = new MetaMaskMultiChainHDWallet(maybeEip6963Provider); + await wallet.initialize(); + const deviceID = await wallet.getDeviceID(); + this.keyring.add(wallet, deviceID); + this.keyring.emit(["MetaMask(ShapeShift Multichain)", deviceID, core.Events.CONNECT], deviceID); + + return wallet; + } +} diff --git a/packages/hdwallet-metamask-shapeshift-multichain/src/bitcoin.ts b/packages/hdwallet-metamask-multichain/src/bitcoin.ts similarity index 100% rename from packages/hdwallet-metamask-shapeshift-multichain/src/bitcoin.ts rename to packages/hdwallet-metamask-multichain/src/bitcoin.ts diff --git a/packages/hdwallet-metamask-shapeshift-multichain/src/bitcoincash.ts b/packages/hdwallet-metamask-multichain/src/bitcoincash.ts similarity index 100% rename from packages/hdwallet-metamask-shapeshift-multichain/src/bitcoincash.ts rename to packages/hdwallet-metamask-multichain/src/bitcoincash.ts diff --git a/packages/hdwallet-metamask-shapeshift-multichain/src/common.ts b/packages/hdwallet-metamask-multichain/src/common.ts similarity index 100% rename from packages/hdwallet-metamask-shapeshift-multichain/src/common.ts rename to packages/hdwallet-metamask-multichain/src/common.ts diff --git a/packages/hdwallet-metamask-shapeshift-multichain/src/cosmos.ts b/packages/hdwallet-metamask-multichain/src/cosmos.ts similarity index 100% rename from packages/hdwallet-metamask-shapeshift-multichain/src/cosmos.ts rename to packages/hdwallet-metamask-multichain/src/cosmos.ts diff --git a/packages/hdwallet-metamask-shapeshift-multichain/src/dogecoin.ts b/packages/hdwallet-metamask-multichain/src/dogecoin.ts similarity index 100% rename from packages/hdwallet-metamask-shapeshift-multichain/src/dogecoin.ts rename to packages/hdwallet-metamask-multichain/src/dogecoin.ts diff --git a/packages/hdwallet-metamask-shapeshift-multichain/src/ethereum.ts b/packages/hdwallet-metamask-multichain/src/ethereum.ts similarity index 100% rename from packages/hdwallet-metamask-shapeshift-multichain/src/ethereum.ts rename to packages/hdwallet-metamask-multichain/src/ethereum.ts diff --git a/packages/hdwallet-metamask-shapeshift-multichain/src/index.ts b/packages/hdwallet-metamask-multichain/src/index.ts similarity index 100% rename from packages/hdwallet-metamask-shapeshift-multichain/src/index.ts rename to packages/hdwallet-metamask-multichain/src/index.ts diff --git a/packages/hdwallet-metamask-shapeshift-multichain/src/litecoin.ts b/packages/hdwallet-metamask-multichain/src/litecoin.ts similarity index 100% rename from packages/hdwallet-metamask-shapeshift-multichain/src/litecoin.ts rename to packages/hdwallet-metamask-multichain/src/litecoin.ts diff --git a/packages/hdwallet-metamask-shapeshift-multichain/src/shapeshift-multichain.test.ts b/packages/hdwallet-metamask-multichain/src/shapeshift-multichain.test.ts similarity index 91% rename from packages/hdwallet-metamask-shapeshift-multichain/src/shapeshift-multichain.test.ts rename to packages/hdwallet-metamask-multichain/src/shapeshift-multichain.test.ts index efcd2bfdb..d51cce35e 100644 --- a/packages/hdwallet-metamask-shapeshift-multichain/src/shapeshift-multichain.test.ts +++ b/packages/hdwallet-metamask-multichain/src/shapeshift-multichain.test.ts @@ -1,9 +1,10 @@ import * as core from "@shapeshiftoss/hdwallet-core"; +import { EIP6963ProviderInfo } from "mipd"; -import { MetaMaskShapeShiftMultiChainHDWallet, MetaMaskShapeShiftMultiChainHDWalletInfo } from "."; +import { MetaMaskMultiChainHDWallet, MetaMaskMultiChainHDWalletInfo } from "."; describe("HDWalletInfo", () => { - const info = new MetaMaskShapeShiftMultiChainHDWalletInfo(); + const info = new MetaMaskMultiChainHDWalletInfo(); it("should have correct metadata", async () => { expect(info.getVendor()).toBe("MetaMask"); @@ -20,13 +21,15 @@ describe("HDWalletInfo", () => { }); }); -describe("MetaMaskShapeShiftMultiChainHDWallet", () => { - let wallet: MetaMaskShapeShiftMultiChainHDWallet; +describe("MetaMaskMultiChainHDWallet", () => { + let wallet: MetaMaskMultiChainHDWallet; beforeEach(() => { - wallet = new MetaMaskShapeShiftMultiChainHDWallet( - core.untouchable("MetaMaskShapeShiftMultiChainHDWallet:provider") - ); + wallet = new MetaMaskMultiChainHDWallet({ + provider: core.untouchable("MetaMaskMultiChainHDWallet:provider"), + info: { rdns: "io.metamask" } as EIP6963ProviderInfo, + }); wallet.ethAddress = "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8"; + wallet.providerRdns = "io.metamask"; }); it("should match the metadata", async () => { @@ -40,7 +43,7 @@ describe("MetaMaskShapeShiftMultiChainHDWallet", () => { expect(wallet.ethSupportsNativeShapeShift()).toBe(false); expect(await wallet.ethSupportsEIP1559()).toBe(true); expect(await wallet.supportsOfflineSigning()).toBe(false); - expect(wallet.supportsBip44Accounts()).toBe(true); + expect(wallet.supportsBip44Accounts()).toBe(false); expect(await wallet.supportsBroadcast()).toBe(true); }); diff --git a/packages/hdwallet-metamask-shapeshift-multichain/src/shapeshift-multichain.ts b/packages/hdwallet-metamask-multichain/src/shapeshift-multichain.ts similarity index 95% rename from packages/hdwallet-metamask-shapeshift-multichain/src/shapeshift-multichain.ts rename to packages/hdwallet-metamask-multichain/src/shapeshift-multichain.ts index c097821b5..cb4c7e461 100644 --- a/packages/hdwallet-metamask-shapeshift-multichain/src/shapeshift-multichain.ts +++ b/packages/hdwallet-metamask-multichain/src/shapeshift-multichain.ts @@ -2,6 +2,7 @@ import * as core from "@shapeshiftoss/hdwallet-core"; import { AddEthereumChainParameter } from "@shapeshiftoss/hdwallet-core"; import { ethErrors, serializeError } from "eth-rpc-errors"; import _ from "lodash"; +import { EIP6963ProviderDetail } from "mipd"; import * as Btc from "./bitcoin"; import * as BtcCash from "./bitcoincash"; @@ -12,11 +13,11 @@ import * as Litecoin from "./litecoin"; import * as Thorchain from "./thorchain"; import * as utxo from "./utxo"; -export function isMetaMask(wallet: core.HDWallet): wallet is MetaMaskShapeShiftMultiChainHDWallet { +export function isMetaMask(wallet: core.HDWallet): wallet is MetaMaskMultiChainHDWallet { return _.isObject(wallet) && (wallet as any)._isMetaMask; } -export class MetaMaskShapeShiftMultiChainHDWalletInfo implements core.HDWalletInfo, core.ETHWalletInfo { +export class MetaMaskMultiChainHDWalletInfo implements core.HDWalletInfo, core.ETHWalletInfo { ethGetChainId?(): Promise { throw new Error("Method not implemented."); } @@ -65,7 +66,8 @@ export class MetaMaskShapeShiftMultiChainHDWalletInfo implements core.HDWalletIn } public supportsBip44Accounts(): boolean { - return true; + // Multi-account not supported in MM/snap, the only BIP44 bits we derive is diff slip44s than 60 (meaning, we support EVM chains) + return false; } public supportsOfflineSigning(): boolean { @@ -78,10 +80,10 @@ export class MetaMaskShapeShiftMultiChainHDWalletInfo implements core.HDWalletIn public describePath(msg: core.DescribePath): core.PathDescription { switch (msg.coin) { - case "bitcoin": - case "bitcoincash": - case "dogecoin": - case "litecoin": { + case "Bitcoin": + case "Bitcoincash": + case "Dogecoin": + case "Litecoin": { const unknown = core.unknownUTXOPath(msg.path, msg.coin, msg.scriptType); if (!msg.scriptType) return unknown; @@ -91,15 +93,14 @@ export class MetaMaskShapeShiftMultiChainHDWalletInfo implements core.HDWalletIn return core.describeUTXOPath(msg.path, msg.coin, msg.scriptType); } - case "atom": + case "Atom": return core.cosmosDescribePath(msg.path); - case "ethereum": + case "Ethereum": return core.describeETHPath(msg.path); - case "rune": - case "trune": - case "thorchain": + case "Rune": + case "Thorchain": return core.thorchainDescribePath(msg.path); default: @@ -266,7 +267,7 @@ export class MetaMaskShapeShiftMultiChainHDWalletInfo implements core.HDWalletIn } } -export class MetaMaskShapeShiftMultiChainHDWallet +export class MetaMaskMultiChainHDWallet implements core.HDWallet, core.BTCWallet, core.ETHWallet, core.CosmosWallet, core.ThorchainWallet { readonly _supportsETH = true; @@ -300,20 +301,23 @@ export class MetaMaskShapeShiftMultiChainHDWallet readonly _supportsThorchainInfo = true; readonly _supportsThorchain = true; - info: MetaMaskShapeShiftMultiChainHDWalletInfo & core.HDWalletInfo; + info: MetaMaskMultiChainHDWalletInfo & core.HDWalletInfo; bitcoinAddress?: string | null; bitcoinCashAddress?: string | null; cosmosAddress?: string | null; dogecoinAddress?: string | null; ethAddress?: string | null; + providerRdns: string; litecoinAddress?: string | null; osmosisAddress?: string | null; thorchainAddress?: string | null; provider: any; - constructor(provider: unknown) { - this.info = new MetaMaskShapeShiftMultiChainHDWalletInfo(); - this.provider = provider; + constructor(provider: EIP6963ProviderDetail) { + this.info = new MetaMaskMultiChainHDWalletInfo(); + + this.providerRdns = provider.info.rdns; + this.provider = provider.provider; } transport?: core.Transport | undefined; @@ -551,11 +555,6 @@ export class MetaMaskShapeShiftMultiChainHDWallet return utxo.utxoSupportsCoin(coin); } - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public btcIsSameAccount(msg: core.BTCAccountPath[]): boolean { - throw new Error("Method not implemented."); - } - /** BITCOIN CASH */ public async bitcoinCashSupportsSecureTransfer(): Promise { @@ -701,8 +700,6 @@ export class MetaMaskShapeShiftMultiChainHDWallet // https://docs.metamask.io/guide/ethereum-provider.html#errors // Internal error, which in the case of wallet_switchEthereumChain call means the chain isn't currently added to the wallet if (error.code === -32603) { - // We only support Avalanche C-Chain currently. It is supported natively in XDEFI, and unsupported in Tally, both with no capabilities to add a new chain - // TODO(gomes): Find a better home for these. When that's done, we'll want to call ethSwitchChain with (params: AddEthereumChainParameter) instead try { await this.ethAddChain(params); return; @@ -868,10 +865,10 @@ export class MetaMaskShapeShiftMultiChainHDWallet } public async getDeviceID(): Promise { - return "metaMask:" + (await this.ethGetAddress(this.provider)); + return this.providerRdns + ":" + (await this.ethGetAddress(this.provider)); } public async getFirmwareVersion(): Promise { - return "metaMask"; + return this.providerRdns; } } diff --git a/packages/hdwallet-metamask-shapeshift-multichain/src/thorchain.ts b/packages/hdwallet-metamask-multichain/src/thorchain.ts similarity index 100% rename from packages/hdwallet-metamask-shapeshift-multichain/src/thorchain.ts rename to packages/hdwallet-metamask-multichain/src/thorchain.ts diff --git a/packages/hdwallet-metamask-shapeshift-multichain/src/utxo.ts b/packages/hdwallet-metamask-multichain/src/utxo.ts similarity index 100% rename from packages/hdwallet-metamask-shapeshift-multichain/src/utxo.ts rename to packages/hdwallet-metamask-multichain/src/utxo.ts diff --git a/packages/hdwallet-metamask-shapeshift-multichain/tsconfig.json b/packages/hdwallet-metamask-multichain/tsconfig.json similarity index 100% rename from packages/hdwallet-metamask-shapeshift-multichain/tsconfig.json rename to packages/hdwallet-metamask-multichain/tsconfig.json diff --git a/packages/hdwallet-metamask-shapeshift-multichain/src/adapter.ts b/packages/hdwallet-metamask-shapeshift-multichain/src/adapter.ts deleted file mode 100644 index 11e0546cc..000000000 --- a/packages/hdwallet-metamask-shapeshift-multichain/src/adapter.ts +++ /dev/null @@ -1,135 +0,0 @@ -import detectEthereumProvider from "@metamask/detect-provider"; -import MetaMaskOnboarding from "@metamask/onboarding"; -import * as core from "@shapeshiftoss/hdwallet-core"; -import { enableShapeShiftSnap, shapeShiftSnapInstalled } from "@shapeshiftoss/metamask-snaps-adapter"; -import { providers } from "ethers"; - -import { SNAP_ID } from "./common"; -import { MetaMaskShapeShiftMultiChainHDWallet } from "./shapeshift-multichain"; - -// https://github.com/wevm/wagmi/blob/21245be51d7c6dff1c7b285226d0c89c4a9d8cac/packages/connectors/src/utils/getInjectedName.ts#L6-L56 -// This will need to be kept up-to-date with the latest list of impersonators -const METAMASK_IMPERSONATORS = [ - "isBraveWallet", - "isTokenary", - "isFrame", - "isLiquality", - "isOpera", - "isTally", - "isStatus", - "isXDEFI", - "isNifty", - "isRonin", - "isBinance", - "isCoinbase", - "isExodus", - "isPhantom", - "isGlow", - "isOneInch", - "isRabby", - "isTrezor", - "isLedger", - "isKeystone", - "isBitBox", - "isGridPlus", - "isJade", - "isPortis", - "isFortmatic", - "isTorus", - "isAuthereum", - "isWalletLink", - "isWalletConnect", - "isDapper", - "isBitski", - "isVenly", - "isSequence", - "isGamestop", - "isZerion", - "isDeBank", - "isKukai", - "isTemple", - "isSpire", - "isWallet", - "isCore", - "isAnchor", - "isWombat", - "isMathWallet", - "isMeetone", - "isHyperPay", - "isTokenPocket", - "isBitpie", - "isAToken", - "isOwnbit", - "isHbWallet", - "isMYKEY", - "isHuobiWallet", - "isEidoo", - "isTrust", - "isImToken", - "isONTO", - "isSafePal", - "isCoin98", - "isVision", -]; - -export class MetaMaskAdapter { - keyring: core.Keyring; - - private constructor(keyring: core.Keyring) { - this.keyring = keyring; - } - - public static useKeyring(keyring: core.Keyring) { - return new MetaMaskAdapter(keyring); - } - - public async initialize(): Promise { - return Object.keys(this.keyring.wallets).length; - } - - public async pairDevice(): Promise { - // TODO: remove casting, @metamask/detect-provider npm package hasn't been published with latest typings - // https://github.com/MetaMask/detect-provider/blame/5ce916fc24779c4b36741531a41d9c8b3cbb0a17/src/index.ts#L37 - const provider = (await detectEthereumProvider({ - mustBeMetaMask: true, - silent: false, - timeout: 3000, - })) as providers.ExternalProvider | null; - if (!provider) { - const onboarding = new MetaMaskOnboarding(); - onboarding.startOnboarding(); - console.error("Please install MetaMask!"); - throw new Error("MetaMask provider not found"); - } - - // Checking for the truthiness of the value isn't enough - some impersonators have the key present but undefined - // This is weird, but welcome to the world of web3 - const isMetaMaskImpersonator = METAMASK_IMPERSONATORS.some((impersonator) => impersonator in provider); - - if (!isMetaMaskImpersonator && !shapeShiftSnapInstalled(SNAP_ID)) { - console.info("ShapeShift Multichain snap not found. Prompting user to install."); - const result = await enableShapeShiftSnap(SNAP_ID); - if (result.success === false) { - throw new Error("Could not install ShapeShift Multichain snap"); - } - } - try { - await provider.request?.({ method: "eth_requestAccounts" }).catch(() => - provider.request?.({ - method: "wallet_requestPermissions", - params: [{ eth_accounts: {} }], - }) - ); - } catch (error) { - console.error("Could not get MetaMask accounts. "); - throw error; - } - const wallet = new MetaMaskShapeShiftMultiChainHDWallet(provider); - await wallet.initialize(); - const deviceID = await wallet.getDeviceID(); - this.keyring.add(wallet, deviceID); - this.keyring.emit(["MetaMask(ShapeShift Multichain)", deviceID, core.Events.CONNECT], deviceID); - - return wallet; - } -} diff --git a/packages/hdwallet-metamask/package.json b/packages/hdwallet-metamask/package.json deleted file mode 100644 index bb33c7b81..000000000 --- a/packages/hdwallet-metamask/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "@shapeshiftoss/hdwallet-metamask", - "version": "1.55.10", - "license": "MIT", - "publishConfig": { - "access": "public" - }, - "main": "dist/index.js", - "source": "src/index.ts", - "types": "dist/index.d.ts", - "scripts": { - "build": "tsc --build", - "clean": "rm -rf dist node_modules tsconfig.tsbuildinfo", - "prepublishOnly": "yarn clean && yarn build" - }, - "dependencies": { - "@metamask/detect-provider": "^1.2.0", - "@metamask/onboarding": "^1.0.1", - "@shapeshiftoss/hdwallet-core": "1.55.10", - "eth-rpc-errors": "^4.0.3", - "lodash": "^4.17.21" - }, - "devDependencies": { - "@types/lodash": "^4.14.168" - } -} diff --git a/packages/hdwallet-metamask/src/adapter.ts b/packages/hdwallet-metamask/src/adapter.ts deleted file mode 100644 index a8f206bbc..000000000 --- a/packages/hdwallet-metamask/src/adapter.ts +++ /dev/null @@ -1,56 +0,0 @@ -import detectEthereumProvider from "@metamask/detect-provider"; -import MetaMaskOnboarding from "@metamask/onboarding"; -import * as core from "@shapeshiftoss/hdwallet-core"; -import { providers } from "ethers"; - -import { MetaMaskHDWallet } from "./metamask"; - -export class MetaMaskAdapter { - keyring: core.Keyring; - - private constructor(keyring: core.Keyring) { - this.keyring = keyring; - } - - public static useKeyring(keyring: core.Keyring) { - return new MetaMaskAdapter(keyring); - } - - public async initialize(): Promise { - return Object.keys(this.keyring.wallets).length; - } - - public async pairDevice(): Promise { - // TODO: remove casting, @metamask/detect-provider npm package hasn't been published with latest typings - // https://github.com/MetaMask/detect-provider/blame/5ce916fc24779c4b36741531a41d9c8b3cbb0a17/src/index.ts#L37 - const provider = (await detectEthereumProvider({ - mustBeMetaMask: true, - silent: false, - timeout: 3000, - })) as providers.ExternalProvider | null; - if (!provider) { - const onboarding = new MetaMaskOnboarding(); - onboarding.startOnboarding(); - console.error("Please install MetaMask!"); - throw new Error("MetaMask provider not found"); - } - try { - await provider.request?.({ method: "eth_requestAccounts" }).catch(() => - provider.request?.({ - method: "wallet_requestPermissions", - params: [{ eth_accounts: {} }], - }) - ); - } catch (error) { - console.error("Could not get MetaMask accounts. "); - throw error; - } - const wallet = new MetaMaskHDWallet(provider); - await wallet.initialize(); - const deviceID = await wallet.getDeviceID(); - this.keyring.add(wallet, deviceID); - this.keyring.emit(["MetaMask", deviceID, core.Events.CONNECT], deviceID); - - return wallet; - } -} diff --git a/packages/hdwallet-metamask/src/ethereum.ts b/packages/hdwallet-metamask/src/ethereum.ts deleted file mode 100644 index 3a6734e84..000000000 --- a/packages/hdwallet-metamask/src/ethereum.ts +++ /dev/null @@ -1,133 +0,0 @@ -import * as core from "@shapeshiftoss/hdwallet-core"; -import { ETHSignedMessage } from "@shapeshiftoss/hdwallet-core"; -import { isHexString } from "ethers/lib/utils"; - -export function describeETHPath(path: core.BIP32Path): core.PathDescription { - const pathStr = core.addressNListToBIP32(path); - const unknown: core.PathDescription = { - verbose: pathStr, - coin: "Ethereum", - isKnown: false, - }; - - if (path.length !== 5) return unknown; - - if (path[0] !== 0x80000000 + 44) return unknown; - - if (path[1] !== 0x80000000 + core.slip44ByCoin("Ethereum")) return unknown; - - if ((path[2] & 0x80000000) >>> 0 !== 0x80000000) return unknown; - - if (path[3] !== 0) return unknown; - - if (path[4] !== 0) return unknown; - - const index = path[2] & 0x7fffffff; - return { - verbose: `Ethereum Account #${index}`, - accountIdx: index, - wholeAccount: true, - coin: "Ethereum", - isKnown: true, - }; -} - -// eslint-disable-next-line @typescript-eslint/no-unused-vars -export async function ethVerifyMessage(msg: core.ETHVerifyMessage, ethereum: any): Promise { - console.error("Method ethVerifyMessage unsupported for MetaMask wallet!"); - return null; -} - -export function ethGetAccountPaths(msg: core.ETHGetAccountPath): Array { - const slip44 = core.slip44ByCoin(msg.coin); - if (slip44 === undefined) return []; - return [ - { - addressNList: [0x80000000 + 44, 0x80000000 + slip44, 0x80000000 + msg.accountIdx, 0, 0], - hardenedPath: [0x80000000 + 44, 0x80000000 + slip44, 0x80000000 + msg.accountIdx], - relPath: [0, 0], - description: "MetaMask", - }, - ]; -} - -// eslint-disable-next-line @typescript-eslint/no-unused-vars -export async function ethSignTx(msg: core.ETHSignTx, ethereum: any, from: string): Promise { - console.error("Method ethSignTx unsupported for MetaMask wallet!"); - return null; -} - -export async function ethSendTx(msg: core.ETHSignTx, ethereum: any, from: string): Promise { - try { - const utxBase = { - from: from, - to: msg.to, - value: msg.value, - data: msg.data, - chainId: msg.chainId, - nonce: msg.nonce, - // MetaMask, like other Web3 libraries, derives its transaction schema from Ethereum's official JSON-RPC API specification - // (https://github.com/ethereum/execution-apis/blob/d63d2a02bcd2a8cef54ae2fc5bbff8b4fac944eb/src/schemas/transaction.json). - // That schema defines the use of the label `gas` to set the transaction's gas limit and not `gasLimit` as used in other - // libraries and as stated in the official yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf). - gas: msg.gasLimit, - }; - - const utx = msg.maxFeePerGas - ? { - ...utxBase, - maxFeePerGas: msg.maxFeePerGas, - maxPriorityFeePerGas: msg.maxPriorityFeePerGas, - } - : { ...utxBase, gasPrice: msg.gasPrice }; - - const signedTx = await ethereum.request({ - method: "eth_sendTransaction", - params: [utx], - }); - - return { - hash: signedTx, - } as core.ETHTxHash; - } catch (error) { - console.error(error); - return null; - } -} - -export async function ethSignMessage( - msg: core.ETHSignMessage, - ethereum: any, - address: string -): Promise { - try { - if (!isHexString(msg.message)) throw new Error("data is not an hex string"); - const signedMsg = await ethereum.request({ - method: "personal_sign", - params: [msg.message, address], - }); - - return { - address: address, - signature: signedMsg, - } as ETHSignedMessage; - } catch (error) { - console.error(error); - return null; - } -} - -export async function ethGetAddress(ethereum: any): Promise { - if (!(ethereum && ethereum.request)) { - return null; - } - try { - const ethAccounts = await ethereum.request({ - method: "eth_accounts", - }); - return ethAccounts[0]; - } catch (error) { - console.error(error); - return null; - } -} diff --git a/packages/hdwallet-metamask/src/index.ts b/packages/hdwallet-metamask/src/index.ts deleted file mode 100644 index 36eb75ae3..000000000 --- a/packages/hdwallet-metamask/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./adapter"; -export * from "./metamask"; diff --git a/packages/hdwallet-metamask/src/metamask.test.ts b/packages/hdwallet-metamask/src/metamask.test.ts deleted file mode 100644 index 05da66e19..000000000 --- a/packages/hdwallet-metamask/src/metamask.test.ts +++ /dev/null @@ -1,168 +0,0 @@ -import * as core from "@shapeshiftoss/hdwallet-core"; - -import { MetaMaskHDWallet, MetaMaskHDWalletInfo } from "."; - -describe("HDWalletInfo", () => { - const info = new MetaMaskHDWalletInfo(); - - it("should have correct metadata", async () => { - expect(info.getVendor()).toBe("MetaMask"); - expect(info.hasOnDevicePinEntry()).toBe(false); - expect(info.hasOnDevicePassphrase()).toBe(true); - expect(info.hasOnDeviceDisplay()).toBe(true); - expect(info.hasOnDeviceRecovery()).toBe(true); - expect(await info.ethSupportsNetwork(1)).toBe(true); - expect(await info.ethSupportsSecureTransfer()).toBe(false); - expect(info.ethSupportsNativeShapeShift()).toBe(false); - expect(await info.ethSupportsEIP1559()).toBe(true); - expect(await info.supportsOfflineSigning()).toBe(false); - expect(await info.supportsBroadcast()).toBe(true); - }); -}); - -describe("MetaMaskHDWallet", () => { - let wallet: MetaMaskHDWallet; - beforeEach(() => { - wallet = new MetaMaskHDWallet(core.untouchable("MetaMaskHDWallet:provider")); - wallet.ethAddress = "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8"; - }); - - it("should match the metadata", async () => { - expect(wallet.getVendor()).toBe("MetaMask"); - expect(wallet.hasOnDevicePinEntry()).toBe(false); - expect(wallet.hasOnDevicePassphrase()).toBe(true); - expect(wallet.hasOnDeviceDisplay()).toBe(true); - expect(wallet.hasOnDeviceRecovery()).toBe(true); - expect(await wallet.ethSupportsNetwork(1)).toBe(true); - expect(await wallet.ethSupportsSecureTransfer()).toBe(false); - expect(wallet.ethSupportsNativeShapeShift()).toBe(false); - expect(await wallet.ethSupportsEIP1559()).toBe(true); - expect(await wallet.supportsOfflineSigning()).toBe(false); - expect(wallet.supportsBip44Accounts()).toBe(false); - expect(await wallet.supportsBroadcast()).toBe(true); - }); - - it("should test ethSignMessage", async () => { - wallet.provider = { - request: jest.fn().mockReturnValue( - `Object { - "address": "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", - "signature": "0x05f51140905ffa33ffdc57f46b0b8d8fbb1d2a99f8cd843ca27893c01c31351c08b76d83dce412731c846e3b50649724415deb522d00950fbf4f2c1459c2b70b1b", - }` - ), - }; - const msg = "0x737570657220736563726574206d657373616765"; // super secret message - expect( - await wallet.ethSignMessage({ - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - message: msg, - }) - ).toMatchInlineSnapshot(` - Object { - "address": "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", - "signature": "Object { - \\"address\\": \\"0x73d0385F4d8E00C5e6504C6030F47BF6212736A8\\", - \\"signature\\": \\"0x05f51140905ffa33ffdc57f46b0b8d8fbb1d2a99f8cd843ca27893c01c31351c08b76d83dce412731c846e3b50649724415deb522d00950fbf4f2c1459c2b70b1b\\", - }", - } - `); - }); - - it("ethSignMessage returns null on error", async () => { - wallet.provider = { - request: jest.fn().mockRejectedValue(new Error("An Error has occurred")), - }; - - const msg = "0x737570657220736563726574206d657373616765"; // super secret message - const sig = await wallet.ethSignMessage({ - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - message: msg, - }); - - expect(sig).toBe(null); - }); - - it("ethGetAddress returns a valid address", async () => { - wallet.provider = { - request: jest.fn().mockReturnValue(["0x73d0385F4d8E00C5e6504C6030F47BF6212736A8"]), - }; - - const msg = "0x737570657220736563726574206d657373616765"; // super secret message - const sig = await wallet.ethSignMessage({ - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - message: msg, - }); - - expect(sig).toMatchObject({ - address: "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", - signature: ["0x73d0385F4d8E00C5e6504C6030F47BF6212736A8"], - }); - }); - it("ethSendTx returns a valid hash", async () => { - wallet.provider = { - request: jest.fn().mockReturnValue("0x123"), - }; - - const hash = await wallet.ethSendTx({ - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - nonce: "0xDEADBEEF", - gasPrice: "0xDEADBEEF", - gasLimit: "0xDEADBEEF", - to: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - value: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - data: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - chainId: 1, - }); - expect(wallet.provider.request).toHaveBeenCalled(); - expect(hash).toMatchObject({ hash: "0x123" }); - }); - it("ethSendTx returns a valid hash if maxFeePerGas is present in msg", async () => { - wallet.provider = { - request: jest.fn().mockReturnValue("0x123"), - }; - - const hash = await wallet.ethSendTx({ - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - nonce: "0xDEADBEEF", - gasLimit: "0xDEADBEEF", - maxFeePerGas: "0xDEADBEEF", - to: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - value: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - data: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - chainId: 1, - }); - expect(wallet.provider.request).toHaveBeenCalled(); - expect(hash).toMatchObject({ hash: "0x123" }); - }); - it("ethSendTx returns null on error", async () => { - wallet.provider = { - request: jest.fn().mockRejectedValue(new Error("An Error has occurred")), - }; - - const hash = await wallet.ethSendTx({ - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - nonce: "0xDEADBEEF", - gasPrice: "0xDEADBEEF", - gasLimit: "0xDEADBEEF", - to: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - value: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - data: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - chainId: 1, - }); - expect(wallet.provider.request).toHaveBeenCalled(); - expect(hash).toBe(null); - }); - it("ethVerifyMessage returns null as its not implemented", async () => { - wallet.provider = { - request: jest.fn().mockReturnValue("0x3f2329C9ADFbcCd9A84f52c906E936A42dA18CB8"), - }; - expect( - await wallet.ethVerifyMessage({ - address: "0x3f2329C9ADFbcCd9A84f52c906E936A42dA18CB8", - message: "hello world", - signature: - "0x29f7212ecc1c76cea81174af267b67506f754ea8c73f144afa900a0d85b24b21319621aeb062903e856352f38305710190869c3ce5a1425d65ef4fa558d0fc251b", - }) - ).toEqual(null); - }); -}); diff --git a/packages/hdwallet-metamask/src/metamask.ts b/packages/hdwallet-metamask/src/metamask.ts deleted file mode 100644 index 3592388e2..000000000 --- a/packages/hdwallet-metamask/src/metamask.ts +++ /dev/null @@ -1,389 +0,0 @@ -import * as core from "@shapeshiftoss/hdwallet-core"; -import { AddEthereumChainParameter } from "@shapeshiftoss/hdwallet-core"; -import { ethErrors, serializeError } from "eth-rpc-errors"; -import _ from "lodash"; - -import * as eth from "./ethereum"; - -export function isMetaMask(wallet: core.HDWallet): wallet is MetaMaskHDWallet { - return _.isObject(wallet) && (wallet as any)._isMetaMask; -} - -export class MetaMaskHDWalletInfo implements core.HDWalletInfo, core.ETHWalletInfo { - readonly _supportsBTCInfo = false; - readonly _supportsETHInfo = true; - readonly _supportsCosmosInfo = false; - readonly _supportsBinanceInfo = false; - readonly _supportsRippleInfo = false; - readonly _supportsEosInfo = false; - readonly _supportsFioInfo = false; - readonly _supportsThorchainInfo = false; - readonly _supportsSecretInfo = false; - readonly _supportsKavaInfo = false; - readonly _supportsTerraInfo = false; - - public getVendor(): string { - return "MetaMask"; - } - - public hasOnDevicePinEntry(): boolean { - return false; - } - - public hasOnDevicePassphrase(): boolean { - return true; - } - - public hasOnDeviceDisplay(): boolean { - return true; - } - - public hasOnDeviceRecovery(): boolean { - return true; - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public hasNativeShapeShift(srcCoin: core.Coin, dstCoin: core.Coin): boolean { - return false; - } - - public supportsBip44Accounts(): boolean { - return false; - } - - public supportsOfflineSigning(): boolean { - return false; - } - - public supportsBroadcast(): boolean { - return true; - } - - public describePath(msg: core.DescribePath): core.PathDescription { - switch (msg.coin) { - case "Ethereum": - return eth.describeETHPath(msg.path); - default: - throw new Error("Unsupported path"); - } - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public ethNextAccountPath(msg: core.ETHAccountPath): core.ETHAccountPath | undefined { - // TODO: What do we do here? - return undefined; - } - - public async ethSupportsNetwork(chainId: number): Promise { - return chainId === 1; - } - - public async ethSupportsSecureTransfer(): Promise { - return false; - } - - public ethSupportsNativeShapeShift(): boolean { - return false; - } - - public async ethSupportsEIP1559(): Promise { - return true; - } - - public ethGetAccountPaths(msg: core.ETHGetAccountPath): Array { - return eth.ethGetAccountPaths(msg); - } -} - -export class MetaMaskHDWallet implements core.HDWallet, core.ETHWallet { - readonly _supportsETH = true; - readonly _supportsETHInfo = true; - readonly _supportsBTCInfo = false; - readonly _supportsBTC = false; - readonly _supportsCosmosInfo = false; - readonly _supportsCosmos = false; - readonly _supportsEthSwitchChain = true; - readonly _supportsAvalanche = true; - readonly _supportsOptimism = true; - readonly _supportsBSC = true; - readonly _supportsPolygon = true; - readonly _supportsGnosis = true; - readonly _supportsArbitrum = true; - readonly _supportsArbitrumNova = true; - readonly _supportsBase = true; - readonly _supportsOsmosisInfo = false; - readonly _supportsOsmosis = false; - readonly _supportsBinanceInfo = false; - readonly _supportsBinance = false; - readonly _supportsDebugLink = false; - readonly _isPortis = false; - readonly _isMetaMask = true; - readonly _supportsRippleInfo = false; - readonly _supportsRipple = false; - readonly _supportsEosInfo = false; - readonly _supportsEos = false; - readonly _supportsFioInfo = false; - readonly _supportsFio = false; - readonly _supportsThorchainInfo = false; - readonly _supportsThorchain = false; - readonly _supportsSecretInfo = false; - readonly _supportsSecret = false; - readonly _supportsKava = false; - readonly _supportsKavaInfo = false; - readonly _supportsTerra = false; - readonly _supportsTerraInfo = false; - - info: MetaMaskHDWalletInfo & core.HDWalletInfo; - ethAddress?: string | null; - provider: any; - - constructor(provider: unknown) { - this.info = new MetaMaskHDWalletInfo(); - this.provider = provider; - } - - async getFeatures(): Promise> { - return {}; - } - - public async isLocked(): Promise { - return !this.provider._metamask.isUnlocked(); - } - - public getVendor(): string { - return "MetaMask"; - } - - public async getModel(): Promise { - return "MetaMask"; - } - - public async getLabel(): Promise { - return "MetaMask"; - } - - public async initialize(): Promise { - // nothing to initialize - } - - public hasOnDevicePinEntry(): boolean { - return this.info.hasOnDevicePinEntry(); - } - - public hasOnDevicePassphrase(): boolean { - return this.info.hasOnDevicePassphrase(); - } - - public hasOnDeviceDisplay(): boolean { - return this.info.hasOnDeviceDisplay(); - } - - public hasOnDeviceRecovery(): boolean { - return this.info.hasOnDeviceRecovery(); - } - - public hasNativeShapeShift(srcCoin: core.Coin, dstCoin: core.Coin): boolean { - return this.info.hasNativeShapeShift(srcCoin, dstCoin); - } - - public supportsBip44Accounts(): boolean { - return this.info.supportsBip44Accounts(); - } - - public supportsOfflineSigning(): boolean { - return false; - } - - public supportsBroadcast(): boolean { - return true; - } - - public async clearSession(): Promise { - // TODO: Can we lock MetaMask from here? - } - - public async ping(msg: core.Ping): Promise { - // no ping function for MetaMask, so just returning Core.Pong - return { msg: msg.msg }; - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async sendPin(pin: string): Promise { - // no concept of pin in MetaMask - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async sendPassphrase(passphrase: string): Promise { - // cannot send passphrase to MetaMask. Could show the widget? - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async sendCharacter(charater: string): Promise { - // no concept of sendCharacter in MetaMask - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async sendWord(word: string): Promise { - // no concept of sendWord in MetaMask - } - - public async cancel(): Promise { - // no concept of cancel in MetaMask - } - - // eslint-disable-next-line @typescript-eslint/no-empty-function - public async wipe(): Promise {} - - // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars - public async reset(msg: core.ResetDevice): Promise {} - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async recover(msg: core.RecoverDevice): Promise { - // no concept of recover in MetaMask - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async loadDevice(msg: core.LoadDevice): Promise { - // TODO: Does MetaMask allow this to be done programatically? - } - - public describePath(msg: core.DescribePath): core.PathDescription { - return this.info.describePath(msg); - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async getPublicKeys(msg: Array): Promise> { - // Ethereum public keys are not exposed by the RPC API - return []; - } - - public async isInitialized(): Promise { - return true; - } - - // eslint-disable-next-line @typescript-eslint/no-empty-function - public async disconnect(): Promise {} - - public async ethSupportsNetwork(chainId = 1): Promise { - return chainId === 1; - } - - public async ethGetChainId(): Promise { - try { - // chainId as hex string - const chainId: string = await this.provider.request({ method: "eth_chainId" }); - return parseInt(chainId, 16); - } catch (e) { - console.error(e); - return null; - } - } - - public async ethAddChain(params: AddEthereumChainParameter): Promise { - // at this point, we know that we're in the context of a valid MetaMask provider - await this.provider.request({ method: "wallet_addEthereumChain", params: [params] }); - } - - public async ethSwitchChain(params: AddEthereumChainParameter): Promise { - try { - // at this point, we know that we're in the context of a valid MetaMask provider - await this.provider.request({ method: "wallet_switchEthereumChain", params: [{ chainId: params.chainId }] }); - } catch (e: any) { - const error = serializeError(e); - // https://docs.metamask.io/guide/ethereum-provider.html#errors - // Internal error, which in the case of wallet_switchEthereumChain call means the chain isn't currently added to the wallet - if (error.code === -32603) { - // We only support Avalanche C-Chain currently. It is supported natively in XDEFI, and unsupported in Tally, both with no capabilities to add a new chain - // TODO(gomes): Find a better home for these. When that's done, we'll want to call ethSwitchChain with (params: AddEthereumChainParameter) instead - try { - await this.ethAddChain(params); - return; - } catch (addChainE: any) { - const addChainError = serializeError(addChainE); - - if (addChainError.code === 4001) { - throw ethErrors.provider.userRejectedRequest(); - } - - throw (addChainError.data as any).originalError as { - code: number; - message: string; - stack: string; - }; - } - } - - if (error.code === 4001) { - throw ethErrors.provider.userRejectedRequest(); - } - - throw (error.data as any).originalError as { - code: number; - message: string; - stack: string; - }; - } - } - - public async ethSupportsSecureTransfer(): Promise { - return false; - } - - public ethSupportsNativeShapeShift(): boolean { - return false; - } - - public async ethSupportsEIP1559(): Promise { - return true; - } - - public ethGetAccountPaths(msg: core.ETHGetAccountPath): Array { - return eth.ethGetAccountPaths(msg); - } - - public ethNextAccountPath(msg: core.ETHAccountPath): core.ETHAccountPath | undefined { - return this.info.ethNextAccountPath(msg); - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async ethGetAddress(_msg: core.ETHGetAddress): Promise { - if (this.ethAddress) { - return this.ethAddress; - } - const address = await eth.ethGetAddress(this.provider); - if (address) { - this.ethAddress = address; - return address; - } else { - this.ethAddress = null; - return null; - } - } - - public async ethSignTx(msg: core.ETHSignTx): Promise { - const address = await this.ethGetAddress(this.provider); - return address ? eth.ethSignTx(msg, this.provider, address) : null; - } - - public async ethSendTx(msg: core.ETHSignTx): Promise { - const address = await this.ethGetAddress(this.provider); - return address ? eth.ethSendTx(msg, this.provider, address) : null; - } - - public async ethSignMessage(msg: core.ETHSignMessage): Promise { - const address = await this.ethGetAddress(this.provider); - return address ? eth.ethSignMessage(msg, this.provider, address) : null; - } - - public async ethVerifyMessage(msg: core.ETHVerifyMessage): Promise { - return eth.ethVerifyMessage(msg, this.provider); - } - - public async getDeviceID(): Promise { - return "metaMask:" + (await this.ethGetAddress(this.provider)); - } - - public async getFirmwareVersion(): Promise { - return "metaMask"; - } -} diff --git a/packages/hdwallet-metamask/tsconfig.json b/packages/hdwallet-metamask/tsconfig.json deleted file mode 100644 index 0c82f8910..000000000 --- a/packages/hdwallet-metamask/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "rootDir": "src", - "outDir": "dist" - }, - "include": ["src/**/*"], - "exclude": ["node_modules", "dist", "**/*.test.ts"], - "references": [{ "path": "../hdwallet-core" }] -} \ No newline at end of file diff --git a/packages/hdwallet-native-vault/package.json b/packages/hdwallet-native-vault/package.json index 91f3afeac..dabd5b50d 100644 --- a/packages/hdwallet-native-vault/package.json +++ b/packages/hdwallet-native-vault/package.json @@ -1,6 +1,6 @@ { "name": "@shapeshiftoss/hdwallet-native-vault", - "version": "1.55.10", + "version": "1.55.11", "license": "MIT", "publishConfig": { "access": "public" @@ -14,7 +14,7 @@ "prepublishOnly": "yarn clean && yarn build" }, "dependencies": { - "@shapeshiftoss/hdwallet-native": "1.55.10", + "@shapeshiftoss/hdwallet-native": "1.55.11", "bip39": "^3.0.4", "hash-wasm": "^4.11.0", "idb-keyval": "^6.0.3", diff --git a/packages/hdwallet-native/package.json b/packages/hdwallet-native/package.json index 3a37b94c2..e2b948f38 100644 --- a/packages/hdwallet-native/package.json +++ b/packages/hdwallet-native/package.json @@ -1,6 +1,6 @@ { "name": "@shapeshiftoss/hdwallet-native", - "version": "1.55.10", + "version": "1.55.11", "license": "MIT", "publishConfig": { "access": "public" @@ -16,7 +16,7 @@ "dependencies": { "@shapeshiftoss/bitcoinjs-lib": "5.2.0-shapeshift.2", "@shapeshiftoss/fiosdk": "1.2.1-shapeshift.6", - "@shapeshiftoss/hdwallet-core": "1.55.10", + "@shapeshiftoss/hdwallet-core": "1.55.11", "@shapeshiftoss/proto-tx-builder": "^0.8.0", "@zxing/text-encoding": "^0.9.0", "bchaddrjs": "^0.4.9", diff --git a/packages/hdwallet-native/src/bitcoin.test.ts b/packages/hdwallet-native/src/bitcoin.test.ts index e51c9199b..dcaca5ed1 100644 --- a/packages/hdwallet-native/src/bitcoin.test.ts +++ b/packages/hdwallet-native/src/bitcoin.test.ts @@ -158,10 +158,6 @@ describe("NativeBTCWalletInfo", () => { expect(await info.btcSupportsScriptType("foobar", "p2pkh" as any)).toBe(false); }); - it("should not do anything when btcIsSameAccount is called", async () => { - expect(untouchable.call(info, "btcIsSameAccount", [])).toBe(false); - }); - it.each([ [ "an undefined scriptType", diff --git a/packages/hdwallet-native/src/bitcoin.ts b/packages/hdwallet-native/src/bitcoin.ts index 7275d9af4..3ca85648d 100644 --- a/packages/hdwallet-native/src/bitcoin.ts +++ b/packages/hdwallet-native/src/bitcoin.ts @@ -101,12 +101,6 @@ export function MixinNativeBTCWalletInfo): boolean { - // TODO: support at some point - return false; - } - btcNextAccountPath(msg: core.BTCAccountPath): core.BTCAccountPath | undefined { const description = core.describeUTXOPath(msg.addressNList, msg.coin, msg.scriptType); diff --git a/packages/hdwallet-native/src/native.ts b/packages/hdwallet-native/src/native.ts index f2131819f..ce127db89 100644 --- a/packages/hdwallet-native/src/native.ts +++ b/packages/hdwallet-native/src/native.ts @@ -161,7 +161,6 @@ class NativeHDWalletInfo case "atom": return core.cosmosDescribePath(msg.path); case "rune": - case "trune": case "thorchain": return core.thorchainDescribePath(msg.path); case "secret": diff --git a/packages/hdwallet-phantom/package.json b/packages/hdwallet-phantom/package.json index 6830d0ae8..66b1e1138 100644 --- a/packages/hdwallet-phantom/package.json +++ b/packages/hdwallet-phantom/package.json @@ -1,6 +1,6 @@ { "name": "@shapeshiftoss/hdwallet-phantom", - "version": "1.55.10", + "version": "1.55.11", "license": "MIT", "publishConfig": { "access": "public" @@ -15,7 +15,7 @@ }, "dependencies": { "@shapeshiftoss/bitcoinjs-lib": "5.2.0-shapeshift.2", - "@shapeshiftoss/hdwallet-core": "1.55.10", + "@shapeshiftoss/hdwallet-core": "1.55.11", "@solana/web3.js": "^1.95.3", "base64-js": "^1.5.1", "bitcoinjs-message": "^2.0.0", diff --git a/packages/hdwallet-phantom/src/phantom.ts b/packages/hdwallet-phantom/src/phantom.ts index 215be8b1b..aeca9b5b8 100644 --- a/packages/hdwallet-phantom/src/phantom.ts +++ b/packages/hdwallet-phantom/src/phantom.ts @@ -154,11 +154,6 @@ export class PhantomHDWalletInfo return btc.btcGetAccountPaths(msg); } - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public btcIsSameAccount(msg: core.BTCAccountPath[]): boolean { - throw new Error("Method not implemented."); - } - // eslint-disable-next-line @typescript-eslint/no-unused-vars public btcNextAccountPath(msg: core.BTCAccountPath): core.BTCAccountPath | undefined { throw new Error("Method not implemented"); diff --git a/packages/hdwallet-portis/package.json b/packages/hdwallet-portis/package.json index 96da7453c..0e841508c 100644 --- a/packages/hdwallet-portis/package.json +++ b/packages/hdwallet-portis/package.json @@ -1,6 +1,6 @@ { "name": "@shapeshiftoss/hdwallet-portis", - "version": "1.55.10", + "version": "1.55.11", "license": "MIT", "publishConfig": { "access": "public" @@ -15,7 +15,7 @@ }, "dependencies": { "@portis/web3": "3.0.10", - "@shapeshiftoss/hdwallet-core": "1.55.10", + "@shapeshiftoss/hdwallet-core": "1.55.11", "base64-js": "^1.5.1", "bip32": "^2.0.4", "bitcoinjs-lib": "^5.1.6", diff --git a/packages/hdwallet-portis/src/portis.ts b/packages/hdwallet-portis/src/portis.ts index 7b146353b..f1e3baef9 100644 --- a/packages/hdwallet-portis/src/portis.ts +++ b/packages/hdwallet-portis/src/portis.ts @@ -88,12 +88,6 @@ export class PortisHDWalletInfo implements core.HDWalletInfo, core.ETHWalletInfo return btc.btcGetAccountPaths(msg); } - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public btcIsSameAccount(msg: Array): boolean { - // TODO: Probably not correct - return false; - } - public btcNextAccountPath(msg: core.BTCAccountPath): core.BTCAccountPath | undefined { return btc.btcNextAccountPath(msg); } @@ -333,10 +327,6 @@ export class PortisHDWallet implements core.HDWallet, core.ETHWallet, core.BTCWa return this.info.btcGetAccountPaths(msg); } - public btcIsSameAccount(msg: Array): boolean { - return this.info.btcIsSameAccount(msg); - } - public btcNextAccountPath(msg: core.BTCAccountPath): core.BTCAccountPath | undefined { return this.info.btcNextAccountPath(msg); } diff --git a/packages/hdwallet-tallyho/package.json b/packages/hdwallet-tallyho/package.json deleted file mode 100644 index a706bb120..000000000 --- a/packages/hdwallet-tallyho/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "@shapeshiftoss/hdwallet-tallyho", - "version": "1.55.10", - "license": "MIT", - "publishConfig": { - "access": "public" - }, - "main": "dist/index.js", - "source": "src/index.ts", - "types": "dist/index.d.ts", - "scripts": { - "build": "tsc --build", - "clean": "rm -rf dist node_modules tsconfig.tsbuildinfo", - "prepublishOnly": "yarn clean && yarn build" - }, - "dependencies": { - "@shapeshiftoss/hdwallet-core": "1.55.10", - "lodash": "^4.17.21", - "tallyho-onboarding": "^1.0.2" - }, - "devDependencies": { - "@types/lodash": "^4.14.168" - } -} diff --git a/packages/hdwallet-tallyho/src/adapter.test.ts b/packages/hdwallet-tallyho/src/adapter.test.ts deleted file mode 100644 index 29c1c0f85..000000000 --- a/packages/hdwallet-tallyho/src/adapter.test.ts +++ /dev/null @@ -1,11 +0,0 @@ -import * as core from "@shapeshiftoss/hdwallet-core"; - -import { TallyHoAdapter } from "./adapter"; - -describe("TallyHoAdapter", () => { - it("throws error if provider is not preset", async () => { - const keyring = new core.Keyring(); - const adapter = TallyHoAdapter.useKeyring(keyring); - await expect(async () => await adapter.pairDevice()).rejects.toThrowError("Could not get Tally Ho accounts."); - }); -}); diff --git a/packages/hdwallet-tallyho/src/adapter.ts b/packages/hdwallet-tallyho/src/adapter.ts deleted file mode 100644 index 06edd9b5e..000000000 --- a/packages/hdwallet-tallyho/src/adapter.ts +++ /dev/null @@ -1,102 +0,0 @@ -import * as core from "@shapeshiftoss/hdwallet-core"; -import { providers } from "ethers"; -import TallyHoOnboarding from "tallyho-onboarding"; - -import { TallyHoHDWallet } from "./tallyho"; - -interface TallyHoEthereumProvider extends providers.ExternalProvider { - isTally?: boolean; -} - -interface Window { - ethereum?: TallyHoEthereumProvider; -} - -export class TallyHoAdapter { - keyring: core.Keyring; - - private constructor(keyring: core.Keyring) { - this.keyring = keyring; - } - - public static useKeyring(keyring: core.Keyring) { - return new TallyHoAdapter(keyring); - } - - public async initialize(): Promise { - return Object.keys(this.keyring.wallets).length; - } - - public async pairDevice(): Promise { - let provider: TallyHoEthereumProvider | null; - // eslint-disable-next-line no-useless-catch - try { - provider = await this.detectTallyProvider(); - } catch (error) { - throw error; - } - if (!provider) { - const onboarding = new TallyHoOnboarding(); - onboarding.startOnboarding(); - console.error("Please install Tally Ho!"); - throw new Error("Could not get Tally Ho accounts."); - } - - // eslint-disable-next-line no-useless-catch - try { - await provider.request?.({ method: "eth_requestAccounts" }); - } catch (error) { - throw error; - } - const wallet = new TallyHoHDWallet(provider); - const deviceID = await wallet.getDeviceID(); - this.keyring.add(wallet, deviceID); - this.keyring.emit(["Tally Ho", deviceID, core.Events.CONNECT], deviceID); - - return wallet; - } - - /* - * Tally works the same way as metamask. - * This code is copied from the @metamask/detect-provider package - * @see https://www.npmjs.com/package/@metamask/detect-provider - */ - private async detectTallyProvider(): Promise { - let handled = false; - - return new Promise((resolve) => { - if ((window as Window).ethereum) { - // eslint-disable-next-line @typescript-eslint/no-use-before-define - handleEthereum(); - } else { - // eslint-disable-next-line @typescript-eslint/no-use-before-define - window.addEventListener("ethereum#initialized", handleEthereum, { once: true }); - - setTimeout(() => { - // eslint-disable-next-line @typescript-eslint/no-use-before-define - handleEthereum(); - }, 3000); - } - - function handleEthereum() { - if (handled) { - return; - } - handled = true; - - window.removeEventListener("ethereum#initialized", handleEthereum); - - const { ethereum } = window as Window; - - if (ethereum && ethereum.isTally) { - resolve(ethereum as unknown as TallyHoEthereumProvider); - } else { - const message = ethereum ? "Non-TallyHo window.ethereum detected." : "Unable to detect window.ethereum."; - - console.error("hdwallet-tallyho: ", message); - resolve(null); - } - } - }); - } -} diff --git a/packages/hdwallet-tallyho/src/ethereum.test.ts b/packages/hdwallet-tallyho/src/ethereum.test.ts deleted file mode 100644 index 9ccaada1b..000000000 --- a/packages/hdwallet-tallyho/src/ethereum.test.ts +++ /dev/null @@ -1,246 +0,0 @@ -import * as core from "@shapeshiftoss/hdwallet-core"; -import { providers } from "ethers"; - -import * as ethereum from "./ethereum"; - -describe("Tally Ho - Ethereum Adapter", () => { - it("ethVerifyMessage returns null as its not implemented", async () => { - const ethereumProvider: providers.ExternalProvider = { - request: jest.fn().mockReturnValue("0x3f2329C9ADFbcCd9A84f52c906E936A42dA18CB8"), - }; - expect( - await ethereum.ethVerifyMessage( - { - address: "0x3f2329C9ADFbcCd9A84f52c906E936A42dA18CB8", - message: "hello world", - signature: - "0x29f7212ecc1c76cea81174af267b67506f754ea8c73f144afa900a0d85b24b21319621aeb062903e856352f38305710190869c3ce5a1425d65ef4fa558d0fc251b", - }, - ethereumProvider - ) - ).toBe(null); - }); - it("ethGetAccountPaths should return correct paths", () => { - const paths = ethereum.ethGetAccountPaths({ coin: "Ethereum", accountIdx: 0 }); - expect(paths).toMatchObject([ - { - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - hardenedPath: core.bip32ToAddressNList("m/44'/60'/0'"), - relPath: [0, 0], - description: "Tally Ho", - }, - ]); - }); - it("ethGetAccountPaths should return empty path", () => { - const paths = ethereum.ethGetAccountPaths({ coin: "RandomCoin", accountIdx: 0 }); - expect(paths).toMatchObject([]); - }); - it("ethSignTx returns null as its not implemented", async () => { - const ethereumProvider: providers.ExternalProvider = { - request: jest.fn().mockReturnValue({ - r: "0x63db3dd3bf3e1fe7dde1969c0fc8850e34116d0b501c0483a0e08c0f77b8ce0a", - s: "0x28297d012cccf389f6332415e96ee3fc0bbf8474d05f646e029cd281a031464b", - v: 38, - serialized: - "0xf86b018501dcd650008256229412ec06288edd7ae2cc41a843fe089237fc7354f0872c68af0bb140008026a063db3dd3bf3e1fe7dde1969c0fc8850e34116d0b501c0483a0e08c0f77b8ce0aa028297d012cccf389f6332415e96ee3fc0bbf8474d05f646e029cd281a031464b", - }), - }; - expect( - await ethereum.ethSignTx( - { - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - nonce: "0xDEADBEEF", - gasPrice: "0xDEADBEEF", - gasLimit: "0xDEADBEEF", - to: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - value: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - data: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - chainId: 1, - }, - ethereumProvider, - "0x123" - ) - ).toEqual(null); - }); - it("ethSendTx returns a valid hash", async () => { - const ethereumProvider: providers.ExternalProvider = { - request: jest.fn().mockReturnValue("0x123"), - }; - - const hash = await ethereum.ethSendTx( - { - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - nonce: "0xDEADBEEF", - gasPrice: "0xDEADBEEF", - gasLimit: "0xDEADBEEF", - to: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - value: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - data: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - chainId: 1, - }, - ethereumProvider, - "0x123" - ); - expect(ethereumProvider.request).toHaveBeenCalled(); - expect(hash).toMatchObject({ hash: "0x123" }); - }); - it("ethSendTx returns a valid hash if maxFeePerGas is present in msg", async () => { - const ethereumProvider: providers.ExternalProvider = { - request: jest.fn().mockReturnValue("0x123"), - }; - - const hash = await ethereum.ethSendTx( - { - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - nonce: "0xDEADBEEF", - gasLimit: "0xDEADBEEF", - maxFeePerGas: "0xDEADBEEF", - to: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - value: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - data: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - chainId: 1, - }, - ethereumProvider, - "0x123" - ); - expect(ethereumProvider.request).toHaveBeenCalled(); - expect(hash).toMatchObject({ hash: "0x123" }); - }); - it("ethSendTx returns null on error", async () => { - const ethereumProvider: providers.ExternalProvider = { - request: jest.fn().mockRejectedValue(new Error("An Error has occurred")), - }; - - const hash = await ethereum.ethSendTx( - { - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - nonce: "0xDEADBEEF", - gasPrice: "0xDEADBEEF", - gasLimit: "0xDEADBEEF", - to: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - value: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - data: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - chainId: 1, - }, - ethereumProvider, - "0x123" - ); - expect(ethereumProvider.request).toHaveBeenCalled(); - expect(hash).toBe(null); - }); - - it("ethSignMessage returns a valid signature object", async () => { - const ethereumProvider: providers.ExternalProvider = { - request: jest.fn().mockReturnValue( - `Object { - "address": "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", - "signature": "0x05f51140905ffa33ffdc57f46b0b8d8fbb1d2a99f8cd843ca27893c01c31351c08b76d83dce412731c846e3b50649724415deb522d00950fbf4f2c1459c2b70b1b", - }` - ), - }; - - const msg = "0x737570657220736563726574206d657373616765"; // super secret message - const sig = await ethereum.ethSignMessage( - { - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - message: msg, - }, - ethereumProvider, - "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8" - ); - - expect(sig).toMatchInlineSnapshot(` - Object { - "address": "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", - "signature": "Object { - \\"address\\": \\"0x73d0385F4d8E00C5e6504C6030F47BF6212736A8\\", - \\"signature\\": \\"0x05f51140905ffa33ffdc57f46b0b8d8fbb1d2a99f8cd843ca27893c01c31351c08b76d83dce412731c846e3b50649724415deb522d00950fbf4f2c1459c2b70b1b\\", - }", - } - `); - }); - - it("ethSignMessage returns a valid signature object when called with bytes message", async () => { - const ethereumProvider = { - request: jest.fn().mockReturnValue( - `Object { - "address": "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", - "signature": "0x05f51140905ffa33ffdc57f46b0b8d8fbb1d2a99f8cd843ca27893c01c31351c08b76d83dce412731c846e3b50649724415deb522d00950fbf4f2c1459c2b70b1b", - }` - ), - }; - - const msg = "0xcf8746d5aa75ecfd907eb3cae0aecf7f698a8bfe1f97eb2d77d6539e8991b0ea"; - const sig = await ethereum.ethSignMessage( - { - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - message: msg, - }, - ethereumProvider, - "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8" - ); - - expect(ethereumProvider.request.mock.calls[0][0]).toMatchInlineSnapshot(` - Object { - "method": "personal_sign", - "params": Array [ - "0xcf8746d5aa75ecfd907eb3cae0aecf7f698a8bfe1f97eb2d77d6539e8991b0ea", - "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", - ], - } - `); - expect(sig).toMatchInlineSnapshot(` - Object { - "address": "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", - "signature": "Object { - \\"address\\": \\"0x73d0385F4d8E00C5e6504C6030F47BF6212736A8\\", - \\"signature\\": \\"0x05f51140905ffa33ffdc57f46b0b8d8fbb1d2a99f8cd843ca27893c01c31351c08b76d83dce412731c846e3b50649724415deb522d00950fbf4f2c1459c2b70b1b\\", - }", - } - `); - }); - - it("ethSignMessage returns null on error", async () => { - const ethereumProvider: providers.ExternalProvider = { - request: jest.fn().mockRejectedValue(new Error("An Error has occurred")), - }; - - const msg = "0x737570657220736563726574206d657373616765"; // super secret message - const sig = await ethereum.ethSignMessage( - { - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - message: msg, - }, - ethereumProvider, - "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8" - ); - - expect(sig).toBe(null); - }); - - it("ethGetAddress returns a valid address", async () => { - const ethereumProvider: providers.ExternalProvider = { - request: jest.fn().mockReturnValue(["0x73d0385F4d8E00C5e6504C6030F47BF6212736A8"]), - }; - - const address = await ethereum.ethGetAddress(ethereumProvider); - - expect(address).toBe("0x73d0385F4d8E00C5e6504C6030F47BF6212736A8"); - }); - it("ethGetAddress returns null on error", async () => { - const ethereumProvider: providers.ExternalProvider = { - request: jest.fn().mockRejectedValue(new Error("An error has occurred")), - }; - - const address = await ethereum.ethGetAddress(ethereumProvider); - - expect(address).toBe(null); - }); - it("ethGetAddress returns null if no provider", async () => { - const ethereumProvider = {}; - - const address = await ethereum.ethGetAddress(ethereumProvider); - - expect(address).toBe(null); - }); -}); diff --git a/packages/hdwallet-tallyho/src/ethereum.ts b/packages/hdwallet-tallyho/src/ethereum.ts deleted file mode 100644 index cc264ec7c..000000000 --- a/packages/hdwallet-tallyho/src/ethereum.ts +++ /dev/null @@ -1,132 +0,0 @@ -import * as core from "@shapeshiftoss/hdwallet-core"; -import { isHexString } from "ethers/lib/utils"; - -export function describeETHPath(path: core.BIP32Path): core.PathDescription { - const pathStr = core.addressNListToBIP32(path); - const unknown: core.PathDescription = { - verbose: pathStr, - coin: "Ethereum", - isKnown: false, - }; - - if (path.length !== 5) return unknown; - - if (path[0] !== 0x80000000 + 44) return unknown; - - if (path[1] !== 0x80000000 + core.slip44ByCoin("Ethereum")) return unknown; - - if ((path[2] & 0x80000000) >>> 0 !== 0x80000000) return unknown; - - if (path[3] !== 0) return unknown; - - if (path[4] !== 0) return unknown; - - const index = path[2] & 0x7fffffff; - return { - verbose: `Ethereum Account #${index}`, - accountIdx: index, - wholeAccount: true, - coin: "Ethereum", - isKnown: true, - }; -} - -// eslint-disable-next-line @typescript-eslint/no-unused-vars -export async function ethVerifyMessage(msg: core.ETHVerifyMessage, ethereum: any): Promise { - console.error("Method ethVerifyMessage unsupported for Tally Ho wallet!"); - return null; -} - -export function ethGetAccountPaths(msg: core.ETHGetAccountPath): Array { - const slip44 = core.slip44ByCoin(msg.coin); - if (slip44 === undefined) return []; - return [ - { - addressNList: [0x80000000 + 44, 0x80000000 + slip44, 0x80000000 + msg.accountIdx, 0, 0], - hardenedPath: [0x80000000 + 44, 0x80000000 + slip44, 0x80000000 + msg.accountIdx], - relPath: [0, 0], - description: "Tally Ho", - }, - ]; -} - -// eslint-disable-next-line @typescript-eslint/no-unused-vars -export async function ethSignTx(msg: core.ETHSignTx, ethereum: any, from: string): Promise { - console.error("Method ethSignTx unsupported for Tally Ho wallet!"); - return null; -} - -export async function ethSendTx(msg: core.ETHSignTx, ethereum: any, from: string): Promise { - try { - const utxBase = { - from: from, - to: msg.to, - value: msg.value, - data: msg.data, - chainId: msg.chainId, - nonce: msg.nonce, - // Tally Ho, like other Web3 libraries, derives its transaction schema from Ethereum's official JSON-RPC API specification - // (https://github.com/ethereum/execution-apis/blob/d63d2a02bcd2a8cef54ae2fc5bbff8b4fac944eb/src/schemas/transaction.json). - // That schema defines the use of the label `gas` to set the transaction's gas limit and not `gasLimit` as used in other - // libraries and as stated in the official yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf). - gas: msg.gasLimit, - }; - - const utx = msg.maxFeePerGas - ? { - ...utxBase, - maxFeePerGas: msg.maxFeePerGas, - maxPriorityFeePerGas: msg.maxPriorityFeePerGas, - } - : { ...utxBase, gasPrice: msg.gasPrice }; - - const signedTx = await ethereum.request({ - method: "eth_sendTransaction", - params: [utx], - }); - - return { - hash: signedTx, - } as core.ETHTxHash; - } catch (error) { - console.error(error); - return null; - } -} - -export async function ethSignMessage( - msg: core.ETHSignMessage, - ethereum: any, - address: string -): Promise { - try { - if (!isHexString(msg.message)) throw new Error("data is not an hex string"); - const signedMsg = await ethereum.request({ - method: "personal_sign", - params: [msg.message, address], - }); - - return { - address: address, - signature: signedMsg, - } as core.ETHSignedMessage; - } catch (error) { - console.error(error); - return null; - } -} - -export async function ethGetAddress(ethereum: any): Promise { - if (!(ethereum && ethereum.request)) { - return null; - } - try { - const ethAccounts = await ethereum.request({ - method: "eth_accounts", - }); - return ethAccounts[0]; - } catch (error) { - console.error(error); - return null; - } -} diff --git a/packages/hdwallet-tallyho/src/index.test.ts b/packages/hdwallet-tallyho/src/index.test.ts deleted file mode 100644 index 7913ea523..000000000 --- a/packages/hdwallet-tallyho/src/index.test.ts +++ /dev/null @@ -1,11 +0,0 @@ -import * as library from "./"; - -describe("Exports all expected classes", () => { - it("should export TallyHoAdapter", () => { - expect(library.TallyHoAdapter.name).toBe("TallyHoAdapter"); - }); - - it("should export XDeFiHDWallet", () => { - expect(library.TallyHoHDWallet.name).toBe("TallyHoHDWallet"); - }); -}); diff --git a/packages/hdwallet-tallyho/src/index.ts b/packages/hdwallet-tallyho/src/index.ts deleted file mode 100644 index db2aa34ab..000000000 --- a/packages/hdwallet-tallyho/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./adapter"; -export * from "./tallyho"; diff --git a/packages/hdwallet-tallyho/src/tallyho.test.ts b/packages/hdwallet-tallyho/src/tallyho.test.ts deleted file mode 100644 index 4c4b3b729..000000000 --- a/packages/hdwallet-tallyho/src/tallyho.test.ts +++ /dev/null @@ -1,203 +0,0 @@ -import * as core from "@shapeshiftoss/hdwallet-core"; - -import { TallyHoHDWallet, TallyHoHDWalletInfo } from "."; - -describe("HDWalletInfo", () => { - const info = new TallyHoHDWalletInfo(); - - it("should have correct metadata", async () => { - expect(info.getVendor()).toBe("Tally Ho"); - expect(info.hasOnDevicePinEntry()).toBe(false); - expect(info.hasOnDevicePassphrase()).toBe(true); - expect(info.hasOnDeviceDisplay()).toBe(true); - expect(info.hasOnDeviceRecovery()).toBe(true); - expect(await info.ethSupportsNetwork(1)).toBe(true); - expect(await info.ethSupportsSecureTransfer()).toBe(false); - expect(info.ethSupportsNativeShapeShift()).toBe(false); - expect(await info.ethSupportsEIP1559()).toBe(true); - expect(await info.supportsOfflineSigning()).toBe(false); - expect(await info.supportsBroadcast()).toBe(true); - }); - it("should produce correct path descriptions", () => { - expect(info.hasNativeShapeShift()).toBe(false); - [ - { - msg: { coin: "Ethereum", path: [44 + 0x80000000, 60 + 0x80000000, 0 + 0x80000000, 0, 0] }, - out: { coin: "Ethereum", verbose: "Ethereum Account #0", isKnown: true }, - }, - ].forEach((x) => expect(info.describePath(x.msg)).toMatchObject(x.out)); - expect(() => info.describePath({ coin: "foobar", path: [1, 2, 3] })).toThrowError("Unsupported path"); - }); -}); - -describe("TallyHoHDWallet", () => { - let wallet: TallyHoHDWallet; - beforeEach(() => { - wallet = new TallyHoHDWallet(core.untouchable("TallyHoHDWallet:provider")); - wallet.ethAddress = "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8"; - }); - - it("should match the metadata", async () => { - expect(wallet.getVendor()).toBe("Tally Ho"); - expect(wallet.hasOnDevicePinEntry()).toBe(false); - expect(wallet.hasOnDevicePassphrase()).toBe(true); - expect(wallet.hasOnDeviceDisplay()).toBe(true); - expect(wallet.hasOnDeviceRecovery()).toBe(true); - expect(await wallet.ethSupportsNetwork(1)).toBe(true); - expect(await wallet.ethSupportsSecureTransfer()).toBe(false); - expect(wallet.ethSupportsNativeShapeShift()).toBe(false); - expect(await wallet.ethSupportsEIP1559()).toBe(true); - expect(await wallet.supportsOfflineSigning()).toBe(false); - expect(wallet.supportsBip44Accounts()).toBe(false); - expect(await wallet.supportsBroadcast()).toBe(true); - }); - - it("should test ethSignTx", async () => { - wallet.ethAddress = "0x123"; - wallet.provider = { - request: jest.fn().mockReturnValue({ - r: "0x63db3dd3bf3e1fe7dde1969c0fc8850e34116d0b501c0483a0e08c0f77b8ce0a", - s: "0x28297d012cccf389f6332415e96ee3fc0bbf8474d05f646e029cd281a031464b", - v: 38, - serialized: - "0xf86b018501dcd650008256229412ec06288edd7ae2cc41a843fe089237fc7354f0872c68af0bb140008026a063db3dd3bf3e1fe7dde1969c0fc8850e34116d0b501c0483a0e08c0f77b8ce0aa028297d012cccf389f6332415e96ee3fc0bbf8474d05f646e029cd281a031464b", - }), - }; - expect( - await wallet.ethSignTx({ - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - nonce: "0xDEADBEEF", - gasPrice: "0xDEADBEEF", - gasLimit: "0xDEADBEEF", - to: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - value: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - data: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - chainId: 1, - }) - ).toEqual(null); - }); - - it("should test ethSignMessage", async () => { - wallet.provider = { - request: jest.fn().mockReturnValue( - `Object { - "address": "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", - "signature": "0x05f51140905ffa33ffdc57f46b0b8d8fbb1d2a99f8cd843ca27893c01c31351c08b76d83dce412731c846e3b50649724415deb522d00950fbf4f2c1459c2b70b1b", - }` - ), - }; - const msg = "0x737570657220736563726574206d657373616765"; // super secret message - expect( - await wallet.ethSignMessage({ - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - message: msg, - }) - ).toMatchInlineSnapshot(` - Object { - "address": "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", - "signature": "Object { - \\"address\\": \\"0x73d0385F4d8E00C5e6504C6030F47BF6212736A8\\", - \\"signature\\": \\"0x05f51140905ffa33ffdc57f46b0b8d8fbb1d2a99f8cd843ca27893c01c31351c08b76d83dce412731c846e3b50649724415deb522d00950fbf4f2c1459c2b70b1b\\", - }", - } - `); - }); - - it("ethSignMessage returns null on error", async () => { - wallet.provider = { - request: jest.fn().mockRejectedValue(new Error("An Error has occurred")), - }; - - const msg = "0x737570657220736563726574206d657373616765"; // super secret message - const sig = await wallet.ethSignMessage({ - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - message: msg, - }); - - expect(sig).toBe(null); - }); - - it("ethGetAddress returns a valid address", async () => { - wallet.provider = { - request: jest.fn().mockReturnValue(["0x73d0385F4d8E00C5e6504C6030F47BF6212736A8"]), - }; - - const msg = "0x737570657220736563726574206d657373616765"; // super secret message - const sig = await wallet.ethSignMessage({ - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - message: msg, - }); - - expect(sig).toMatchObject({ - address: "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", - signature: ["0x73d0385F4d8E00C5e6504C6030F47BF6212736A8"], - }); - }); - it("ethSendTx returns a valid hash", async () => { - wallet.provider = { - request: jest.fn().mockReturnValue("0x123"), - }; - - const hash = await wallet.ethSendTx({ - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - nonce: "0xDEADBEEF", - gasPrice: "0xDEADBEEF", - gasLimit: "0xDEADBEEF", - to: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - value: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - data: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - chainId: 1, - }); - expect(wallet.provider.request).toHaveBeenCalled(); - expect(hash).toMatchObject({ hash: "0x123" }); - }); - it("ethSendTx returns a valid hash if maxFeePerGas is present in msg", async () => { - wallet.provider = { - request: jest.fn().mockReturnValue("0x123"), - }; - - const hash = await wallet.ethSendTx({ - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - nonce: "0xDEADBEEF", - gasLimit: "0xDEADBEEF", - maxFeePerGas: "0xDEADBEEF", - to: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - value: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - data: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - chainId: 1, - }); - expect(wallet.provider.request).toHaveBeenCalled(); - expect(hash).toMatchObject({ hash: "0x123" }); - }); - it("ethSendTx returns null on error", async () => { - wallet.provider = { - request: jest.fn().mockRejectedValue(new Error("An Error has occurred")), - }; - - const hash = await wallet.ethSendTx({ - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - nonce: "0xDEADBEEF", - gasPrice: "0xDEADBEEF", - gasLimit: "0xDEADBEEF", - to: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - value: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - data: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - chainId: 1, - }); - expect(wallet.provider.request).toHaveBeenCalled(); - expect(hash).toBe(null); - }); - it("ethVerifyMessage returns null as its not implemented", async () => { - wallet.provider = { - request: jest.fn().mockReturnValue("0x3f2329C9ADFbcCd9A84f52c906E936A42dA18CB8"), - }; - expect( - await wallet.ethVerifyMessage({ - address: "0x3f2329C9ADFbcCd9A84f52c906E936A42dA18CB8", - message: "hello world", - signature: - "0x29f7212ecc1c76cea81174af267b67506f754ea8c73f144afa900a0d85b24b21319621aeb062903e856352f38305710190869c3ce5a1425d65ef4fa558d0fc251b", - }) - ).toEqual(null); - }); -}); diff --git a/packages/hdwallet-tallyho/src/tallyho.ts b/packages/hdwallet-tallyho/src/tallyho.ts deleted file mode 100644 index 628522f7e..000000000 --- a/packages/hdwallet-tallyho/src/tallyho.ts +++ /dev/null @@ -1,315 +0,0 @@ -import * as core from "@shapeshiftoss/hdwallet-core"; -import { AddEthereumChainParameter } from "@shapeshiftoss/hdwallet-core"; -import _ from "lodash"; - -import * as eth from "./ethereum"; - -export function isTallyHo(wallet: core.HDWallet): wallet is TallyHoHDWallet { - return _.isObject(wallet) && (wallet as any)._isTallyHo; -} - -export class TallyHoHDWalletInfo implements core.HDWalletInfo, core.ETHWalletInfo { - readonly _supportsETHInfo = true; - private _ethAddress: string | null = null; - - public getVendor(): string { - return "Tally Ho"; - } - - public hasOnDevicePinEntry(): boolean { - return false; - } - - public hasOnDevicePassphrase(): boolean { - return true; - } - - public hasOnDeviceDisplay(): boolean { - return true; - } - - public hasOnDeviceRecovery(): boolean { - return true; - } - - public hasNativeShapeShift(): boolean { - // It doesn't... yet? - never ever never ever ever - return false; - } - - public supportsBip44Accounts(): boolean { - return false; // unsure - } - - public supportsOfflineSigning(): boolean { - return false; - } - - public supportsBroadcast(): boolean { - return true; - } - - public describePath(msg: core.DescribePath): core.PathDescription { - switch (msg.coin) { - case "Ethereum": - return eth.describeETHPath(msg.path); - default: - throw new Error("Unsupported path"); - } - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public ethNextAccountPath(_msg: core.ETHAccountPath): core.ETHAccountPath | undefined { - return undefined; - } - - public async ethSupportsNetwork(chainId = 1): Promise { - return chainId === 1; - } - - public async ethSupportsSecureTransfer(): Promise { - return false; - } - - public ethSupportsNativeShapeShift(): boolean { - return false; - } - - public async ethSupportsEIP1559(): Promise { - return true; - } - - public ethGetAccountPaths(msg: core.ETHGetAccountPath): Array { - return eth.ethGetAccountPaths(msg); - } -} - -export class TallyHoHDWallet implements core.HDWallet, core.ETHWallet { - readonly _supportsETH = true; - readonly _supportsETHInfo = true; - readonly _supportsEthSwitchChain = false; - readonly _supportsAvalanche = false; - readonly _supportsOptimism = false; - readonly _supportsPolygon = true; - readonly _supportsGnosis = false; - readonly _supportsArbitrum = true; - readonly _supportsArbitrumNova = false; - readonly _supportsBase = false; - readonly _supportsBSC = false; - readonly _isTallyHo = true; - - info: TallyHoHDWalletInfo & core.HDWalletInfo; - ethAddress?: string | null; - provider: any; - - constructor(provider: unknown) { - this.info = new TallyHoHDWalletInfo(); - this.provider = provider; - } - - async getFeatures(): Promise> { - return {}; - } - - public async isLocked(): Promise { - return !this.provider.tallyHo.isUnlocked(); - } - - public getVendor(): string { - return "Tally Ho"; - } - - public async getModel(): Promise { - return "Tally Ho"; - } - - public async getLabel(): Promise { - return "Tally Ho"; - } - - public async initialize(): Promise { - // nothing to initialize - } - - public hasOnDevicePinEntry(): boolean { - return this.info.hasOnDevicePinEntry(); - } - - public hasOnDevicePassphrase(): boolean { - return this.info.hasOnDevicePassphrase(); - } - - public hasOnDeviceDisplay(): boolean { - return this.info.hasOnDeviceDisplay(); - } - - public hasOnDeviceRecovery(): boolean { - return this.info.hasOnDeviceRecovery(); - } - - public hasNativeShapeShift(srcCoin: core.Coin, dstCoin: core.Coin): boolean { - return this.info.hasNativeShapeShift(srcCoin, dstCoin); - } - - public supportsBip44Accounts(): boolean { - return this.info.supportsBip44Accounts(); - } - - public supportsOfflineSigning(): boolean { - // Keep an eye on the status of the refactor PR here: https://github.com/tallycash/extension/pull/1165/files. This will add offline signing support to Tally Ho, at which point this should return true. - return false; - } - - public supportsBroadcast(): boolean { - return true; - } - - public async clearSession(): Promise { - // TODO: Can we lock Tally Ho from here? - } - - public async ping(msg: core.Ping): Promise { - // no ping function for Tally Ho, so just returning Core.Pong - return { msg: msg.msg }; - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async sendPin(pin: string): Promise { - // no concept of pin in Tally Ho - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async sendPassphrase(passphrase: string): Promise { - // cannot send passphrase to Tally Ho. Could show the widget? - } - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async sendCharacter(charater: string): Promise { - // no concept of sendCharacter in Tally Ho - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async sendWord(word: string): Promise { - // no concept of sendWord in Tally Ho - } - - public async cancel(): Promise { - // no concept of cancel in Tally Ho - } - // eslint-disable-next-line @typescript-eslint/no-empty-function - public async wipe(): Promise {} - - // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars - public async reset(msg: core.ResetDevice): Promise {} - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async recover(msg: core.RecoverDevice): Promise { - // no concept of recover in Tally Ho - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async loadDevice(msg: core.LoadDevice): Promise { - // TODO: Does Tally Ho allow this to be done programatically? - } - - public describePath(msg: core.DescribePath): core.PathDescription { - return this.info.describePath(msg); - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async getPublicKeys(msg: Array): Promise> { - // Ethereum public keys are not exposed by the RPC API - return []; - } - - public async isInitialized(): Promise { - return true; - } - - // eslint-disable-next-line @typescript-eslint/no-empty-function - public async disconnect(): Promise {} - - public async ethSupportsNetwork(chainId = 1): Promise { - return chainId === 1; - } - - public async ethGetChainId(): Promise { - try { - // chainId as hex string - const chainId: string = await this.provider.request({ method: "eth_chainId" }); - return parseInt(chainId, 16); - } catch (e) { - console.error(e); - return null; - } - } - - public async ethSupportsSecureTransfer(): Promise { - return false; - } - - public ethSupportsNativeShapeShift(): boolean { - return false; - } - - public async ethSwitchChain(params: AddEthereumChainParameter): Promise { - try { - // at this point, we know that we're in the context of a valid TallyHo provider - await this.provider.request({ method: "wallet_switchEthereumChain", params: [{ chainId: params.chainId }] }); - } catch (e: any) { - const error: core.SerializedEthereumRpcError = e; - console.error(error); - // https://docs.metamask.io/guide/ethereum-provider.html#errors - // Internal error, which in the case of wallet_switchEthereumChain call means the chain isn't currently added to the wallet - if (error.code === -32603) { - // TODO: TallyHo currently supports a finite number of chains natively (Mainnet + Polygon/Arbitrum/Optimism under feature flag), with no capabilities to add new chains - } - - throw new Error(e); - } - } - - public async ethSupportsEIP1559(): Promise { - return true; - } - - public ethGetAccountPaths(msg: core.ETHGetAccountPath): Array { - return eth.ethGetAccountPaths(msg); - } - - public ethNextAccountPath(msg: core.ETHAccountPath): core.ETHAccountPath | undefined { - return this.info.ethNextAccountPath(msg); - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async ethGetAddress(msg: core.ETHGetAddress): Promise { - this.ethAddress ??= await eth.ethGetAddress(this.provider); - return this.ethAddress; - } - - public async ethSignTx(msg: core.ETHSignTx): Promise { - const address = await this.ethGetAddress(this.provider); - return address ? eth.ethSignTx(msg, this.provider, address) : null; - } - - public async ethSendTx(msg: core.ETHSignTx): Promise { - const address = await this.ethGetAddress(this.provider); - return address ? eth.ethSendTx(msg, this.provider, address) : null; - } - - public async ethSignMessage(msg: core.ETHSignMessage): Promise { - const address = await this.ethGetAddress(this.provider); - return address ? eth.ethSignMessage(msg, this.provider, address) : null; - } - - public async ethVerifyMessage(msg: core.ETHVerifyMessage): Promise { - return eth.ethVerifyMessage(msg, this.provider); - } - - public async getDeviceID(): Promise { - return "tallyho:" + (await this.ethGetAddress(this.provider)); - } - - public async getFirmwareVersion(): Promise { - return "tallyho"; - } -} diff --git a/packages/hdwallet-tallyho/tsconfig.json b/packages/hdwallet-tallyho/tsconfig.json deleted file mode 100644 index 5e65c10c0..000000000 --- a/packages/hdwallet-tallyho/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "rootDir": "src", - "outDir": "dist" - }, - "include": ["src/**/*"], - "exclude": ["node_modules", "dist", "**/*test.ts"], - "references": [{ "path": "../hdwallet-core" }] -} diff --git a/packages/hdwallet-trezor-connect/package.json b/packages/hdwallet-trezor-connect/package.json index c5e911156..c9c3a81d3 100644 --- a/packages/hdwallet-trezor-connect/package.json +++ b/packages/hdwallet-trezor-connect/package.json @@ -1,6 +1,6 @@ { "name": "@shapeshiftoss/hdwallet-trezor-connect", - "version": "1.55.10", + "version": "1.55.11", "license": "MIT", "publishConfig": { "access": "public" @@ -14,8 +14,8 @@ "prepublishOnly": "yarn clean && yarn build" }, "dependencies": { - "@shapeshiftoss/hdwallet-core": "1.55.10", - "@shapeshiftoss/hdwallet-trezor": "1.55.10", + "@shapeshiftoss/hdwallet-core": "1.55.11", + "@shapeshiftoss/hdwallet-trezor": "1.55.11", "@trezor/rollout": "^1.2.0", "trezor-connect": "^8.2.1" } diff --git a/packages/hdwallet-trezor/package.json b/packages/hdwallet-trezor/package.json index 7623ede37..e908230c3 100644 --- a/packages/hdwallet-trezor/package.json +++ b/packages/hdwallet-trezor/package.json @@ -1,6 +1,6 @@ { "name": "@shapeshiftoss/hdwallet-trezor", - "version": "1.55.10", + "version": "1.55.11", "license": "MIT", "publishConfig": { "access": "public" @@ -17,7 +17,7 @@ "dependencies": { "@ethereumjs/common": "^2.4.0", "@ethereumjs/tx": "^3.3.0", - "@shapeshiftoss/hdwallet-core": "1.55.10", + "@shapeshiftoss/hdwallet-core": "1.55.11", "base64-js": "^1.5.1", "lodash": "^4.17.21" }, diff --git a/packages/hdwallet-trezor/src/bitcoin.ts b/packages/hdwallet-trezor/src/bitcoin.ts index 0b329adc0..d64e42184 100644 --- a/packages/hdwallet-trezor/src/bitcoin.ts +++ b/packages/hdwallet-trezor/src/bitcoin.ts @@ -225,9 +225,3 @@ export function btcGetAccountPaths(msg: core.BTCGetAccountPaths): Array): boolean { - // Trezor does not support mixed-mode segwit, and only lets you spend from - // a single account (otherwise change is represented as an output). - return msg.length == 1; -} diff --git a/packages/hdwallet-trezor/src/trezor.ts b/packages/hdwallet-trezor/src/trezor.ts index e799f3832..d39272fdc 100644 --- a/packages/hdwallet-trezor/src/trezor.ts +++ b/packages/hdwallet-trezor/src/trezor.ts @@ -150,10 +150,6 @@ export class TrezorHDWalletInfo implements core.HDWalletInfo, core.BTCWalletInfo return Btc.btcGetAccountPaths(msg); } - public btcIsSameAccount(msg: Array): boolean { - return Btc.btcIsSameAccount(msg); - } - public async ethSupportsNetwork(chain_id: number): Promise { return Eth.ethSupportsNetwork(chain_id); } @@ -523,10 +519,6 @@ export class TrezorHDWallet implements core.HDWallet, core.BTCWallet, core.ETHWa return Btc.btcGetAccountPaths(msg); } - public btcIsSameAccount(msg: Array): boolean { - return this.info.btcIsSameAccount(msg); - } - public async ethSignTx(msg: core.ETHSignTx): Promise { return Eth.ethSignTx(this, this.transport, msg); } diff --git a/packages/hdwallet-walletconnect/package.json b/packages/hdwallet-walletconnect/package.json index 2714b9251..441895f3e 100644 --- a/packages/hdwallet-walletconnect/package.json +++ b/packages/hdwallet-walletconnect/package.json @@ -1,6 +1,6 @@ { "name": "@shapeshiftoss/hdwallet-walletconnect", - "version": "1.55.10", + "version": "1.55.11", "license": "MIT", "publishConfig": { "access": "public" @@ -15,7 +15,7 @@ "prepublishOnly": "yarn clean && yarn build" }, "dependencies": { - "@shapeshiftoss/hdwallet-core": "1.55.10", + "@shapeshiftoss/hdwallet-core": "1.55.11", "@walletconnect/qrcode-modal": "^1.7.8", "@walletconnect/web3-provider": "^1.7.8", "ethers": "^5.6.5" diff --git a/packages/hdwallet-walletconnectV2/package.json b/packages/hdwallet-walletconnectV2/package.json index f0a7d4aa4..8a112771f 100644 --- a/packages/hdwallet-walletconnectV2/package.json +++ b/packages/hdwallet-walletconnectV2/package.json @@ -1,6 +1,6 @@ { "name": "@shapeshiftoss/hdwallet-walletconnectv2", - "version": "1.55.10", + "version": "1.55.11", "license": "MIT", "publishConfig": { "access": "public" @@ -15,7 +15,7 @@ "prepublishOnly": "yarn clean && yarn build" }, "dependencies": { - "@shapeshiftoss/hdwallet-core": "1.55.10", + "@shapeshiftoss/hdwallet-core": "1.55.11", "@walletconnect/ethereum-provider": "^2.10.1", "@walletconnect/modal": "^2.6.2", "ethers": "^5.6.5" diff --git a/packages/hdwallet-xdefi/package.json b/packages/hdwallet-xdefi/package.json deleted file mode 100644 index ab030a2a8..000000000 --- a/packages/hdwallet-xdefi/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "@shapeshiftoss/hdwallet-xdefi", - "version": "1.55.10", - "license": "MIT", - "publishConfig": { - "access": "public" - }, - "main": "dist/index.js", - "source": "src/index.ts", - "types": "dist/index.d.ts", - "scripts": { - "build": "tsc --build", - "clean": "rm -rf dist node_modules tsconfig.tsbuildinfo", - "prepublishOnly": "yarn clean && yarn build" - }, - "dependencies": { - "@shapeshiftoss/hdwallet-core": "1.55.10", - "lodash": "^4.17.21" - }, - "devDependencies": { - "@types/lodash": "^4.14.168" - } -} diff --git a/packages/hdwallet-xdefi/src/adapter.test.ts b/packages/hdwallet-xdefi/src/adapter.test.ts deleted file mode 100644 index 6d0cacb57..000000000 --- a/packages/hdwallet-xdefi/src/adapter.test.ts +++ /dev/null @@ -1,26 +0,0 @@ -import * as core from "@shapeshiftoss/hdwallet-core"; - -import { XDEFIAdapter } from "./adapter"; -import { XDEFIHDWallet } from "./xdefi"; - -describe("XDEFIAdapter", () => { - it("throws error if provider is not preset", async () => { - const keyring = new core.Keyring(); - const adapter = XDEFIAdapter.useKeyring(keyring); - expect(await adapter.initialize()).toBe(0); - await expect(async () => await adapter.pairDevice()).rejects.toThrowError("XDEFI provider not found"); - }); - it("creates a unique wallet per deviceId", async () => { - Object.defineProperty(globalThis, "xfi", { - value: { ethereum: { request: jest.fn().mockReturnValue(["0x123"]) } }, - }); - const keyring = new core.Keyring(); - const adapter = XDEFIAdapter.useKeyring(keyring); - const add = jest.spyOn(adapter.keyring, "add"); - expect(await adapter.initialize()).toBe(0); - const wallet = await adapter.pairDevice(); - expect(wallet).toBeInstanceOf(XDEFIHDWallet); - expect(add).toBeCalled(); - expect(await wallet?.getDeviceID()).toBe("xDeFi:0x123"); - }); -}); diff --git a/packages/hdwallet-xdefi/src/adapter.ts b/packages/hdwallet-xdefi/src/adapter.ts deleted file mode 100644 index df3d710e4..000000000 --- a/packages/hdwallet-xdefi/src/adapter.ts +++ /dev/null @@ -1,52 +0,0 @@ -import * as core from "@shapeshiftoss/hdwallet-core"; -import { providers } from "ethers"; - -import { XDEFIHDWallet } from "./xdefi"; - -declare global { - // https://stackoverflow.com/questions/59459312/using-globalthis-in-typescript - // Global declarations require the use of var - // eslint-disable-next-line no-var - var xfi: { ethereum: providers.ExternalProvider } | null; -} - -export class XDEFIAdapter { - keyring: core.Keyring; - - // wallet id to remove from the keyring when the active wallet changes - currentDeviceID?: string; - - private constructor(keyring: core.Keyring) { - this.keyring = keyring; - } - - public static useKeyring(keyring: core.Keyring) { - return new XDEFIAdapter(keyring); - } - - public async initialize(): Promise { - return Object.keys(this.keyring.wallets).length; - } - - public async pairDevice(): Promise { - const provider = globalThis.xfi?.ethereum; - if (!provider) { - console.error("Please install XDEFI!"); - throw new Error("XDEFI provider not found"); - } - try { - await provider.request?.({ method: "eth_requestAccounts" }); - } catch (error) { - console.error("Could not get XDEFI accounts. "); - throw error; - } - const wallet = new XDEFIHDWallet(provider); - await wallet.initialize(); - const deviceID = await wallet.getDeviceID(); - this.keyring.add(wallet, deviceID); - this.currentDeviceID = deviceID; - this.keyring.emit(["XDEFI", deviceID, core.Events.CONNECT], deviceID); - - return wallet; - } -} diff --git a/packages/hdwallet-xdefi/src/ethereum.test.ts b/packages/hdwallet-xdefi/src/ethereum.test.ts deleted file mode 100644 index a615e6e4a..000000000 --- a/packages/hdwallet-xdefi/src/ethereum.test.ts +++ /dev/null @@ -1,255 +0,0 @@ -import * as core from "@shapeshiftoss/hdwallet-core"; -import { providers } from "ethers"; - -import * as ethereum from "./ethereum"; - -describe("XDEFI - Ethereum Adapter", () => { - it("ethVerifyMessage returns null as its not implemented", async () => { - const ethereumProvider: providers.ExternalProvider = { - request: jest.fn().mockReturnValue("0x3f2329C9ADFbcCd9A84f52c906E936A42dA18CB8"), - }; - expect( - await ethereum.ethVerifyMessage( - { - address: "0x3f2329C9ADFbcCd9A84f52c906E936A42dA18CB8", - message: "hello world", - signature: - "0x29f7212ecc1c76cea81174af267b67506f754ea8c73f144afa900a0d85b24b21319621aeb062903e856352f38305710190869c3ce5a1425d65ef4fa558d0fc251b", - }, - ethereumProvider - ) - ).toBe(true); - }); - it("ethGetAccountPaths should return correct paths", () => { - const paths = ethereum.ethGetAccountPaths({ coin: "Ethereum", accountIdx: 0 }); - expect(paths).toMatchObject([ - { - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - hardenedPath: core.bip32ToAddressNList("m/44'/60'/0'"), - relPath: [0, 0], - description: "XDEFI", - }, - ]); - }); - it("ethGetAccountPaths should return empty path", () => { - const paths = ethereum.ethGetAccountPaths({ coin: "RandomCoin", accountIdx: 0 }); - expect(paths).toMatchObject([]); - }); - it("ethSignTx returns null as its not implemented", async () => { - const ethereumProvider: providers.ExternalProvider = { - request: jest.fn().mockReturnValue({ - r: "0x63db3dd3bf3e1fe7dde1969c0fc8850e34116d0b501c0483a0e08c0f77b8ce0a", - s: "0x28297d012cccf389f6332415e96ee3fc0bbf8474d05f646e029cd281a031464b", - v: 38, - serialized: - "0xf86b018501dcd650008256229412ec06288edd7ae2cc41a843fe089237fc7354f0872c68af0bb140008026a063db3dd3bf3e1fe7dde1969c0fc8850e34116d0b501c0483a0e08c0f77b8ce0aa028297d012cccf389f6332415e96ee3fc0bbf8474d05f646e029cd281a031464b", - }), - }; - expect( - await ethereum.ethSignTx( - { - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - nonce: "0xDEADBEEF", - gasPrice: "0xDEADBEEF", - gasLimit: "0xDEADBEEF", - to: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - value: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - data: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - chainId: 1, - }, - ethereumProvider, - "0x123" - ) - ).toEqual({ - r: "0x63db3dd3bf3e1fe7dde1969c0fc8850e34116d0b501c0483a0e08c0f77b8ce0a", - s: "0x28297d012cccf389f6332415e96ee3fc0bbf8474d05f646e029cd281a031464b", - v: 38, - serialized: - "0xf86b018501dcd650008256229412ec06288edd7ae2cc41a843fe089237fc7354f0872c68af0bb140008026a063db3dd3bf3e1fe7dde1969c0fc8850e34116d0b501c0483a0e08c0f77b8ce0aa028297d012cccf389f6332415e96ee3fc0bbf8474d05f646e029cd281a031464b", - }); - }); - it("ethSendTx returns a valid hash", async () => { - const ethereumProvider: providers.ExternalProvider = { - request: jest.fn().mockReturnValue("0x123"), - }; - - const hash = await ethereum.ethSendTx( - { - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - nonce: "0xDEADBEEF", - gasPrice: "0xDEADBEEF", - gasLimit: "0xDEADBEEF", - to: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - value: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - data: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - chainId: 1, - }, - ethereumProvider, - "0x123" - ); - expect(ethereumProvider.request).toHaveBeenCalled(); - expect(hash).toMatchObject({ hash: "0x123" }); - }); - it("ethSendTx returns a valid hash if maxFeePerGas is present in msg", async () => { - const ethereumProvider: providers.ExternalProvider = { - request: jest.fn().mockReturnValue("0x123"), - }; - - const hash = await ethereum.ethSendTx( - { - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - nonce: "0xDEADBEEF", - gasLimit: "0xDEADBEEF", - maxFeePerGas: "0xDEADBEEF", - maxPriorityFeePerGas: "0xDEADBEEF", - to: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - value: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - data: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - chainId: 1, - }, - ethereumProvider, - "0x123" - ); - expect(ethereumProvider.request).toHaveBeenCalled(); - expect(hash).toMatchObject({ hash: "0x123" }); - }); - it("ethSendTx returns null on error", async () => { - const ethereumProvider: providers.ExternalProvider = { - request: jest.fn().mockRejectedValue(new Error("An Error has occurred")), - }; - - const hash = await ethereum.ethSendTx( - { - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - nonce: "0xDEADBEEF", - gasPrice: "0xDEADBEEF", - gasLimit: "0xDEADBEEF", - to: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - value: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - data: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - chainId: 1, - }, - ethereumProvider, - "0x123" - ); - expect(ethereumProvider.request).toHaveBeenCalled(); - expect(hash).toBe(null); - }); - - it("ethSignMessage returns a valid signature object when called with bytes message", async () => { - const ethereumProvider = { - request: jest.fn().mockReturnValue( - `Object { - "address": "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", - "signature": "0x05f51140905ffa33ffdc57f46b0b8d8fbb1d2a99f8cd843ca27893c01c31351c08b76d83dce412731c846e3b50649724415deb522d00950fbf4f2c1459c2b70b1b", - }` - ), - }; - - const msg = "0xcf8746d5aa75ecfd907eb3cae0aecf7f698a8bfe1f97eb2d77d6539e8991b0ea"; - - const sig = await ethereum.ethSignMessage( - { - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - message: msg, - }, - ethereumProvider, - "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8" - ); - - expect(ethereumProvider.request.mock.calls[0][0]).toMatchInlineSnapshot(` - Object { - "method": "personal_sign", - "params": Array [ - "0xcf8746d5aa75ecfd907eb3cae0aecf7f698a8bfe1f97eb2d77d6539e8991b0ea", - "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", - ], - } - `); - - expect(sig).toMatchInlineSnapshot(` - Object { - "address": "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", - "signature": "Object { - \\"address\\": \\"0x73d0385F4d8E00C5e6504C6030F47BF6212736A8\\", - \\"signature\\": \\"0x05f51140905ffa33ffdc57f46b0b8d8fbb1d2a99f8cd843ca27893c01c31351c08b76d83dce412731c846e3b50649724415deb522d00950fbf4f2c1459c2b70b1b\\", - }", - } - `); - }); - - it("ethSignMessage returns a valid signature object", async () => { - const ethereumProvider: providers.ExternalProvider = { - request: jest.fn().mockReturnValue( - `Object { - "address": "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", - "signature": "0x05f51140905ffa33ffdc57f46b0b8d8fbb1d2a99f8cd843ca27893c01c31351c08b76d83dce412731c846e3b50649724415deb522d00950fbf4f2c1459c2b70b1b", - }` - ), - }; - - const msg = "0x737570657220736563726574206d657373616765"; // super secret message - const sig = await ethereum.ethSignMessage( - { - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - message: msg, - }, - ethereumProvider, - "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8" - ); - - expect(sig).toMatchInlineSnapshot(` - Object { - "address": "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", - "signature": "Object { - \\"address\\": \\"0x73d0385F4d8E00C5e6504C6030F47BF6212736A8\\", - \\"signature\\": \\"0x05f51140905ffa33ffdc57f46b0b8d8fbb1d2a99f8cd843ca27893c01c31351c08b76d83dce412731c846e3b50649724415deb522d00950fbf4f2c1459c2b70b1b\\", - }", - } - `); - }); - - it("ethSignMessage returns null on error", async () => { - const ethereumProvider: providers.ExternalProvider = { - request: jest.fn().mockRejectedValue(new Error("An Error has occurred")), - }; - - const msg = "0x737570657220736563726574206d657373616765"; // super secret message - const sig = await ethereum.ethSignMessage( - { - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - message: msg, - }, - ethereumProvider, - "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8" - ); - - expect(sig).toBe(null); - }); - - it("ethGetAddress returns a valid address", async () => { - const ethereumProvider: providers.ExternalProvider = { - request: jest.fn().mockReturnValue(["0x73d0385F4d8E00C5e6504C6030F47BF6212736A8"]), - }; - - const address = await ethereum.ethGetAddress(ethereumProvider); - - expect(address).toBe("0x73d0385F4d8E00C5e6504C6030F47BF6212736A8"); - }); - it("ethGetAddress returns null on error", async () => { - const ethereumProvider: providers.ExternalProvider = { - request: jest.fn().mockRejectedValue(new Error("An error has occurred")), - }; - - const address = await ethereum.ethGetAddress(ethereumProvider); - - expect(address).toBe(null); - }); - it("ethGetAddress returns null if no provider", async () => { - const ethereumProvider: providers.ExternalProvider = {}; - - const address = await ethereum.ethGetAddress(ethereumProvider); - - expect(address).toBe(null); - }); -}); diff --git a/packages/hdwallet-xdefi/src/ethereum.ts b/packages/hdwallet-xdefi/src/ethereum.ts deleted file mode 100644 index 43ed76973..000000000 --- a/packages/hdwallet-xdefi/src/ethereum.ts +++ /dev/null @@ -1,104 +0,0 @@ -import * as core from "@shapeshiftoss/hdwallet-core"; -import { ETHSignedMessage } from "@shapeshiftoss/hdwallet-core"; -import { isHexString } from "ethers/lib/utils"; - -export async function ethVerifyMessage(msg: core.ETHVerifyMessage, ethereum: any): Promise { - const recoveredAddress = await ethereum.request({ - method: "personal_ecRecover", - params: [msg.message, msg.signature], - }); - return recoveredAddress === msg.address; -} - -export function ethGetAccountPaths(msg: core.ETHGetAccountPath): Array { - const slip44 = core.slip44ByCoin(msg.coin); - if (slip44 === undefined) return []; - return [ - { - addressNList: [0x80000000 + 44, 0x80000000 + slip44, 0x80000000 + msg.accountIdx, 0, 0], - hardenedPath: [0x80000000 + 44, 0x80000000 + slip44, 0x80000000 + msg.accountIdx], - relPath: [0, 0], - description: "XDEFI", - }, - ]; -} - -export async function ethSignTx(msg: core.ETHSignTx, ethereum: any, from: string): Promise { - const signedTx = await ethereum.request({ - method: "eth_signTransaction", - params: [{ ...msg, from }], - }); - return signedTx; -} - -export async function ethSendTx(msg: core.ETHSignTx, ethereum: any, from: string): Promise { - try { - const utxBase = { - from: from, - to: msg.to, - value: msg.value, - data: msg.data, - chainId: msg.chainId, - nonce: msg.nonce, - gas: msg.gasLimit, - gasPrice: msg.gasPrice, - }; - - const utx = msg.maxFeePerGas - ? { - ...utxBase, - maxFeePerGas: msg.maxFeePerGas, - maxPriorityFeePerGas: msg.maxPriorityFeePerGas, - } - : { ...utxBase, gasPrice: msg.gasPrice }; - - const signedTx = await ethereum.request({ - method: "eth_sendTransaction", - params: [utx], - }); - - return { - hash: signedTx, - } as core.ETHTxHash; - } catch (error) { - console.error(error); - return null; - } -} - -export async function ethSignMessage( - msg: core.ETHSignMessage, - ethereum: any, - address: string -): Promise { - try { - if (!isHexString(msg.message)) throw new Error("data is not an hex string"); - const signedMsg = await ethereum.request({ - method: "personal_sign", - params: [msg.message, address], - }); - - return { - address: address, - signature: signedMsg, - } as ETHSignedMessage; - } catch (error) { - console.error(error); - return null; - } -} - -export async function ethGetAddress(ethereum: any): Promise { - if (!(ethereum && ethereum.request)) { - return null; - } - try { - const ethAccounts = await ethereum.request({ - method: "eth_accounts", - }); - return ethAccounts[0]; - } catch (error) { - console.error(error); - return null; - } -} diff --git a/packages/hdwallet-xdefi/src/index.test.ts b/packages/hdwallet-xdefi/src/index.test.ts deleted file mode 100644 index 7e5b115de..000000000 --- a/packages/hdwallet-xdefi/src/index.test.ts +++ /dev/null @@ -1,11 +0,0 @@ -import * as library from "./"; - -describe("Exports all expected classes", () => { - it("should export XDEFIAdapter", () => { - expect(library.XDEFIAdapter.name).toBe("XDEFIAdapter"); - }); - - it("should export XDEFIHDWallet", () => { - expect(library.XDEFIHDWallet.name).toBe("XDEFIHDWallet"); - }); -}); diff --git a/packages/hdwallet-xdefi/src/index.ts b/packages/hdwallet-xdefi/src/index.ts deleted file mode 100644 index ce7d96bd4..000000000 --- a/packages/hdwallet-xdefi/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./adapter"; -export * from "./xdefi"; diff --git a/packages/hdwallet-xdefi/src/xdefi.test.ts b/packages/hdwallet-xdefi/src/xdefi.test.ts deleted file mode 100644 index fa73a160c..000000000 --- a/packages/hdwallet-xdefi/src/xdefi.test.ts +++ /dev/null @@ -1,211 +0,0 @@ -import * as core from "@shapeshiftoss/hdwallet-core"; - -import { XDEFIHDWallet, XDEFIHDWalletInfo } from "."; - -describe("XDeFIHDWalletInfo", () => { - const info = new XDEFIHDWalletInfo(); - - it("should have correct metadata", async () => { - expect(info.getVendor()).toBe("XDEFI"); - expect(info.hasOnDevicePinEntry()).toBe(false); - expect(info.hasOnDevicePassphrase()).toBe(false); - expect(info.hasOnDeviceDisplay()).toBe(false); - expect(info.hasOnDeviceRecovery()).toBe(false); - expect(await info.ethSupportsNetwork(1)).toBe(true); - expect(await info.ethSupportsSecureTransfer()).toBe(false); - expect(info.ethSupportsNativeShapeShift()).toBe(false); - expect(await info.ethSupportsEIP1559()).toBe(true); - expect(await info.supportsOfflineSigning()).toBe(false); - expect(info.supportsBip44Accounts()).toBe(false); - expect(await info.supportsBroadcast()).toBe(true); - }); - it("should produce correct path descriptions", () => { - expect(info.hasNativeShapeShift()).toBe(false); - [ - { - msg: { coin: "Ethereum", path: [44 + 0x80000000, 60 + 0x80000000, 0 + 0x80000000, 0, 0] }, - out: { coin: "Ethereum", verbose: "Ethereum Account #0", isKnown: true }, - }, - ].forEach((x) => expect(info.describePath(x.msg)).toMatchObject(x.out)); - expect(() => info.describePath({ coin: "foobar", path: [1, 2, 3] })).toThrowError("Unsupported path"); - }); -}); - -describe("XDEFIHDWallet", () => { - let wallet: XDEFIHDWallet; - beforeEach(() => { - wallet = new XDEFIHDWallet(core.untouchable("XDEFIHDWallet:provider")); - wallet.ethAddress = "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8"; - }); - - it("should match the metadata", async () => { - expect(wallet.getVendor()).toBe("XDEFI"); - expect(wallet.hasOnDevicePinEntry()).toBe(false); - expect(wallet.hasOnDevicePassphrase()).toBe(false); - expect(wallet.hasOnDeviceDisplay()).toBe(false); - expect(wallet.hasOnDeviceRecovery()).toBe(false); - expect(await wallet.ethSupportsNetwork(1)).toBe(true); - expect(await wallet.ethSupportsSecureTransfer()).toBe(false); - expect(wallet.ethSupportsNativeShapeShift()).toBe(false); - expect(await wallet.ethSupportsEIP1559()).toBe(true); - expect(await wallet.supportsOfflineSigning()).toBe(false); - expect(wallet.supportsBip44Accounts()).toBe(false); - expect(await wallet.supportsBroadcast()).toBe(true); - }); - - it("should test ethSignTx", async () => { - wallet.ethAddress = "0x123"; - wallet.provider = { - request: jest.fn().mockReturnValue({ - r: "0x63db3dd3bf3e1fe7dde1969c0fc8850e34116d0b501c0483a0e08c0f77b8ce0a", - s: "0x28297d012cccf389f6332415e96ee3fc0bbf8474d05f646e029cd281a031464b", - v: 38, - serialized: - "0xf86b018501dcd650008256229412ec06288edd7ae2cc41a843fe089237fc7354f0872c68af0bb140008026a063db3dd3bf3e1fe7dde1969c0fc8850e34116d0b501c0483a0e08c0f77b8ce0aa028297d012cccf389f6332415e96ee3fc0bbf8474d05f646e029cd281a031464b", - }), - }; - expect( - await wallet.ethSignTx({ - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - nonce: "0xDEADBEEF", - gasPrice: "0xDEADBEEF", - gasLimit: "0xDEADBEEF", - to: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - value: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - data: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - chainId: 1, - }) - ).toEqual({ - r: "0x63db3dd3bf3e1fe7dde1969c0fc8850e34116d0b501c0483a0e08c0f77b8ce0a", - s: "0x28297d012cccf389f6332415e96ee3fc0bbf8474d05f646e029cd281a031464b", - v: 38, - serialized: - "0xf86b018501dcd650008256229412ec06288edd7ae2cc41a843fe089237fc7354f0872c68af0bb140008026a063db3dd3bf3e1fe7dde1969c0fc8850e34116d0b501c0483a0e08c0f77b8ce0aa028297d012cccf389f6332415e96ee3fc0bbf8474d05f646e029cd281a031464b", - }); - }); - - it("should test ethSignMessage", async () => { - wallet.provider = { - request: jest.fn().mockReturnValue( - `Object { - "address": "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", - "signature": "0x05f51140905ffa33ffdc57f46b0b8d8fbb1d2a99f8cd843ca27893c01c31351c08b76d83dce412731c846e3b50649724415deb522d00950fbf4f2c1459c2b70b1b", - }` - ), - }; - const msg = "0x737570657220736563726574206d657373616765"; // super secret message - expect( - await wallet.ethSignMessage({ - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - message: msg, - }) - ).toMatchInlineSnapshot(` - Object { - "address": "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", - "signature": "Object { - \\"address\\": \\"0x73d0385F4d8E00C5e6504C6030F47BF6212736A8\\", - \\"signature\\": \\"0x05f51140905ffa33ffdc57f46b0b8d8fbb1d2a99f8cd843ca27893c01c31351c08b76d83dce412731c846e3b50649724415deb522d00950fbf4f2c1459c2b70b1b\\", - }", - } - `); - }); - - it("ethSignMessage returns null on error", async () => { - wallet.provider = { - request: jest.fn().mockRejectedValue(new Error("An Error has occurred")), - }; - - const msg = "0x737570657220736563726574206d657373616765"; // super secret message - const sig = await wallet.ethSignMessage({ - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - message: msg, - }); - - expect(sig).toBe(null); - }); - - it("ethGetAddress returns a valid address", async () => { - wallet.provider = { - request: jest.fn().mockReturnValue(["0x73d0385F4d8E00C5e6504C6030F47BF6212736A8"]), - }; - - const msg = "0x737570657220736563726574206d657373616765"; // super secret message - const sig = await wallet.ethSignMessage({ - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - message: msg, - }); - - expect(sig).toMatchObject({ - address: "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", - signature: ["0x73d0385F4d8E00C5e6504C6030F47BF6212736A8"], - }); - }); - it("ethSendTx returns a valid hash", async () => { - wallet.provider = { - request: jest.fn().mockReturnValue("0x123"), - }; - - const hash = await wallet.ethSendTx({ - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - nonce: "0xDEADBEEF", - gasPrice: "0xDEADBEEF", - gasLimit: "0xDEADBEEF", - to: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - value: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - data: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - chainId: 1, - }); - expect(wallet.provider.request).toHaveBeenCalled(); - expect(hash).toMatchObject({ hash: "0x123" }); - }); - it("ethSendTx returns a valid hash if maxFeePerGas is present in msg", async () => { - wallet.provider = { - request: jest.fn().mockReturnValue("0x123"), - }; - - const hash = await wallet.ethSendTx({ - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - nonce: "0xDEADBEEF", - gasLimit: "0xDEADBEEF", - maxFeePerGas: "0xDEADBEEF", - maxPriorityFeePerGas: "0xDEADBEEF", - to: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - value: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - data: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - chainId: 1, - }); - expect(wallet.provider.request).toHaveBeenCalled(); - expect(hash).toMatchObject({ hash: "0x123" }); - }); - it("ethSendTx returns null on error", async () => { - wallet.provider = { - request: jest.fn().mockRejectedValue(new Error("An Error has occurred")), - }; - - const hash = await wallet.ethSendTx({ - addressNList: core.bip32ToAddressNList("m/44'/60'/0'/0/0"), - nonce: "0xDEADBEEF", - gasPrice: "0xDEADBEEF", - gasLimit: "0xDEADBEEF", - to: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - value: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - data: "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF", - chainId: 1, - }); - expect(wallet.provider.request).toHaveBeenCalled(); - expect(hash).toBe(null); - }); - it("ethVerifyMessage returns null as its not implemented", async () => { - wallet.provider = { - request: jest.fn().mockReturnValue("0x3f2329C9ADFbcCd9A84f52c906E936A42dA18CB8"), - }; - expect( - await wallet.ethVerifyMessage({ - address: "0x3f2329C9ADFbcCd9A84f52c906E936A42dA18CB8", - message: "hello world", - signature: - "0x29f7212ecc1c76cea81174af267b67506f754ea8c73f144afa900a0d85b24b21319621aeb062903e856352f38305710190869c3ce5a1425d65ef4fa558d0fc251b", - }) - ).toEqual(true); - }); -}); diff --git a/packages/hdwallet-xdefi/src/xdefi.ts b/packages/hdwallet-xdefi/src/xdefi.ts deleted file mode 100644 index 10fcd5bca..000000000 --- a/packages/hdwallet-xdefi/src/xdefi.ts +++ /dev/null @@ -1,329 +0,0 @@ -import * as core from "@shapeshiftoss/hdwallet-core"; -import { AddEthereumChainParameter } from "@shapeshiftoss/hdwallet-core"; -import isObject from "lodash/isObject"; - -import * as eth from "./ethereum"; - -export function isXDEFI(wallet: core.HDWallet): wallet is XDEFIHDWallet { - return isObject(wallet) && (wallet as any)._isXDEFI; -} - -export class XDEFIHDWalletInfo implements core.HDWalletInfo, core.ETHWalletInfo { - readonly _supportsETHInfo = true; - readonly _supportsBTCInfo = false; - readonly _supportsCosmosInfo = false; - - public getVendor(): string { - return "XDEFI"; - } - - public hasOnDevicePinEntry(): boolean { - return false; - } - - public hasOnDevicePassphrase(): boolean { - return false; - } - - public hasOnDeviceDisplay(): boolean { - return false; - } - - public hasOnDeviceRecovery(): boolean { - return false; - } - - public hasNativeShapeShift(): boolean { - return false; - } - - public supportsBip44Accounts(): boolean { - return false; - } - - public supportsOfflineSigning(): boolean { - return false; - } - - public supportsBroadcast(): boolean { - return true; - } - - public describePath(msg: core.DescribePath): core.PathDescription { - switch (msg.coin) { - case "Ethereum": - return core.describeETHPath(msg.path); - default: - throw new Error("Unsupported path"); - } - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public ethNextAccountPath(msg: core.ETHAccountPath): core.ETHAccountPath | undefined { - // TODO: What do we do here? - return undefined; - } - - public async ethSupportsNetwork(chainId = 1): Promise { - return chainId === 1; - } - - public async ethSupportsSecureTransfer(): Promise { - return false; - } - - public ethSupportsNativeShapeShift(): boolean { - return false; - } - - public async ethSupportsEIP1559(): Promise { - return true; - } - - public ethGetAccountPaths(msg: core.ETHGetAccountPath): Array { - return eth.ethGetAccountPaths(msg); - } -} - -export class XDEFIHDWallet implements core.HDWallet, core.ETHWallet { - readonly _supportsETH = true; - readonly _supportsETHInfo = true; - readonly _supportsEthSwitchChain = true; - readonly _supportsAvalanche = true; - readonly _supportsOptimism = true; - readonly _supportsBSC = true; - readonly _supportsPolygon = true; - readonly _supportsGnosis = false; - readonly _supportsArbitrum = true; - readonly _supportsArbitrumNova = false; - readonly _supportsBase = false; - readonly _supportsBTCInfo = false; - readonly _supportsBTC = false; - readonly _supportsCosmosInfo = false; - readonly _supportsCosmos = false; - readonly _isXDEFI = true; - - info: XDEFIHDWalletInfo & core.HDWalletInfo; - ethAddress?: string | null; - provider: any; - - constructor(provider: unknown) { - this.info = new XDEFIHDWalletInfo(); - this.provider = provider; - } - - async getFeatures(): Promise> { - return {}; - } - - public async isLocked(): Promise { - return !this.provider.xdefi.isUnlocked(); - } - - public getVendor(): string { - return "XDEFI"; - } - - public async getModel(): Promise { - return "XDEFI"; - } - - public async getLabel(): Promise { - return "XDEFI"; - } - - public async initialize(): Promise { - // nothing to initialize - } - - public hasOnDevicePinEntry(): boolean { - return this.info.hasOnDevicePinEntry(); - } - - public hasOnDevicePassphrase(): boolean { - return this.info.hasOnDevicePassphrase(); - } - - public hasOnDeviceDisplay(): boolean { - return this.info.hasOnDeviceDisplay(); - } - - public hasOnDeviceRecovery(): boolean { - return this.info.hasOnDeviceRecovery(); - } - - public hasNativeShapeShift(srcCoin: core.Coin, dstCoin: core.Coin): boolean { - return this.info.hasNativeShapeShift(srcCoin, dstCoin); - } - - public supportsBip44Accounts(): boolean { - return this.info.supportsBip44Accounts(); - } - - public supportsOfflineSigning(): boolean { - return false; - } - - public supportsBroadcast(): boolean { - return true; - } - - public async clearSession(): Promise { - // TODO: Can we lock XDEFI from here? - } - - public async ping(msg: core.Ping): Promise { - // no ping function for XDEFI, so just returning Core.Pong - return { msg: msg.msg }; - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async sendPin(pin: string): Promise { - // no concept of pin in XDEFI - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async sendPassphrase(passphrase: string): Promise { - // cannot send passphrase to XDEFI. Could show the widget? - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async sendCharacter(charater: string): Promise { - // no concept of sendCharacter in XDEFI - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async sendWord(word: string): Promise { - // no concept of sendWord in XDEFI - } - - public async cancel(): Promise { - // no concept of cancel in XDEFI - } - - // eslint-disable-next-line @typescript-eslint/no-empty-function - public async wipe(): Promise {} - - // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function - public async reset(msg: core.ResetDevice): Promise {} - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async recover(msg: core.RecoverDevice): Promise { - // no concept of recover in XDEFI - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async loadDevice(msg: core.LoadDevice): Promise { - // TODO: Does XDEFI allow this to be done programatically? - } - - public describePath(msg: core.DescribePath): core.PathDescription { - return this.info.describePath(msg); - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async getPublicKeys(msg: Array): Promise> { - // Ethereum public keys are not exposed by the RPC API - return []; - } - - public async isInitialized(): Promise { - return true; - } - - // eslint-disable-next-line @typescript-eslint/no-empty-function - public async disconnect(): Promise {} - - public async ethSupportsNetwork(chainId = 1): Promise { - return chainId === 1; - } - - public async ethGetChainId(): Promise { - try { - // chainId as hex string - const chainId: string = await this.provider.request({ method: "eth_chainId" }); - return parseInt(chainId, 16); - } catch (e) { - console.error(e); - return null; - } - } - - public async ethSwitchChain(params: AddEthereumChainParameter): Promise { - try { - // at this point, we know that we're in the context of a valid XDEFI provider - await this.provider.request({ method: "wallet_switchEthereumChain", params: [{ chainId: params.chainId }] }); - } catch (e: any) { - const error: core.SerializedEthereumRpcError = e; - console.error(error); - // https://docs.metamask.io/guide/ethereum-provider.html#errors - // Internal error, which in the case of wallet_switchEthereumChain call means the chain isn't currently added to the wallet - if (error.code === -32603) { - // TODO: XDEFI currently supports a finite number of chains natively, with no capabilities to add new chains - } - - throw new Error(e); - } - } - - public async ethSupportsSecureTransfer(): Promise { - return false; - } - - public ethSupportsNativeShapeShift(): boolean { - return false; - } - - public async ethSupportsEIP1559(): Promise { - return true; - } - - public ethGetAccountPaths(msg: core.ETHGetAccountPath): Array { - return eth.ethGetAccountPaths(msg); - } - - public ethNextAccountPath(msg: core.ETHAccountPath): core.ETHAccountPath | undefined { - return this.info.ethNextAccountPath(msg); - } - - public async ethGetAddress(): Promise { - if (this.ethAddress) { - return this.ethAddress; - } - const address = await eth.ethGetAddress(this.provider); - if (address) { - this.ethAddress = address; - return address; - } else { - this.ethAddress = null; - return null; - } - } - - public async ethSignTx(msg: core.ETHSignTx): Promise { - const address = await this.ethGetAddress(); - return address ? eth.ethSignTx(msg, this.provider, address) : null; - } - - public async ethSendTx(msg: core.ETHSignTx): Promise { - const address = await this.ethGetAddress(); - return address ? eth.ethSendTx(msg, this.provider, address) : null; - } - - public async ethSignMessage(msg: core.ETHSignMessage): Promise { - const address = await this.ethGetAddress(); - return address ? eth.ethSignMessage(msg, this.provider, address) : null; - } - - public async ethVerifyMessage(msg: core.ETHVerifyMessage): Promise { - return eth.ethVerifyMessage(msg, this.provider); - } - - public async getDeviceID(): Promise { - return "xDeFi:" + (await this.ethGetAddress()); - } - - public async getFirmwareVersion(): Promise { - return "xDeFi"; - } -} diff --git a/packages/hdwallet-xdefi/tsconfig.json b/packages/hdwallet-xdefi/tsconfig.json deleted file mode 100644 index 2ca240aa5..000000000 --- a/packages/hdwallet-xdefi/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "rootDir": "src", - "outDir": "dist" - }, - "include": ["src/**/*"], - "exclude": ["node_modules", "dist", "**/*test.ts"], - "references": [{ "path": "../hdwallet-core" }] -} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 9edad8055..6780738be 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -43,18 +43,15 @@ { "path": "./packages/hdwallet-ledger" }, { "path": "./packages/hdwallet-ledger-webhid" }, { "path": "./packages/hdwallet-ledger-webusb" }, - { "path": "./packages/hdwallet-metamask" }, - { "path": "./packages/hdwallet-metamask-shapeshift-multichain" }, - { "path": "./packages/hdwallet-coinbase" }, + { "path": "./packages/hdwallet-metamask-multichain" }, { "path": "./packages/hdwallet-native" }, { "path": "./packages/hdwallet-portis" }, - { "path": "./packages/hdwallet-tallyho" }, { "path": "./packages/hdwallet-trezor" }, { "path": "./packages/hdwallet-trezor-connect" }, { "path": "./packages/hdwallet-walletconnect" }, { "path": "./packages/hdwallet-walletconnectV2" }, - { "path": "./packages/hdwallet-xdefi" }, { "path": "./packages/hdwallet-keplr" }, + { "path": "./packages/hdwallet-coinbase" }, { "path": "./packages/hdwallet-phantom" } ] } diff --git a/yarn.lock b/yarn.lock index 9b9b84914..edbdec2e5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4706,34 +4706,35 @@ resolved "https://registry.yarnpkg.com/@shapeshiftoss/logger/-/logger-1.1.3.tgz#ff05765775351c8adc99cf747f14b5619311e023" integrity sha512-II9vFeaB5RCnGiEUVGpZC599vJeO3JK186v1SPUIMM7Q+U/FjroN5MybHgnJ+buBx3f8HpXorv6ksgVT2f5Xwg== -"@shapeshiftoss/metamask-snaps-adapter@^1.0.10": - version "1.0.10" - resolved "https://registry.yarnpkg.com/@shapeshiftoss/metamask-snaps-adapter/-/metamask-snaps-adapter-1.0.10.tgz#4838ce7e8b23dbc6d189b52fa381e8cb48376eba" - integrity sha512-5n4G47h7qJdSvVSjOugpVSP3ewBhrHVHu3bULdNEYI8hKLBQSkrip2mAGJmG18ejgVxhQQAwXpjVbdm8NFxpxw== +"@shapeshiftoss/metamask-snaps-adapter@^1.0.12": + version "1.0.12" + resolved "https://registry.yarnpkg.com/@shapeshiftoss/metamask-snaps-adapter/-/metamask-snaps-adapter-1.0.12.tgz#f4e1ff87e0b8e311f0cc1afe23ce72d23953c039" + integrity sha512-8o7dHY7TdDd1lnyL0uYBdXKjfaMZyWUQKzyk1SxTxQa2pbvKq5M4TZAzoNiucPCCcZJUi2a+mKT842E4kxGWHQ== dependencies: "@ethersproject/providers" "^5.7.2" "@metamask/detect-provider" "^2.0.0" "@metamask/snaps-ui" "1.0.2" "@shapeshiftoss/hdwallet-core" "^1.55.1" "@shapeshiftoss/logger" "^1.1.3" - "@shapeshiftoss/metamask-snaps" "^1.0.10" - "@shapeshiftoss/metamask-snaps-types" "^1.0.10" + "@shapeshiftoss/metamask-snaps" "^1.0.12" + "@shapeshiftoss/metamask-snaps-types" "^1.0.12" + mipd "^0.0.7" p-queue "^7.4.1" -"@shapeshiftoss/metamask-snaps-types@^1.0.10": - version "1.0.10" - resolved "https://registry.yarnpkg.com/@shapeshiftoss/metamask-snaps-types/-/metamask-snaps-types-1.0.10.tgz#4b04eade535ed31a5fa987f91f5d020edf3ddc4e" - integrity sha512-Fb4WvBBGckZpfqVCPlbLwTqskcAvcI5Q4mAQEmNDNiN1orFrnH2YSMNh18qVeR3PHcrL/qt0UMnBspWkEPZPkg== +"@shapeshiftoss/metamask-snaps-types@^1.0.12": + version "1.0.12" + resolved "https://registry.yarnpkg.com/@shapeshiftoss/metamask-snaps-types/-/metamask-snaps-types-1.0.12.tgz#de35ef36e66c7a4bfcae48ef83af752aeb02a25b" + integrity sha512-TOmFetdvoGpGt8UHeXcAu9YvDkyYckP310Piihoc6nm7ViPtCxniuaDyrOb8j8MtoSyj3yVYZafB85tSM5itIw== dependencies: "@metamask/types" "^1.1.0" "@shapeshiftoss/hdwallet-core" "^1.55.1" "@shapeshiftoss/hdwallet-native" "^1.55.1" "@shapeshiftoss/unchained-client" "^10.1.1" -"@shapeshiftoss/metamask-snaps@^1.0.10": - version "1.0.10" - resolved "https://registry.yarnpkg.com/@shapeshiftoss/metamask-snaps/-/metamask-snaps-1.0.10.tgz#670cd0791923a27cc6a67a247c01d7cf8330d905" - integrity sha512-Elr+q5Y0WEN3gBmmZU94/XH6OQOj/fhR2EZ3Y6MAuZx7soVt32AXNnFmCgwKlOnnD7KHmZMiSU2qSs6BBFR/uA== +"@shapeshiftoss/metamask-snaps@^1.0.12": + version "1.0.12" + resolved "https://registry.yarnpkg.com/@shapeshiftoss/metamask-snaps/-/metamask-snaps-1.0.12.tgz#cf1b83f576b76ef01be638d1743493daf41baa24" + integrity sha512-SeHGw5+ZPLvtDi5SIH8r/cWczoBCaJzq3qsLrmBaXLVsdwn2pmRgbk4f0Mp1V6ti91pMtGYLnpBh2YvNQslSyg== dependencies: "@ethersproject/providers" "^5.7.0" "@metamask/detect-provider" "^2.0.0" @@ -4744,7 +4745,7 @@ "@shapeshiftoss/hdwallet-core" "^1.55.1" "@shapeshiftoss/hdwallet-native" "^1.55.1" "@shapeshiftoss/logger" "^1.1.2" - "@shapeshiftoss/metamask-snaps-types" "^1.0.10" + "@shapeshiftoss/metamask-snaps-types" "^1.0.12" "@shapeshiftoss/types" "^8.3.0" "@shapeshiftoss/unchained-client" "10.1.1" eth-rpc-errors "^4.0.3" @@ -10203,7 +10204,7 @@ eth-sig-util@^1.4.2: resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.2.tgz#8d958202c7edbaae839707fba6f09ff327606210" integrity sha512-iNZ576iTOGcfllftB73cPB5AN+XUQAT/T8xzsILsghXC1o8gJUqe3RHlcDqagu+biFpYQ61KQrZZJza8eRSYqw== dependencies: - ethereumjs-abi "git+https://github.com/ethereumjs/ethereumjs-abi.git" + ethereumjs-abi "^0.6.8" ethereumjs-util "^5.1.1" ethereum-bloom-filters@^1.0.6: @@ -10274,13 +10275,6 @@ ethereumjs-abi@^0.6.8: bn.js "^4.11.8" ethereumjs-util "^6.0.0" -"ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git": - version "0.6.8" - resolved "git+https://github.com/ethereumjs/ethereumjs-abi.git#ee3994657fa7a427238e6ba92a84d0b529bbcde0" - dependencies: - bn.js "^4.11.8" - ethereumjs-util "^6.0.0" - ethereumjs-account@^2.0.3: version "2.0.5" resolved "https://registry.yarnpkg.com/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz#eeafc62de544cb07b0ee44b10f572c9c49e00a84" @@ -14427,6 +14421,11 @@ minizlib@^2.1.1, minizlib@^2.1.2: minipass "^3.0.0" yallist "^4.0.0" +mipd@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mipd/-/mipd-0.0.7.tgz#bb5559e21fa18dc3d9fe1c08902ef14b7ce32fd9" + integrity sha512-aAPZPNDQ3uMTdKbuO2YmAw2TxLHO0moa4YKAyETM/DTj5FloZo+a+8tU+iv4GmW+sOxKLSRwcSFuczk+Cpt6fg== + mixin-deep@^1.2.0: version "1.3.2" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" @@ -18107,13 +18106,6 @@ system-architecture@^0.1.0: resolved "https://registry.yarnpkg.com/system-architecture/-/system-architecture-0.1.0.tgz#71012b3ac141427d97c67c56bc7921af6bff122d" integrity sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA== -tallyho-onboarding@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/tallyho-onboarding/-/tallyho-onboarding-1.0.2.tgz#afc7dc4eb05b3a7861ead215e798585e1cbe2e91" - integrity sha512-bdFT/fNrFrq1BYVgjl/JKtwDmeS+z2u0415PoxmGmmYYRfdcKqXtEPImMoEbVwGtOeN0iFVohuS8ESrrAe+w7w== - dependencies: - bowser "^2.9.0" - tar-stream@~2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287"