-
-
Notifications
You must be signed in to change notification settings - Fork 15
feat: named CAIP structs #228
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
Changes from all commits
2297ebe
3518871
8969892
a920704
c88c8fe
9eac420
fd3102e
7f8e764
044d318
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,7 @@ | ||
| import type { Infer, Struct } from '@metamask/superstruct'; | ||
| import { is, pattern, string } from '@metamask/superstruct'; | ||
| import type { Infer } from '@metamask/superstruct'; | ||
| import { is } from '@metamask/superstruct'; | ||
|
|
||
| import { definePattern } from './superstruct'; | ||
|
|
||
| export const CAIP_CHAIN_ID_REGEX = | ||
| /^(?<namespace>[-a-z0-9]{3,8}):(?<reference>[-_a-zA-Z0-9]{1,32})$/u; | ||
|
|
@@ -28,83 +30,95 @@ export const CAIP_ASSET_ID_REGEX = | |
| /** | ||
| * A CAIP-2 chain ID, i.e., a human-readable namespace and reference. | ||
| */ | ||
| export const CaipChainIdStruct = pattern( | ||
| string(), | ||
| export const CaipChainIdStruct = definePattern<`${string}:${string}`>( | ||
| 'CaipChainId', | ||
| CAIP_CHAIN_ID_REGEX, | ||
| ) as Struct<CaipChainId, null>; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the PR description you say that the struct is being inferred as a string, but it looks like we were using a type assertion before to ensure that this was not the case. So, was it really being inferred as a string? It's not clear to me what effects these changes have, as the only tests being added in this PR are for
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Meaning that using With the new export const CaipChainIdStruct = pattern(
string(),
CAIP_CHAIN_ID_REGEX,
); // Would be: Struct<string, null> (which is why we were type-casting)
export const CaipChainIdStruct = definePattern<`${string}:${string}`>(
'CaipChainId',
CAIP_CHAIN_ID_REGEX,
); // Would be: Struct<`${string}:${string}`, null> (no more type-casting required)In addition to that, we use |
||
| export type CaipChainId = `${string}:${string}`; | ||
| ); | ||
| export type CaipChainId = Infer<typeof CaipChainIdStruct>; | ||
|
|
||
| /** | ||
| * A CAIP-2 namespace, i.e., the first part of a CAIP chain ID. | ||
| */ | ||
| export const CaipNamespaceStruct = pattern(string(), CAIP_NAMESPACE_REGEX); | ||
| export const CaipNamespaceStruct = definePattern( | ||
| 'CaipNamespace', | ||
| CAIP_NAMESPACE_REGEX, | ||
| ); | ||
| export type CaipNamespace = Infer<typeof CaipNamespaceStruct>; | ||
|
|
||
| /** | ||
| * A CAIP-2 reference, i.e., the second part of a CAIP chain ID. | ||
| */ | ||
| export const CaipReferenceStruct = pattern(string(), CAIP_REFERENCE_REGEX); | ||
| export const CaipReferenceStruct = definePattern( | ||
| 'CaipReference', | ||
| CAIP_REFERENCE_REGEX, | ||
| ); | ||
| export type CaipReference = Infer<typeof CaipReferenceStruct>; | ||
|
|
||
| /** | ||
| * A CAIP-10 account ID, i.e., a human-readable namespace, reference, and account address. | ||
| */ | ||
| export const CaipAccountIdStruct = pattern( | ||
| string(), | ||
| CAIP_ACCOUNT_ID_REGEX, | ||
| ) as Struct<CaipAccountId, null>; | ||
| export type CaipAccountId = `${string}:${string}:${string}`; | ||
| export const CaipAccountIdStruct = | ||
| definePattern<`${string}:${string}:${string}`>( | ||
| 'CaipAccountId', | ||
| CAIP_ACCOUNT_ID_REGEX, | ||
| ); | ||
| export type CaipAccountId = Infer<typeof CaipAccountIdStruct>; | ||
|
|
||
| /** | ||
| * A CAIP-10 account address, i.e., the third part of the CAIP account ID. | ||
| */ | ||
| export const CaipAccountAddressStruct = pattern( | ||
| string(), | ||
| export const CaipAccountAddressStruct = definePattern( | ||
| 'CaipAccountAddress', | ||
| CAIP_ACCOUNT_ADDRESS_REGEX, | ||
| ); | ||
| export type CaipAccountAddress = Infer<typeof CaipAccountAddressStruct>; | ||
|
|
||
| /** | ||
| * A CAIP-19 asset namespace, i.e., a namespace domain of an asset. | ||
| */ | ||
| export const CaipAssetNamespaceStruct = pattern( | ||
| string(), | ||
| export const CaipAssetNamespaceStruct = definePattern( | ||
| 'CaipAssetNamespace', | ||
| CAIP_ASSET_NAMESPACE_REGEX, | ||
| ); | ||
| export type CaipAssetNamespace = Infer<typeof CaipAssetNamespaceStruct>; | ||
|
|
||
| /** | ||
| * A CAIP-19 asset reference, i.e., an identifier for an asset within a given namespace. | ||
| */ | ||
| export const CaipAssetReferenceStruct = pattern( | ||
| string(), | ||
| export const CaipAssetReferenceStruct = definePattern( | ||
| 'CaipAssetReference', | ||
| CAIP_ASSET_REFERENCE_REGEX, | ||
| ); | ||
| export type CaipAssetReference = Infer<typeof CaipAssetReferenceStruct>; | ||
|
|
||
| /** | ||
| * A CAIP-19 asset token ID, i.e., a unique identifier for an addressable asset of a given type | ||
| */ | ||
| export const CaipTokenIdStruct = pattern(string(), CAIP_TOKEN_ID_REGEX); | ||
| export const CaipTokenIdStruct = definePattern( | ||
| 'CaipTokenId', | ||
| CAIP_TOKEN_ID_REGEX, | ||
| ); | ||
| export type CaipTokenId = Infer<typeof CaipTokenIdStruct>; | ||
|
|
||
| /** | ||
| * A CAIP-19 asset type identifier, i.e., a human-readable type of asset identifier. | ||
| */ | ||
| export const CaipAssetTypeStruct = pattern( | ||
| string(), | ||
| CAIP_ASSET_TYPE_REGEX, | ||
| ) as Struct<CaipAssetType, null>; | ||
| export type CaipAssetType = `${string}:${string}/${string}:${string}`; | ||
| export const CaipAssetTypeStruct = | ||
| definePattern<`${string}:${string}/${string}:${string}`>( | ||
| 'CaipAssetType', | ||
| CAIP_ASSET_TYPE_REGEX, | ||
| ); | ||
| export type CaipAssetType = Infer<typeof CaipAssetTypeStruct>; | ||
|
|
||
| /** | ||
| * A CAIP-19 asset ID identifier, i.e., a human-readable type of asset ID. | ||
| */ | ||
| export const CaipAssetIdStruct = pattern( | ||
| string(), | ||
| CAIP_ASSET_ID_REGEX, | ||
| ) as Struct<CaipAssetId, null>; | ||
| export type CaipAssetId = `${string}:${string}/${string}:${string}/${string}`; | ||
| export const CaipAssetIdStruct = | ||
| definePattern<`${string}:${string}/${string}:${string}/${string}`>( | ||
| 'CaipAssetId', | ||
| CAIP_ASSET_ID_REGEX, | ||
| ); | ||
| export type CaipAssetId = Infer<typeof CaipAssetIdStruct>; | ||
|
|
||
| /** Known CAIP namespaces. */ | ||
| export enum KnownCaipNamespace { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| import { assert, is, pattern, string } from '@metamask/superstruct'; | ||
|
|
||
| import { definePattern } from './superstruct'; | ||
|
|
||
| describe('definePattern', () => { | ||
| const hexPattern = /^0x[0-9a-f]+$/u; | ||
| const HexStringPattern = pattern(string(), hexPattern); | ||
| const HexString = definePattern('HexString', hexPattern); | ||
|
|
||
| it('is similar to superstruct.pattern', () => { | ||
| expect(is('0xdeadbeef', HexStringPattern)).toBe(true); | ||
| expect(is('0xdeadbeef', HexString)).toBe(true); | ||
| expect(is('foobar', HexStringPattern)).toBe(false); | ||
| expect(is('foobar', HexString)).toBe(false); | ||
| }); | ||
|
|
||
| it('throws and error if assert fails', () => { | ||
| const value = 'foobar'; | ||
| expect(() => assert(value, HexString)).toThrow( | ||
| `Expected a value of type \`HexString\`, but received: \`"foobar"\``, | ||
| ); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| import type { Struct } from '@metamask/superstruct'; | ||
| import { define } from '@metamask/superstruct'; | ||
|
|
||
| /** | ||
| * Defines a new string-struct matching a regular expression. | ||
| * | ||
| * @example | ||
| * const EthAddressStruct = definePattern('EthAddress', /^0x[0-9a-f]{40}$/iu); | ||
| * type EthAddress = Infer<typeof EthAddressStruct>; // string | ||
| * | ||
| * const CaipChainIdStruct = defineTypedPattern<`${string}:${string}`>( | ||
| * 'CaipChainId', | ||
| * /^[-a-z0-9]{3,8}:[-_a-zA-Z0-9]{1,32}$/u; | ||
| * ); | ||
| * type CaipChainId = Infer<typeof CaipChainIdStruct>; // `${string}:${string}` | ||
| * @param name - Type name. | ||
| * @param pattern - Regular expression to match. | ||
| * @template Pattern - The pattern type, defaults to `string`. | ||
| * @returns A new string-struct that matches the given pattern. | ||
| */ | ||
| export function definePattern<Pattern extends string = string>( | ||
ccharly marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| name: string, | ||
| pattern: RegExp, | ||
| ): Struct<Pattern, null> { | ||
| return define<Pattern>(name, (value: unknown): boolean | string => { | ||
| return typeof value === 'string' && pattern.test(value); | ||
| }); | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.