Skip to content

Commit

Permalink
Add message schema validators
Browse files Browse the repository at this point in the history
  • Loading branch information
aryzing committed May 28, 2024
1 parent f51b9f3 commit 8585ac9
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 49 deletions.
18 changes: 18 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
"jsontokens": "4.0.1",
"lodash.omit": "4.5.0"
},
"peerDependencies": {
"zod": ">=3.23.8"
},
"devDependencies": {
"@types/jest": "^29.2.6",
"@types/lodash.omit": "4.5.9",
Expand Down
14 changes: 8 additions & 6 deletions src/addresses/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { z } from 'zod';
import type { RequestOptions, RequestPayload } from '../types';

export enum AddressPurpose {
Expand All @@ -20,12 +21,13 @@ export enum AddressType {
stacks = 'stacks',
}

export interface Address {
address: string;
publicKey: string;
purpose?: AddressPurpose;
addressType?: AddressType;
}
export const addressSchema = z.object({
address: z.string(),
publicKey: z.string(),
purpose: z.nativeEnum(AddressPurpose),
addressType: z.nativeEnum(AddressType),
});
export type Address = z.infer<typeof addressSchema>;

export interface GetAddressResponse {
addresses: Address[];
Expand Down
97 changes: 54 additions & 43 deletions src/request/types/btcMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,54 @@
* Represents the types and interfaces related to BTC methods.
*/

import { Address, AddressPurpose } from '../../addresses';
import { MethodParamsAndResult } from '../../types';

type GetInfoResult = {
version: number | string;
methods?: Array<string>;
supports?: Array<string>;
};

export type GetInfo = MethodParamsAndResult<null, GetInfoResult>;

type GetAddressesParams = {
import { z } from 'zod';
import { Address, AddressPurpose, addressSchema } from '../../addresses';
import { MethodParamsAndResult, rpcRequestMessageSchema } from '../../types';

export const getInfoMethodName = 'getInfo';
export const getInfoParamsSchema = z.undefined();
export const getInfoResultSchema = z.object({
version: z.union([z.number(), z.string()]),
methods: z.array(z.string()).optional(),
supports: z.array(z.string()),
});
export const getInfoSchema = rpcRequestMessageSchema.extend({
method: z.literal(getInfoMethodName),
params: getInfoParamsSchema,
id: z.string(),
});
export type GetInfo = MethodParamsAndResult<
z.infer<typeof getInfoParamsSchema>,
z.infer<typeof getInfoResultSchema>
>;

export const getAddressesMethodName = 'getAddresses';
export const getAddressesParamsSchema = z.object({
/**
* The purposes for which to generate addresses.
* possible values are "payment", "ordinals", ...
*/
purposes: Array<AddressPurpose>;
purposes: z.array(z.nativeEnum(AddressPurpose)),
/**
* a message to be displayed to the user in the request prompt.
* A message to be displayed to the user in the request prompt.
*/
message?: string;
};

/**
* The addresses generated for the given purposes.
*/
type GetAddressesResult = {
addresses: Array<Address>;
};

export type GetAddresses = MethodParamsAndResult<GetAddressesParams, GetAddressesResult>;
message: z.string().optional(),
});
export const getAddressesResultSchema = z.object({
/**
* The addresses generated for the given purposes.
*/
addresses: z.array(addressSchema),
});
export const getAddressesRequestMessageSchema = rpcRequestMessageSchema.extend({
method: z.literal(getAddressesMethodName),
params: getAddressesParamsSchema,
id: z.string(),
});
export type GetAddresses = MethodParamsAndResult<
z.infer<typeof getAddressesParamsSchema>,
z.infer<typeof getAddressesResultSchema>
>;

export type SignMessageParams = {
/**
Expand Down Expand Up @@ -124,21 +141,15 @@ export type SignPsbtResult = {

export type SignPsbt = MethodParamsAndResult<SignPsbtParams, SignPsbtResult>;

export type GetAccountsParams = {
/**
* The purposes for which to generate addresses.
* possible values are "payment", "ordinals", ...
*/
purposes: Array<AddressPurpose>;
/**
* a message to be displayed to the user in the request prompt.
*/
/**
* a message to be displayed to the user in the request prompt.
*/
message?: string;
};

export type GetAccountResult = Address[];

export type GetAccounts = MethodParamsAndResult<GetAccountsParams, GetAccountResult>;
export const getAccountsMethodName = 'getAccounts';
export const getAccountsParamsSchema = getAddressesParamsSchema;
export const getAccountsResultSchema = z.array(addressSchema);
export const getAccountsRequestMessageSchema = rpcRequestMessageSchema.extend({
method: z.literal(getAccountsMethodName),
params: getAccountsParamsSchema,
id: z.string(),
});
export type GetAccounts = MethodParamsAndResult<
z.infer<typeof getAccountsParamsSchema>,
z.infer<typeof getAccountsResultSchema>
>;
10 changes: 10 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { z } from 'zod';
import type { BitcoinProvider } from './provider';
import { Requests, Return } from './request';

Expand All @@ -24,6 +25,15 @@ export interface RequestOptions<Payload extends RequestPayload, Response> {

// RPC Request and Response types

export const rpcRequestMessageSchema = z.object({
jsonrpc: z.literal('2.0'),
method: z.string(),
params: z.union([z.array(z.unknown()), z.object({}).passthrough()]).optional(),
id: z.union([z.string(), z.number(), z.null()]).optional(),
});

export type RpcRequestMessage = z.infer<typeof rpcRequestMessageSchema>;

export type RpcId = string | null;

export interface RpcBase {
Expand Down

0 comments on commit 8585ac9

Please sign in to comment.