Merge pull request #1113 from cosmos/bech32-normalize

Create normalizeBech32
This commit is contained in:
Simon Warta 2022-04-07 09:09:28 +02:00 committed by GitHub
commit 363e9f780c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 4 deletions

View File

@ -6,6 +6,10 @@ and this project adheres to
## [Unreleased]
### Added
- @cosmjs/encoding: Create `normalizeBech32`.
## [0.28.1] - 2022-03-30
### Added

View File

@ -1,12 +1,12 @@
import { fromBech32, toBech32 } from "./bech32";
import { fromBech32, normalizeBech32, toBech32 } from "./bech32";
import { fromHex } from "./hex";
describe("Bech32", () => {
describe("bech32", () => {
// test data generate using https://github.com/nym-zone/bech32
// bech32 -e -h eth 9d4e856e572e442f0a4b2763e72d08a0e99d8ded
const ethAddressRaw = fromHex("9d4e856e572e442f0a4b2763e72d08a0e99d8ded");
describe("encode", () => {
describe("toBech32", () => {
it("works", () => {
expect(toBech32("eth", ethAddressRaw)).toEqual("eth1n48g2mjh9ezz7zjtya37wtgg5r5emr0drkwlgw");
});
@ -44,7 +44,7 @@ describe("Bech32", () => {
});
});
describe("decode", () => {
describe("fromBech32", () => {
it("works", () => {
expect(fromBech32("eth1n48g2mjh9ezz7zjtya37wtgg5r5emr0drkwlgw")).toEqual({
prefix: "eth",
@ -52,6 +52,15 @@ describe("Bech32", () => {
});
});
it("works for upper case address", () => {
// "For presentation, lowercase is usually preferable, but inside QR codes uppercase SHOULD be used, as those permit the use of alphanumeric mode, which is 45% more compact than the normal byte mode."
// https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
expect(fromBech32("ETH1N48G2MJH9EZZ7ZJTYA37WTGG5R5EMR0DRKWLGW")).toEqual({
prefix: "eth",
data: ethAddressRaw,
});
});
it("works for addresses which exceed the specification limit of 90 characters", () => {
// Example from https://github.com/cosmos/cosmos-sdk/pull/6237#issuecomment-658116534
expect(() =>
@ -70,5 +79,34 @@ describe("Bech32", () => {
),
).toThrowError(/exceeds length limit/i);
});
it("throws for mixed case addresses", () => {
// "Decoders MUST NOT accept strings where some characters are uppercase and some are lowercase (such strings are referred to as mixed case strings)."
// https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
expect(() => fromBech32("Eth1n48g2mjh9ezz7zjtya37wtgg5r5emr0drkwlgw")).toThrowError(/Mixed-case/i);
expect(() => fromBech32("eTh1n48g2mjh9ezz7zjtya37wtgg5r5emr0drkwlgw")).toThrowError(/Mixed-case/i);
expect(() => fromBech32("ETH1n48g2mjh9ezz7zjtya37wtgg5r5emr0drkwlgw")).toThrowError(/Mixed-case/i);
expect(() => fromBech32("eth1n48g2mjh9Ezz7zjtya37wtgg5r5emr0drkwlgw")).toThrowError(/Mixed-case/i);
});
});
describe("normalizeBech32", () => {
it("works", () => {
expect(normalizeBech32("eth1n48g2mjh9ezz7zjtya37wtgg5r5emr0drkwlgw")).toEqual(
"eth1n48g2mjh9ezz7zjtya37wtgg5r5emr0drkwlgw",
);
expect(normalizeBech32("ETH1N48G2MJH9EZZ7ZJTYA37WTGG5R5EMR0DRKWLGW")).toEqual(
"eth1n48g2mjh9ezz7zjtya37wtgg5r5emr0drkwlgw",
);
});
it("throws for mixed case addresses", () => {
// "Decoders MUST NOT accept strings where some characters are uppercase and some are lowercase (such strings are referred to as mixed case strings)."
// https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
expect(() => normalizeBech32("Eth1n48g2mjh9ezz7zjtya37wtgg5r5emr0drkwlgw")).toThrowError(/Mixed-case/i);
expect(() => normalizeBech32("eTh1n48g2mjh9ezz7zjtya37wtgg5r5emr0drkwlgw")).toThrowError(/Mixed-case/i);
expect(() => normalizeBech32("ETH1n48g2mjh9ezz7zjtya37wtgg5r5emr0drkwlgw")).toThrowError(/Mixed-case/i);
expect(() => normalizeBech32("eth1n48g2mjh9Ezz7zjtya37wtgg5r5emr0drkwlgw")).toThrowError(/Mixed-case/i);
});
});
});

View File

@ -16,6 +16,17 @@ export function fromBech32(
};
}
/**
* Takes a bech32 address and returns a normalized (i.e. lower case) representation of it.
*
* The input is validated along the way, which makes this significantly safer than
* using `address.toLowerCase()`.
*/
export function normalizeBech32(address: string): string {
const { prefix, data } = fromBech32(address);
return toBech32(prefix, data);
}
/**
* @deprecated This class is deprecated and will be removed soon. Please use fromBech32() and toBech32() instead. For more details please refer to https://github.com/cosmos/cosmjs/issues/1053.
*/