Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: improve string type safety #145

Merged
merged 21 commits into from
Nov 30, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
bd430f6
feat(core): add utils for custom string types, safer pool id types
mkazlauskas Nov 23, 2021
91c0f59
refactor: add ProviderFailure.InvalidResponse, use improved PoolId type
mkazlauskas Nov 23, 2021
bd6506d
refactor(core): convert Cardano/util and Cardano/StakePool into dirs
mkazlauskas Nov 24, 2021
eeb2074
refactor: improve Cardano.Address and Cardano.RewardAccount types
mkazlauskas Nov 24, 2021
90a1544
refactor: improve Cardano.TransactionId type
mkazlauskas Nov 24, 2021
b24a899
refactor: add Cardano.BlockId type
mkazlauskas Nov 24, 2021
bc8953d
refactor: add Ed25519Signature and Ed25519PublicKey types
mkazlauskas Nov 24, 2021
9ee9070
refactor: update StakePool.rewardAccount to Cardano.RewardAccount
mkazlauskas Nov 24, 2021
98ce920
refactor: convert Hash16 to a validated type, add Ed25519KeyHash and …
mkazlauskas Nov 25, 2021
3f3dad6
refactor: change StakePool.owners to be Cardano.RewardAccount[]
mkazlauskas Nov 25, 2021
b2c3048
refactor: split Hash16 into 2 more concrete types
mkazlauskas Nov 25, 2021
28de368
refactor: convert TxAlonzo.witness.signatures to Map, resolve some TODOs
mkazlauskas Nov 25, 2021
28f2ccf
refactor: rename MIR certificate 'address' to 'rewardAccount' and cha…
mkazlauskas Nov 25, 2021
4fc6ad8
refactor: improve Tip type to use the new BlockId type
mkazlauskas Nov 25, 2021
9781ae2
refactor: improve asset id types, convert TokenMap to Map
mkazlauskas Nov 26, 2021
ec523a7
fix: change stakepool metadata extVkey field type to bech32 string
mkazlauskas Nov 29, 2021
69e1f8e
chore: rm some obsolete TODO comments
mkazlauskas Nov 29, 2021
854e9cb
refactor: convert tx signature key type to hex
mkazlauskas Nov 29, 2021
d4200ef
refactor: change PoolParameters.vrf type to VrkVkHex
mkazlauskas Nov 29, 2021
914fab8
refactor(core): change type of requiredExtraSignatures to Ed25519KeyHash
mkazlauskas Nov 29, 2021
4ab2fda
refactor: improve name for PoolMdVk, improve opaque string tests
mkazlauskas Nov 29, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/blockfrost/src/blockfrostWalletProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ export const blockfrostWalletProvider = (options: Options, logger = dummyLogger)
slotLeader: Cardano.PoolId(response.slot_leader),
totalOutput: BigInt(response.output || '0'),
txCount: response.tx_count,
vrf: response.block_vrf
vrf: Cardano.VrfVkBech32(response.block_vrf)
};
});
};
Expand Down
2 changes: 1 addition & 1 deletion packages/blockfrost/test/blockfrostWalletProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,7 @@ describe('blockfrostWalletProvider', () => {
slotLeader: Cardano.PoolId('pool1zuevzm3xlrhmwjw87ec38mzs02tlkwec9wxpgafcaykmwg7efhh'),
totalOutput: 9_249_073_880n,
txCount: 3,
vrf: 'vrf_vk19j362pkr4t9y0m3qxgmrv0365vd7c4ze03ny4jh84q8agjy4ep4s99zvg8'
vrf: Cardano.VrfVkBech32('vrf_vk19j362pkr4t9y0m3qxgmrv0365vd7c4ze03ny4jh84q8agjy4ep4s99zvg8')
} as Cardano.Block
]);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export class StakePoolMetadata implements Cardano.StakePoolMetadata {
@Field({ nullable: true })
extSigUrl?: string;
@Field(() => String, { nullable: true })
extVkey?: Cardano.Hash32ByteBase16;
extVkey?: Cardano.VrfVkBech32;
@Field(() => ExtendedStakePoolMetadata, { nullable: true })
@Directive('@hasInverse(field: metadata)')
ext?: Cardano.ExtendedStakePoolMetadata;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const toCoreStakePool = (responseStakePool: GraphqlStakePool) => {
}
}
: undefined,
extVkey: stakePool.metadata.extVkey ? Cardano.Hash32ByteBase16(stakePool.metadata.extVkey) : undefined
extVkey: stakePool.metadata.extVkey ? Cardano.VrfVkBech32(stakePool.metadata.extVkey) : undefined
}
: undefined,
metadataJson: stakePool.metadataJson
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe('StakePoolSearchClient', () => {
},
extDataUrl: 'http://extdata',
extSigUrl: 'http://extsig',
extVkey: '886206542d63b23a047864021fbfccf291d78e47c1e59bd4c75fbc67b248c5e8',
extVkey: 'poolmd_vk19j362pkr4t9y0m3qxgmrv0365vd7c4ze03ny4jh84q8agjy4ep4stmm43m',
homepage: 'http://homepage',
name: 'some pool',
ticker: 'TICKR'
Expand Down
10 changes: 8 additions & 2 deletions packages/core/src/Cardano/types/Block.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { BlockAlonzo, BlockNo, BlockSize, Slot } from '@cardano-ogmios/schema';
import { Cardano } from '../..';
import { Epoch, Lovelace, PoolId } from '.';
import { Hash32ByteBase16 } from '../util';
import { Hash32ByteBase16, OpaqueString, typedBech32 } from '../util';

/**
* block hash as hex string
Expand All @@ -21,7 +21,13 @@ export interface Tip {
export const BlockId = (value: string): BlockId => Hash32ByteBase16<'BlockId'>(value);

export { BlockSize };
export type VrfVkBech32 = string;

/**
* 32 byte ed25519 verification key as bech32 string.
* poolmd_vk prefix might be used in extended stake pool metadata (cip6).
*/
export type VrfVkBech32 = OpaqueString<'VrfVkBech32'>;
export const VrfVkBech32 = (value: string) => typedBech32<VrfVkBech32>(value, ['vrf_vk', 'poolmd_vk'], 52);

type OgmiosHeader = NonNullable<BlockAlonzo['header']>;
export type PartialBlockHeader = Pick<OgmiosHeader, 'blockHeight' | 'slot'> & {
Expand Down
5 changes: 2 additions & 3 deletions packages/core/src/Cardano/types/StakePool/StakePool.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ExtendedStakePoolMetadata } from './ExtendedStakePoolMetadata';
import { Hash32ByteBase16, Lovelace, TransactionId } from '..';
import { Lovelace, TransactionId, VrfVkBech32 } from '..';
import { PoolIdHex } from './primitives';
import { PoolParameters } from './PoolParameters';

Expand All @@ -22,12 +22,11 @@ export interface Cip6MetadataFields {
* 128 Characters Maximum, must be a valid URL
*/
extSigUrl?: string;
// TODO: this is probably wrong, as CIP says it's 68 characters long. Find and validate the correct format.
/**
* the public Key for verification
* optional, 68 Characters
*/
extVkey?: Hash32ByteBase16;
extVkey?: VrfVkBech32;
}

export interface StakePoolMetadataFields {
Expand Down
9 changes: 9 additions & 0 deletions packages/core/src/Cardano/util/primitives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ export const assertIsBech32WithPrefix = (
}
};

export const typedBech32 = <T>(
target: string,
prefix: string | string[],
expectedDecodedLength?: number | number[]
) => {
assertIsBech32WithPrefix(target, prefix, expectedDecodedLength);
return target as unknown as T;
};

/**
* @param {string} target bech32 string to decode
* @param {string} expectedLength expected string length, >0
Expand Down
7 changes: 6 additions & 1 deletion packages/core/test/Cardano/types/Block.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { BlockId } from '../../../src/Cardano';
import { BlockId, VrfVkBech32 } from '../../../src/Cardano';

describe('Cardano/types/Block', () => {
it('BlockId() accepts a valid transaction hash', () => {
expect(() => BlockId('0dbe461fb5f981c0d01615332b8666340eb1a692b3034f46bcb5f5ea4172b2ed')).not.toThrow();
});

it('VrfVkBech32() accepts a valid vrf verification key bech32 string with vrf_vk or poolmd_vk prefix', () => {
rhyslbw marked this conversation as resolved.
Show resolved Hide resolved
expect(() => VrfVkBech32('vrf_vk19j362pkr4t9y0m3qxgmrv0365vd7c4ze03ny4jh84q8agjy4ep4s99zvg8')).not.toThrow();
expect(() => VrfVkBech32('poolmd_vk19j362pkr4t9y0m3qxgmrv0365vd7c4ze03ny4jh84q8agjy4ep4stmm43m')).not.toThrow();
});
});