Skip to content

Commit

Permalink
refactor(experimental): add coercion utility functions
Browse files Browse the repository at this point in the history
  • Loading branch information
buffalojoec committed Sep 25, 2023
1 parent c93679a commit b3e8de6
Show file tree
Hide file tree
Showing 10 changed files with 130 additions and 0 deletions.
17 changes: 17 additions & 0 deletions packages/addresses/src/__tests__/coercions-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { address, Base58EncodedAddress } from '../base58';

describe('coercions', () => {
describe('address', () => {
it('can coerce to `Base58EncodedAddress`', () => {
// See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json
const raw =
'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Base58EncodedAddress<'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G'>;
const coerced = address('GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G');
expect(coerced).toBe(raw);
});
it('throws on invalid `Base58EncodedAddress`', () => {
const thisThrows = () => address('3333333333333333');
expect(thisThrows).toThrow('`3333333333333333` is not a base-58 encoded address');
});
});
});
3 changes: 3 additions & 0 deletions packages/addresses/src/__typetests__/coercions-typetests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { address, Base58EncodedAddress } from '../base58';

address('555555555555555555555555') satisfies Base58EncodedAddress<'555555555555555555555555'>;
7 changes: 7 additions & 0 deletions packages/addresses/src/base58.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ export function assertIsBase58EncodedAddress(
}
}

export function address<TAddress extends string = string>(
putativeBase58EncodedAddress: TAddress
): Base58EncodedAddress<TAddress> {
assertIsBase58EncodedAddress(putativeBase58EncodedAddress);
return putativeBase58EncodedAddress as Base58EncodedAddress<TAddress>;
}

export function getBase58EncodedAddressCodec(
config?: Readonly<{
description: string;
Expand Down
67 changes: 67 additions & 0 deletions packages/rpc-core/src/__tests__/coercions-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { lamports, LamportsUnsafeBeyond2Pow53Minus1 } from '../lamports';
import { StringifiedBigInt, stringifiedBigInt } from '../stringified-bigint';
import { StringifiedNumber, stringifiedNumber } from '../stringified-number';
import { TransactionSignature, transactionSignature } from '../transaction-signature';
import { UnixTimestamp, unixTimestamp } from '../unix-timestamp';

describe('coercions', () => {
describe('lamports', () => {
it('can coerce to `LamportsUnsafeBeyond2Pow53Minus1`', () => {
const raw = 1234n as LamportsUnsafeBeyond2Pow53Minus1;
const coerced = lamports(1234n);
expect(coerced).toBe(raw);
});
it('throws on invalid `LamportsUnsafeBeyond2Pow53Minus1`', () => {
const thisThrows = () => lamports(-5n);
expect(thisThrows).toThrow('Input for 64-bit unsigned integer cannot be negative');
});
});
describe('stringifiedBigInt', () => {
it('can coerce to `StringifiedBigInt`', () => {
const raw = '1234' as StringifiedBigInt;
const coerced = stringifiedBigInt('1234');
expect(coerced).toBe(raw);
});
it('throws on invalid `StringifiedBigInt`', () => {
const thisThrows = () => stringifiedBigInt('test');
expect(thisThrows).toThrow('`test` cannot be parsed as a BigInt');
});
});
describe('stringifiedNumber', () => {
it('can coerce to `StringifiedNumber`', () => {
const raw = '1234' as StringifiedNumber;
const coerced = stringifiedNumber('1234');
expect(coerced).toBe(raw);
});
it('throws on invalid `StringifiedNumber`', () => {
const thisThrows = () => stringifiedNumber('test');
expect(thisThrows).toThrow('`test` cannot be parsed as a Number');
});
});
describe('transactionSignature', () => {
it('can coerce to `TransactionSignature`', () => {
// Randomly generated
const raw =
'3bwsNoq6EP89sShUAKBeB26aCC3KLGNajRm5wqwr6zRPP3gErZH7erSg3332SVY7Ru6cME43qT35Z7JKpZqCoPaL' as TransactionSignature;
const coerced = transactionSignature(
'3bwsNoq6EP89sShUAKBeB26aCC3KLGNajRm5wqwr6zRPP3gErZH7erSg3332SVY7Ru6cME43qT35Z7JKpZqCoPaL'
);
expect(coerced).toBe(raw);
});
it('throws on invalid `TransactionSignature`', () => {
const thisThrows = () => transactionSignature('test');
expect(thisThrows).toThrow('`test` is not a transaction signature');
});
});
describe('unixTimestamp', () => {
it('can coerce to `UnixTimestamp`', () => {
const raw = 1234 as UnixTimestamp;
const coerced = unixTimestamp(1234);
expect(coerced).toBe(raw);
});
it('throws on invalid `UnixTimestamp`', () => {
const thisThrows = () => unixTimestamp(8.75e15);
expect(thisThrows).toThrow('`8750000000000000` is not a timestamp');
});
});
});
11 changes: 11 additions & 0 deletions packages/rpc-core/src/__typetests__/coercions-typetests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { lamports, LamportsUnsafeBeyond2Pow53Minus1 } from '../lamports';
import { StringifiedBigInt, stringifiedBigInt } from '../stringified-bigint';
import { StringifiedNumber, stringifiedNumber } from '../stringified-number';
import { TransactionSignature, transactionSignature } from '../transaction-signature';
import { UnixTimestamp, unixTimestamp } from '../unix-timestamp';

lamports(50_000_000_000_000n) satisfies LamportsUnsafeBeyond2Pow53Minus1;
stringifiedBigInt('50_000_000_000_000') satisfies StringifiedBigInt;
stringifiedNumber('50_000_000_000_000') satisfies StringifiedNumber;
transactionSignature('x') satisfies TransactionSignature;
unixTimestamp(0) satisfies UnixTimestamp;
5 changes: 5 additions & 0 deletions packages/rpc-core/src/lamports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,8 @@ export function assertIsLamports(
throw new Error('Input number is too large to be represented as a 64-bit unsigned integer');
}
}

export function lamports(putativeLamports: bigint): LamportsUnsafeBeyond2Pow53Minus1 {
assertIsLamports(putativeLamports);
return putativeLamports;
}
5 changes: 5 additions & 0 deletions packages/rpc-core/src/stringified-bigint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,8 @@ export function assertIsStringifiedBigInt(putativeBigInt: string): asserts putat
});
}
}

export function stringifiedBigInt(putativeBigInt: string): StringifiedBigInt {
assertIsStringifiedBigInt(putativeBigInt);
return putativeBigInt;
}
5 changes: 5 additions & 0 deletions packages/rpc-core/src/stringified-number.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@ export function assertIsStringifiedNumber(putativeNumber: string): asserts putat
throw new Error(`\`${putativeNumber}\` cannot be parsed as a Number`);
}
}

export function stringifiedNumber(putativeNumber: string): StringifiedNumber {
assertIsStringifiedNumber(putativeNumber);
return putativeNumber;
}
5 changes: 5 additions & 0 deletions packages/rpc-core/src/transaction-signature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,8 @@ export function assertIsTransactionSignature(
});
}
}

export function transactionSignature(putativeTransactionSignature: string): TransactionSignature {
assertIsTransactionSignature(putativeTransactionSignature);
return putativeTransactionSignature;
}
5 changes: 5 additions & 0 deletions packages/rpc-core/src/unix-timestamp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,8 @@ export function assertIsUnixTimestamp(putativeTimestamp: number): asserts putati
});
}
}

export function unixTimestamp(putativeTimestamp: number): UnixTimestamp {
assertIsUnixTimestamp(putativeTimestamp);
return putativeTimestamp;
}

0 comments on commit b3e8de6

Please sign in to comment.