@effectstream/utils 0.100.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,188 @@
1
+ /**
2
+ * Process spawn abstraction using node:child_process.
3
+ */
4
+
5
+ import { spawn as nodeSpawn } from "node:child_process";
6
+ import { Readable, Writable } from "node:stream";
7
+
8
+ /** Result of a spawned process. stdout/stderr are Web ReadableStreams so they can be pipeTo()'d. */
9
+ export interface SpawnChild {
10
+ readonly pid: number;
11
+ /** Present when options.stdin === "piped". */
12
+ readonly stdin?: WritableStream<Uint8Array>;
13
+ readonly stdout: ReadableStream<Uint8Array>;
14
+ readonly stderr: ReadableStream<Uint8Array>;
15
+ readonly status: Promise<{
16
+ success: boolean;
17
+ code?: number;
18
+ signal?: string;
19
+ }>;
20
+ kill(signal?: NodeJS.Signals): void;
21
+ ref(): void;
22
+ }
23
+
24
+ export interface SpawnOptions {
25
+ args?: string[];
26
+ cwd?: string;
27
+ env?: Record<string, string>;
28
+ signal?: AbortSignal;
29
+ stdin?: "inherit" | "piped" | "null";
30
+ stdout?: "inherit" | "piped" | "null";
31
+ stderr?: "inherit" | "piped" | "null";
32
+ }
33
+
34
+ /** Output from a completed process (for spawnOutput). */
35
+ export interface SpawnOutputResult {
36
+ stdout: Uint8Array;
37
+ stderr: Uint8Array;
38
+ success: boolean;
39
+ code?: number;
40
+ signal?: string;
41
+ }
42
+
43
+ /** Empty stream used when stdio is "inherit" so callers can always use pipeTo. */
44
+ function emptyReadableStream(): ReadableStream<Uint8Array> {
45
+ return new ReadableStream({
46
+ start(controller) {
47
+ controller.close();
48
+ },
49
+ });
50
+ }
51
+
52
+ /**
53
+ * Spawn a child process. Returns a handle with Web ReadableStreams for stdout/stderr
54
+ * so they can be used with pipeTo() in any runtime.
55
+ */
56
+ export function spawn(command: string, options: SpawnOptions = {}): SpawnChild {
57
+ const args = options.args ?? [];
58
+ const stdio: ("inherit" | "pipe" | "ignore")[] = [
59
+ options.stdin === "piped"
60
+ ? "pipe"
61
+ : options.stdin === "null"
62
+ ? "ignore"
63
+ : "inherit",
64
+ options.stdout === "piped"
65
+ ? "pipe"
66
+ : options.stdout === "null"
67
+ ? "ignore"
68
+ : "inherit",
69
+ options.stderr === "piped"
70
+ ? "pipe"
71
+ : options.stderr === "null"
72
+ ? "ignore"
73
+ : "inherit",
74
+ ];
75
+
76
+ const cp = nodeSpawn(command, args, {
77
+ cwd: options.cwd,
78
+ env: { ...process.env, ...options.env, FORCE_COLOR: "true" },
79
+ stdio,
80
+ signal: options.signal,
81
+ });
82
+
83
+ const stdout: ReadableStream<Uint8Array> =
84
+ options.stdout === "piped" && cp.stdout
85
+ ? (Readable.toWeb(cp.stdout) as unknown as ReadableStream<Uint8Array>)
86
+ : emptyReadableStream();
87
+ const stderr: ReadableStream<Uint8Array> =
88
+ options.stderr === "piped" && cp.stderr
89
+ ? (Readable.toWeb(cp.stderr) as unknown as ReadableStream<Uint8Array>)
90
+ : emptyReadableStream();
91
+
92
+ const status = new Promise<{
93
+ success: boolean;
94
+ code?: number;
95
+ signal?: string;
96
+ }>((resolve) => {
97
+ cp.on("close", (code: number | null, signal: string | null) => {
98
+ resolve({
99
+ success: code === 0,
100
+ code: code ?? undefined,
101
+ signal: signal ?? undefined,
102
+ });
103
+ });
104
+ });
105
+
106
+ let stdinStream: WritableStream<Uint8Array> | undefined;
107
+ if (options.stdin === "piped" && cp.stdin) {
108
+ stdinStream = Writable.toWeb(cp.stdin) as WritableStream<Uint8Array>;
109
+ }
110
+
111
+ return {
112
+ get pid() {
113
+ return cp.pid ?? 0;
114
+ },
115
+ stdin: stdinStream,
116
+ stdout,
117
+ stderr,
118
+ status,
119
+ kill(signal?: NodeJS.Signals) {
120
+ cp.kill(signal ?? "SIGTERM");
121
+ },
122
+ ref() {
123
+ if (typeof cp.ref === "function") cp.ref();
124
+ },
125
+ };
126
+ }
127
+
128
+ /**
129
+ * Run a command and wait for it to complete, returning collected stdout/stderr.
130
+ * Use for short-lived commands (e.g. tmux install, kill-server).
131
+ */
132
+ export async function spawnOutput(
133
+ command: string,
134
+ options: SpawnOptions & { stdinInput?: Uint8Array } = {},
135
+ ): Promise<SpawnOutputResult> {
136
+ const { stdinInput, ...spawnOpts } = options;
137
+ const useStdin = stdinInput != null;
138
+ const child = spawn(command, {
139
+ ...spawnOpts,
140
+ stdin: useStdin ? "piped" : spawnOpts.stdin,
141
+ stdout: "piped",
142
+ stderr: "piped",
143
+ });
144
+
145
+ if (useStdin && child.stdin) {
146
+ const writer = child.stdin.getWriter();
147
+ await writer.write(stdinInput);
148
+ await writer.close();
149
+ }
150
+
151
+ const [stdout, stderr, status] = await Promise.all([
152
+ streamToUint8Array(child.stdout),
153
+ streamToUint8Array(child.stderr),
154
+ child.status,
155
+ ]);
156
+
157
+ return {
158
+ stdout,
159
+ stderr,
160
+ success: status.success,
161
+ code: status.code,
162
+ signal: status.signal,
163
+ };
164
+ }
165
+
166
+ async function streamToUint8Array(
167
+ stream: ReadableStream<Uint8Array>,
168
+ ): Promise<Uint8Array> {
169
+ const chunks: Uint8Array[] = [];
170
+ const reader = stream.getReader();
171
+ try {
172
+ while (true) {
173
+ const { done, value } = await reader.read();
174
+ if (done) break;
175
+ if (value) chunks.push(value);
176
+ }
177
+ } finally {
178
+ reader.releaseLock();
179
+ }
180
+ const total = chunks.reduce((n, c) => n + c.length, 0);
181
+ const out = new Uint8Array(total);
182
+ let offset = 0;
183
+ for (const c of chunks) {
184
+ out.set(c, offset);
185
+ offset += c.length;
186
+ }
187
+ return out;
188
+ }
package/src/runtime.ts ADDED
@@ -0,0 +1,89 @@
1
+ type RuntimeEnvironment = 'backend' | 'frontend' | 'unknown';
2
+ type Runtime = 'node' | 'deno' | 'bun' | 'browser' | 'unknown';
3
+
4
+ export function getRuntime(): {runtime: Runtime, environment: RuntimeEnvironment} {
5
+ // Check for Deno
6
+ // @ts-ignore: Deno is added to global scope in Deno environments
7
+ if (typeof Deno !== 'undefined') {
8
+ return { runtime: 'deno', environment: 'backend' };
9
+ }
10
+
11
+ // Check for Bun
12
+ // @ts-ignore: Bun is added to global scope in Bun environments
13
+ if (typeof Bun !== 'undefined') {
14
+ return { runtime: 'bun', environment: 'backend' };
15
+ }
16
+
17
+ // Check for Node.js
18
+ // Node environments have a `process` object with versions
19
+ if (
20
+ typeof process !== 'undefined' &&
21
+ (process as any).versions &&
22
+ (process as any).versions.node
23
+ ) {
24
+ return { runtime: 'node', environment: 'backend' };
25
+ }
26
+
27
+ // Check for Browser
28
+ // Browsers typically have `window` and `document`
29
+ if (
30
+ typeof window !== 'undefined' &&
31
+ // @ts-ignore: document is added to global scope in browser environments
32
+ typeof document !== 'undefined'
33
+ ) {
34
+ return { runtime: 'browser', environment: 'frontend' };
35
+ }
36
+
37
+ return { runtime: 'unknown', environment: 'unknown' };
38
+ }
39
+
40
+ /**
41
+ * Helpers for common process operations.
42
+ */
43
+
44
+ /** Get environment variable. */
45
+ export function getEnv(key: string): string | undefined {
46
+ return process.env[key];
47
+ }
48
+
49
+ /** Set environment variable. */
50
+ export function setEnv(key: string, value: string): void {
51
+ process.env[key] = value;
52
+ }
53
+
54
+ /** CLI arguments (argv without script path). */
55
+ export function args(): string[] {
56
+ return process.argv.slice(2);
57
+ }
58
+
59
+ /** Exit process with code. */
60
+ export function exit(code: number): never {
61
+ return process.exit(code);
62
+ }
63
+
64
+ /** Current working directory. */
65
+ export function cwd(): string {
66
+ return process.cwd();
67
+ }
68
+
69
+ /** Terminal size when available. */
70
+ export function consoleSize(): { columns: number; rows: number } {
71
+ return {
72
+ columns: process.stdout.columns ?? 80,
73
+ rows: (process.stdout as any).rows ?? 24,
74
+ };
75
+ }
76
+
77
+ /** Set process exit code (for graceful shutdown). */
78
+ export function setExitCode(code: number): void {
79
+ process.exitCode = code;
80
+ }
81
+
82
+ /** Check if error is "file/dir not found". */
83
+ export function isNotFoundError(err: unknown): boolean {
84
+ if (err && typeof err === "object") {
85
+ const e = err as { code?: string };
86
+ if (e.code === "ENOENT") return true;
87
+ }
88
+ return false;
89
+ }
@@ -0,0 +1,36 @@
1
+ export type ErrorCode = number;
2
+ export type ErrorMessageMapping = Record<ErrorCode, string>;
3
+
4
+ export type ErrorMessageFxn = (errorCode: ErrorCode) => string;
5
+
6
+ export interface SuccessfulResultMessage {
7
+ success: true;
8
+ message: string;
9
+ }
10
+
11
+ export interface SuccessfulResult<T> {
12
+ success: true;
13
+ result: T;
14
+ }
15
+
16
+ export interface FailedResult {
17
+ success: false;
18
+ errorMessage: string;
19
+ errorCode?: number;
20
+ }
21
+
22
+ export type Result<T> = SuccessfulResult<T> | FailedResult;
23
+
24
+ export type InternalServerErrorResult = FailedResult;
25
+
26
+ /** comes from the `tsoa` package, but we don't want it as a dependency just for this type */
27
+ export interface FieldErrors {
28
+ [name: string]: {
29
+ message: string;
30
+ value?: any;
31
+ };
32
+ }
33
+ export interface ValidateErrorResult {
34
+ message: "Validation Failed";
35
+ details?: FieldErrors;
36
+ }
@@ -0,0 +1,173 @@
1
+ import type { TObject } from "@sinclair/typebox";
2
+ import type { EvmAddress } from "./nominal.ts";
3
+
4
+ export type IntersectObject<T, Obj> = T extends TObject<infer O>
5
+ ? TObject<ShallowMergeIntersects<O & Obj>>
6
+ : never;
7
+
8
+ // TODO: this probably doesn't belong in this file
9
+ export type TransactionTemplate = {
10
+ data: string;
11
+ to: EvmAddress;
12
+ gasPrice: string;
13
+ };
14
+
15
+ /**
16
+ * @description Combines members of an intersection into a readable type.
17
+ *
18
+ * @see {@link https://twitter.com/Riyaadh_Abr/status/1622736576303312899/photo/1}
19
+ * @example
20
+ * MergeIntersects<{ a: string } & { b: string } & { c: number, d: bigint }>
21
+ * => { a: string, b: string, c: number, d: bigint }
22
+ */
23
+ export type MergeIntersects<T> = T extends
24
+ | Record<string, unknown>
25
+ | readonly Record<string, unknown>[]
26
+ ? T extends infer Obj ? { [K in keyof Obj]: MergeIntersects<Obj[K]> }
27
+ : never
28
+ : T;
29
+
30
+ /**
31
+ * Same as the above, but shallow (not recursive)
32
+ * This is useful if you don't want Typescript to expand an underlying type
33
+ *
34
+ * ex: avoid { foo: FooType } turning into { foo: { a: string, b: string } }
35
+ */
36
+ export type ShallowMergeIntersects<T> =
37
+ & {
38
+ [K in keyof T]: T[K];
39
+ }
40
+ & {};
41
+
42
+ /**
43
+ * Flips an object so key are values and values are keys
44
+ *
45
+ * ex: Record<A, B> becomes Partial<Record<B, A>>
46
+ */
47
+ export type FlipObject<T extends Record<any, any>> = {
48
+ [Value in T[keyof T]]: keyof {
49
+ [Key in keyof T as Value extends T[Key] ? Key : never]: any;
50
+ };
51
+ };
52
+
53
+ export type NoUndefinedField<T> = { [P in keyof T]-?: NonNullable<T[P]> };
54
+
55
+ export type ElementOf<T extends readonly any[]> = T extends (infer Elem)[]
56
+ ? Elem
57
+ : never;
58
+ export type ValueOf<T> = T[keyof T];
59
+
60
+ export type Satisfies<Base, T> = T extends Base ? true : false;
61
+
62
+ export type RemoveNeverEntries<T extends Record<any, any>> = {
63
+ [K in keyof T as T[K] extends never ? never : K]: T[K];
64
+ };
65
+ export type IdxOf<T> = { [idx in keyof T]: idx }[any];
66
+
67
+ export type RemoveUnknown<T> = unknown extends T
68
+ ? (T extends unknown ? never : T)
69
+ : T;
70
+
71
+ type ImmutablePrimitive =
72
+ | undefined
73
+ | null
74
+ | boolean
75
+ | string
76
+ | number
77
+ | Function;
78
+ export type Mutable<T> = { -readonly [P in keyof T]: T[P] };
79
+ export type DeepMutable<T> = T extends ImmutablePrimitive ? T
80
+ : T extends ReadonlyArray<infer U> ? Array<DeepMutable<U>>
81
+ : T extends ReadonlySet<infer U> ? Set<DeepMutable<U>>
82
+ : T extends ReadonlyMap<infer K, infer V>
83
+ ? Map<DeepMutable<K>, DeepMutable<V>>
84
+ : T extends Function ? T
85
+ : T extends object ? { -readonly [K in keyof T]: DeepMutable<T[K]> }
86
+ : T;
87
+ export type DeepReadonly<T> = T extends ImmutablePrimitive ? T
88
+ : T extends Array<infer U> ? ReadonlyArray<DeepReadonly<U>>
89
+ : T extends Map<infer K, infer V>
90
+ ? ReadonlyMap<DeepReadonly<K>, DeepReadonly<V>>
91
+ : T extends Set<infer M> ? ReadonlySet<DeepReadonly<M>>
92
+ : {
93
+ readonly [K in keyof T]: DeepReadonly<T[K]>;
94
+ };
95
+
96
+ export type UnionToIntersection<U> =
97
+ (U extends any ? (k: U) => void : never) extends (
98
+ k: infer I extends U,
99
+ ) => void ? I
100
+ : never;
101
+
102
+ const __TypeError = Symbol("OpaqueTypeError");
103
+ type TypeError<BaseType extends string> = BaseType & {
104
+ readonly [__TypeError]: BaseType;
105
+ };
106
+ /**
107
+ * Prints custom error message
108
+ * Taken from https://github.com/wevm/abitype/blob/main/packages/abitype/src/types.ts#L11
109
+ *
110
+ * @param messages - Error message
111
+ * @returns Custom error message
112
+ *
113
+ * @example
114
+ * type Result = Error<'Custom error message'>
115
+ * // ^? type Result = ['Error: Custom error message']
116
+ */
117
+ export type TypeErrorMessage<messages extends string | string[]> =
118
+ messages extends string ? TypeError<messages>
119
+ : {
120
+ [key in keyof messages]: messages[key] extends
121
+ infer message extends string ? TypeError<message>
122
+ : never;
123
+ };
124
+
125
+ /**
126
+ * Types that Typescript allows inside a string template
127
+ */
128
+ export type Stringifiable =
129
+ | string
130
+ | number
131
+ | bigint
132
+ | boolean
133
+ | null
134
+ | undefined;
135
+
136
+ /**
137
+ * Turns an Object whose keys are numbers into an equivalent tuple
138
+ * WARNING: This ONLY works if the keys are consecutive numbers starting from 0
139
+ */
140
+ export type ToTupleSimple<
141
+ T extends { [key: number]: any },
142
+ Acc extends any[] = [],
143
+ > = Acc["length"] extends keyof T ? ToTupleSimple<T, [...Acc, T[Acc["length"]]]>
144
+ : Acc;
145
+
146
+ // Helper type to build a tuple up to a given length `N`, inserting `never` for missing entries
147
+ type BuildTuple<
148
+ T extends { [key: number]: any },
149
+ MaxSize extends number,
150
+ Acc extends any[] = [],
151
+ > = Acc["length"] extends MaxSize ? Acc
152
+ : BuildTuple<
153
+ T,
154
+ MaxSize,
155
+ [...Acc, Acc["length"] extends keyof T ? T[Acc["length"]] : never]
156
+ >;
157
+
158
+ // Helper type to filter out `never` values from a tuple
159
+ type FilterNeverArray<T extends any[]> = T extends [infer First, ...infer Rest]
160
+ ? [First] extends [never] ? FilterNeverArray<Rest>
161
+ : [First, ...FilterNeverArray<Rest>]
162
+ : [];
163
+
164
+ /**
165
+ * Turns an Object whose keys are numbers into an equivalent tuple
166
+ * WARNING: This supports objects that are missing entries (not consecutive numbers starting from 0)
167
+ * However, you MUST specify the maximum value in the object keys instead
168
+ * This is required since Typescript doesn't easily support artihmetic at the type level
169
+ */
170
+ export type ToTupleComplex<
171
+ T extends { [key: number]: any },
172
+ MaxSize extends number,
173
+ > = FilterNeverArray<BuildTuple<T, MaxSize>>;
@@ -0,0 +1,6 @@
1
+ export type * from "./misc.ts";
2
+ export type * from "./json-query.ts";
3
+ export type * from "./nominal.ts";
4
+ export * from "./typebox-helpers.ts";
5
+ export * from "./utils.ts";
6
+ export * from "./validators/mod.ts";
@@ -0,0 +1,168 @@
1
+ import type { FastFlavor } from "@coderspirit/nominal";
2
+
3
+ /**
4
+ * TODO: remove any instance of this in the codebase
5
+ * Note: often this is uncertainty between HexString0x and HexStringNo0x
6
+ */
7
+ export type UnknownFormat = string;
8
+
9
+ export type URI = FastFlavor<string, "Uri">;
10
+
11
+ export type Caip2 = FastFlavor<string, "Caip2">;
12
+ /**
13
+ * TODO: probably best to make this more granular to different cryptographic schemes
14
+ * esp. since some return 0x and others don't
15
+ */
16
+ export type EvmSignature = FastFlavor<HexString0x, "EvmSignature">;
17
+ export type GenericSignature = FastFlavor<string, "OtherSignature">;
18
+ export type Signature =
19
+ | EvmSignature
20
+ | GenericSignature
21
+ | MidnightSignature
22
+ ;
23
+
24
+ export type VersionString = `${number}.${number}.${number}`;
25
+
26
+ // TODO: should probably differentiate between block numbers of different networks
27
+ // and maybe even Paima block number / emulated block number
28
+ export type EffectstreamBlockNumber = FastFlavor<number, "EffectstreamBlockNumber">;
29
+ export type EvmBlockNumber = FastFlavor<number, "EvmBlockNumber">;
30
+ export type NtpBlockNumber = FastFlavor<number, "NtpBlockNumber">;
31
+ export type MidnightBlockNumber = FastFlavor<number, "MidnightBlockNumber">;
32
+ export type CardanoBlockNumber = FastFlavor<number, "CardanoBlockNumber">;
33
+ export type BitcoinBlockNumber = FastFlavor<number, "BitcoinBlockNumber">;
34
+
35
+ export type BlockNumber =
36
+ | EffectstreamBlockNumber
37
+ | EvmBlockNumber
38
+ | NtpBlockNumber
39
+ | MidnightBlockNumber
40
+ | CardanoBlockNumber
41
+ | BitcoinBlockNumber;
42
+
43
+ /**
44
+ * recall: slots may be empty, so absolute slot number is not usually equal to block number
45
+ */
46
+ export type AbsoluteSlotNumber = FastFlavor<number, "AbsoluteSlotNumber">;
47
+ export type RelativeSlotNumber = FastFlavor<number, "RelativeSlotNumber">;
48
+ export type EpochNumber = FastFlavor<number, "EpochNumber">;
49
+
50
+ // don't make it a flavor so it can easily be assigned to/from flavors
51
+ export type HexString0x = `0x${string}`;
52
+ export type HexStringNo0x = FastFlavor<string, "HexStringNo0x">;
53
+ export type Base64String = FastFlavor<string, "Base64String">;
54
+
55
+ // TODO: change these to brands later
56
+ export type IntervalMs = FastFlavor<number, "IntervalMs">;
57
+ export type IntervalSec = FastFlavor<number, "IntervalSec">;
58
+ export type TimestampMs = FastFlavor<number, "TimestampMs">;
59
+ export type TimestampMsStr = FastFlavor<string, "TimestampMsStr">;
60
+ export type TimestampSec = FastFlavor<number, "TimestampSec">;
61
+ export type TimestampIso8601 = FastFlavor<string, "TimestampIso8601">;
62
+
63
+ export type AlgorandBlockHash = FastFlavor<UnknownFormat, "AlgorandBlockHash">;
64
+ export type AlgorandTxHash = FastFlavor<UnknownFormat, "AlgorandTxHash">;
65
+ // TODO: this is close to /^[A-Z2-7]{58}$/
66
+ export type AlgorandAddress = FastFlavor<string, "AlgorandAddress">;
67
+
68
+ export type AvailBlockHash = FastFlavor<UnknownFormat, "AvailBlockHash">;
69
+ export type AvailTxHash = FastFlavor<UnknownFormat, "AvailTxHash">;
70
+ export type AvailAddress = SubstrateAddress;
71
+
72
+ export type CardanoBlockHash = FastFlavor<string, "CardanoBlockHash">;
73
+ export type CardanoTxHash = FastFlavor<string, "CardanoTxHash">;
74
+ // TODO: bech32 string
75
+ export type CardanoAddress = FastFlavor<string, "CardanoAddress">;
76
+ export type CardanoCredential = FastFlavor<string, "CardanoCredential">;
77
+ export type CardanoPolicyId = FastFlavor<string, "CardanoPolicyId">;
78
+ export type CardanoAssetName = FastFlavor<string, "CardanoAssetName">;
79
+ export type CardanoCip14Fingerprint = FastFlavor<
80
+ string,
81
+ "CardanoCip14Fingerprint"
82
+ >;
83
+ export type CardanoPoolId = FastFlavor<string, "CardanoPoolId">;
84
+ export type CardanoAmountLovelace = FastFlavor<string, "CardanoAmountLovelace">;
85
+
86
+ export type NtpBlockHash = FastFlavor<string, "NtpBlockHash">;
87
+ export type NtpTxHash = FastFlavor<string, "NtpTxHash">; // TODO: is this needed?
88
+ export type NtpAddress = FastFlavor<string, "NtpAddress">; // TODO: is this needed?
89
+
90
+ export type EvmBlockHash = FastFlavor<HexString0x, "EvmBlockHash">;
91
+ export type EvmTxHash = FastFlavor<HexString0x, "EvmTxHash">;
92
+ export type EvmAddress = FastFlavor<HexString0x, "EvmAddress">;
93
+ export type EvmSelector = FastFlavor<HexString0x, "EvmSelector">;
94
+ export type Evm4ByteSelector = FastFlavor<HexString0x, "Evm4ByteSelector">;
95
+
96
+ export type MidnightBlockHash = FastFlavor<HexString0x, "MidnightBlockHash">;
97
+ export type MidnightTxHash = FastFlavor<HexString0x, "MidnightTxHash">;
98
+ export type MidnightAddress = FastFlavor<string, "MidnightAddress">;
99
+ export type MidnightSignature = FastFlavor<string, "MidnightSignature">;
100
+
101
+ export type MinaBlockHash = FastFlavor<UnknownFormat, "MinaBlockHash">;
102
+ export type MinaTxHash = FastFlavor<UnknownFormat, "MinaTxHash">;
103
+ export type MinaAddress = FastFlavor<string, "MinaAddress">;
104
+
105
+ export type PolkadotAddress = SubstrateAddress;
106
+ export type PolkadotBlockHash = FastFlavor<UnknownFormat, "PolkadotBlockHash">;
107
+ export type PolkadotTxHash = FastFlavor<UnknownFormat, "PolkadotTxHash">;
108
+
109
+ // TODO: close to the regex /^[1-9A-HJ-NP-Za-km-z]{47,48}$/
110
+ export type SubstrateAddress = FastFlavor<string, "SubstrateAddress">;
111
+
112
+ export type NearAddress = FastFlavor<string, "NearAddress">;
113
+
114
+ export type BitcoinBlockHash = FastFlavor<string, "BitcoinBlockHash">;
115
+ export type BitcoinTxId = FastFlavor<string, "BitcoinTxId">;
116
+ export type BitcoinAddress = FastFlavor<string, "BitcoinAddress">;
117
+
118
+ export type WalletAddress =
119
+ | AlgorandAddress
120
+ | AvailAddress
121
+ | CardanoAddress
122
+ | EvmAddress
123
+ | MidnightAddress
124
+ | MinaAddress
125
+ | SubstrateAddress
126
+ | BitcoinAddress;
127
+
128
+ /**
129
+ * TODO: probably best to make this more granular to different cryptographic schemes
130
+ */
131
+ export type EvmPrivateKey = FastFlavor<HexString0x, "EvmPrivateKey">;
132
+ export type GenericPrivateKey = FastFlavor<string, "GenericPrivateKey">;
133
+ export type PrivateKey =
134
+ | EvmPrivateKey
135
+ | GenericPrivateKey;
136
+
137
+ export type EffectstreamTxHash = FastFlavor<HexString0x, "EffectstreamTxHash">;
138
+ export type TxHash =
139
+ | AlgorandTxHash
140
+ | AvailTxHash
141
+ | CardanoTxHash
142
+ | EvmTxHash
143
+ | MidnightTxHash
144
+ | MinaTxHash
145
+ | EffectstreamTxHash
146
+ | NtpTxHash;
147
+ // | SubstrateTxHash;
148
+
149
+ export type EffectstreamBlockHash = FastFlavor<HexString0x, "EffectstreamBlockHash">;
150
+ export type BlockHash =
151
+ | AlgorandBlockHash
152
+ | AvailBlockHash
153
+ | CardanoBlockHash
154
+ | EvmBlockHash
155
+ | MidnightBlockHash
156
+ | MinaBlockHash
157
+ | EffectstreamBlockHash
158
+ | NtpBlockHash
159
+ | BitcoinBlockHash;
160
+ // | SubstrateBlockHash;
161
+
162
+ export type NtpPageJson = FastFlavor<string, "NTPPageJson">;
163
+ export type EvmRpcPageJson = FastFlavor<string, "EvmRpcPageJson">;
164
+ export type CarpCursorJson = FastFlavor<string, "CarpCursorJson">;
165
+ export type MidnightEncodedStateJson = FastFlavor<
166
+ string,
167
+ "MidnightEncodedStateJson"
168
+ >;