diff --git a/examples/sandbox/index.ts b/examples/sandbox/index.ts index eb3d1f5d6..47bc9a0fe 100644 --- a/examples/sandbox/index.ts +++ b/examples/sandbox/index.ts @@ -439,7 +439,7 @@ $getXpubs.on("click", async (e) => { curve: "secp256k1", showDisplay: true, // Not supported by TrezorConnect or Ledger, but KeepKey should do it coin: "Bitcoin", - scriptType: core.BTCInputScriptType.SpendP2SHWitness, + scriptType: core.BTCScriptType.ScriptHashWitness, }, { addressNList: [0x80000000 + 44, 0x80000000 + 2, 0x80000000 + 0], @@ -993,7 +993,7 @@ $thorchainSignSwap.on("click", async (e) => { let inputs = [ { addressNList: [0x80000000 + 44, 0x80000000 + 0, 0x80000000 + 0, 0, 0], - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, amount: String(10000), vout: 1, txid: txid, @@ -1152,7 +1152,7 @@ $thorchainSignAddLiquidity.on("click", async (e) => { let inputs = [ { addressNList: [0x80000000 + 44, 0x80000000 + 0, 0x80000000 + 0, 0, 0], - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, amount: String(10000), vout: 1, txid: txid, @@ -1879,7 +1879,7 @@ $btcAddr.on("click", async (e) => { let res = await wallet.btcGetAddress({ addressNList: [0x80000000 + 44, 0x80000000 + 0, 0x80000000 + 0, 0, 0], coin: "Bitcoin", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, showDisplay: true, }); $btcResults.val(res); @@ -1904,7 +1904,7 @@ $btcTx.on("click", async (e) => { let inputs = [ { addressNList: [0x80000000 + 44, 0x80000000 + 0, 0x80000000 + 0, 0, 0], - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, amount: String(10000), vout: 1, txid: txid, @@ -1917,7 +1917,7 @@ $btcTx.on("click", async (e) => { { address: "1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1", addressType: core.BTCOutputAddressType.Spend, - scriptType: core.BTCOutputScriptType.PayToAddress, + scriptType: core.BTCScriptType.KeyHash, amount: String(10000 - 1000), isChange: false, }, @@ -1948,7 +1948,7 @@ $btcSign.on("click", async (e) => { let res = await wallet.btcSignMessage({ addressNList: core.bip32ToAddressNList("m/44'/0'/0'/0/0"), coin: "Bitcoin", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, message: "Hello World", }); $btcResults.val(res.address + " " + res.signature); @@ -1992,7 +1992,7 @@ const $ltcVerify = $("#ltcVerify"); const $ltcResults = $("#ltcResults"); const ltcBip44 = { - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, addressNList: [0x80000000 + 44, 0x80000000 + 2, 0x80000000 + 0, 0, 0], }; @@ -2030,7 +2030,7 @@ $ltcTx.on("click", async (e) => { const inputs = [ { addressNList: ltcBip44.addressNList, - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, amount: String(2160258), vout: 0, txid, @@ -2044,7 +2044,7 @@ $ltcTx.on("click", async (e) => { { address: "LLe4PciAJgMMJSAtQQ5nkC13t6SSMmERJ3", addressType: core.BTCOutputAddressType.Spend, - scriptType: core.BTCOutputScriptType.PayToAddress, + scriptType: core.BTCScriptType.KeyHash, amount: String(261614), isChange: false, }, @@ -2074,7 +2074,7 @@ $ltcSign.on("click", async (e) => { let res = await wallet.btcSignMessage({ addressNList: ltcBip44.addressNList, coin: "Litecoin", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, message: "Hello World", }); $ltcResults.val(res.address + " " + res.signature); @@ -2098,7 +2098,7 @@ const $dogeTx = $("#dogeTx"); const $dogeResults = $("#dogeResults"); const dogeBip44 = { - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, addressNList: [0x80000000 + 44, 0x80000000 + 3, 0x80000000 + 0], }; $dogeAddr.on("click", async (e) => { @@ -2135,7 +2135,7 @@ $dogeTx.on("click", async (e) => { const inputs = [ { addressNList: dogeBip44.addressNList.concat([0, 0]), - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, amount: String(35577380098), vout: 1, txid: txid, @@ -2149,7 +2149,7 @@ $dogeTx.on("click", async (e) => { { address: "DMEHVGRsELY5zyYbfgta3pAhedKGeaDeJd", addressType: core.BTCOutputAddressType.Spend, - scriptType: core.BTCOutputScriptType.PayToAddress, + scriptType: core.BTCScriptType.KeyHash, amount: String(35577380098), isChange: false, }, @@ -2181,7 +2181,7 @@ const $bchTx = $("#bchTx"); const $bchResults = $("#bchResults"); const bchBip44 = { - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, addressNList: [0x80000000 + 44, 0x80000000 + 145, 0x80000000 + 0], }; @@ -2219,7 +2219,7 @@ $bchTx.on("click", async (e) => { const inputs = [ { addressNList: bchBip44.addressNList.concat([0, 0]), - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, amount: String(13813640), vout: 0, txid: txid, @@ -2230,11 +2230,13 @@ $bchTx.on("click", async (e) => { const outputs = [ { - address: (await wallet.btcSupportsScriptType("BitcoinCash", core.BTCInputScriptType.CashAddr)) - ? "bitcoincash:qq5mg2xtp9y5pvvgy7m4k2af5a7s5suulueyywgvnf" - : "14oWXZFPhgP9DA3ggPzhHpUUaikDSjAuMC", + // TODO: replace with btcSupportsAddressFormat + // address: (await wallet.btcSupportsAddressFormat("BitcoinCash", core.BTCAddressFormat.CashAddr)) + // ? "bitcoincash:qq5mg2xtp9y5pvvgy7m4k2af5a7s5suulueyywgvnf" + // : "14oWXZFPhgP9DA3ggPzhHpUUaikDSjAuMC", + address: "14oWXZFPhgP9DA3ggPzhHpUUaikDSjAuMC", addressType: core.BTCOutputAddressType.Spend, - scriptType: core.BTCOutputScriptType.PayToAddress, + scriptType: core.BTCScriptType.KeyHash, amount: String(13813640), isChange: false, }, @@ -2266,7 +2268,7 @@ const $dashTx = $("#dashTx"); const $dashResults = $("#dashResults"); const dashBip44 = { - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, addressNList: [0x80000000 + 44, 0x80000000 + 5, 0x80000000 + 0], }; @@ -2304,7 +2306,7 @@ $dashTx.on("click", async (e) => { const inputs = [ { addressNList: dashBip44.addressNList.concat([0, 0]), - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, amount: String(4954359), vout: 0, txid: txid, @@ -2318,7 +2320,7 @@ $dashTx.on("click", async (e) => { { address: "XexybzTUtH9V9eY4UJN2aCcBT3utan5C8N", addressType: core.BTCOutputAddressType.Spend, - scriptType: core.BTCOutputScriptType.PayToAddress, + scriptType: core.BTCScriptType.KeyHash, amount: String(4000000), isChange: false, }, @@ -2349,7 +2351,7 @@ const $dgbTx = $("#dgbTx"); const $dgbResults = $("#dgbResults"); const dgbBip44 = { - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, addressNList: [0x80000000 + 44, 0x80000000 + 20, 0x80000000 + 0], }; @@ -2389,7 +2391,7 @@ $dgbTx.on("click", async (e) => { const inputs = [ { addressNList: dgbBip44.addressNList.concat([0, 0]), - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, amount: String(480000000), vout: 15, txid: "be150359df4123b379f1f12de978bfced92644645da17b97c7613879f4306a90", @@ -2398,7 +2400,7 @@ $dgbTx.on("click", async (e) => { }, { addressNList: dgbBip44.addressNList.concat([0, 0]), - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, amount: String(10000000), vout: 0, txid: "528ec23eaf123282e9bce297ebb3edfb05e8b4d5875cbc9c271a98d72a202340", @@ -2411,14 +2413,14 @@ $dgbTx.on("click", async (e) => { { address: "SWpe93hQL2pLUDLy7swsDPWQJGCHSsgmun", addressType: null, - scriptType: core.BTCOutputScriptType.PayToMultisig, + scriptType: core.BTCScriptType.ScriptHash, amount: String(400000000), isChange: false, }, { address: "DNLcBry65dHehGExGYjBkM8kxDYr7mZ3BT", addressType: null, - scriptType: core.BTCOutputScriptType.PayToAddress, + scriptType: core.BTCScriptType.KeyHash, relpath: "1/9", amount: String(90000000), isChange: true, @@ -2467,7 +2469,7 @@ $btcAddrSegWit.on("click", async (e) => { let res = await wallet.btcGetAddress({ addressNList: [0x80000000 + 49, 0x80000000 + 0, 0x80000000 + 0, 0, 0], coin: "Bitcoin", - scriptType: core.BTCInputScriptType.SpendP2SHWitness, + scriptType: core.BTCScriptType.ScriptHashWitness, showDisplay: true, }); @@ -2490,7 +2492,7 @@ $btcAddrSegWitNative.on("click", async (e) => { let res = await wallet.btcGetAddress({ addressNList: [0x80000000 + 84, 0x80000000 + 0, 0x80000000 + 0, 0, 0], coin: "Bitcoin", - scriptType: core.BTCInputScriptType.SpendWitness, + scriptType: core.BTCScriptType.Witness, showDisplay: true, }); $btcResultsSegWit.val(res); @@ -2517,7 +2519,7 @@ $btcTxSegWit.on("click", async (e) => { amount: String(100000), vout: 0, txid: txid, - scriptType: core.BTCInputScriptType.SpendP2SHWitness, + scriptType: core.BTCScriptType.ScriptHashWitness, tx: btcSegWitTxJson, hex, }, @@ -2527,7 +2529,7 @@ $btcTxSegWit.on("click", async (e) => { { address: "3Eq3agTHEhMCC8sZHnJJcCcZFB7BBSJKWr", addressType: core.BTCOutputAddressType.Spend, - scriptType: core.BTCOutputScriptType.PayToAddress, + scriptType: core.BTCScriptType.KeyHash, amount: String(89869), isChange: false, }, @@ -2569,7 +2571,7 @@ $btcTxSegWitNative.on("click", async (e) => { amount: String(9426), vout: 0, txid: txid, - scriptType: core.BTCInputScriptType.SpendWitness, + scriptType: core.BTCScriptType.Witness, tx: btcBech32TxJson, hex, }, @@ -2579,7 +2581,7 @@ $btcTxSegWitNative.on("click", async (e) => { { address: "bc1qc5dgazasye0yrzdavnw6wau5up8td8gdqh7t6m", addressType: core.BTCOutputAddressType.Spend, - scriptType: core.BTCOutputScriptType.PayToAddress, + scriptType: core.BTCScriptType.KeyHash, amount: String(1337), isChange: false, }, diff --git a/integration/src/bitcoin/bitcoin.ts b/integration/src/bitcoin/bitcoin.ts index c93a9d171..980e01ed5 100644 --- a/integration/src/bitcoin/bitcoin.ts +++ b/integration/src/bitcoin/bitcoin.ts @@ -87,37 +87,37 @@ export function bitcoinTests(get: () => { wallet: core.HDWallet; info: core.HDWa coin: "Bitcoin", addressNList: core.bip32ToAddressNList(`m/49'/0'/0'`), curve: "secp256k1", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, }, { coin: "Bitcoin", addressNList: core.bip32ToAddressNList(`m/49'/0'/0'`), curve: "secp256k1", - scriptType: core.BTCInputScriptType.SpendP2SHWitness, + scriptType: core.BTCScriptType.ScriptHashWitness, }, { coin: "Bitcoin", addressNList: core.bip32ToAddressNList(`m/49'/0'/0'`), curve: "secp256k1", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, }, { coin: "Bitcoin", addressNList: core.bip32ToAddressNList(`m/84'/0'/0'`), curve: "secp256k1", - scriptType: core.BTCInputScriptType.SpendWitness, + scriptType: core.BTCScriptType.Witness, }, { coin: "Bitcoin", addressNList: core.bip32ToAddressNList(`m/0'/0'/0'`), curve: "secp256k1", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, }, { coin: "Litecoin", addressNList: core.bip32ToAddressNList(`m/0'/0'/0'`), curve: "secp256k1", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, }, ]) ).toEqual([ @@ -155,35 +155,35 @@ export function bitcoinTests(get: () => { wallet: core.HDWallet; info: core.HDWa "Show", "Bitcoin", "m/44'/0'/0'/0/0", - core.BTCInputScriptType.SpendAddress, + core.BTCScriptType.KeyHash, "1FH6ehAd5ZFXCM1cLGzHxK1s4dGdq1JusM", ], [ "Show", "Bitcoin", "m/49'/0'/0'/0/0", - core.BTCInputScriptType.SpendP2SHWitness, + core.BTCScriptType.ScriptHashWitness, "3AnYTd2FGxJLNKL1AzxfW3FJMntp9D2KKX", ], [ "Tell", "Bitcoin", "m/49'/0'/0'/0/0", - core.BTCInputScriptType.SpendP2SHWitness, + core.BTCScriptType.ScriptHashWitness, "3AnYTd2FGxJLNKL1AzxfW3FJMntp9D2KKX", ], [ "Tell", "Litecoin", "m/49'/2'/0'/0/0", - core.BTCInputScriptType.SpendP2SHWitness, + core.BTCScriptType.ScriptHashWitness, "MFoQRU1KQq365Sy3cXhix3ygycEU4YWB1V", ], [ "Tell", "Dash", "m/44'/5'/0'/0/0", - core.BTCInputScriptType.SpendAddress, + core.BTCScriptType.KeyHash, "XxKhGNv6ECbqVswm9KYcLPQnyWgZ86jJ6Q", ], ], @@ -191,7 +191,7 @@ export function bitcoinTests(get: () => { wallet: core.HDWallet; info: core.HDWa let mode = args[0] as string; let coin = args[1] as core.Coin; let path = args[2] as string; - let scriptType = args[3] as core.BTCInputScriptType; + let scriptType = args[3] as core.BTCScriptType; let expected = args[4] as string; if (!(await wallet.btcSupportsCoin(coin))) return; @@ -249,7 +249,7 @@ export function bitcoinTests(get: () => { wallet: core.HDWallet; info: core.HDWa const inputs: core.BTCSignTxInputUnguarded[] = [ { addressNList: core.bip32ToAddressNList("m/0"), - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, amount: String(390000), vout: 0, txid: "d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882", @@ -261,7 +261,7 @@ export function bitcoinTests(get: () => { wallet: core.HDWallet; info: core.HDWa { address: "1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1", addressType: core.BTCOutputAddressType.Spend, - // scriptType: core.BTCOutputScriptType.PayToAddress, + // scriptType: core.BTCScriptType.KeyHash, amount: String(390000 - 10000), isChange: false, }, @@ -325,7 +325,7 @@ export function bitcoinTests(get: () => { wallet: core.HDWallet; info: core.HDWa const inputs: core.BTCSignTxInputUnguarded[] = [ { addressNList: core.bip32ToAddressNList("m/0"), - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, amount: String(390000), vout: 0, txid: "d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882", @@ -343,7 +343,7 @@ export function bitcoinTests(get: () => { wallet: core.HDWallet; info: core.HDWa { addressNList: core.bip32ToAddressNList("m/44'/0'/0'/0/0"), addressType: core.BTCOutputAddressType.Change, - scriptType: core.BTCOutputScriptType.PayToAddress, + scriptType: core.BTCScriptType.KeyHash, amount: String(9000), isChange: true, }, @@ -384,7 +384,7 @@ export function bitcoinTests(get: () => { wallet: core.HDWallet; info: core.HDWa let res = wallet.btcSignMessage({ addressNList: core.bip32ToAddressNList("m/44'/0'/0'/0/0"), coin: "Bitcoin", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, message: "Hello World", }); @@ -481,20 +481,20 @@ export function bitcoinTests(get: () => { wallet: core.HDWallet; info: core.HDWa await each( [ ["Bitcoin", 0, undefined], - ["Bitcoin", 1, core.BTCInputScriptType.SpendAddress], - ["Bitcoin", 3, core.BTCInputScriptType.SpendP2SHWitness], - ["Bitcoin", 2, core.BTCInputScriptType.SpendWitness], - ["Litecoin", 1, core.BTCInputScriptType.SpendAddress], - ["Litecoin", 1, core.BTCInputScriptType.SpendP2SHWitness], - ["Dash", 0, core.BTCInputScriptType.SpendAddress], - ["Dogecoin", 0, core.BTCInputScriptType.SpendAddress], - ["BitcoinCash", 0, core.BTCInputScriptType.SpendAddress], - ["BitcoinGold", 0, core.BTCInputScriptType.SpendAddress], + ["Bitcoin", 1, core.BTCScriptType.KeyHash], + ["Bitcoin", 3, core.BTCScriptType.ScriptHashWitness], + ["Bitcoin", 2, core.BTCScriptType.Witness], + ["Litecoin", 1, core.BTCScriptType.KeyHash], + ["Litecoin", 1, core.BTCScriptType.ScriptHashWitness], + ["Dash", 0, core.BTCScriptType.KeyHash], + ["Dogecoin", 0, core.BTCScriptType.KeyHash], + ["BitcoinCash", 0, core.BTCScriptType.KeyHash], + ["BitcoinGold", 0, core.BTCScriptType.KeyHash], ], async (args) => { let coin = args[0] as core.Coin; let accountIdx = args[1] as number; - let scriptType = args[2] as core.BTCInputScriptType; + let scriptType = args[2] as core.BTCScriptType; if (!wallet) return; if (!(await wallet.btcSupportsCoin(coin))) return; expect(await info.btcSupportsCoin(coin)).toBeTruthy(); diff --git a/integration/src/bitcoin/litecoin.ts b/integration/src/bitcoin/litecoin.ts index e19f323d7..45e81c11e 100644 --- a/integration/src/bitcoin/litecoin.ts +++ b/integration/src/bitcoin/litecoin.ts @@ -39,21 +39,21 @@ export function litecoinTests(get: () => { wallet: core.HDWallet; info: core.HDW "Show", "Litecoin", "m/44'/2'/0'/0/0", - core.BTCInputScriptType.SpendAddress, + core.BTCScriptType.KeyHash, "LYXTv5RdsPYKC4qGmb6x6SuKoFMxUdSjLQ", ], [ "Tell", "Litecoin", "m/49'/2'/0'/0/0", - core.BTCInputScriptType.SpendP2SHWitness, + core.BTCScriptType.ScriptHashWitness, "MFoQRU1KQq365Sy3cXhix3ygycEU4YWB1V", ], [ "Tell", "Litecoin", "m/84'/2'/0'/0/0", - core.BTCInputScriptType.SpendWitness, + core.BTCScriptType.Witness, "ltc1qf6pwfkw4wd0fetq2pfrwzlfknskjg6nyvt6ngv", ], ], @@ -61,7 +61,7 @@ export function litecoinTests(get: () => { wallet: core.HDWallet; info: core.HDW let mode = args[0] as string; let coin = args[1] as core.Coin; let path = args[2] as string; - let scriptType = args[3] as core.BTCInputScriptType; + let scriptType = args[3] as core.BTCScriptType; let expected = args[4] as string; if (!(await wallet.btcSupportsScriptType(coin, scriptType))) return; @@ -83,14 +83,14 @@ export function litecoinTests(get: () => { wallet: core.HDWallet; info: core.HDW async () => { await each( [ - ["Litecoin", 1, core.BTCInputScriptType.SpendAddress], - ["Litecoin", 1, core.BTCInputScriptType.SpendP2SHWitness], - ["Litecoin", 1, core.BTCInputScriptType.SpendWitness], + ["Litecoin", 1, core.BTCScriptType.KeyHash], + ["Litecoin", 1, core.BTCScriptType.ScriptHashWitness], + ["Litecoin", 1, core.BTCScriptType.Witness], ], async (args) => { let coin = args[0] as core.Coin; let accountIdx = args[1] as number; - let scriptType = args[2] as core.BTCInputScriptType; + let scriptType = args[2] as core.BTCScriptType; if (!wallet) return; if (!(await wallet.btcSupportsCoin(coin))) return; if (!(await wallet.btcSupportsScriptType(coin, scriptType))) return; diff --git a/integration/src/bitcoin/testnet.ts b/integration/src/bitcoin/testnet.ts index ec0cda6da..c0726ab4a 100644 --- a/integration/src/bitcoin/testnet.ts +++ b/integration/src/bitcoin/testnet.ts @@ -37,7 +37,7 @@ export function testnetTests(get: () => { wallet: core.HDWallet; info: core.HDWa const inputs: core.BTCSignTxInputUnguarded[] = [ { addressNList: core.bip32ToAddressNList("m/49'/1'/0'/1/0"), - scriptType: core.BTCInputScriptType.SpendP2SHWitness, + scriptType: core.BTCScriptType.ScriptHashWitness, amount: String(123456789), vout: 0, txid: "20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337", @@ -54,7 +54,7 @@ export function testnetTests(get: () => { wallet: core.HDWallet; info: core.HDWa }, { addressNList: core.bip32ToAddressNList("m/49'/1'/0'/1/0"), - scriptType: core.BTCOutputScriptType.PayToP2SHWitness, + scriptType: core.BTCScriptType.ScriptHashWitness, addressType: core.BTCOutputAddressType.Change, amount: String(123456789 - 11000 - 12300000), isChange: true, @@ -94,7 +94,7 @@ export function testnetTests(get: () => { wallet: core.HDWallet; info: core.HDWa const inputs: core.BTCSignTxInputUnguarded[] = [ { addressNList: core.bip32ToAddressNList("m/84'/1'/0'/0/0"), - scriptType: core.BTCInputScriptType.SpendWitness, + scriptType: core.BTCScriptType.Witness, amount: String(100000), vout: 0, txid: "e4b5b24159856ea18ab5819832da3b4a6330f9c3c0a46d96674e632df504b56b", @@ -111,7 +111,7 @@ export function testnetTests(get: () => { wallet: core.HDWallet; info: core.HDWa }, { addressNList: core.bip32ToAddressNList("m/84'/1'/0'/1/0"), - scriptType: core.BTCOutputScriptType.PayToWitness, + scriptType: core.BTCScriptType.Witness, addressType: core.BTCOutputAddressType.Change, amount: String(100000 - 1000 - 50000), isChange: true, diff --git a/integration/src/wallets/keepkey.ts b/integration/src/wallets/keepkey.ts index a161e31e1..f5e556986 100644 --- a/integration/src/wallets/keepkey.ts +++ b/integration/src/wallets/keepkey.ts @@ -141,6 +141,7 @@ export function selfTest(get: () => core.HDWallet): void { .btcGetAddress({ coin: "Bitcoin", addressNList: core.bip32ToAddressNList("m/44'/0'/0'/0/0"), + scriptType: core.BTCScriptType.KeyHash, showDisplay: true, }) .then((address) => { @@ -151,6 +152,7 @@ export function selfTest(get: () => core.HDWallet): void { .btcGetAddress({ coin: "Bitcoin", addressNList: core.bip32ToAddressNList("m/44'/0'/0'/0/1"), + scriptType: core.BTCScriptType.KeyHash, showDisplay: true, }) .then((address) => { @@ -161,6 +163,7 @@ export function selfTest(get: () => core.HDWallet): void { .btcGetAddress({ coin: "Bitcoin", addressNList: core.bip32ToAddressNList("m/44'/0'/0'/0/2"), + scriptType: core.BTCScriptType.KeyHash, showDisplay: true, }) .then((address) => { @@ -190,6 +193,7 @@ export function selfTest(get: () => core.HDWallet): void { const addrPromise = wallet.btcGetAddress({ coin: "Bitcoin", addressNList: core.bip32ToAddressNList("m/44'/0'/0'/0/0"), + scriptType: core.BTCScriptType.KeyHash, showDisplay: true, }); @@ -213,6 +217,7 @@ export function selfTest(get: () => core.HDWallet): void { wallet.btcGetAddress({ coin: "Bitcoin", addressNList: core.bip32ToAddressNList("m/44'/0'/0'/0/0"), + scriptType: core.BTCScriptType.KeyHash, showDisplay: true, }) ).resolves.toEqual("1JAd7XCBzGudGpJQSDSfpmJhiygtLQWaGL"); @@ -231,17 +236,17 @@ export function selfTest(get: () => core.HDWallet): void { expect(paths).toEqual([ { addressNList: [2147483692, 2147483650, 2147483651], - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, coin: "Litecoin", }, { addressNList: [2147483697, 2147483650, 2147483651], - scriptType: core.BTCInputScriptType.SpendP2SHWitness, + scriptType: core.BTCScriptType.ScriptHashWitness, coin: "Litecoin", }, { addressNList: [2147483732, 2147483650, 2147483651], - scriptType: core.BTCInputScriptType.SpendWitness, + scriptType: core.BTCScriptType.Witness, coin: "Litecoin", }, ]); @@ -330,13 +335,13 @@ export function selfTest(get: () => core.HDWallet): void { wallet.info.describePath({ path: core.bip32ToAddressNList("m/44'/0'/0'/0/0"), coin: "Bitcoin", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, }) ).toEqual({ verbose: "Bitcoin Account #0, Address #0 (Legacy)", coin: "Bitcoin", isKnown: true, - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, accountIdx: 0, addressIdx: 0, wholeAccount: false, @@ -350,13 +355,13 @@ export function selfTest(get: () => core.HDWallet): void { wallet.info.describePath({ path: core.bip32ToAddressNList("m/44'/0'/0'/0/0"), coin: "BitcoinCash", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, }) ).toEqual({ verbose: "BitcoinCash Account #0, Address #0 (Prefork)", coin: "BitcoinCash", isKnown: true, - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, accountIdx: 0, addressIdx: 0, wholeAccount: false, @@ -370,13 +375,13 @@ export function selfTest(get: () => core.HDWallet): void { wallet.info.describePath({ path: core.bip32ToAddressNList("m/84'/0'/0'/0/0"), coin: "BitcoinGold", - scriptType: core.BTCInputScriptType.SpendWitness, + scriptType: core.BTCScriptType.Witness, }) ).toEqual({ verbose: "BitcoinGold Account #0, Address #0 (Prefork, Segwit Native)", coin: "BitcoinGold", isKnown: true, - scriptType: core.BTCInputScriptType.SpendWitness, + scriptType: core.BTCScriptType.Witness, accountIdx: 0, addressIdx: 0, wholeAccount: false, @@ -390,13 +395,13 @@ export function selfTest(get: () => core.HDWallet): void { wallet.info.describePath({ path: core.bip32ToAddressNList("m/44'/0'/7'/1/5"), coin: "Bitcoin", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, }) ).toEqual({ verbose: "Bitcoin Account #7, Change Address #5 (Legacy)", coin: "Bitcoin", isKnown: true, - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, accountIdx: 7, addressIdx: 5, wholeAccount: false, @@ -410,7 +415,7 @@ export function selfTest(get: () => core.HDWallet): void { wallet.info.describePath({ path: core.bip32ToAddressNList("m/44'/0'/7'/1/5"), coin: "BitcoinCash", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, }) ).toEqual({ accountIdx: 7, diff --git a/integration/src/wallets/ledger.ts b/integration/src/wallets/ledger.ts index 498c490c4..779c4b2ce 100644 --- a/integration/src/wallets/ledger.ts +++ b/integration/src/wallets/ledger.ts @@ -297,17 +297,17 @@ export function selfTest(get: () => core.HDWallet): void { expect(paths).toEqual([ { addressNList: [2147483697, 2147483650, 2147483651], - scriptType: core.BTCInputScriptType.SpendP2SHWitness, + scriptType: core.BTCScriptType.ScriptHashWitness, coin: "Litecoin", }, { addressNList: [2147483692, 2147483650, 2147483651], - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, coin: "Litecoin", }, { addressNList: [2147483732, 2147483650, 2147483651], - scriptType: core.BTCInputScriptType.SpendWitness, + scriptType: core.BTCScriptType.Witness, coin: "Litecoin", }, ]); @@ -366,12 +366,12 @@ export function selfTest(get: () => core.HDWallet): void { wallet.info.describePath({ path: core.bip32ToAddressNList("m/44'/0'/0'/0/0"), coin: "Bitcoin", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, }) ).toEqual({ verbose: "Bitcoin Account #0, Address #0 (Legacy)", coin: "Bitcoin", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, isKnown: true, accountIdx: 0, addressIdx: 0, @@ -384,12 +384,12 @@ export function selfTest(get: () => core.HDWallet): void { wallet.info.describePath({ path: core.bip32ToAddressNList("m/44'/0'/7'/1/5"), coin: "Bitcoin", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, }) ).toEqual({ verbose: "Bitcoin Account #7, Change Address #5 (Legacy)", coin: "Bitcoin", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, isKnown: true, accountIdx: 7, addressIdx: 5, @@ -402,12 +402,12 @@ export function selfTest(get: () => core.HDWallet): void { wallet.info.describePath({ path: core.bip32ToAddressNList("m/44'/0'/7'/1/5"), coin: "BitcoinCash", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, }) ).toEqual({ verbose: "m/44'/0'/7'/1/5", coin: "BitcoinCash", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, isKnown: false, }); diff --git a/integration/src/wallets/native.ts b/integration/src/wallets/native.ts index 9acb1a8d5..a5152d84d 100644 --- a/integration/src/wallets/native.ts +++ b/integration/src/wallets/native.ts @@ -242,17 +242,17 @@ export function selfTest(get: () => core.HDWallet): void { expect(paths).toEqual([ { addressNList: [2147483692, 2147483650, 2147483651], - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, coin: "Litecoin", }, { addressNList: [2147483697, 2147483650, 2147483651], - scriptType: core.BTCInputScriptType.SpendP2SHWitness, + scriptType: core.BTCScriptType.ScriptHashWitness, coin: "Litecoin", }, { addressNList: [2147483732, 2147483650, 2147483651], - scriptType: core.BTCInputScriptType.SpendWitness, + scriptType: core.BTCScriptType.Witness, coin: "Litecoin", }, ]); @@ -333,7 +333,7 @@ export function selfTest(get: () => core.HDWallet): void { coin: "Litecoin", isKnown: true, scriptType: "p2wpkh", - verbose: "Litecoin Account #4 (Segwit)", + verbose: "Litecoin Account #4 (Segwit Native)", wholeAccount: true, isPrefork: false, }, @@ -345,13 +345,13 @@ export function selfTest(get: () => core.HDWallet): void { wallet.describePath({ path: core.bip32ToAddressNList("m/44'/0'/0'/0/0"), coin: "Bitcoin", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, }) ).toEqual({ verbose: "Bitcoin Account #0, Address #0 (Legacy)", coin: "Bitcoin", isKnown: true, - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, accountIdx: 0, addressIdx: 0, wholeAccount: false, @@ -365,13 +365,13 @@ export function selfTest(get: () => core.HDWallet): void { wallet.describePath({ path: core.bip32ToAddressNList("m/84'/0'/0'/0/0"), coin: "Bitcoin", - scriptType: core.BTCInputScriptType.Bech32, + scriptType: core.BTCScriptType.Witness, }) ).toEqual({ verbose: "Bitcoin Account #0, Address #0 (Segwit Native)", coin: "Bitcoin", isKnown: true, - scriptType: core.BTCInputScriptType.Bech32, + scriptType: core.BTCScriptType.Witness, accountIdx: 0, addressIdx: 0, wholeAccount: false, @@ -385,13 +385,13 @@ export function selfTest(get: () => core.HDWallet): void { wallet.describePath({ path: core.bip32ToAddressNList("m/44'/0'/7'/1/5"), coin: "Bitcoin", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, }) ).toEqual({ verbose: "Bitcoin Account #7, Change Address #5 (Legacy)", coin: "Bitcoin", isKnown: true, - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, accountIdx: 7, addressIdx: 5, wholeAccount: false, @@ -405,13 +405,13 @@ export function selfTest(get: () => core.HDWallet): void { wallet.describePath({ path: core.bip32ToAddressNList("m/44'/0'/0'/0/0"), coin: "BitcoinCash", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, }) ).toEqual({ verbose: "BitcoinCash Account #0, Address #0 (Prefork)", coin: "BitcoinCash", isKnown: true, - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, accountIdx: 0, addressIdx: 0, wholeAccount: false, @@ -425,13 +425,13 @@ export function selfTest(get: () => core.HDWallet): void { wallet.describePath({ path: core.bip32ToAddressNList("m/84'/0'/0'/0/0"), coin: "BitcoinGold", - scriptType: core.BTCInputScriptType.SpendWitness, + scriptType: core.BTCScriptType.Witness, }) ).toEqual({ verbose: "BitcoinGold Account #0, Address #0 (Prefork, Segwit Native)", coin: "BitcoinGold", isKnown: true, - scriptType: core.BTCInputScriptType.SpendWitness, + scriptType: core.BTCScriptType.Witness, accountIdx: 0, addressIdx: 0, wholeAccount: false, @@ -445,13 +445,13 @@ export function selfTest(get: () => core.HDWallet): void { wallet.describePath({ path: core.bip32ToAddressNList("m/44'/0'/7'/1/5"), coin: "Bitcoin", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, }) ).toEqual({ verbose: "Bitcoin Account #7, Change Address #5 (Legacy)", coin: "Bitcoin", isKnown: true, - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, accountIdx: 7, addressIdx: 5, wholeAccount: false, @@ -465,7 +465,7 @@ export function selfTest(get: () => core.HDWallet): void { wallet.describePath({ path: core.bip32ToAddressNList("m/44'/0'/7'/1/5"), coin: "BitcoinCash", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, }) ).toEqual({ accountIdx: 7, diff --git a/integration/src/wallets/trezor.ts b/integration/src/wallets/trezor.ts index 1c06c8ea4..4799a8b6a 100644 --- a/integration/src/wallets/trezor.ts +++ b/integration/src/wallets/trezor.ts @@ -425,17 +425,17 @@ export function selfTest(get: () => core.HDWallet): void { expect(paths).toEqual([ { addressNList: [2147483697, 2147483650, 2147483651], - scriptType: core.BTCInputScriptType.SpendP2SHWitness, + scriptType: core.BTCScriptType.ScriptHashWitness, coin: "Litecoin", }, { addressNList: [2147483692, 2147483650, 2147483651], - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, coin: "Litecoin", }, { addressNList: [2147483732, 2147483650, 2147483651], - scriptType: core.BTCInputScriptType.SpendWitness, + scriptType: core.BTCScriptType.Witness, coin: "Litecoin", }, ]); @@ -496,12 +496,12 @@ export function selfTest(get: () => core.HDWallet): void { wallet.info.describePath({ path: core.bip32ToAddressNList("m/44'/0'/0'/0/0"), coin: "Bitcoin", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, }) ).toEqual({ verbose: "Bitcoin Account #0, Address #0 (Legacy)", coin: "Bitcoin", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, isKnown: true, accountIdx: 0, addressIdx: 0, @@ -514,12 +514,12 @@ export function selfTest(get: () => core.HDWallet): void { wallet.info.describePath({ path: core.bip32ToAddressNList("m/44'/0'/7'/1/5"), coin: "Bitcoin", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, }) ).toEqual({ verbose: "Bitcoin Account #7, Change Address #5 (Legacy)", coin: "Bitcoin", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, isKnown: true, accountIdx: 7, addressIdx: 5, @@ -532,12 +532,12 @@ export function selfTest(get: () => core.HDWallet): void { wallet.info.describePath({ path: core.bip32ToAddressNList("m/44'/0'/7'/1/5"), coin: "BitcoinCash", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, }) ).toEqual({ verbose: "m/44'/0'/7'/1/5", coin: "BitcoinCash", - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, isKnown: false, }); diff --git a/packages/hdwallet-core/src/bitcoin.ts b/packages/hdwallet-core/src/bitcoin.ts index 1ab52165e..e1ec62b38 100644 --- a/packages/hdwallet-core/src/bitcoin.ts +++ b/packages/hdwallet-core/src/bitcoin.ts @@ -18,7 +18,8 @@ type GuardedUnion = GuardedUnionInner; export type BTCGetAddress = { coin: Coin; addressNList: BIP32Path; - scriptType?: BTCInputScriptType; // Defaults to BTCInputScriptType.SpendAddress + scriptType: BTCScriptType; + addressFormat?: BTCAddressFormat; showDisplay?: boolean; }; @@ -76,7 +77,7 @@ type BTCSignTxInputNativeBase = BTCSignTxInputBase & { }; type BTCSignTxInputNativeSegwitBase = BTCSignTxInputNativeBase & { - scriptType: BTCInputScriptType.SpendWitness | BTCInputScriptType.SpendP2SHWitness; + scriptType: BTCScriptType.Witness | BTCScriptType.ScriptHashWitness; }; type BTCSignTxInputNativeSegwitWithHex = BTCSignTxInputNativeSegwitBase & { @@ -92,7 +93,7 @@ type BTCSignTxInputNativeSegwitWithTx = BTCSignTxInputNativeSegwitBase & { type BTCSignTxInputNativeSegwit = BTCSignTxInputNativeSegwitWithHex | BTCSignTxInputNativeSegwitWithTx; type BTCSignTxInputNativeNonSegwit = BTCSignTxInputNativeBase & { - scriptType: Exclude; + scriptType: Exclude; hex: string; }; @@ -106,12 +107,12 @@ type BTCSignTxInputKKBase = BTCSignTxInputBase & { }; type BTCSignTxInputKKSegwit = BTCSignTxInputKKBase & { - scriptType: BTCInputScriptType.SpendWitness | BTCInputScriptType.SpendP2SHWitness | BTCInputScriptType.External; + scriptType: BTCScriptType.Witness | BTCScriptType.ScriptHashWitness; hex?: string; }; type BTCSignTxInputKKNonSegwit = BTCSignTxInputKKBase & { - scriptType: Exclude; + scriptType: Exclude; } & ( | { tx: BitcoinTx; @@ -127,12 +128,12 @@ export type BTCSignTxInputKK = GuardedUnion; export type BTCSignTxInputTrezor = BTCSignTxInputBase & { txid: string; amount: string; - scriptType: BTCInputScriptType; + scriptType: BTCScriptType; }; export type BTCSignTxInputLedger = BTCSignTxInputBase & { addressNList: BIP32Path; - scriptType: BTCInputScriptType; + scriptType: BTCScriptType; hex: string; }; @@ -145,7 +146,7 @@ export type BTCSignTxInputUnguarded = BTCSignTxInputNativeUnguarded & // Stick to this common subset of input fields to avoid type hell. export type BTCSignTxInputSafe = { addressNList: BIP32Path; - scriptType: BTCInputScriptType; + scriptType: BTCScriptType; hex: string; txid: string; amount: string; @@ -167,21 +168,21 @@ export type BTCSignTxOutputSpendP2PKH = { addressType?: BTCOutputAddressType.Spend; amount: string; address: string; - scriptType: BTCOutputScriptType.PayToAddress; + scriptType: BTCScriptType.KeyHash; }; export type BTCSignTxOutputSpendP2SH = { addressType?: BTCOutputAddressType.Spend; amount: string; address: string; - scriptType: BTCOutputScriptType.PayToMultisig | BTCOutputScriptType.PayToP2SHWitness; + scriptType: BTCScriptType.ScriptHash | BTCScriptType.ScriptHashWitness; }; export type BTCSignTxOutputSpendP2WPKH = { addressType?: BTCOutputAddressType.Spend; amount: string; address: string; - scriptType: BTCOutputScriptType.PayToWitness; + scriptType: BTCScriptType.Witness; }; export type BTCSignTxOutputTransfer = { @@ -189,7 +190,7 @@ export type BTCSignTxOutputTransfer = { amount: string; /** bip32 path for destination (device must `btcSupportsSecureTransfer()`) */ addressNList: BIP32Path; - scriptType: BTCOutputScriptType; + scriptType: BTCScriptType; }; export type BTCSignTxOutputChange = { @@ -197,7 +198,7 @@ export type BTCSignTxOutputChange = { amount: string; /** bip32 path for destination (device must `btcSupportsSecureTransfer()`) */ addressNList: BIP32Path; - scriptType: BTCOutputScriptType; + scriptType: BTCScriptType; isChange: true; }; @@ -249,23 +250,32 @@ export interface BTCSignedTx { serializedTx: string; } -// Bech32 info https://en.bitcoin.it/wiki/BIP_0173 -export enum BTCInputScriptType { - CashAddr = "cashaddr", // for Bitcoin Cash - Bech32 = "bech32", - SpendAddress = "p2pkh", - SpendMultisig = "p2sh", - External = "external", - SpendWitness = "p2wpkh", - SpendP2SHWitness = "p2sh-p2wpkh", +export enum BTCScriptType { + KeyHash = "p2pkh", + ScriptHash = "p2sh", + Witness = "p2wpkh", + ScriptHashWitness = "p2sh-p2wpkh", } -export enum BTCOutputScriptType { - PayToAddress = "p2pkh", - PayToMultisig = "p2sh", +export enum BTCAddressFormat { + Base58CheckP2PKH = "bs58check:p2pkh", + Base58CheckP2SH = "bs58check:p2sh", Bech32 = "bech32", - PayToWitness = "p2wpkh", - PayToP2SHWitness = "p2sh-p2wpkh", + CashAddr = "cashaddr", +} + +export function defaultAddressFormatForScriptType(scriptType: BTCScriptType): BTCAddressFormat { + switch (scriptType) { + case BTCScriptType.KeyHash: return BTCAddressFormat.Base58CheckP2PKH; + case BTCScriptType.ScriptHash: return BTCAddressFormat.Base58CheckP2SH; + case BTCScriptType.Witness: return BTCAddressFormat.Bech32; + case BTCScriptType.ScriptHashWitness: return BTCAddressFormat.Base58CheckP2SH; + default: throw new TypeError("scriptType"); + } +} + +export function isSegwitScript(scriptType: BTCScriptType): boolean { + return [BTCScriptType.ScriptHashWitness, BTCScriptType.Witness].includes(scriptType) } export enum BTCOutputAddressType { @@ -278,7 +288,7 @@ export enum BTCOutputAddressType { export interface BTCSignMessage { addressNList: BIP32Path; coin: Coin; - scriptType?: BTCInputScriptType; + scriptType?: BTCScriptType; message: string; } @@ -297,12 +307,12 @@ export interface BTCVerifyMessage { export interface BTCGetAccountPaths { coin: Coin; accountIdx: number; - scriptType?: BTCInputScriptType; + scriptType?: BTCScriptType; } export interface BTCAccountPath { coin: Coin; - scriptType: BTCInputScriptType; + scriptType: BTCScriptType; addressNList: BIP32Path; } @@ -318,7 +328,7 @@ export interface BTCWalletInfo extends HDWalletInfo { * Does the device support the given script type for the given coin? * Assumes that `btcSupportsCoin(coin)` for the given coin. */ - btcSupportsScriptType(coin: Coin, scriptType?: BTCInputScriptType): Promise; + btcSupportsScriptType(coin: Coin, scriptType: BTCScriptType): Promise; /** * Does the device support internal transfers without the user needing to @@ -372,7 +382,7 @@ export interface BTCWallet extends BTCWalletInfo, HDWallet { btcVerifyMessage(msg: BTCVerifyMessage): Promise; } -export function unknownUTXOPath(path: BIP32Path, coin: Coin, scriptType?: BTCInputScriptType): PathDescription { +export function unknownUTXOPath(path: BIP32Path, coin: Coin, scriptType?: BTCScriptType): PathDescription { return { verbose: addressNListToBIP32(path), coin, @@ -381,7 +391,7 @@ export function unknownUTXOPath(path: BIP32Path, coin: Coin, scriptType?: BTCInp }; } -export function describeUTXOPath(path: BIP32Path, coin: Coin, scriptType: BTCInputScriptType): PathDescription { +export function describeUTXOPath(path: BIP32Path, coin: Coin, scriptType: BTCScriptType): PathDescription { const unknown = unknownUTXOPath(path, coin, scriptType); if (path.length !== 3 && path.length !== 5) return unknown; @@ -392,19 +402,18 @@ export function describeUTXOPath(path: BIP32Path, coin: Coin, scriptType: BTCInp if (![44, 49, 84].includes(purpose)) return unknown; - if (purpose === 44 && scriptType !== BTCInputScriptType.SpendAddress) return unknown; + if (purpose === 44 && scriptType !== BTCScriptType.KeyHash) return unknown; - if (purpose === 49 && scriptType !== BTCInputScriptType.SpendP2SHWitness) return unknown; + if (purpose === 49 && scriptType !== BTCScriptType.ScriptHashWitness) return unknown; let wholeAccount = path.length === 3; let script = ( { - [BTCInputScriptType.SpendAddress]: ["Legacy"], - [BTCInputScriptType.SpendP2SHWitness]: [], - [BTCInputScriptType.SpendWitness]: ["Segwit"], - [BTCInputScriptType.Bech32]: ["Segwit Native"], - } as Partial> + [BTCScriptType.KeyHash]: ["Legacy"], + [BTCScriptType.ScriptHashWitness]: [], + [BTCScriptType.Witness]: ["Segwit Native"], + } as Partial> )[scriptType]; let isPrefork = false; @@ -479,7 +488,7 @@ export function describeUTXOPath(path: BIP32Path, coin: Coin, scriptType: BTCInp export function legacyAccount(coin: Coin, slip44: number, accountIdx: number): BTCAccountPath { return { coin, - scriptType: BTCInputScriptType.SpendAddress, + scriptType: BTCScriptType.KeyHash, addressNList: [0x80000000 + 44, 0x80000000 + slip44, 0x80000000 + accountIdx], }; } @@ -487,7 +496,7 @@ export function legacyAccount(coin: Coin, slip44: number, accountIdx: number): B export function segwitAccount(coin: Coin, slip44: number, accountIdx: number): BTCAccountPath { return { coin, - scriptType: BTCInputScriptType.SpendP2SHWitness, + scriptType: BTCScriptType.ScriptHashWitness, addressNList: [0x80000000 + 49, 0x80000000 + slip44, 0x80000000 + accountIdx], }; } @@ -495,7 +504,7 @@ export function segwitAccount(coin: Coin, slip44: number, accountIdx: number): B export function segwitNativeAccount(coin: Coin, slip44: number, accountIdx: number): BTCAccountPath { return { coin, - scriptType: BTCInputScriptType.SpendWitness, + scriptType: BTCScriptType.Witness, addressNList: [0x80000000 + 84, 0x80000000 + slip44, 0x80000000 + accountIdx], }; } diff --git a/packages/hdwallet-core/src/wallet.ts b/packages/hdwallet-core/src/wallet.ts index a50d2bfee..a2c199a05 100644 --- a/packages/hdwallet-core/src/wallet.ts +++ b/packages/hdwallet-core/src/wallet.ts @@ -1,7 +1,7 @@ import _ from "lodash"; import { BinanceWallet, BinanceWalletInfo } from "./binance"; -import { BTCInputScriptType, BTCWallet, BTCWalletInfo } from "./bitcoin"; +import { BTCScriptType, BTCWallet, BTCWalletInfo } from "./bitcoin"; import { CosmosWallet, CosmosWalletInfo } from "./cosmos"; import { OsmosisWallet, OsmosisWalletInfo } from "./osmosis"; import { DebugLinkWallet } from "./debuglink"; @@ -20,7 +20,7 @@ export type BIP32Path = Array; export interface GetPublicKey { addressNList: BIP32Path; showDisplay?: boolean; - scriptType?: BTCInputScriptType; // Defaults to BTCInputScriptType.SpendAddress + scriptType?: BTCScriptType; // Defaults to BTCScriptType.KeyHash curve: string; coin: Coin; } @@ -79,22 +79,22 @@ export interface ExchangeType { signedExchangeResponse: string; withdrawalCoinName: string; withdrawalAddressNList: BIP32Path; - withdrawalScriptType?: BTCInputScriptType; + withdrawalScriptType?: BTCScriptType; returnAddressNList: BIP32Path; - returnScriptType?: BTCInputScriptType; + returnScriptType?: BTCScriptType; } export interface DescribePath { path: BIP32Path; coin: Coin; - scriptType?: BTCInputScriptType; + scriptType?: BTCScriptType; } export interface PathDescription { isKnown: boolean; verbose: string; coin: Coin; - scriptType?: BTCInputScriptType; + scriptType?: BTCScriptType; accountIdx?: number; addressIdx?: number; isChange?: boolean; diff --git a/packages/hdwallet-keepkey/src/bitcoin.ts b/packages/hdwallet-keepkey/src/bitcoin.ts index 968dc252e..5476b1e8d 100644 --- a/packages/hdwallet-keepkey/src/bitcoin.ts +++ b/packages/hdwallet-keepkey/src/bitcoin.ts @@ -19,7 +19,7 @@ const segwitCoins = ["Bitcoin", "Testnet", "BitcoinGold", "Litecoin"]; function legacyAccount(coin: core.Coin, slip44: number, accountIdx: number): core.BTCAccountPath { return { coin, - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, addressNList: [0x80000000 + 44, 0x80000000 + slip44, 0x80000000 + accountIdx], }; } @@ -27,7 +27,7 @@ function legacyAccount(coin: core.Coin, slip44: number, accountIdx: number): cor function segwitAccount(coin: core.Coin, slip44: number, accountIdx: number): core.BTCAccountPath { return { coin, - scriptType: core.BTCInputScriptType.SpendP2SHWitness, + scriptType: core.BTCScriptType.ScriptHashWitness, addressNList: [0x80000000 + 49, 0x80000000 + slip44, 0x80000000 + accountIdx], }; } @@ -35,7 +35,7 @@ function segwitAccount(coin: core.Coin, slip44: number, accountIdx: number): cor function segwitNativeAccount(coin: core.Coin, slip44: number, accountIdx: number): core.BTCAccountPath { return { coin, - scriptType: core.BTCInputScriptType.SpendWitness, + scriptType: core.BTCScriptType.Witness, addressNList: [0x80000000 + 84, 0x80000000 + slip44, 0x80000000 + accountIdx], }; } @@ -89,11 +89,11 @@ function prepareSignTx( outExchangeType.setWithdrawalCoinName(output.exchangeType.withdrawalCoinName); outExchangeType.setWithdrawalAddressNList(output.exchangeType.withdrawalAddressNList); outExchangeType.setWithdrawalScriptType( - translateInputScriptType(output.exchangeType.withdrawalScriptType || core.BTCInputScriptType.SpendAddress) + translateInputScriptType(output.exchangeType.withdrawalScriptType || core.BTCScriptType.KeyHash) ); outExchangeType.setReturnAddressNList(output.exchangeType.returnAddressNList); outExchangeType.setReturnScriptType( - translateInputScriptType(output.exchangeType.returnScriptType || core.BTCInputScriptType.SpendAddress) + translateInputScriptType(output.exchangeType.returnScriptType || core.BTCScriptType.KeyHash) ); newOutput.setAmount(val); newOutput.setAddress(core.mustBeDefined(signedExchange.toObject().responsev2?.depositAddress?.address)); @@ -128,12 +128,7 @@ function prepareSignTx( inputs.forEach((inputTx) => { if (inputTx.txid in txmap) return; - if ( - inputTx.scriptType === core.BTCInputScriptType.SpendP2SHWitness || - inputTx.scriptType === core.BTCInputScriptType.SpendWitness || - inputTx.scriptType === core.BTCInputScriptType.External - ) - return; + if ([core.BTCScriptType.Witness, core.BTCScriptType.ScriptHashWitness].includes(inputTx.scriptType)) return; const prevTx = ((): core.BitcoinTx => { if (inputTx.tx) return inputTx.tx; @@ -255,10 +250,9 @@ export async function btcSupportsCoin(coin: core.Coin): Promise { return supportedCoins.includes(coin); } -export async function btcSupportsScriptType(coin: core.Coin, scriptType?: core.BTCInputScriptType): Promise { +export async function btcSupportsScriptType(coin: core.Coin, scriptType: core.BTCScriptType): Promise { if (!supportedCoins.includes(coin)) return false; - if (!segwitCoins.includes(coin) && scriptType === core.BTCInputScriptType.SpendP2SHWitness) return false; - if (!segwitCoins.includes(coin) && scriptType === core.BTCInputScriptType.SpendWitness) return false; + if (!segwitCoins.includes(coin) && core.isSegwitScript(scriptType)) return false; return true; } @@ -269,11 +263,17 @@ export async function btcGetAddress( ): Promise { await ensureCoinSupport(wallet, msg.coin); + const scriptType = msg.scriptType ?? core.BTCScriptType.KeyHash + const addressFormat = msg.addressFormat ?? core.defaultAddressFormatForScriptType(msg.scriptType) + if (addressFormat !== core.defaultAddressFormatForScriptType(msg.scriptType)) { + throw new Error("unsupported address format"); + } + const addr = new Messages.GetAddress(); addr.setAddressNList(msg.addressNList); addr.setCoinName(msg.coin); addr.setShowDisplay(msg.showDisplay || false); - addr.setScriptType(translateInputScriptType(msg.scriptType || core.BTCInputScriptType.SpendAddress)); + addr.setScriptType(translateInputScriptType(scriptType)); const response = await transport.call( Messages.MessageType.MESSAGETYPE_GETADDRESS, @@ -517,7 +517,7 @@ export async function btcSignMessage( sign.setAddressNList(msg.addressNList); sign.setMessage(toUTF8Array(msg.message)); sign.setCoinName(msg.coin || "Bitcoin"); - sign.setScriptType(translateInputScriptType(msg.scriptType ?? core.BTCInputScriptType.SpendAddress)); + sign.setScriptType(translateInputScriptType(msg.scriptType ?? core.BTCScriptType.KeyHash)); const event = await transport.call( Messages.MessageType.MESSAGETYPE_SIGNMESSAGE, sign, @@ -607,10 +607,10 @@ export function btcIsSameAccount(msg: Array): boolean { // 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>; + [core.BTCScriptType.KeyHash]: 0x80000000 + 44, + [core.BTCScriptType.ScriptHashWitness]: 0x80000000 + 49, + [core.BTCScriptType.Witness]: 0x80000000 + 84, + } as Partial>; if (purposeForScriptType[account0.scriptType] !== purpose) return false; // Coin must be hardened diff --git a/packages/hdwallet-keepkey/src/ethereum.ts b/packages/hdwallet-keepkey/src/ethereum.ts index fbe89b2f5..b08bbdb43 100644 --- a/packages/hdwallet-keepkey/src/ethereum.ts +++ b/packages/hdwallet-keepkey/src/ethereum.ts @@ -73,11 +73,11 @@ export async function ethSignTx(transport: Transport, msg: core.ETHSignTx): Prom exchangeType.setWithdrawalCoinName(msg.exchangeType.withdrawalCoinName); // KeepKey firmware will complain if this doesn't match signed exchange response exchangeType.setWithdrawalAddressNList(msg.exchangeType.withdrawalAddressNList); exchangeType.setWithdrawalScriptType( - translateInputScriptType(msg.exchangeType.withdrawalScriptType || core.BTCInputScriptType.SpendAddress) + translateInputScriptType(msg.exchangeType.withdrawalScriptType || core.BTCScriptType.KeyHash) ); exchangeType.setReturnAddressNList(msg.exchangeType.returnAddressNList); exchangeType.setReturnScriptType( - translateInputScriptType(msg.exchangeType.returnScriptType || core.BTCInputScriptType.SpendAddress) + translateInputScriptType(msg.exchangeType.returnScriptType || core.BTCScriptType.KeyHash) ); est.setExchangeType(exchangeType); } else { diff --git a/packages/hdwallet-keepkey/src/keepkey.ts b/packages/hdwallet-keepkey/src/keepkey.ts index de357dcd2..2dc751bdd 100644 --- a/packages/hdwallet-keepkey/src/keepkey.ts +++ b/packages/hdwallet-keepkey/src/keepkey.ts @@ -53,7 +53,7 @@ function describeETHPath(path: core.BIP32Path): core.PathDescription { function describeUTXOPath( path: core.BIP32Path, coin: core.Coin, - scriptType?: core.BTCInputScriptType + scriptType?: core.BTCScriptType ): core.PathDescription { let pathStr = core.addressNListToBIP32(path); let unknown: core.PathDescription = { @@ -76,21 +76,21 @@ function describeUTXOPath( if (![44, 49, 84].includes(purpose)) return unknown; - if (purpose === 44 && scriptType !== core.BTCInputScriptType.SpendAddress) return unknown; + if (purpose === 44 && scriptType !== core.BTCScriptType.KeyHash) return unknown; - if (purpose === 49 && scriptType !== core.BTCInputScriptType.SpendP2SHWitness) return unknown; + if (purpose === 49 && scriptType !== core.BTCScriptType.ScriptHashWitness) return unknown; - if (purpose === 84 && scriptType !== core.BTCInputScriptType.SpendWitness) return unknown; + if (purpose === 84 && scriptType !== core.BTCScriptType.Witness) return unknown; let wholeAccount = path.length === 3; let script = scriptType ? ( { - [core.BTCInputScriptType.SpendAddress]: ["Legacy"], - [core.BTCInputScriptType.SpendP2SHWitness]: [], - [core.BTCInputScriptType.SpendWitness]: ["Segwit Native"], - } as Partial> + [core.BTCScriptType.KeyHash]: ["Legacy"], + [core.BTCScriptType.ScriptHashWitness]: [], + [core.BTCScriptType.Witness]: ["Segwit Native"], + } as Partial> )[scriptType] ?? [] : []; @@ -388,7 +388,7 @@ export class KeepKeyHDWalletInfo return Btc.btcSupportsCoin(coin); } - public async btcSupportsScriptType(coin: core.Coin, scriptType: core.BTCInputScriptType): Promise { + public async btcSupportsScriptType(coin: core.Coin, scriptType: core.BTCScriptType): Promise { return Btc.btcSupportsScriptType(coin, scriptType); } @@ -701,7 +701,7 @@ export class KeepKeyHDWallet implements core.HDWallet, core.BTCWallet, core.ETHW GPK.setAddressNList(addressNList); GPK.setShowDisplay(showDisplay || false); GPK.setEcdsaCurveName(curve || "secp256k1"); - GPK.setScriptType(translateInputScriptType(scriptType || core.BTCInputScriptType.SpendAddress)); + GPK.setScriptType(translateInputScriptType(scriptType || core.BTCScriptType.KeyHash)); const event = await this.transport.call( Messages.MessageType.MESSAGETYPE_GETPUBLICKEY, @@ -1133,7 +1133,7 @@ export class KeepKeyHDWallet implements core.HDWallet, core.BTCWallet, core.ETHW return this.info.btcSupportsCoin(coin); } - public async btcSupportsScriptType(coin: core.Coin, scriptType: core.BTCInputScriptType): Promise { + public async btcSupportsScriptType(coin: core.Coin, scriptType: core.BTCScriptType): Promise { return this.info.btcSupportsScriptType(coin, scriptType); } diff --git a/packages/hdwallet-keepkey/src/utils.ts b/packages/hdwallet-keepkey/src/utils.ts index 667d760d7..a4be1af22 100644 --- a/packages/hdwallet-keepkey/src/utils.ts +++ b/packages/hdwallet-keepkey/src/utils.ts @@ -34,30 +34,29 @@ export function toUTF8Array(str: string): Uint8Array { return new Uint8Array(utf8); } -export function translateInputScriptType(scriptType: core.BTCInputScriptType): any { +export function translateInputScriptType(scriptType: core.BTCScriptType): any { switch (scriptType) { - case core.BTCInputScriptType.CashAddr: - case core.BTCInputScriptType.SpendAddress: + case core.BTCScriptType.KeyHash: return Types.InputScriptType.SPENDADDRESS; - case core.BTCInputScriptType.SpendMultisig: + case core.BTCScriptType.ScriptHash: return Types.InputScriptType.SPENDMULTISIG; - case core.BTCInputScriptType.SpendP2SHWitness: + case core.BTCScriptType.ScriptHashWitness: return Types.InputScriptType.SPENDP2SHWITNESS; - case core.BTCInputScriptType.SpendWitness: + case core.BTCScriptType.Witness: return Types.InputScriptType.SPENDWITNESS; } throw new Error("unhandled InputSriptType enum: " + scriptType); } -export function translateOutputScriptType(scriptType: core.BTCOutputScriptType): any { +export function translateOutputScriptType(scriptType: core.BTCScriptType): any { switch (scriptType) { - case core.BTCOutputScriptType.PayToAddress: + case core.BTCScriptType.KeyHash: return Types.OutputScriptType.PAYTOADDRESS; - case core.BTCOutputScriptType.PayToMultisig: + case core.BTCScriptType.ScriptHash: return Types.OutputScriptType.PAYTOMULTISIG; - case core.BTCOutputScriptType.PayToP2SHWitness: + case core.BTCScriptType.ScriptHashWitness: return Types.OutputScriptType.PAYTOP2SHWITNESS; - case core.BTCOutputScriptType.PayToWitness: + case core.BTCScriptType.Witness: return Types.OutputScriptType.PAYTOWITNESS; } throw new Error("unhandled OutputScriptType enum: " + scriptType); diff --git a/packages/hdwallet-ledger/src/bitcoin.ts b/packages/hdwallet-ledger/src/bitcoin.ts index 9aab59c2f..ad76d20d9 100644 --- a/packages/hdwallet-ledger/src/bitcoin.ts +++ b/packages/hdwallet-ledger/src/bitcoin.ts @@ -7,7 +7,7 @@ import * as bitcoinMsg from "bitcoinjs-message"; import _ from "lodash"; import { LedgerTransport } from "./transport"; -import { createXpub, compressPublicKey, translateScriptType, networksUtil, handleError } from "./utils"; +import { createXpub, compressPublicKey, translateAddressFormat, networksUtil, handleError } from "./utils"; import { CreateTransactionArg } from "@ledgerhq/hw-app-btc/lib/createTransaction"; export const supportedCoins = ["Testnet", "Bitcoin", "BitcoinCash", "Litecoin", "Dash", "DigiByte", "Dogecoin"]; @@ -18,25 +18,28 @@ export async function btcSupportsCoin(coin: core.Coin): Promise { return supportedCoins.includes(coin); } -export async function btcSupportsScriptType(coin: core.Coin, scriptType?: core.BTCInputScriptType): Promise { +export async function btcSupportsScriptType(coin: core.Coin, scriptType: core.BTCScriptType): Promise { const supported = { Bitcoin: [ - core.BTCInputScriptType.SpendAddress, - core.BTCInputScriptType.SpendWitness, - core.BTCInputScriptType.SpendP2SHWitness, + core.BTCScriptType.KeyHash, + core.BTCScriptType.Witness, + core.BTCScriptType.ScriptHashWitness, ], - BitcoinCash: [core.BTCInputScriptType.SpendAddress], - } as Partial>>; + BitcoinCash: [core.BTCScriptType.KeyHash], + } as Partial>>; const scriptTypes = supported[coin]; return !!scriptTypes && !!scriptType && scriptTypes.includes(scriptType); } export async function btcGetAddress(transport: LedgerTransport, msg: core.BTCGetAddress): Promise { + const scriptType = msg.scriptType ?? core.BTCScriptType.KeyHash + const addressFormat = msg.addressFormat ?? core.defaultAddressFormatForScriptType(msg.scriptType) + const bip32path = core.addressNListToBIP32(msg.addressNList); const opts = { verify: !!msg.showDisplay, - format: translateScriptType(msg.scriptType ?? core.BTCInputScriptType.SpendAddress), + format: translateAddressFormat(addressFormat), }; const res = await transport.call("Btc", "getWalletPublicKey", bip32path, opts); @@ -84,7 +87,7 @@ export async function btcGetPublicKeys( const coinDetails = networksUtil[core.mustBeDefined(core.slip44ByCoin(coin))]; const childNum: number = addressNList[addressNList.length - 1]; - scriptType = scriptType || core.BTCInputScriptType.SpendAddress; + scriptType = scriptType || core.BTCScriptType.KeyHash; const networkMagic = coinDetails.bitcoinjs.bip32.public[scriptType]; if (!networkMagic) throw new Error("unable to get networkMagic"); @@ -188,11 +191,7 @@ export async function btcSignTx( const outputScriptHex = outputScriptRes.payload.toString("hex"); for (let i = 0; i < msg.inputs.length; i++) { - if ( - msg.inputs[i].scriptType === core.BTCInputScriptType.SpendWitness || - msg.inputs[i].scriptType === core.BTCInputScriptType.SpendP2SHWitness - ) - segwit = true; + if (core.isSegwitScript(msg.inputs[i].scriptType)) segwit = true; const keySet = core.addressNListToBIP32(msg.inputs[i].addressNList).replace(/^m\//, ""); @@ -264,7 +263,7 @@ export async function btcSignMessage( addressNList: msg.addressNList, coin, showDisplay: false, - scriptType: msg.scriptType ?? core.BTCInputScriptType.SpendAddress, + scriptType: msg.scriptType ?? core.BTCScriptType.KeyHash, }); return { @@ -283,17 +282,17 @@ export function btcGetAccountPaths(msg: core.BTCGetAccountPaths): Array> + [core.BTCScriptType.KeyHash]: " (Legacy)", + [core.BTCScriptType.ScriptHashWitness]: "", + [core.BTCScriptType.Witness]: " (Segwit Native)", + } as Partial> )[scriptType] : undefined; @@ -146,7 +148,7 @@ export class LedgerHDWalletInfo implements core.HDWalletInfo, core.BTCWalletInfo return btc.btcSupportsCoin(coin); } - public async btcSupportsScriptType(coin: core.Coin, scriptType: core.BTCInputScriptType): Promise { + public async btcSupportsScriptType(coin: core.Coin, scriptType: core.BTCScriptType): Promise { return btc.btcSupportsScriptType(coin, scriptType); } @@ -477,7 +479,7 @@ export class LedgerHDWallet implements core.HDWallet, core.BTCWallet, core.ETHWa return this.info.btcSupportsCoin(coin); } - public async btcSupportsScriptType(coin: core.Coin, scriptType: core.BTCInputScriptType): Promise { + public async btcSupportsScriptType(coin: core.Coin, scriptType: core.BTCScriptType): Promise { return this.info.btcSupportsScriptType(coin, scriptType); } diff --git a/packages/hdwallet-ledger/src/utils.ts b/packages/hdwallet-ledger/src/utils.ts index c9d236dbb..53b2eacd5 100644 --- a/packages/hdwallet-ledger/src/utils.ts +++ b/packages/hdwallet-ledger/src/utils.ts @@ -54,14 +54,14 @@ export function handleError>(result: T, trans } } -export function translateScriptType(scriptType: core.BTCInputScriptType): AddressFormat { - const scriptTypeMap: Partial> = { - [core.BTCInputScriptType.SpendAddress]: "legacy", - [core.BTCInputScriptType.CashAddr]: "cashaddr", - [core.BTCInputScriptType.SpendWitness]: "bech32", - [core.BTCInputScriptType.SpendP2SHWitness]: "p2sh", +export function translateAddressFormat(addressFormat: core.BTCAddressFormat): AddressFormat { + const addressFormatMap: Partial> = { + [core.BTCAddressFormat.Base58CheckP2PKH]: "legacy", + [core.BTCAddressFormat.Base58CheckP2SH]: "p2sh", + [core.BTCAddressFormat.CashAddr]: "cashaddr", + [core.BTCAddressFormat.Bech32]: "bech32", } - return core.mustBeDefined(scriptTypeMap[scriptType]); + return core.mustBeDefined(addressFormatMap[addressFormat]); } export const compressPublicKey = (publicKey: Uint8Array) => { @@ -100,7 +100,7 @@ type NetworkMagic = { bech32?: string, bip32: { private?: number, - public: Partial>, + public: Partial>, }, messagePrefix: string, pubKeyHash?: number, diff --git a/packages/hdwallet-native/src/bitcoin.test.ts b/packages/hdwallet-native/src/bitcoin.test.ts index bfa2a0a74..9d141dadd 100644 --- a/packages/hdwallet-native/src/bitcoin.test.ts +++ b/packages/hdwallet-native/src/bitcoin.test.ts @@ -149,9 +149,6 @@ describe("NativeBTCWalletInfo", () => { expect(await info.btcSupportsScriptType("bitcoin", "p2sh" as any)).toBe(true); expect(await info.btcSupportsScriptType("bitcoin", "p2wpkh" as any)).toBe(true); expect(await info.btcSupportsScriptType("bitcoin", "p2sh-p2wpkh" as any)).toBe(true); - expect(await info.btcSupportsScriptType("bitcoin", "bech32" as any)).toBe(true); - expect(await info.btcSupportsScriptType("bitcoin", "cashaddr" as any)).toBe(false); - expect(await info.btcSupportsScriptType("bitcoincash", "cashaddr" as any)).toBe(false); expect(await info.btcSupportsScriptType("bitcoin", "foobar" as any)).toBe(false); expect(await info.btcSupportsScriptType("foobar", "p2pkh" as any)).toBe(false); }); @@ -434,7 +431,7 @@ describe("NativeBTCWallet", () => { outputs: [ { addressNList: core.bip32ToAddressNList("m/44'/0'/0'/0/1"), - scriptType: core.BTCOutputScriptType.PayToAddress, + scriptType: core.BTCScriptType.KeyHash, amount: "99000", isChange: false, }, diff --git a/packages/hdwallet-native/src/bitcoin.ts b/packages/hdwallet-native/src/bitcoin.ts index 582ec9815..cf965087d 100644 --- a/packages/hdwallet-native/src/bitcoin.ts +++ b/packages/hdwallet-native/src/bitcoin.ts @@ -9,10 +9,6 @@ import * as util from "./util"; const supportedCoins = ["bitcoin", "dash", "digibyte", "dogecoin", "litecoin", "bitcoincash", "testnet"]; -const segwit = ["p2wpkh", "p2sh-p2wpkh", "bech32"]; - -export type BTCScriptType = core.BTCInputScriptType | core.BTCOutputScriptType; - type NonWitnessUtxo = Buffer; type WitnessUtxo = { @@ -37,33 +33,24 @@ export function MixinNativeBTCWalletInfo { - return this.btcSupportsCoinSync(coin); + return supportedCoins.includes(String(coin).toLowerCase()); } - btcSupportsScriptTypeSync(coin: core.Coin, scriptType?: core.BTCInputScriptType): boolean { - if (!this.btcSupportsCoinSync(coin)) return false; + async btcSupportsScriptType(coin: core.Coin, scriptType: core.BTCScriptType): Promise { + if (!(await this.btcSupportsCoin(coin))) return false; switch (scriptType) { - case core.BTCInputScriptType.SpendMultisig: - case core.BTCInputScriptType.SpendAddress: - case core.BTCInputScriptType.SpendWitness: - case core.BTCInputScriptType.Bech32: - case core.BTCInputScriptType.SpendP2SHWitness: + case core.BTCScriptType.ScriptHash: + case core.BTCScriptType.KeyHash: + case core.BTCScriptType.Witness: + case core.BTCScriptType.ScriptHashWitness: return true; default: return false; } } - async btcSupportsScriptType(coin: core.Coin, scriptType: core.BTCInputScriptType): Promise { - return this.btcSupportsScriptTypeSync(coin, scriptType); - } - async btcSupportsSecureTransfer(): Promise { return false; } @@ -115,9 +102,9 @@ export function MixinNativeBTCWalletInfo { msg: { coin: "bitcoin", path: [44 + 0x80000000, 0 + 0x80000000, 0 + 0x80000000, 0, 0], - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, }, out: { coin: "bitcoin", verbose: "m/44'/0'/0'/0/0", isKnown: false }, }, @@ -39,7 +39,7 @@ describe("NativeHDWalletInfo", () => { msg: { coin: "Bitcoin", path: [44 + 0x80000000, 0 + 0x80000000, 0 + 0x80000000], - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, }, out: { coin: "Bitcoin", verbose: "Bitcoin Account #0 (Legacy)", isKnown: true, wholeAccount: true }, }, @@ -47,13 +47,13 @@ describe("NativeHDWalletInfo", () => { msg: { coin: "Bitcoin", path: [44 + 0x80000000, 0 + 0x80000000, 0 + 0x80000000, 0, 0], - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, }, out: { coin: "Bitcoin", verbose: "Bitcoin Account #0, Address #0 (Legacy)", isKnown: true }, }, { - msg: { coin: "dash", path: [1, 2, 3], scriptType: core.BTCInputScriptType.SpendWitness }, - out: { coin: "dash", verbose: "m/1/2/3", scriptType: core.BTCInputScriptType.SpendWitness, isKnown: false }, + msg: { coin: "dash", path: [1, 2, 3], scriptType: core.BTCScriptType.Witness }, + out: { coin: "dash", verbose: "m/1/2/3", scriptType: core.BTCScriptType.Witness, isKnown: false }, }, { msg: { coin: "bitcoincash", path: [1, 2, 3] }, diff --git a/packages/hdwallet-native/src/native.ts b/packages/hdwallet-native/src/native.ts index fc235f405..ffa0fa2f7 100644 --- a/packages/hdwallet-native/src/native.ts +++ b/packages/hdwallet-native/src/native.ts @@ -139,8 +139,8 @@ class NativeHDWalletInfo const unknown = core.unknownUTXOPath(msg.path, msg.coin, msg.scriptType); if (!msg.scriptType) return unknown; - if (!super.btcSupportsCoinSync(msg.coin)) return unknown; - if (!super.btcSupportsScriptTypeSync(msg.coin, msg.scriptType)) return unknown; + if (!super.btcSupportsCoin(msg.coin)) return unknown; + if (!super.btcSupportsScriptType(msg.coin, msg.scriptType)) return unknown; return core.describeUTXOPath(msg.path, msg.coin, msg.scriptType); case "ethereum": diff --git a/packages/hdwallet-native/src/networks.ts b/packages/hdwallet-native/src/networks.ts index 1f0f56891..b271a4d23 100644 --- a/packages/hdwallet-native/src/networks.ts +++ b/packages/hdwallet-native/src/networks.ts @@ -1,8 +1,6 @@ import * as core from "@shapeshiftoss/hdwallet-core"; import * as bitcoin from "bitcoinjs-lib"; -import { BTCScriptType } from "./bitcoin" - type BIP32 = { bip32: { public: number; @@ -10,28 +8,28 @@ type BIP32 = { }; }; -type BIP32ByScriptType = Partial>; +type BIP32ByScriptType = Partial>; const bip32BTC: BIP32ByScriptType = { - p2sh: { + [core.BTCScriptType.ScriptHash]: { bip32: { public: 0x0488b21e, private: 0x0488ade4, }, }, - p2pkh: { + [core.BTCScriptType.KeyHash]: { bip32: { public: 0x0488b21e, private: 0x0488ade4, }, }, - "p2sh-p2wpkh": { + [core.BTCScriptType.ScriptHashWitness]: { bip32: { public: 0x049d7cb2, private: 0x049d7878, }, }, - p2wpkh: { + [core.BTCScriptType.Witness]: { bip32: { public: 0x04b24746, private: 0x04b2430c, @@ -165,14 +163,14 @@ const networks: Networks = { for (const coin of ["bitcoincash", "thorchain", "secret", "terra", "kava", "cardano", "cosmos", "osmosis", "binance", "ethereum"]) networks[coin] = networks.bitcoin; -export function getNetwork(coin: string, scriptType?: BTCScriptType): bitcoin.Network { +export function getNetwork(coin: string, scriptType?: core.BTCScriptType): bitcoin.Network { coin = coin.toLowerCase(); - scriptType = scriptType || core.BTCOutputScriptType.PayToMultisig; + scriptType = scriptType ?? core.BTCScriptType.ScriptHash; if (!(coin in networks)) throw new Error(`${coin} network not supported`); let network = networks[coin]; - const bip32 = network[scriptType as core.BTCOutputScriptType]; + const bip32 = network[scriptType]; if (!bip32) { throw new Error(`${scriptType} not supported for ${coin} network`); } diff --git a/packages/hdwallet-native/src/util.ts b/packages/hdwallet-native/src/util.ts index dd1be7d94..8104e915b 100644 --- a/packages/hdwallet-native/src/util.ts +++ b/packages/hdwallet-native/src/util.ts @@ -1,6 +1,5 @@ import * as core from "@shapeshiftoss/hdwallet-core"; -import { BTCScriptType } from "./bitcoin"; import { getNetwork } from "./networks"; import * as Isolation from "./crypto/isolation"; @@ -12,7 +11,7 @@ export async function getKeyPair( node: Isolation.Core.BIP32.Node, addressNList: number[], coin: core.Coin, - scriptType?: BTCScriptType, + scriptType?: core.BTCScriptType, ): Promise { const network = getNetwork(coin, scriptType); const wallet = await Isolation.Adapters.BIP32.create(node, network); diff --git a/packages/hdwallet-portis/src/bitcoin.ts b/packages/hdwallet-portis/src/bitcoin.ts index ebed312c5..b94112faa 100644 --- a/packages/hdwallet-portis/src/bitcoin.ts +++ b/packages/hdwallet-portis/src/bitcoin.ts @@ -4,7 +4,7 @@ import * as bip32 from "bip32"; import * as bitcoin from "bitcoinjs-lib"; import * as bitcoinMsg from "bitcoinjs-message"; -export function describeUTXOPath(path: core.BIP32Path, coin: core.Coin, scriptType?: core.BTCInputScriptType): core.PathDescription { +export function describeUTXOPath(path: core.BIP32Path, coin: core.Coin, scriptType?: core.BTCScriptType): core.PathDescription { let pathStr = core.addressNListToBIP32(path); let unknown: core.PathDescription = { verbose: pathStr, @@ -21,19 +21,19 @@ export function describeUTXOPath(path: core.BIP32Path, coin: core.Coin, scriptTy if (![44, 49, 84].includes(purpose)) return unknown; - if (purpose === 44 && scriptType !== core.BTCInputScriptType.SpendAddress) return unknown; + if (purpose === 44 && scriptType !== core.BTCScriptType.KeyHash) return unknown; - if (purpose === 49 && scriptType !== core.BTCInputScriptType.SpendP2SHWitness) return unknown; + if (purpose === 49 && scriptType !== core.BTCScriptType.ScriptHashWitness) return unknown; - if (purpose === 84 && scriptType !== core.BTCInputScriptType.SpendWitness) return unknown; + if (purpose === 84 && scriptType !== core.BTCScriptType.Witness) return unknown; let wholeAccount = path.length === 3; let script = scriptType ? ({ - [core.BTCInputScriptType.SpendAddress]: ["Legacy"], - [core.BTCInputScriptType.SpendP2SHWitness]: [], - [core.BTCInputScriptType.SpendWitness]: ["Segwit Native"], - } as Partial>)[scriptType] ?? [] as string[] : [] as string[]; + [core.BTCScriptType.KeyHash]: ["Legacy"], + [core.BTCScriptType.ScriptHashWitness]: [], + [core.BTCScriptType.Witness]: ["Segwit Native"], + } as Partial>)[scriptType] ?? [] as string[] : [] as string[]; let isPrefork = false; const slip44 = core.slip44ByCoin(coin); @@ -122,13 +122,13 @@ export async function btcGetAddress(msg: core.BTCGetAddress, portis: any): Promi let result: bitcoin.payments.Payment; switch (scriptType) { - case core.BTCInputScriptType.SpendAddress: + case core.BTCScriptType.KeyHash: result = bitcoin.payments.p2pkh(args); break; - case core.BTCInputScriptType.SpendWitness: + case core.BTCScriptType.Witness: result = bitcoin.payments.p2wpkh(args); break; - case core.BTCInputScriptType.SpendP2SHWitness: + case core.BTCScriptType.ScriptHashWitness: result = bitcoin.payments.p2sh({ redeem: bitcoin.payments.p2wpkh(args), }); @@ -148,18 +148,18 @@ export async function btcGetAddress(msg: core.BTCGetAddress, portis: any): Promi return core.mustBeDefined(result.address); } -export function verifyScriptTypePurpose(scriptType: core.BTCInputScriptType, purpose: number): boolean { +export function verifyScriptTypePurpose(scriptType: core.BTCScriptType, purpose: number): boolean { return ( - (purpose === 0x80000000 + 44 && scriptType === core.BTCInputScriptType.SpendAddress) || - (purpose === 0x80000000 + 49 && scriptType === core.BTCInputScriptType.SpendP2SHWitness) || - (purpose === 0x80000000 + 84 && scriptType === core.BTCInputScriptType.SpendWitness) + (purpose === 0x80000000 + 44 && scriptType === core.BTCScriptType.KeyHash) || + (purpose === 0x80000000 + 49 && scriptType === core.BTCScriptType.ScriptHashWitness) || + (purpose === 0x80000000 + 84 && scriptType === core.BTCScriptType.Witness) ); } export function legacyAccount(coin: core.Coin, slip44: number, accountIdx: number): core.BTCAccountPath { return { coin, - scriptType: core.BTCInputScriptType.SpendAddress, + scriptType: core.BTCScriptType.KeyHash, addressNList: [0x80000000 + 44, 0x80000000 + slip44, 0x80000000 + accountIdx], }; } @@ -167,7 +167,7 @@ export function legacyAccount(coin: core.Coin, slip44: number, accountIdx: numbe export function segwitAccount(coin: core.Coin, slip44: number, accountIdx: number): core.BTCAccountPath { return { coin, - scriptType: core.BTCInputScriptType.SpendP2SHWitness, + scriptType: core.BTCScriptType.ScriptHashWitness, addressNList: [0x80000000 + 49, 0x80000000 + slip44, 0x80000000 + accountIdx], }; } @@ -175,7 +175,7 @@ export function segwitAccount(coin: core.Coin, slip44: number, accountIdx: numbe export function segwitNativeAccount(coin: core.Coin, slip44: number, accountIdx: number): core.BTCAccountPath { return { coin, - scriptType: core.BTCInputScriptType.SpendWitness, + scriptType: core.BTCScriptType.Witness, addressNList: [0x80000000 + 84, 0x80000000 + slip44, 0x80000000 + accountIdx], }; } @@ -204,13 +204,13 @@ export function btcGetAccountPaths(msg: core.BTCGetAccountPaths): Array { +export async function btcSupportsScriptType(coin: core.Coin, scriptType: core.BTCScriptType): Promise { if (coin !== "Bitcoin") return Promise.resolve(false); switch (scriptType) { - case core.BTCInputScriptType.SpendAddress: - case core.BTCInputScriptType.SpendWitness: - case core.BTCInputScriptType.SpendP2SHWitness: + case core.BTCScriptType.KeyHash: + case core.BTCScriptType.Witness: + case core.BTCScriptType.ScriptHashWitness: return true; default: return false; diff --git a/packages/hdwallet-portis/src/portis.ts b/packages/hdwallet-portis/src/portis.ts index 0720c0a2d..cde50b6c5 100644 --- a/packages/hdwallet-portis/src/portis.ts +++ b/packages/hdwallet-portis/src/portis.ts @@ -213,7 +213,7 @@ export class PortisHDWallet implements core.HDWallet, core.ETHWallet, core.BTCWa return this.info.btcSupportsCoin(coin); } - public async btcSupportsScriptType(coin: core.Coin, scriptType: core.BTCInputScriptType): Promise { + public async btcSupportsScriptType(coin: core.Coin, scriptType: core.BTCScriptType): Promise { return this.info.btcSupportsScriptType(coin, scriptType); } @@ -350,7 +350,7 @@ export class PortisHDWalletInfo implements core.HDWalletInfo, core.ETHWalletInfo return btc.btcSupportsCoin(coin); } - public async btcSupportsScriptType(coin: core.Coin, scriptType: core.BTCInputScriptType): Promise { + public async btcSupportsScriptType(coin: core.Coin, scriptType: core.BTCScriptType): Promise { return btc.btcSupportsScriptType(coin, scriptType); } diff --git a/packages/hdwallet-trezor/src/bitcoin.ts b/packages/hdwallet-trezor/src/bitcoin.ts index 156d1cbd5..b4d378332 100644 --- a/packages/hdwallet-trezor/src/bitcoin.ts +++ b/packages/hdwallet-trezor/src/bitcoin.ts @@ -28,29 +28,29 @@ function translateCoin(coin: core.Coin): string { const segwitCoins = ["Bitcoin", "Litecoin", "BitcoinGold", "Testnet"]; -function translateInputScriptType(scriptType?: core.BTCInputScriptType): string { +function translateInputScriptType(scriptType?: core.BTCScriptType): string { switch (scriptType) { - case core.BTCInputScriptType.SpendAddress: + case core.BTCScriptType.KeyHash: return "SPENDADDRESS"; - case core.BTCInputScriptType.SpendMultisig: + case core.BTCScriptType.ScriptHash: return "SPENDMULTISIG"; - case core.BTCInputScriptType.SpendWitness: + case core.BTCScriptType.Witness: return "SPENDWITNESS"; - case core.BTCInputScriptType.SpendP2SHWitness: + case core.BTCScriptType.ScriptHashWitness: return "SPENDP2SHWITNESS"; } throw new Error(`Un-handled enum entry: '${scriptType}'`); } -function translateOutputScriptType(scriptType?: core.BTCOutputScriptType): string { +function translateOutputScriptType(scriptType?: core.BTCScriptType): string { switch (scriptType) { - case core.BTCOutputScriptType.PayToAddress: + case core.BTCScriptType.KeyHash: return "PAYTOADDRESS"; - case core.BTCOutputScriptType.PayToMultisig: + case core.BTCScriptType.ScriptHash: return "PAYTOMULTISIG"; - case core.BTCOutputScriptType.PayToWitness: + case core.BTCScriptType.Witness: return "PAYTOWITNESS"; - case core.BTCOutputScriptType.PayToP2SHWitness: + case core.BTCScriptType.ScriptHashWitness: return "PAYTOP2SHWITNESS"; } throw new Error(`Un-handled enum entry: '${scriptType}'`); @@ -60,10 +60,9 @@ export async function btcSupportsCoin(coin: core.Coin): Promise { return translateCoin(coin) !== undefined; } -export async function btcSupportsScriptType(coin: core.Coin, scriptType?: core.BTCInputScriptType): Promise { +export async function btcSupportsScriptType(coin: core.Coin, scriptType: core.BTCScriptType): Promise { if (translateCoin(coin) === undefined) return false; - if (!segwitCoins.includes(coin) && scriptType === core.BTCInputScriptType.SpendP2SHWitness) return false; - if (!segwitCoins.includes(coin) && scriptType === core.BTCInputScriptType.SpendWitness) return false; + if (!segwitCoins.includes(coin) && scriptType && core.isSegwitScript(scriptType)) return false; return true; } @@ -115,7 +114,7 @@ export async function btcSignTx(wallet: core.BTCWallet, transport: TrezorTranspo return { address: output.address, amount: output.amount, - script_type: translateOutputScriptType(core.BTCOutputScriptType.PayToAddress) + script_type: translateOutputScriptType(core.BTCScriptType.KeyHash) }; } @@ -191,17 +190,17 @@ export function btcGetAccountPaths(msg: core.BTCGetAccountPaths): Array> + [core.BTCScriptType.KeyHash]: " (Legacy)", + [core.BTCScriptType.ScriptHashWitness]: "", + [core.BTCScriptType.Witness]: " (Segwit Native)", + } as Partial> )[scriptType] ?? "" : ""; @@ -134,7 +136,7 @@ export class TrezorHDWalletInfo implements core.HDWalletInfo, core.BTCWalletInfo return Btc.btcSupportsCoin(coin); } - public async btcSupportsScriptType(coin: core.Coin, scriptType: core.BTCInputScriptType): Promise { + public async btcSupportsScriptType(coin: core.Coin, scriptType: core.BTCScriptType): Promise { return Btc.btcSupportsScriptType(coin, scriptType); } @@ -337,26 +339,11 @@ export class TrezorHDWallet implements core.HDWallet, core.BTCWallet, core.ETHWa }), }); handleError(this.transport, res, "Could not load xpubs from Trezor"); - return (res.payload as Array<{ xpubSegwit?: string; xpub?: string }>).map((result, i) => { - const scriptType = msg[i].scriptType; - switch (scriptType) { - case core.BTCInputScriptType.SpendP2SHWitness: - case core.BTCInputScriptType.SpendWitness: { - const xpub = result.xpubSegwit; - if (!xpub) throw new Error("unable to get public key"); - return { - xpub, - }; - } - case core.BTCInputScriptType.SpendAddress: - default: { - const xpub = result.xpub; - if (!xpub) throw new Error("unable to get public key"); - return { - xpub, - }; - } - } + return (res.payload as Array<{ xpubSegwit?: string, xpub?: string }>).map((result, i) => { + const scriptType: core.BTCScriptType = msg[i].scriptType ?? core.BTCScriptType.KeyHash; + const xpub = core.isSegwitScript(scriptType) ? result.xpubSegwit : result.xpub; + if (!xpub) throw new Error("unable to get public key"); + return { xpub }; }); } @@ -471,7 +458,7 @@ export class TrezorHDWallet implements core.HDWallet, core.BTCWallet, core.ETHWa return this.info.btcSupportsCoin(coin); } - public async btcSupportsScriptType(coin: core.Coin, scriptType: core.BTCInputScriptType): Promise { + public async btcSupportsScriptType(coin: core.Coin, scriptType: core.BTCScriptType): Promise { return this.info.btcSupportsScriptType(coin, scriptType); }