Skip to content

Commit

Permalink
Merge pull request #1936 from aeternity/feature/fixes
Browse files Browse the repository at this point in the history
Multiple encodings in `isAddressValid`, simplify exports in tx builder, correct schema picking
  • Loading branch information
davidyuk authored Jan 23, 2024
2 parents 1c50247 + 00a6c34 commit 15534df
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 86 deletions.
1 change: 0 additions & 1 deletion docs/guides/error-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ BaseError
├── TransactionError
│ ├── DecodeError
│ ├── EncodeError
│ ├── PayloadLengthError
│ ├── DryRunError
│ ├── IllegalBidFeeError
Expand Down
12 changes: 9 additions & 3 deletions src/tx/builder/common.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { decode as rlpDecode, encode as rlpEncode } from 'rlp';
import { Field, BinaryData } from './field-types';
import { ArgumentError, DecodeError, SchemaNotFoundError } from '../../utils/errors';
import {
ArgumentError, DecodeError, SchemaNotFoundError, InternalError,
} from '../../utils/errors';
import {
Encoding, Encoded, encode, decode,
} from '../../utils/encoder';
import { readInt } from './helpers';

type Schemas = ReadonlyArray<{
tag: { constValue: number } & Field;
version: { constValue: number } & Field;
version: { constValue: number; constValueOptional: boolean } & Field;
}>;

export function getSchema(
Expand All @@ -19,7 +21,11 @@ export function getSchema(
): Array<[string, Field]> {
const subSchemas = schemas.filter((s) => s.tag.constValue === tag);
if (subSchemas.length === 0) throw new SchemaNotFoundError(`${Tag[tag]} (${tag})`, 0);
version ??= Math.max(...subSchemas.map((s) => s.version.constValue));
if (version == null) {
const defaultSchema = subSchemas.find((schema) => schema.version.constValueOptional);
if (defaultSchema == null) throw new InternalError(`Can't find default schema of ${Tag[tag]} (${tag})`);
version = defaultSchema.version.constValue;
}
const schema = subSchemas.find((s) => s.version.constValue === version);
if (schema == null) throw new SchemaNotFoundError(`${Tag[tag]} (${tag})`, version);
return Object.entries(schema);
Expand Down
93 changes: 30 additions & 63 deletions src/tx/builder/field-types/index.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
import abiVersion from './abi-version';
import address from './address';
import array from './array';
import boolean from './boolean';
import coinAmount from './coin-amount';
import ctVersion from './ct-version';
import encoded from './encoded';
import entry from './entry';
import enumeration from './enumeration';
import fee from './fee';
import field from './field';
import gasLimit from './gas-limit';
import gasPrice from './gas-price';
import map from './map';
import mptree from './mptree';
import name from './name';
import nameFee from './name-fee';
import nameId from './name-id';
import nonce from './nonce';
import pointers from './pointers';
import queryFee from './query-fee';
import raw from './raw';
import shortUInt from './short-u-int';
import shortUIntConst from './short-u-int-const';
import string from './string';
import ttl from './ttl';
import uInt from './u-int';
import withDefault from './with-default';
import withFormatting from './with-formatting';
import wrapped from './wrapped';
export { default as abiVersion } from './abi-version';
export { default as address } from './address';
export { default as array } from './array';
export { default as boolean } from './boolean';
export { default as coinAmount } from './coin-amount';
export { default as ctVersion } from './ct-version';
export { default as encoded } from './encoded';
export { default as entry } from './entry';
export { default as enumeration } from './enumeration';
export { default as fee } from './fee';
export { default as field } from './field';
export { default as gasLimit } from './gas-limit';
export { default as gasPrice } from './gas-price';
export { default as map } from './map';
export { default as mptree } from './mptree';
export { default as name } from './name';
export { default as nameFee } from './name-fee';
export { default as nameId } from './name-id';
export { default as nonce } from './nonce';
export { default as pointers } from './pointers';
export { default as queryFee } from './query-fee';
export { default as raw } from './raw';
export { default as shortUInt } from './short-u-int';
export { default as shortUIntConst } from './short-u-int-const';
export { default as string } from './string';
export { default as ttl } from './ttl';
export { default as uInt } from './u-int';
export { default as withDefault } from './with-default';
export { default as withFormatting } from './with-formatting';
export { default as wrapped } from './wrapped';

export type BinaryData = Buffer | Buffer[] | Buffer[][]
| Array<[Buffer, Array<[Buffer, Buffer[]]>]>;
Expand All @@ -37,36 +37,3 @@ export interface Field {
deserialize: (value: BinaryData, options: any) => any;
recursiveType?: boolean;
}

export {
abiVersion,
address,
array,
boolean,
coinAmount,
ctVersion,
encoded,
entry,
enumeration,
fee,
field,
gasLimit,
gasPrice,
map,
mptree,
name,
nameFee,
nameId,
nonce,
pointers,
queryFee,
raw,
shortUInt,
shortUIntConst,
string,
ttl,
uInt,
withDefault,
withFormatting,
wrapped,
};
34 changes: 20 additions & 14 deletions src/utils/crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import nacl, { SignKeyPair } from 'tweetnacl';
import { blake2b } from 'blakejs/blake2b.js';
import { encode as varuintEncode } from 'varuint-bitcoin';

import { concatBuffers } from './other';
import { concatBuffers, isItemOfArray } from './other';
import {
decode, encode, Encoded, Encoding,
} from './encoder';
Expand All @@ -22,23 +22,29 @@ export function getAddressFromPriv(secret: string | Uint8Array): Encoded.Account
}

/**
* Check if address is valid
* @param address - Address
* @param prefix - Transaction prefix. Default: 'ak'
* @returns is valid
* Check if data is encoded in one of provided encodings
* @param maybeEncoded - Data to check
* @param encodings - Rest parameters with encodings to check against
*/
export function isAddressValid(
address: string,
prefix: Encoding = Encoding.AccountAddress,
): boolean {
export function isAddressValid(maybeEncoded: string): maybeEncoded is Encoded.AccountAddress;
export function isAddressValid<E extends Encoding>(
maybeEncoded: string,
...encodings: E[]
): maybeEncoded is Encoded.Generic<E>;
export function isAddressValid(maybeEncoded: string, ...encodings: Encoding[]): boolean {
if (encodings.length === 0) encodings = [Encoding.AccountAddress];
try {
decode(address as Encoded.Generic<typeof prefix>);
const actualPrefix = address.split('_')[0];
if (actualPrefix !== prefix) {
throw new ArgumentError('Encoded string type', prefix, actualPrefix);
decode(maybeEncoded as Encoded.Any);
const encoding = maybeEncoded.split('_')[0];
if (!isItemOfArray(encoding, encodings)) {
throw new ArgumentError(
'Encoded string type',
encodings.length > 1 ? `one of ${encodings.join(', ')}` : encodings[0],
encoding,
);
}
return true;
} catch (e) {
} catch (error) {
return false;
}
}
Expand Down
33 changes: 28 additions & 5 deletions test/unit/crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { assert, expect } from 'chai';
import {
buildTxHash, decode, Encoded,
generateKeyPair, getAddressFromPriv, verifyMessage, isValidKeypair, isAddressValid, hash, genSalt,
sign, verify, messageToHash, signMessage,
sign, verify, messageToHash, signMessage, Encoding,
} from '../../src';

// These keys are fixations for the encryption lifecycle tests and will
Expand Down Expand Up @@ -54,10 +54,33 @@ describe('crypto', () => {
});
});

it('isAddressValid', () => {
expect(isAddressValid('test')).to.be.equal(false);
expect(isAddressValid('th_11111111111111111111111111111111273Yts')).to.be.equal(false);
expect(isAddressValid('ak_11111111111111111111111111111111273Yts')).to.be.equal(true);
describe('isAddressValid', () => {
it('rejects invalid encoded data', () => {
expect(isAddressValid('test')).to.be.equal(false);
expect(isAddressValid('th_11111111111111111111111111111111273Yts')).to.be.equal(false);
expect(isAddressValid('ak_11111111111111111111111111111111273Yts', Encoding.TxHash))
.to.be.equal(false);
});

it('returns true for a valid address', () => {
const maybeValue: string = 'ak_11111111111111111111111111111111273Yts';
const result = isAddressValid(maybeValue);
expect(result).to.be.equal(true);
// @ts-expect-error `result` is not chcked yet
let value: Encoded.AccountAddress = maybeValue;
if (result) value = maybeValue;
expect(value);
});

it('correctly checks against multiple encodings', () => {
const maybeValue: string = 'th_HZMNgTvEiyKeATpauJjjeWwZcyHapKG8bDgy2S1sCUEUQnbwK';
const result = isAddressValid(maybeValue, Encoding.Name, Encoding.TxHash);
expect(result).to.be.equal(true);
// @ts-expect-error `result` is not chcked yet
let value: Encoded.Name | Encoded.TxHash = maybeValue;
if (result) value = maybeValue;
expect(value);
});
});

describe('sign', () => {
Expand Down

0 comments on commit 15534df

Please sign in to comment.