Skip to content

Commit d46f081

Browse files
committed
Document @solana/rpc-types with TypeDoc
1 parent 02bd005 commit d46f081

12 files changed

+586
-100
lines changed

packages/rpc-graphql/src/resolvers/block.ts

+9-4
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,15 @@ export const resolveBlock = (fieldName?: string) => {
8383
})
8484
] = data[0];
8585
} else if (typeof data === 'object') {
86-
const jsonParsedData = data;
87-
jsonParsedData.message.instructions = mapJsonParsedInstructions(
88-
jsonParsedData.message.instructions,
89-
) as unknown as (typeof jsonParsedData)['message']['instructions'];
86+
const jsonParsedData: typeof data = {
87+
...data,
88+
message: {
89+
...data.message,
90+
instructions: mapJsonParsedInstructions(
91+
data.message.instructions,
92+
) as unknown as (typeof jsonParsedData)['message']['instructions'],
93+
},
94+
};
9095

9196
const loadedInnerInstructions = loadedTransaction.meta?.innerInstructions;
9297
if (loadedInnerInstructions) {

packages/rpc-types/src/account-info.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ import type {
99
import type { Lamports } from './lamports';
1010

1111
export type AccountInfoBase = Readonly<{
12-
/** indicates if the account contains a program (and is strictly read-only) */
12+
/** Indicates if the account contains a program (and is strictly read-only) */
1313
executable: boolean;
14-
/** number of lamports assigned to this account */
14+
/** Number of {@link Lamports} assigned to this account */
1515
lamports: Lamports;
16-
/** pubkey of the program this account has been assigned to */
16+
/** Address of the program this account has been assigned to */
1717
owner: Address;
18-
/** the epoch at which this account will next owe rent */
18+
/** The epoch at which this account will next owe rent */
1919
rentEpoch: bigint;
20-
/** the size of the account data in bytes (excluding the 128 bytes of header) */
20+
/** The size of the account data in bytes (excluding the 128 bytes of header) */
2121
space: bigint;
2222
}>;
2323

packages/rpc-types/src/blockhash.ts

+107
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,24 @@ function getMemoizedBase58Decoder(): Decoder<string> {
3131
return memoizedBase58Decoder;
3232
}
3333

34+
/**
35+
* A type guard that returns `true` if the input string conforms to the {@link Blockhash} type, and
36+
* refines its type for use in your program.
37+
*
38+
* @example
39+
* ```ts
40+
* import { isBlockhash } from '@solana/rpc-types';
41+
*
42+
* if (isBlockhash(blockhash)) {
43+
* // At this point, `blockhash` has been refined to a
44+
* // `Blockhash` that can be used with the RPC.
45+
* const { value: isValid } = await rpc.isBlockhashValid(blockhash).send();
46+
* setBlockhashIsFresh(isValid);
47+
* } else {
48+
* setError(`${blockhash} is not a blockhash`);
49+
* }
50+
* ```
51+
*/
3452
export function isBlockhash(putativeBlockhash: string): putativeBlockhash is Blockhash {
3553
// Fast-path; see if the input string is of an acceptable length.
3654
if (
@@ -51,6 +69,31 @@ export function isBlockhash(putativeBlockhash: string): putativeBlockhash is Blo
5169
return true;
5270
}
5371

72+
/**
73+
* From time to time you might acquire a string, that you expect to validate as a blockhash, from an
74+
* untrusted network API or user input. Use this function to assert that such an arbitrary string is
75+
* a base58-encoded blockhash.
76+
*
77+
* @example
78+
* ```ts
79+
* import { assertIsBlockhash } from '@solana/rpc-types';
80+
*
81+
* // Imagine a function that determines whether a blockhash is fresh when a user submits a form.
82+
* function handleSubmit() {
83+
* // We know only that what the user typed conforms to the `string` type.
84+
* const blockhash: string = blockhashInput.value;
85+
* try {
86+
* // If this type assertion function doesn't throw, then
87+
* // Typescript will upcast `blockhash` to `Blockhash`.
88+
* assertIsBlockhash(blockhash);
89+
* // At this point, `blockhash` is a `Blockhash` that can be used with the RPC.
90+
* const { value: isValid } = await rpc.isBlockhashValid(blockhash).send();
91+
* } catch (e) {
92+
* // `blockhash` turned out not to be a base58-encoded blockhash
93+
* }
94+
* }
95+
* ```
96+
*/
5497
export function assertIsBlockhash(putativeBlockhash: string): asserts putativeBlockhash is Blockhash {
5598
// Fast-path; see if the input string is of an acceptable length.
5699
if (
@@ -74,21 +117,85 @@ export function assertIsBlockhash(putativeBlockhash: string): asserts putativeBl
74117
}
75118
}
76119

120+
/**
121+
* Combines _asserting_ that a string is a blockhash with _coercing_ it to the {@link Blockhash}
122+
* type. It's most useful with untrusted input.
123+
*
124+
* @example
125+
* ```ts
126+
* import { blockhash } from '@solana/rpc-types';
127+
*
128+
* const { value: isValid } = await rpc.isBlockhashValid(blockhash(blockhashFromUserInput)).send();
129+
* ```
130+
*
131+
* > [!TIP]
132+
* > When starting from a known-good blockhash as a string, it's more efficient to typecast it
133+
* rather than to use the {@link blockhash} helper, because the helper unconditionally performs
134+
* validation on its input.
135+
* >
136+
* > ```ts
137+
* > import { Blockhash } from '@solana/rpc-types';
138+
* >
139+
* > const blockhash = 'ABmPH5KDXX99u6woqFS5vfBGSNyKG42SzpvBMWWqAy48' as Blockhash;
140+
* > ```
141+
*/
77142
export function blockhash(putativeBlockhash: string): Blockhash {
78143
assertIsBlockhash(putativeBlockhash);
79144
return putativeBlockhash;
80145
}
81146

147+
/**
148+
* Returns an encoder that you can use to encode a base58-encoded blockhash to a byte array.
149+
*
150+
* @example
151+
* ```ts
152+
* import { getBlockhashEncoder } from '@solana/rpc-types';
153+
*
154+
* const blockhash = 'ABmPH5KDXX99u6woqFS5vfBGSNyKG42SzpvBMWWqAy48' as Blockhash;
155+
* const blockhashEncoder = getBlockhashEncoder();
156+
* const blockhashBytes = blockhashEncoder.encode(blockhash);
157+
* // Uint8Array(32) [
158+
* // 136, 123, 44, 249, 43, 19, 60, 14,
159+
* // 144, 16, 168, 241, 121, 111, 70, 232,
160+
* // 186, 26, 140, 202, 213, 64, 231, 82,
161+
* // 179, 66, 103, 237, 52, 117, 217, 93
162+
* // ]
163+
* ```
164+
*/
82165
export function getBlockhashEncoder(): FixedSizeEncoder<Blockhash, 32> {
83166
return transformEncoder(fixEncoderSize(getMemoizedBase58Encoder(), 32), putativeBlockhash =>
84167
blockhash(putativeBlockhash),
85168
);
86169
}
87170

171+
/**
172+
* Returns a decoder that you can use to convert an array of 32 bytes representing a blockhash to
173+
* the base58-encoded representation of that blockhash.
174+
*
175+
* @example
176+
* ```ts
177+
* import { getBlockhashDecoder } from '@solana/rpc-types';
178+
*
179+
* const blockhashBytes = new Uint8Array([
180+
* 136, 123, 44, 249, 43, 19, 60, 14,
181+
* 144, 16, 168, 241, 121, 111, 70, 232,
182+
* 186, 26, 140, 202, 213, 64, 231, 82,
183+
* 179, 66, 103, 237, 52, 117, 217, 93
184+
* ]);
185+
* const blockhashDecoder = getBlockhashDecoder();
186+
* const blockhash = blockhashDecoder.decode(blockhashBytes); // ABmPH5KDXX99u6woqFS5vfBGSNyKG42SzpvBMWWqAy48
187+
* ```
188+
*/
88189
export function getBlockhashDecoder(): FixedSizeDecoder<Blockhash, 32> {
89190
return fixDecoderSize(getMemoizedBase58Decoder(), 32) as FixedSizeDecoder<Blockhash, 32>;
90191
}
91192

193+
/**
194+
* Returns a codec that you can use to encode from or decode to a base-58 encoded blockhash.
195+
*
196+
* @see {@link getBlockhashDecoder}
197+
* @see {@link getBlockhashEncoder}
198+
*/
92199
export function getBlockhashCodec(): FixedSizeCodec<Blockhash, Blockhash, 32> {
93200
return combineCodec(getBlockhashEncoder(), getBlockhashDecoder());
94201
}

packages/rpc-types/src/cluster-url.ts

+3
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@ export type DevnetUrl = string & { '~cluster': 'devnet' };
33
export type TestnetUrl = string & { '~cluster': 'testnet' };
44
export type ClusterUrl = DevnetUrl | MainnetUrl | TestnetUrl | string;
55

6+
/** Given a URL casts it to a type that is only accepted where mainnet URLs are expected. */
67
export function mainnet(putativeString: string): MainnetUrl {
78
return putativeString as MainnetUrl;
89
}
10+
/** Given a URL casts it to a type that is only accepted where devnet URLs are expected. */
911
export function devnet(putativeString: string): DevnetUrl {
1012
return putativeString as DevnetUrl;
1113
}
14+
/** Given a URL casts it to a type that is only accepted where testnet URLs are expected. */
1215
export function testnet(putativeString: string): TestnetUrl {
1316
return putativeString as TestnetUrl;
1417
}

packages/rpc-types/src/commitment.ts

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import { SOLANA_ERROR__INVARIANT_VIOLATION__SWITCH_MUST_BE_EXHAUSTIVE, SolanaError } from '@solana/errors';
22

3+
/**
4+
* A union of all possible commitment statuses -- each a measure of the network confirmation and
5+
* stake levels on a particular block.
6+
*
7+
* Read more about the statuses themselves, [here](https://docs.solana.com/cluster/commitments).
8+
*/
39
export type Commitment = 'confirmed' | 'finalized' | 'processed';
410

511
function getCommitmentScore(commitment: Commitment): number {

packages/rpc-types/src/index.ts

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
/**
2+
* This package defines types for values used in the
3+
* [Solana JSON-RPC](https://docs.solana.com/api/http) and a series of helpers for working with
4+
* them. It can be used standalone, but it is also exported as part of Kit
5+
* [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).
6+
*
7+
* @packageDocumentation
8+
*/
19
export * from './account-filters';
210
export * from './account-info';
311
export * from './blockhash';

packages/rpc-types/src/lamports.ts

+114
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ import {
1111
import { getU64Decoder, getU64Encoder, NumberCodec, NumberDecoder, NumberEncoder } from '@solana/codecs-numbers';
1212
import { SOLANA_ERROR__LAMPORTS_OUT_OF_RANGE, SolanaError } from '@solana/errors';
1313

14+
/**
15+
* Represents an integer value denominated in Lamports (ie. $1 \times 10^{-9}$ ◎).
16+
*
17+
* It is represented as a `bigint` in client code and an `u64` in server code.
18+
*/
1419
export type Lamports = bigint & { readonly __brand: unique symbol };
1520

1621
// Largest possible value to be represented by a u64
@@ -29,37 +34,134 @@ function getMemoizedU64Decoder(): FixedSizeDecoder<bigint, 8> {
2934
return memoizedU64Decoder;
3035
}
3136

37+
/**
38+
* This is a type guard that accepts a `bigint` as input. It will both return `true` if the integer
39+
* conforms to the {@link Lamports} type and will refine the type for use in your program.
40+
*
41+
* @example
42+
* ```ts
43+
* import { isLamports } from '@solana/rpc-types';
44+
*
45+
* if (isLamports(lamports)) {
46+
* // At this point, `lamports` has been refined to a
47+
* // `Lamports` that can be used anywhere Lamports are expected.
48+
* await transfer(fromAddress, toAddress, lamports);
49+
* } else {
50+
* setError(`${lamports} is not a quantity of Lamports`);
51+
* }
52+
* ```
53+
*/
3254
export function isLamports(putativeLamports: bigint): putativeLamports is Lamports {
3355
return putativeLamports >= 0 && putativeLamports <= maxU64Value;
3456
}
3557

58+
/**
59+
* Lamport values returned from the RPC API conform to the type {@link Lamports}. You can use a
60+
* value of that type wherever a quantity of Lamports is expected.
61+
*
62+
* @example
63+
* From time to time you might acquire a number that you expect to be a quantity of Lamports, from
64+
* an untrusted network API or user input. To assert that such an arbitrary number is usable as a
65+
* quantity of Lamports, use this function.
66+
*
67+
* ```ts
68+
* import { assertIsLamports } from '@solana/rpc-types';
69+
*
70+
* // Imagine a function that creates a transfer instruction when a user submits a form.
71+
* function handleSubmit() {
72+
* // We know only that what the user typed conforms to the `number` type.
73+
* const lamports: number = parseInt(quantityInput.value, 10);
74+
* try {
75+
* // If this type assertion function doesn't throw, then
76+
* // Typescript will upcast `lamports` to `Lamports`.
77+
* assertIsLamports(lamports);
78+
* // At this point, `lamports` is a `Lamports` that can be used anywhere Lamports are expected.
79+
* await transfer(fromAddress, toAddress, lamports);
80+
* } catch (e) {
81+
* // `lamports` turned out not to validate as a quantity of Lamports.
82+
* }
83+
* }
84+
* ```
85+
*/
3686
export function assertIsLamports(putativeLamports: bigint): asserts putativeLamports is Lamports {
3787
if (putativeLamports < 0 || putativeLamports > maxU64Value) {
3888
throw new SolanaError(SOLANA_ERROR__LAMPORTS_OUT_OF_RANGE);
3989
}
4090
}
4191

92+
/**
93+
* This helper combines _asserting_ that a number is a possible number of {@link Lamports} with
94+
* _coercing_ it to the {@link Lamports} type. It's best used with untrusted input.
95+
*
96+
* @example
97+
* ```ts
98+
* import { lamports } from '@solana/rpc-types';
99+
*
100+
* await transfer(address(fromAddress), address(toAddress), lamports(100000n));
101+
* ```
102+
*/
42103
export function lamports(putativeLamports: bigint): Lamports {
43104
assertIsLamports(putativeLamports);
44105
return putativeLamports;
45106
}
46107

47108
type ExtractAdditionalProps<T, U> = Omit<T, keyof U>;
48109

110+
/**
111+
* Returns an encoder that you can use to encode a 64-bit {@link Lamports} value to 8 bytes in
112+
* little endian order.
113+
*/
49114
export function getDefaultLamportsEncoder(): FixedSizeEncoder<Lamports, 8> {
50115
return getLamportsEncoder(getMemoizedU64Encoder());
51116
}
52117

118+
/**
119+
* Returns an encoder that you can use to encode a {@link Lamports} value to a byte array.
120+
*
121+
* You must supply a number decoder that will determine how encode the numeric value.
122+
*
123+
* @example
124+
* ```ts
125+
* import { getLamportsEncoder } from '@solana/rpc-types';
126+
* import { getU16Encoder } from '@solana/codecs-numbers';
127+
*
128+
* const lamports = lamports(256n);
129+
* const lamportsEncoder = getLamportsEncoder(getU16Encoder());
130+
* const lamportsBytes = lamportsEncoder.encode(lamports);
131+
* // Uint8Array(2) [ 0, 1 ]
132+
* ```
133+
*/
53134
export function getLamportsEncoder<TEncoder extends NumberEncoder>(
54135
innerEncoder: TEncoder,
55136
): Encoder<Lamports> & ExtractAdditionalProps<TEncoder, NumberEncoder> {
56137
return innerEncoder;
57138
}
58139

140+
/**
141+
* Returns a decoder that you can use to decode a byte array representing a 64-bit little endian
142+
* number to a {@link Lamports} value.
143+
*/
59144
export function getDefaultLamportsDecoder(): FixedSizeDecoder<Lamports, 8> {
60145
return getLamportsDecoder(getMemoizedU64Decoder());
61146
}
62147

148+
/**
149+
* Returns a decoder that you can use to convert an array of bytes representing a number to a
150+
* {@link Lamports} value.
151+
*
152+
* You must supply a number decoder that will determine how many bits to use to decode the numeric
153+
* value.
154+
*
155+
* @example
156+
* ```ts
157+
* import { getLamportsDecoder } from '@solana/rpc-types';
158+
* import { getU16Decoder } from '@solana/codecs-numbers';
159+
*
160+
* const lamportsBytes = new Uint8Array([ 0, 1 ]);
161+
* const lamportsDecoder = getLamportsDecoder(getU16Decoder());
162+
* const lamports = lamportsDecoder.decode(lamportsBytes); // lamports(256n)
163+
* ```
164+
*/
63165
export function getLamportsDecoder<TDecoder extends NumberDecoder>(
64166
innerDecoder: TDecoder,
65167
): Decoder<Lamports> & ExtractAdditionalProps<TDecoder, NumberDecoder> {
@@ -68,10 +170,22 @@ export function getLamportsDecoder<TDecoder extends NumberDecoder>(
68170
) as Decoder<Lamports> & ExtractAdditionalProps<TDecoder, NumberDecoder>;
69171
}
70172

173+
/**
174+
* Returns a codec that you can use to encode from or decode to a 64-bit {@link Lamports} value.
175+
*
176+
* @see {@link getDefaultLamportsDecoder}
177+
* @see {@link getDefaultLamportsEncoder}
178+
*/
71179
export function getDefaultLamportsCodec(): FixedSizeCodec<Lamports, Lamports, 8> {
72180
return combineCodec(getDefaultLamportsEncoder(), getDefaultLamportsDecoder());
73181
}
74182

183+
/**
184+
* Returns a codec that you can use to encode from or decode to {@link Lamports} value.
185+
*
186+
* @see {@link getLamportsDecoder}
187+
* @see {@link getLamportsEncoder}
188+
*/
75189
export function getLamportsCodec<TCodec extends NumberCodec>(
76190
innerCodec: TCodec,
77191
): Codec<Lamports, Lamports> & ExtractAdditionalProps<TCodec, NumberCodec> {

0 commit comments

Comments
 (0)