Skip to content

Commit 6487af5

Browse files
authored
add event node support (#985)
1 parent 6d3cb3b commit 6487af5

29 files changed

Lines changed: 517 additions & 18 deletions
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
"@codama/errors": patch
3+
"@codama/node-types": minor
4+
"@codama/nodes-from-anchor": patch
5+
"@codama/nodes": minor
6+
"@codama/visitors-core": patch
7+
---
8+
9+
Add new `EventNode` to `ProgramNode` and update the Anchor adapter accordingly.

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,15 @@ Feel free to PR your own visitor here for others to discover. Note that they are
114114

115115
### Generates program clients
116116

117-
| Visitor | Description | Maintainer |
118-
| ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
119-
| `@codama/renderers-go` ([docs](https://github.com/codama-idl/renderers-go)) | Generates a Go client compatible with [the Solana Go SDK](https://github.com/gagliardetto/solana-go). | [Sonic](hhttps://github.com/sonicfromnewyoke)|
120-
| `@codama/renderers-js` ([docs](https://github.com/codama-idl/renderers-js)) | Generates a JavaScript client compatible with [Solana Kit](https://www.solanakit.com/). | [Anza](https://www.anza.xyz/) |
121-
| `@codama/renderers-js-umi` ([docs](https://github.com/codama-idl/renderers-js-umi)) | Generates a JavaScript client compatible with [the Umi framework](https://developers.metaplex.com/umi). | [Metaplex](https://www.metaplex.com/) |
122-
| `@codama/renderers-rust` ([docs](https://github.com/codama-idl/renderers-rust)) | Generates a Rust client compatible with [the Solana SDK](https://github.com/anza-xyz/solana-sdk). | [Anza](https://www.anza.xyz/) |
123-
| `@codama/renderers-vixen-parser` ([docs](https://github.com/codama-idl/renderers-vixen-parser)) | Generates [Yellowstone](https://github.com/rpcpool/yellowstone-grpc) account and instruction parsers. | [Triton One](https://triton.one/) |
124-
| `@limechain/codama-dart` ([docs](https://github.com/limechain/codama-dart)) | Generates a Dart client. | [LimeChain](https://github.com/limechain/) |
125-
| `codama-py` ([docs](https://github.com/Solana-ZH/codama-py)) | Generates a Python client. | [Solar](https://github.com/Solana-ZH) |
117+
| Visitor | Description | Maintainer |
118+
| ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
119+
| `@codama/renderers-go` ([docs](https://github.com/codama-idl/renderers-go)) | Generates a Go client compatible with [the Solana Go SDK](https://github.com/gagliardetto/solana-go). | [Sonic](hhttps://github.com/sonicfromnewyoke) |
120+
| `@codama/renderers-js` ([docs](https://github.com/codama-idl/renderers-js)) | Generates a JavaScript client compatible with [Solana Kit](https://www.solanakit.com/). | [Anza](https://www.anza.xyz/) |
121+
| `@codama/renderers-js-umi` ([docs](https://github.com/codama-idl/renderers-js-umi)) | Generates a JavaScript client compatible with [the Umi framework](https://developers.metaplex.com/umi). | [Metaplex](https://www.metaplex.com/) |
122+
| `@codama/renderers-rust` ([docs](https://github.com/codama-idl/renderers-rust)) | Generates a Rust client compatible with [the Solana SDK](https://github.com/anza-xyz/solana-sdk). | [Anza](https://www.anza.xyz/) |
123+
| `@codama/renderers-vixen-parser` ([docs](https://github.com/codama-idl/renderers-vixen-parser)) | Generates [Yellowstone](https://github.com/rpcpool/yellowstone-grpc) account and instruction parsers. | [Triton One](https://triton.one/) |
124+
| `@limechain/codama-dart` ([docs](https://github.com/limechain/codama-dart)) | Generates a Dart client. | [LimeChain](https://github.com/limechain/) |
125+
| `codama-py` ([docs](https://github.com/Solana-ZH/codama-py)) | Generates a Python client. | [Solar](https://github.com/Solana-ZH) |
126126

127127
### Provides utility
128128

packages/errors/src/codes.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export const CODAMA_ERROR__ANCHOR__TYPE_PATH_MISSING = 2100003;
6262
export const CODAMA_ERROR__ANCHOR__SEED_KIND_UNIMPLEMENTED = 2100004;
6363
export const CODAMA_ERROR__ANCHOR__PROGRAM_ID_KIND_UNIMPLEMENTED = 2100005;
6464
export const CODAMA_ERROR__ANCHOR__GENERIC_TYPE_MISSING = 2100006;
65+
export const CODAMA_ERROR__ANCHOR__EVENT_TYPE_MISSING = 2100007;
6566

6667
// Renderers-related errors.
6768
// Reserve error codes in the range [2800000-2800999].
@@ -86,6 +87,7 @@ export const CODAMA_ERROR__RENDERERS__MISSING_DEPENDENCY_VERSIONS = 2800001;
8687
export type CodamaErrorCode =
8788
| typeof CODAMA_ERROR__ANCHOR__ACCOUNT_TYPE_MISSING
8889
| typeof CODAMA_ERROR__ANCHOR__ARGUMENT_TYPE_MISSING
90+
| typeof CODAMA_ERROR__ANCHOR__EVENT_TYPE_MISSING
8991
| typeof CODAMA_ERROR__ANCHOR__GENERIC_TYPE_MISSING
9092
| typeof CODAMA_ERROR__ANCHOR__PROGRAM_ID_KIND_UNIMPLEMENTED
9193
| typeof CODAMA_ERROR__ANCHOR__SEED_KIND_UNIMPLEMENTED

packages/errors/src/context.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
import {
2323
CODAMA_ERROR__ANCHOR__ACCOUNT_TYPE_MISSING,
2424
CODAMA_ERROR__ANCHOR__ARGUMENT_TYPE_MISSING,
25+
CODAMA_ERROR__ANCHOR__EVENT_TYPE_MISSING,
2526
CODAMA_ERROR__ANCHOR__GENERIC_TYPE_MISSING,
2627
CODAMA_ERROR__ANCHOR__PROGRAM_ID_KIND_UNIMPLEMENTED,
2728
CODAMA_ERROR__ANCHOR__SEED_KIND_UNIMPLEMENTED,
@@ -71,6 +72,9 @@ export type CodamaErrorContext = DefaultUnspecifiedErrorContextToUndefined<{
7172
[CODAMA_ERROR__ANCHOR__ARGUMENT_TYPE_MISSING]: {
7273
name: string;
7374
};
75+
[CODAMA_ERROR__ANCHOR__EVENT_TYPE_MISSING]: {
76+
name: string;
77+
};
7478
[CODAMA_ERROR__ANCHOR__GENERIC_TYPE_MISSING]: {
7579
name: string;
7680
};

packages/errors/src/messages.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import {
77
CODAMA_ERROR__ANCHOR__ACCOUNT_TYPE_MISSING,
88
CODAMA_ERROR__ANCHOR__ARGUMENT_TYPE_MISSING,
9+
CODAMA_ERROR__ANCHOR__EVENT_TYPE_MISSING,
910
CODAMA_ERROR__ANCHOR__GENERIC_TYPE_MISSING,
1011
CODAMA_ERROR__ANCHOR__PROGRAM_ID_KIND_UNIMPLEMENTED,
1112
CODAMA_ERROR__ANCHOR__SEED_KIND_UNIMPLEMENTED,
@@ -51,6 +52,7 @@ export const CodamaErrorMessages: Readonly<{
5152
}> = {
5253
[CODAMA_ERROR__ANCHOR__ACCOUNT_TYPE_MISSING]: 'Account type [$name] is missing from the IDL types.',
5354
[CODAMA_ERROR__ANCHOR__ARGUMENT_TYPE_MISSING]: 'Argument name [$name] is missing from the instruction definition.',
55+
[CODAMA_ERROR__ANCHOR__EVENT_TYPE_MISSING]: 'Event type [$name] is missing from the IDL types.',
5456
[CODAMA_ERROR__ANCHOR__GENERIC_TYPE_MISSING]: 'Generic type [$name] is missing from the IDL types.',
5557
[CODAMA_ERROR__ANCHOR__PROGRAM_ID_KIND_UNIMPLEMENTED]: 'Program ID kind [$kind] is not implemented.',
5658
[CODAMA_ERROR__ANCHOR__SEED_KIND_UNIMPLEMENTED]: 'Seed kind [$kind] is not implemented.',
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import type { DiscriminatorNode } from './discriminatorNodes';
2+
import type { CamelCaseString, Docs } from './shared';
3+
import type { TypeNode } from './typeNodes';
4+
5+
export interface EventNode<
6+
TData extends TypeNode = TypeNode,
7+
TDiscriminators extends DiscriminatorNode[] | undefined = DiscriminatorNode[] | undefined,
8+
> {
9+
readonly kind: 'eventNode';
10+
11+
// Data.
12+
readonly name: CamelCaseString;
13+
readonly docs?: Docs;
14+
15+
// Children.
16+
readonly data: TData;
17+
readonly discriminators?: TDiscriminators;
18+
}

packages/node-types/src/Node.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { RegisteredCountNode } from './countNodes/CountNode';
44
import type { DefinedTypeNode } from './DefinedTypeNode';
55
import type { RegisteredDiscriminatorNode } from './discriminatorNodes/DiscriminatorNode';
66
import type { ErrorNode } from './ErrorNode';
7+
import type { EventNode } from './EventNode';
78
import type { InstructionAccountNode } from './InstructionAccountNode';
89
import type { InstructionArgumentNode } from './InstructionArgumentNode';
910
import type { InstructionByteDeltaNode } from './InstructionByteDeltaNode';
@@ -24,6 +25,7 @@ export type Node =
2425
| AccountNode
2526
| DefinedTypeNode
2627
| ErrorNode
28+
| EventNode
2729
| InstructionAccountNode
2830
| InstructionArgumentNode
2931
| InstructionByteDeltaNode

packages/node-types/src/ProgramNode.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { AccountNode } from './AccountNode';
22
import type { DefinedTypeNode } from './DefinedTypeNode';
33
import type { ErrorNode } from './ErrorNode';
4+
import type { EventNode } from './EventNode';
45
import type { InstructionNode } from './InstructionNode';
56
import type { PdaNode } from './PdaNode';
67
import type { CamelCaseString, Docs, ProgramVersion } from './shared';
@@ -11,6 +12,7 @@ export interface ProgramNode<
1112
TInstructions extends InstructionNode[] = InstructionNode[],
1213
TDefinedTypes extends DefinedTypeNode[] = DefinedTypeNode[],
1314
TErrors extends ErrorNode[] = ErrorNode[],
15+
TEvents extends EventNode[] = EventNode[],
1416
> {
1517
readonly kind: 'programNode';
1618

@@ -26,5 +28,6 @@ export interface ProgramNode<
2628
readonly instructions: TInstructions;
2729
readonly definedTypes: TDefinedTypes;
2830
readonly pdas: TPdas;
31+
readonly events: TEvents;
2932
readonly errors: TErrors;
3033
}

packages/node-types/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export * from './AccountNode';
22
export * from './DefinedTypeNode';
33
export * from './ErrorNode';
4+
export * from './EventNode';
45
export * from './InstructionAccountNode';
56
export * from './InstructionArgumentNode';
67
export * from './InstructionByteDeltaNode';
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { CODAMA_ERROR__ANCHOR__EVENT_TYPE_MISSING, CodamaError } from '@codama/errors';
2+
import {
3+
bytesTypeNode,
4+
camelCase,
5+
constantDiscriminatorNode,
6+
constantValueNode,
7+
EventNode,
8+
eventNode,
9+
fixedSizeTypeNode,
10+
hiddenPrefixTypeNode,
11+
} from '@codama/nodes';
12+
13+
import { getAnchorDiscriminatorV01 } from './../discriminators';
14+
import type { IdlV01Event, IdlV01TypeDef } from './idl';
15+
import { typeNodeFromAnchorV01 } from './typeNodes';
16+
import type { GenericsV01 } from './unwrapGenerics';
17+
18+
export function eventNodeFromAnchorV01(idl: IdlV01Event, types: IdlV01TypeDef[], generics: GenericsV01): EventNode {
19+
const name = camelCase(idl.name);
20+
const type = types.find(candidate => candidate.name === idl.name);
21+
22+
if (!type) {
23+
throw new CodamaError(CODAMA_ERROR__ANCHOR__EVENT_TYPE_MISSING, { name: idl.name });
24+
}
25+
26+
const data = typeNodeFromAnchorV01(type.type, generics);
27+
const discriminator = getAnchorDiscriminatorV01(idl.discriminator);
28+
const discriminatorConstant = constantValueNode(
29+
fixedSizeTypeNode(bytesTypeNode(), idl.discriminator.length),
30+
discriminator,
31+
);
32+
33+
return eventNode({
34+
data: hiddenPrefixTypeNode(data, [discriminatorConstant]),
35+
discriminators: [constantDiscriminatorNode(discriminatorConstant)],
36+
name,
37+
});
38+
}

0 commit comments

Comments
 (0)