Skip to content
Merged
Prev Previous commit
Next Next commit
Adjust
  • Loading branch information
jacogr committed Feb 3, 2021
commit 1e1d5d0f0f53cd784bc12214a97c66c54a993ee4
12 changes: 5 additions & 7 deletions packages/util-crypto/src/address/checksum.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0

import { assert } from '@polkadot/util';

import { sshash } from './sshash';

export function checkAddressChecksum (decoded: Uint8Array): [boolean, number, number, number] {
assert((decoded[0] & 0b1000_0000) === 0, 'Invalid ssPrefix byte received, expected <= 127');

const ss58Length = (decoded[0] & 0b0100_0000) ? 2 : 1;
const ss58Decoded = ss58Length === 1
? decoded[0]
Expand All @@ -21,9 +17,11 @@ export function checkAddressChecksum (decoded: Uint8Array): [boolean, number, nu
const hash = sshash(decoded.subarray(0, length));

// see if the hash actually matches
const isValid = isPublicKey
? decoded[decoded.length - 2] === hash[0] && decoded[decoded.length - 1] === hash[1]
: decoded[decoded.length - 1] === hash[0];
const isValid = (decoded[0] & 0b1000_0000) === 0 && (
isPublicKey
? decoded[decoded.length - 2] === hash[0] && decoded[decoded.length - 1] === hash[1]
: decoded[decoded.length - 1] === hash[0]
);

return [isValid, length, ss58Length, ss58Decoded];
}
29 changes: 12 additions & 17 deletions packages/util-crypto/src/address/decode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,27 @@ import { base58Decode } from '../base58/decode';
import { checkAddressChecksum } from './checksum';
import { defaults } from './defaults';

// eslint-disable-next-line @typescript-eslint/no-unused-vars
export function decodeAddress (encoded: string | Uint8Array, ignoreChecksum?: boolean, ss58Format: Prefix = -1): Uint8Array {
if (isU8a(encoded) || isHex(encoded)) {
return u8aToU8a(encoded);
}

const wrapError = (message: string) => `Decoding ${encoded as string}: ${message}`;
let decoded;

try {
decoded = base58Decode(encoded);
} catch (error) {
throw new Error(wrapError((error as Error).message));
}
const decoded = base58Decode(encoded);

// assert(defaults.allowedPrefix.includes(decoded[0] as Prefix), error('Invalid decoded address prefix'));
assert(defaults.allowedEncodedLengths.includes(decoded.length), wrapError('Invalid decoded address length'));
assert(defaults.allowedEncodedLengths.includes(decoded.length), 'Invalid decoded address length');

const [isValid, endPos, ss58Length, ss58Decoded] = checkAddressChecksum(decoded);
const [isValid, endPos, ss58Length, ss58Decoded] = checkAddressChecksum(decoded);

// TODO Unless it is an "use everywhere" prefix, throw an error
if (ss58Format !== -1 && (ss58Decoded !== ss58Format)) {
console.log(`WARN: Expected ssPrefix ${ss58Format}, received ${ss58Decoded}`);
}
// TODO Unless it is an "use everywhere" prefix, throw an error
if (ss58Format !== -1 && (ss58Decoded !== ss58Format)) {
console.log(`WARN: Expected ssPrefix ${ss58Format}, received ${ss58Decoded}`);
}

assert(ignoreChecksum || isValid, wrapError('Invalid decoded address checksum'));
assert(ignoreChecksum || isValid, 'Invalid decoded address checksum');

return decoded.slice(ss58Length, endPos);
return decoded.slice(ss58Length, endPos);
} catch (error) {
throw new Error(`Decoding ${encoded as string}: ${(error as Error).message}`);
}
}