-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support only for P2PKH and P2WPKH addresses in dApp (#256)
Closes #239 The user can have several BTC addresses of different types (segwit, native segwit, legacy). Not all of these addresses we support to execute stake. The user should use the legacy or native segwit address. This PR adds support for invalid types of addresses. ### What has been done - Added a validation function to the SDK. - Tooltip when the user is connected using not supported address.
- Loading branch information
Showing
8 changed files
with
270 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,10 @@ | ||
import { BITCOIN_NETWORK } from "#/constants" | ||
import { isPublicKeyHashTypeAddress } from "@acre-btc/sdk" | ||
|
||
export function truncateAddress(address: string): string { | ||
return `${address.slice(0, 6)}…${address.slice(-5)}` | ||
} | ||
|
||
// tBTC v2 deposit process supports only 2PKH or P2WPKH Bitcoin address | ||
export const isSupportedBTCAddressType = (address: string): boolean => | ||
isPublicKeyHashTypeAddress(address, BITCOIN_NETWORK) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { | ||
BitcoinAddressConverter, | ||
BitcoinNetwork, | ||
BitcoinScriptUtils, | ||
} from "@keep-network/tbtc-v2.ts" | ||
|
||
/** | ||
* Checks if the address is of type P2PKH or P2WPKH. | ||
* @param address The address to be checked. | ||
* @param network The network for which the check will be done. | ||
*/ | ||
// eslint-disable-next-line import/prefer-default-export | ||
export const isPublicKeyHashTypeAddress = ( | ||
address: string, | ||
network: BitcoinNetwork, | ||
): boolean => { | ||
try { | ||
const outputScript = BitcoinAddressConverter.addressToOutputScript( | ||
address, | ||
network, | ||
) | ||
|
||
return ( | ||
BitcoinScriptUtils.isP2PKHScript(outputScript) || | ||
BitcoinScriptUtils.isP2WPKHScript(outputScript) | ||
) | ||
} catch (error) { | ||
// eslint-disable-next-line no-console | ||
console.error(error) | ||
return false | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export * from "./transaction" | ||
export * from "./network" | ||
export * from "./address" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import { | ||
BitcoinAddressConverter, | ||
BitcoinScriptUtils, | ||
} from "@keep-network/tbtc-v2.ts" | ||
import { isPublicKeyHashTypeAddress } from "../../../src" | ||
import { btcAddresses } from "./data" | ||
|
||
// tBTC v2 deposit process supports: | ||
// - Deposit supports: P2PKH or P2WPKH (as recovery address) | ||
// - Redemption supports: P2PKH, P2WPKH, P2SH, and P2WSH (as redeemer address) | ||
const isSupportedByTBTC = (type: string): boolean => | ||
type === "P2PKH" || type === "P2WPKH" || type === "P2SH" || type === "P2WSH" | ||
|
||
describe("isPublicKeyHashTypeAddress", () => { | ||
const btcAddressesWithExpectedResult = btcAddresses.map((address) => ({ | ||
...address, | ||
expectedResult: address.type === "P2PKH" || address.type === "P2WPKH", | ||
})) | ||
|
||
describe("when an address is supported by tBTC network", () => { | ||
const supportedAddresses = btcAddressesWithExpectedResult.filter( | ||
({ type }) => isSupportedByTBTC(type), | ||
) | ||
|
||
describe.each(supportedAddresses)( | ||
"when it is $type $network address", | ||
({ expectedResult, network, address, scriptPubKey }) => { | ||
const spyOnAddressToOutputScript = jest.spyOn( | ||
BitcoinAddressConverter, | ||
"addressToOutputScript", | ||
) | ||
let result: boolean | ||
|
||
beforeAll(() => { | ||
result = isPublicKeyHashTypeAddress(address, network) | ||
}) | ||
|
||
it("should convert address to output script", () => { | ||
expect(spyOnAddressToOutputScript).toHaveBeenCalledWith( | ||
address, | ||
network, | ||
) | ||
|
||
expect(spyOnAddressToOutputScript).toHaveReturnedWith(scriptPubKey) | ||
}) | ||
|
||
it(`should return ${expectedResult}`, () => { | ||
expect(result).toBe(expectedResult) | ||
}) | ||
}, | ||
) | ||
}) | ||
|
||
describe("when an address is not supported by tBTC network", () => { | ||
const notSupportedAddresses = btcAddressesWithExpectedResult.filter( | ||
({ type }) => !isSupportedByTBTC(type), | ||
) | ||
|
||
describe.each(notSupportedAddresses)( | ||
"when it is $type $network address", | ||
({ network, address }) => { | ||
const spyOnAddressToOutputScript = jest.spyOn( | ||
BitcoinAddressConverter, | ||
"addressToOutputScript", | ||
) | ||
let spyOnIsP2PKHScript: jest.SpyInstance<boolean> | ||
let spyOnIsP2WPKHScript: jest.SpyInstance<boolean> | ||
let result: boolean | ||
|
||
beforeAll(() => { | ||
spyOnIsP2PKHScript = jest.spyOn(BitcoinScriptUtils, "isP2PKHScript") | ||
spyOnIsP2WPKHScript = jest.spyOn(BitcoinScriptUtils, "isP2WPKHScript") | ||
|
||
result = isPublicKeyHashTypeAddress(address, network) | ||
}) | ||
|
||
it("should not be able to convert address to output script", () => { | ||
expect(spyOnAddressToOutputScript).toThrow() | ||
}) | ||
|
||
it("should not check if an address is P2PKH or P2WPKH", () => { | ||
expect(spyOnIsP2PKHScript).not.toHaveBeenCalled() | ||
expect(spyOnIsP2WPKHScript).not.toHaveBeenCalled() | ||
}) | ||
|
||
it("should return false", () => { | ||
expect(result).toBeFalsy() | ||
}) | ||
}, | ||
) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { BitcoinNetwork, Hex } from "../../../src" | ||
|
||
// eslint-disable-next-line import/prefer-default-export | ||
export const btcAddresses: { | ||
type: string | ||
network: BitcoinNetwork | ||
address: string | ||
scriptPubKey: Hex | ||
}[] = [ | ||
// Testnet addresses. | ||
{ | ||
type: "P2PKH", | ||
network: BitcoinNetwork.Testnet, | ||
address: "mjc2zGWypwpNyDi4ZxGbBNnUA84bfgiwYc", | ||
scriptPubKey: Hex.from( | ||
"76a9142cd680318747b720d67bf4246eb7403b476adb3488ac", | ||
), | ||
}, | ||
{ | ||
type: "P2WPKH", | ||
network: BitcoinNetwork.Testnet, | ||
address: "tb1qumuaw3exkxdhtut0u85latkqfz4ylgwstkdzsx", | ||
scriptPubKey: Hex.from("0014e6f9d74726b19b75f16fe1e9feaec048aa4fa1d0"), | ||
}, | ||
{ | ||
type: "P2SH", | ||
network: BitcoinNetwork.Testnet, | ||
address: "2MsM67NLa71fHvTUBqNENW15P68nHB2vVXb", | ||
scriptPubKey: Hex.from("a914011beb6fb8499e075a57027fb0a58384f2d3f78487"), | ||
}, | ||
{ | ||
type: "P2WSH", | ||
network: BitcoinNetwork.Testnet, | ||
address: "tb1qau95mxzh2249aa3y8exx76ltc2sq0e7kw8hj04936rdcmnynhswqqz02vv", | ||
scriptPubKey: Hex.from( | ||
"0020ef0b4d985752aa5ef6243e4c6f6bebc2a007e7d671ef27d4b1d0db8dcc93bc1c", | ||
), | ||
}, | ||
{ | ||
type: "P2TR", | ||
network: BitcoinNetwork.Testnet, | ||
address: "tb1pwrq754496svp5dkxht4chuezy4zt6fwf2l8lpv0gexudeggqzuesvd985f", | ||
scriptPubKey: Hex.from( | ||
"512070c1ea56a5d4181a36c6baeb8bf3222544bd25c957cff0b1e8c9b8dca1001733", | ||
), | ||
}, | ||
// Mainnet addresses. | ||
{ | ||
type: "P2PKH", | ||
network: BitcoinNetwork.Mainnet, | ||
address: "12higDjoCCNXSA95xZMWUdPvXNmkAduhWv", | ||
scriptPubKey: Hex.from( | ||
"76a91412ab8dc588ca9d5787dde7eb29569da63c3a238c88ac", | ||
), | ||
}, | ||
{ | ||
type: "P2WPKH", | ||
network: BitcoinNetwork.Mainnet, | ||
address: "bc1q34aq5drpuwy3wgl9lhup9892qp6svr8ldzyy7c", | ||
scriptPubKey: Hex.from("00148d7a0a3461e3891723e5fdf8129caa0075060cff"), | ||
}, | ||
{ | ||
type: "P2SH", | ||
network: BitcoinNetwork.Mainnet, | ||
address: "342ftSRCvFHfCeFFBuz4xwbeqnDw6BGUey", | ||
scriptPubKey: Hex.from("a91419a7d869032368fd1f1e26e5e73a4ad0e474960e87"), | ||
}, | ||
{ | ||
type: "P2WSH", | ||
network: BitcoinNetwork.Mainnet, | ||
address: "bc1qeklep85ntjz4605drds6aww9u0qr46qzrv5xswd35uhjuj8ahfcqgf6hak", | ||
scriptPubKey: Hex.from( | ||
"0020cdbf909e935c855d3e8d1b61aeb9c5e3c03ae8021b286839b1a72f2e48fdba70", | ||
), | ||
}, | ||
{ | ||
type: "P2TR", | ||
network: BitcoinNetwork.Mainnet, | ||
address: "bc1pxwww0ct9ue7e8tdnlmug5m2tamfn7q06sahstg39ys4c9f3340qqxrdu9k", | ||
scriptPubKey: Hex.from( | ||
"5120339ce7e165e67d93adb3fef88a6d4beed33f01fa876f05a225242b82a631abc0", | ||
), | ||
}, | ||
] |