Skip to content

Commit

Permalink
Merge pull request #402 from ensdomains/feat/taproot-addresses
Browse files Browse the repository at this point in the history
feat: taproot addresses
  • Loading branch information
TateB authored Feb 28, 2024
2 parents 766db72 + b932bc7 commit 4bb847b
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 23 deletions.
14 changes: 11 additions & 3 deletions src/coin/btc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,26 @@ describe.each([
hex: "0014751e76e8199196d454941c45d1b3a323f1433bd6",
},
{
text: "bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx",
text: "bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kt5nd6y",
hex: "5128751e76e8199196d454941c45d1b3a323f1433bd6751e76e8199196d454941c45d1b3a323f1433bd6",
},
{ text: "bc1sw50qa3jx3s", hex: "6002751e" },
{ text: "bc1sw50qgdz25j", hex: "6002751e" },
{
text: "bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj",
text: "bc1zw508d6qejxtdg4y5r3zarvaryvaxxpcs",
hex: "5210751e76e8199196d454941c45d1b3a323",
},
{
text: "bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3",
hex: "00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262",
},
{
text: "bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3",
hex: "00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262",
},
{
text: "bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0",
hex: "512079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
}
])("btc address", ({ text, hex }) => {
test(`encode: ${text}`, () => {
expect(encodeBtcAddress(hexToBytes(hex))).toEqual(text);
Expand Down
4 changes: 2 additions & 2 deletions src/coin/btg.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ describe.each([
hex: "a9145ece0cadddc415b1980f001785947120acdb36fc87",
},
{
text: "btg1zw508d6qejxtdg4y5r3zarvaryv2eet8g",
text: "btg1zw508d6qejxtdg4y5r3zarvaryvl9f8z2",
hex: "5210751e76e8199196d454941c45d1b3a323",
},
{
text: "btg1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kc36v4c",
text: "btg1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kdd2qs6",
hex: "5128751e76e8199196d454941c45d1b3a323f1433bd6751e76e8199196d454941c45d1b3a323f1433bd6",
},
])("btg address", ({ text, hex }) => {
Expand Down
2 changes: 1 addition & 1 deletion src/coin/mona.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe.each([
hex: "a9146449f568c9cd2378138f2636e1567112a184a9e887",
},
{
text: "mona1zw508d6qejxtdg4y5r3zarvaryvhm3vz7",
text: "mona1zw508d6qejxtdg4y5r3zarvaryvz8pq8u",
hex: "5210751e76e8199196d454941c45d1b3a323",
},
])("mona address", ({ text, hex }) => {
Expand Down
2 changes: 1 addition & 1 deletion src/coin/nuls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const decodePrefix = (source: string): string => {
return source.slice(i + 1);
}
}
throw Error("Unrecognised address format");
throw new Error("Unrecognised address format");
};

export const encodeNulsAddress = (source: Uint8Array): string => {
Expand Down
8 changes: 4 additions & 4 deletions src/utils/base58.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const createBase58VersionedEncoder =
source[source.length - 2] !== 0x88 ||
source[source.length - 1] !== 0xac
) {
throw Error("Unrecognised address format");
throw new Error("Unrecognised address format");
}
return base58CheckEncode(
concatBytes(p2pkhVersion, source.slice(3, 3 + source[2]))
Expand All @@ -32,14 +32,14 @@ export const createBase58VersionedEncoder =
// P2SH: OP_HASH160 <scriptHash> OP_EQUAL
if (source[0] === 0xa9) {
if (source[source.length - 1] !== 0x87) {
throw Error("Unrecognised address format");
throw new Error("Unrecognised address format");
}
return base58CheckEncode(
concatBytes(p2shVersion, source.slice(2, 2 + source[1]))
);
}

throw Error("Unrecognised address format");
throw new Error("Unrecognised address format");
};

export const createBase58VersionedDecoder =
Expand All @@ -65,5 +65,5 @@ export const createBase58VersionedDecoder =
addr.slice(p2shVersions[0].length),
new Uint8Array([0x87])
);
throw Error("Unrecognised address format");
throw new Error("Unrecognised address format");
};
32 changes: 22 additions & 10 deletions src/utils/bech32.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ const createInternalBech32Decoder =
(source: string): Uint8Array => {
const { prefix, words } = bechLib.decode(source, limit);
if (prefix !== hrp) {
throw Error("Unexpected human-readable part in bech32 encoded address");
throw new Error(
"Unexpected human-readable part in bech32 encoded address"
);
}
return new Uint8Array(bechLib.fromWords(words));
};
Expand All @@ -42,27 +44,37 @@ export const createBech32SegwitEncoder =
if (version >= 0x51 && version <= 0x60) {
version -= 0x50;
} else if (version !== 0x00) {
throw Error("Unrecognised address format");
throw new Error("Unrecognised address format");
}

const words = [version].concat(
bech32.toWords(source.slice(2, source[1] + 2))
);
let words: number[] = [];
if (version > 0 && version < 17) {
words = [version].concat(bech32m.toWords(source.slice(2, source[1] + 2)));
return bech32m.encode(hrp, words);
}
words = [version].concat(bech32.toWords(source.slice(2, source[1] + 2)));
return bech32.encode(hrp, words);
};

export const createBech32SegwitDecoder =
(hrp: string) =>
(source: string): Uint8Array => {
const { prefix, words } = bech32.decode(source);
if (prefix !== hrp) {
throw Error("Unexpected human-readable part in bech32 encoded address");
}
const decodedObj =
bech32.decodeUnsafe(source) || bech32m.decodeUnsafe(source);

if (!decodedObj) throw new Error("Unrecognised address format");
const { prefix, words } = decodedObj;

if (prefix !== hrp)
throw new Error(
"Unexpected human-readable part in bech32 encoded address"
);

const script = bech32.fromWords(words.slice(1));
let version = words[0];
if (version > 0) {
version += 0x50;
}

return concatBytes(
new Uint8Array([version, script.length]),
new Uint8Array(script)
Expand Down
3 changes: 2 additions & 1 deletion src/utils/eosio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ export const createEosEncoder =
export const createEosDecoder =
(prefix: string) =>
(source: string): Uint8Array => {
if (!source.startsWith(prefix)) throw Error("Unrecognised address format");
if (!source.startsWith(prefix))
throw new Error("Unrecognised address format");
const prefixStripped = source.slice(prefix.length);
const decoded = base58UncheckedDecode(prefixStripped);
const checksummed = eosChecksum.decode(decoded);
Expand Down
2 changes: 1 addition & 1 deletion src/utils/hex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export const createHexChecksummedEncoder =
export const createHexChecksummedDecoder =
(chainId?: number) => (source: string) => {
if (!isValidChecksumAddress(source, chainId)) {
throw Error("Unrecognised address format");
throw new Error("Unrecognised address format");
}
return hexToBytes(source as Hex);
};

0 comments on commit 4bb847b

Please sign in to comment.