Răsfoiți Sursa

Add node documentation — Part 4: Top-level nodes (#99)

Loris Leiva 1 an în urmă
părinte
comite
4d0d3afb16

+ 81 - 0
packages/nodes/docs/AccountNode.md

@@ -0,0 +1,81 @@
+# `AccountNode`
+
+This node defines an on-chain account. It is characterized by its name, data structure, and optional attributes such as PDA definition and account discriminators.
+
+![Diagram](https://github.com/kinobi-so/kinobi/assets/3642397/77974dad-212e-49b1-8e41-5d466c273a02)
+
+## Attributes
+
+### Data
+
+| Attribute | Type              | Description                                                                         |
+| --------- | ----------------- | ----------------------------------------------------------------------------------- |
+| `kind`    | `"accountNode"`   | The node discriminator.                                                             |
+| `name`    | `CamelCaseString` | The name of the account.                                                            |
+| `docs`    | `string[]`        | Markdown documentation for the account.                                             |
+| `size`    | `number`          | (Optional) The size of the account in bytes, if the account's data length is fixed. |
+
+### Children
+
+| Attribute        | Type                                                                                                 | Description                                                                                                                                                              |
+| ---------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `data`           | [`NestedTypeNode`](./typeNodes/NestedTypeNode.md)<[`StructTypeNode`](./typeNodes/StructTypeNode.md)> | The type node that describes the account's data. Note that it must be a struct so we can access its fields via other nodes.                                              |
+| `pda`            | [`PdaLinkNode`](./linkNodes/PdaLinkNode.md)                                                          | (Optional) The link node that describes the account's PDA, if its address is derived from one.                                                                           |
+| `discriminators` | [`DiscriminatorNode`](./discriminatorNodes/README.md)[]                                              | (Optional) The nodes that distinguish this account from others in the program. If multiple discriminators are provided, they are combined using a logical AND operation. |
+
+## Functions
+
+### `accountNode(input)`
+
+Helper function that creates a `AccountNode` object from an input object.
+
+```ts
+const node = accountNode({
+    name: 'myCounter',
+    data: structTypeNode([
+        structFieldTypeNode({ name: 'authority', type: publicKeyTypeNode() }),
+        structFieldTypeNode({ name: 'value', type: numberTypeNode('u64') }),
+    ]),
+});
+```
+
+## Examples
+
+### A fixed-size account
+
+```ts
+const node = accountNode({
+    name: 'token',
+    data: structTypeNode([
+        structFieldTypeNode({ name: 'mint', type: publicKeyTypeNode() }),
+        structFieldTypeNode({ name: 'owner', type: publicKeyTypeNode() }),
+        structFieldTypeNode({ name: 'amount', type: numberTypeNode('u64') }),
+    ]),
+    discriminators: [sizeDiscriminatorNode(72)],
+    size: 72,
+});
+```
+
+### An account with a linked PDA
+
+```ts
+programNode({
+    name: 'myProgram',
+    accounts: [
+        accountNode({
+            name: 'token',
+            data: structTypeNode([structFieldTypeNode({ name: 'authority', type: publicKeyTypeNode() })]),
+            pda: pdaLinkNode('myPda'),
+        }),
+    ],
+    pdas: [
+        pdaNode({
+            name: 'myPda',
+            seeds: [
+                constantPdaSeedNodeFromString('utf8', 'token'),
+                variablePdaSeedNode('authority', publicKeyTypeNode()),
+            ],
+        }),
+    ],
+});
+```

+ 35 - 0
packages/nodes/docs/ErrorNode.md

@@ -0,0 +1,35 @@
+# `ErrorNode`
+
+This node defines an error that can be returned by a program.
+
+![Diagram](https://github.com/kinobi-so/kinobi/assets/3642397/0bde98ea-0327-404b-bf38-137d105826b0)
+
+## Attributes
+
+### Data
+
+| Attribute | Type              | Description                                      |
+| --------- | ----------------- | ------------------------------------------------ |
+| `kind`    | `"errorNode"`     | The node discriminator.                          |
+| `name`    | `CamelCaseString` | The name of the error.                           |
+| `code`    | `number`          | The error code.                                  |
+| `message` | `string`          | A human-friendly message describing the error.   |
+| `docs`    | `string[]`        | Additional Markdown documentation for the error. |
+
+### Children
+
+_This node has no children._
+
+## Functions
+
+### `errorNode(input)`
+
+Helper function that creates a `ErrorNode` object from an input object.
+
+```ts
+const node = errorNode({
+    name: 'invalidAmountArgument',
+    code: 1,
+    message: 'The amount argument is invalid.',
+});
+```

+ 64 - 0
packages/nodes/docs/InstructionAccountNode.md

@@ -0,0 +1,64 @@
+# `InstructionAccountNode`
+
+This node defines an account used by an instruction. It is characterized by its name and various requirements such as whether it needs to be writable or a signer.
+
+![Diagram](https://github.com/kinobi-so/kinobi/assets/3642397/4656a08b-2f89-49c2-b428-5378cb1a0b9e)
+
+## Attributes
+
+### Data
+
+| Attribute    | Type                       | Description                                                                                                                                                                                                                                            |
+| ------------ | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `kind`       | `"instructionAccountNode"` | The node discriminator.                                                                                                                                                                                                                                |
+| `name`       | `CamelCaseString`          | The name of the instruction account.                                                                                                                                                                                                                   |
+| `isWritable` | `boolean`                  | Whether of not the account needs to be writable.                                                                                                                                                                                                       |
+| `isSigner`   | `boolean` \| `"either"`    | Whether or not the account needs to be a signer. If the value `"either"` is provided, the account can be either a signer or not depending on the context.                                                                                              |
+| `isOptional` | `boolean`                  | (Optional) Whether or not the account is optional. If this is `true`, the account should be handled as an optional account according to the `optionalAccountStrategy` attribute of the [`InstructionNode`.](./InstructionNode.md) Defaults to `false`. |
+| `docs`       | `string[]`                 | Markdown documentation for the instruction account.                                                                                                                                                                                                    |
+
+### Children
+
+| Attribute      | Type                                                                               | Description                                                                                                       |
+| -------------- | ---------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
+| `defaultValue` | [`InstructionInputValueNode`](./contextualValueNodes/InstructionInputValueNode.md) | (Optional) A default value for the account should this account not be provided when constructing the instruction. |
+
+## Functions
+
+### `instructionAccountNode(input)`
+
+Helper function that creates a `InstructionAccountNode` object from an input object.
+
+```ts
+const node = instructionAccountNode({
+    name: 'authority',
+    isWritable: false,
+    isSigner: true,
+    docs: ['This account that has the authority to perform this instruction.'],
+});
+```
+
+## Examples
+
+### An optional account
+
+```ts
+instructionAccountNode({
+    name: 'freezeAuthority',
+    isWritable: false,
+    isSigner: false,
+    isOptional: true,
+    docs: ['The freeze authority to set on the asset, if any.'],
+});
+```
+
+### An optional signer account
+
+```ts
+instructionAccountNode({
+    name: 'owner',
+    isWritable: true,
+    isSigner: 'either',
+    docs: ['The owner of the asset. The owner must only sign the transaction if the asset is being updated.'],
+});
+```

+ 60 - 0
packages/nodes/docs/InstructionArgumentNode.md

@@ -0,0 +1,60 @@
+# `InstructionArgumentNode`
+
+This node defines an argument that is passed to an instruction. When all arguments are combined and serialized next to each other, they form the instruction's data.
+
+![Diagram](https://github.com/kinobi-so/kinobi/assets/3642397/7e2def82-949a-4663-bdc3-ac599d39d2d2)
+
+## Attributes
+
+### Data
+
+| Attribute              | Type                        | Description                                                                                                                                                                                                                                                                                                                        |
+| ---------------------- | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `kind`                 | `"instructionArgumentNode"` | The node discriminator.                                                                                                                                                                                                                                                                                                            |
+| `name`                 | `CamelCaseString`           | The name of the instruction argument.                                                                                                                                                                                                                                                                                              |
+| `docs`                 | `string[]`                  | Markdown documentation for the instruction argument.                                                                                                                                                                                                                                                                               |
+| `defaultValueStrategy` | `"optional"` \| `"omitted"` | (Optional) The strategy to use when a default value is provided for the argument. `"optional"` means that the argument's default value may be overriden by a provided argument, while `"omitted"` means that no argument should be provided and the default value should always be the argument's value. Defaults to `"optional"`. |
+
+### Children
+
+| Attribute      | Type                                                                               | Description                                                                                                         |
+| -------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
+| `type`         | [`TypeNode`](./typeNodes/README.md)                                                | The `TypeNode` that describes the argument's data.                                                                  |
+| `defaultValue` | [`InstructionInputValueNode`](./contextualValueNodes/InstructionInputValueNode.md) | (Optional) A default value for the argument should this argument not be provided when constructing the instruction. |
+
+## Functions
+
+### `instructionArgumentNode(input)`
+
+Helper function that creates a `InstructionArgumentNode` object from an input object.
+
+```ts
+const node = instructionArgumentNode({
+    name: 'amount',
+    type: numberTypeNode('u64'),
+    docs: ['This amount of tokens to transfer.'],
+});
+```
+
+## Examples
+
+### An argument with a default value
+
+```ts
+instructionArgumentNode({
+    name: 'amount',
+    type: numberTypeNode('u64'),
+    defaultValue: numberValueNode(0),
+});
+```
+
+### An argument with an omitted default value
+
+```ts
+instructionArgumentNode({
+    name: 'instructionDiscriminator',
+    type: numberTypeNode('u8'),
+    defaultValue: numberValueNode(42),
+    defaultValueStrategy: 'omitted',
+});
+```

+ 49 - 0
packages/nodes/docs/InstructionByteDeltaNode.md

@@ -0,0 +1,49 @@
+# `InstructionByteDeltaNode`
+
+This node represents a difference in bytes stored on-chain from executing an instruction. For instance, if an instruction creates a new account of 42 bytes, this node can provide this information. This enables clients to allocate the right amount of lamports to cover the cost of executing the instruction.
+
+## Attributes
+
+### Data
+
+| Attribute    | Type                         | Description                                                                                                                                                                       |
+| ------------ | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `kind`       | `"instructionByteDeltaNode"` | The node discriminator.                                                                                                                                                           |
+| `withHeader` | `boolean`                    | (Optional) Whether or not we should add the account header size — i.e. 128 bytes — to the value. Default to `false` when the value is a `ResolverValueNode` and `true` otherwise. |
+| `subtract`   | `boolean`                    | (Optional) Whether or not the provided value should be subtracted from the total byte delta. Defaults to `false`.                                                                 |
+
+### Children
+
+| Attribute | Type                                                                                                                                                                                                                                                    | Description                                                                                                                                                                                                                                                                                                                                                        |
+| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `value`   | [`AccountLinkNode`](./linkNodes/AccountLinkNode.md) \| [`ArgumentValueNode`](./contextualValueNodes/ArgumentValueNode.md) \| [`NumberValueNode`](./valueNodes/NumberValueNode.md) \| [`ResolverValueNode`](./contextualValueNodes/ResolverValueNode.md) | The value representing the byte delta. If an `AccountLinkNode` is used, the size of the linked account will be used. If an `ArgumentValueNode` is used, the value of the instruction argument will be used. If a `NumberValueNode` is used, that explicit number will be used. Otherwise, a `ResolverValueNode` can be used as a fallback for more complex values. |
+
+## Functions
+
+### `instructionByteDeltaNode(value, options?)`
+
+Helper function that creates a `InstructionByteDeltaNode` object from a value node and some options.
+
+```ts
+const node = instructionByteDeltaNode(numberValueNode(42), { withHeader: false });
+```
+
+## Examples
+
+### A byte delta that represents a new account
+
+```ts
+instructionByteDeltaNode(accountLinkNode('token'));
+```
+
+### A byte delta that represents an account deletion
+
+```ts
+instructionByteDeltaNode(accountLinkNode('token'), { subtract: true });
+```
+
+### A byte delta that uses an argument value to increase the space of an account
+
+```ts
+instructionByteDeltaNode(argumentValueNode('additionalSpace'), { withHeader: false });
+```

+ 169 - 0
packages/nodes/docs/InstructionNode.md

@@ -0,0 +1,169 @@
+# `InstructionNode`
+
+This node represents an instruction in a program.
+
+![Diagram](https://github.com/kinobi-so/kinobi/assets/3642397/0d8edced-cfa4-4500-b80c-ebc56181a338)
+
+## Attributes
+
+### Data
+
+| Attribute                 | Type                         | Description                                                                                                                                                                                                                                                                                                             |
+| ------------------------- | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `kind`                    | `"instructionNode"`          | The node discriminator.                                                                                                                                                                                                                                                                                                 |
+| `name`                    | `CamelCaseString`            | The name of the instruction.                                                                                                                                                                                                                                                                                            |
+| `docs`                    | `string[]`                   | Markdown documentation for the instruction.                                                                                                                                                                                                                                                                             |
+| `optionalAccountStrategy` | `"omitted"` \| `"programId"` | (Optional) Determines how to handle optional accounts. `"omitted"` means optional accounts that are not provided will be omitted from the list of accounts, `"programId"` means they will be replaced by the address of the program to ensure account ordering with only 1 byte of overhead. Defaults to `"programId"`. |
+
+### Children
+
+| Attribute           | Type                                                                          | Description                                                                                                                                                                             |
+| ------------------- | ----------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `accounts`          | [`InstructionAccountNode`](./InstructionAccountNode.md)[]                     | The list of accounts that the instruction uses and their requirements.                                                                                                                  |
+| `arguments`         | [`InstructionArgumentNode`](./InstructionArgumentNode.md)[]                   | The arguments the constitute the instruction's data.                                                                                                                                    |
+| `extraArguments`    | [`InstructionArgumentNode`](./InstructionArgumentNode.md)[]                   | (Optional) Additional arguments that do not contribute to the instruction's data but may help when defining default values.                                                             |
+| `remainingAccounts` | [`InstructionRemainingAccountsNode`](./InstructionRemainingAccountsNode.md)[] | (Optional) The list of dynamic remaining accounts requirements for the instruction. For instance, an instruction may have a variable number of signers at the end of the accounts list. |
+| `byteDeltas`        | [`InstructionByteDeltaNode`](./InstructionByteDeltaNode.md)[]                 | (Optional) The list of byte variations that the instruction causes. They should all be added together unless the `subtract` attribute is used.                                          |
+| `discriminators`    | [`DiscriminatorNode`](./DiscriminatorNode.md)[]                               | (Optional) The nodes that distinguish this instruction from others in the program. If multiple discriminators are provided, they are combined using a logical AND operation.            |
+| `subInstructions`   | [`InstructionNode`](./InstructionNode.md)[]                                   | (Optional) A list of nested instructions should this instruction be split into multiple sub-instructions to define distinct scenarios.                                                  |
+
+## Functions
+
+### `instructionNode(input)`
+
+Helper function that creates a `InstructionNode` object from an input object.
+
+```ts
+const node = instructionNode({
+    name: 'increment',
+    accounts: [
+        instructionAccountNode({ name: 'counter', isWritable: true, isSigner: false }),
+        instructionAccountNode({ name: 'authority', isWritable: false, isSigner: true }),
+    ],
+    arguments: [instructionArgumentNode({ name: 'amount', type: numberTypeNode('u8') })],
+});
+```
+
+### `getAllInstructionArguments(instruction)`
+
+Helper function that returns all arguments — including extra arguments — of an instruction as a `InstructionArgumentNode[]`.
+
+```ts
+const allArguments = getAllInstructionArguments(instruction);
+```
+
+### `getAllInstructionsWithSubs()`
+
+Helper function that returns all instructions with their nested sub-instructions, if any. It can be called on a `RootNode`, `ProgramNode`, or `InstructionNode`.
+
+```ts
+const allInstructionsFromTheRoot = getAllInstructionsWithSubs(rootNode);
+const allInstructionsFromThisProgram = getAllInstructionsWithSubs(programNode);
+const allInstructionsFromThisInstruction = getAllInstructionsWithSubs(instructionNode);
+```
+
+## Examples
+
+### An instruction with a u8 discriminator
+
+```ts
+instructionNode({
+    name: 'increment',
+    accounts: [
+        instructionAccountNode({ name: 'counter', isWritable: true, isSigner: true }),
+        instructionAccountNode({ name: 'authority', isWritable: false, isSigner: false }),
+    ],
+    arguments: [
+        instructionArgumentNode({
+            name: 'discriminator',
+            type: numberTypeNode('u8'),
+            defaultValue: numberValueNode(42),
+            defaultValueStrategy: 'omitted',
+        }),
+    ],
+});
+```
+
+### An instruction that creates a new account
+
+```ts
+instructionNode({
+    name: 'createCounter',
+    accounts: [
+        instructionAccountNode({ name: 'counter', isWritable: true, isSigner: true }),
+        instructionAccountNode({ name: 'authority', isWritable: false, isSigner: false }),
+    ],
+    byteDeltas: [instructionByteDeltaNode(accountLinkNode('counter'))],
+});
+```
+
+### An instruction with omitted optional accounts
+
+```ts
+instructionNode({
+    name: 'initialize',
+    accounts: [
+        instructionAccountNode({ name: 'counter', isWritable: true, isSigner: true }),
+        instructionAccountNode({ name: 'authority', isWritable: false, isSigner: false }),
+        instructionAccountNode({ name: 'freezeAuthority', isWritable: false, isSigner: false, isOptional: true }),
+    ],
+    optionalAccountStrategy: 'omitted',
+});
+```
+
+### An instruction with remaining signers
+
+```ts
+instructionNode({
+    name: 'multisigIncrement',
+    accounts: [instructionAccountNode({ name: 'counter', isWritable: true, isSigner: false })],
+    remainingAccounts: [instructionRemainingAccountsNode(argumentValueNode('authorities'), { isSigner: true })],
+});
+```
+
+### An instruction with nested versionned instructions
+
+```ts
+instructionNode({
+    name: 'increment',
+    accounts: [
+        instructionAccountNode({ name: 'counter', isWritable: true, isSigner: 'either' }),
+        instructionAccountNode({ name: 'authority', isWritable: false, isSigner: true }),
+    ],
+    arguments: [
+        instructionArgumentNode({ name: 'version', type: numberTypeNode('u8') }),
+        instructionArgumentNode({ name: 'amount', type: numberTypeNode('u8') }),
+    ],
+    subInstructions: [
+        instructionNode({
+            name: 'incrementV1',
+            accounts: [instructionAccountNode({ name: 'counter', isWritable: true, isSigner: true })],
+            arguments: [
+                instructionArgumentNode({
+                    name: 'version',
+                    type: numberTypeNode('u8'),
+                    defaultValue: numberValueNode(0),
+                    defaultValueStrategy: 'omitted',
+                }),
+                instructionArgumentNode({ name: 'amount', type: numberTypeNode('u8') }),
+            ],
+        }),
+        instructionNode({
+            name: 'incrementV2',
+            accounts: [
+                instructionAccountNode({ name: 'counter', isWritable: true, isSigner: false }),
+                instructionAccountNode({ name: 'authority', isWritable: false, isSigner: true }),
+            ],
+            arguments: [
+                instructionArgumentNode({
+                    name: 'version',
+                    type: numberTypeNode('u8'),
+                    defaultValue: numberValueNode(1),
+                    defaultValueStrategy: 'omitted',
+                }),
+                instructionArgumentNode({ name: 'amount', type: numberTypeNode('u8') }),
+            ],
+        }),
+    ],
+});
+```

+ 63 - 0
packages/nodes/docs/InstructionRemainingAccountsNode.md

@@ -0,0 +1,63 @@
+# `InstructionRemainingAccountsNode`
+
+This node represents a list of remaining accounts for an instruction. It can be used to represent a dynamic list of accounts that are not explicitly defined in the instruction but may be required for the instruction to execute.
+
+## Attributes
+
+### Data
+
+| Attribute    | Type                                 | Description                                                                                                                                                                   |
+| ------------ | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `kind`       | `"instructionRemainingAccountsNode"` | The node discriminator.                                                                                                                                                       |
+| `docs`       | `string[]`                           | Markdown documentation explaining the remaining accounts of an instruction.                                                                                                   |
+| `isOptional` | `boolean`                            | (Optional) Whether the remaining accounts are optional. Defaults to `false`.                                                                                                  |
+| `isSigner`   | `boolean` \| `"either"`              | (Optional) Whether the remaining accounts are signers. If `true`, all are. If `false`, none are. If `"either"`, they may each either be a signer or not. Defaults to `false`. |
+
+### Children
+
+| Attribute | Type                                                                                                                                     | Description                                                                                                                                                                                                                                                                                    |
+| --------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `value`   | [`ArgumentValueNode`](./contextualValueNodes/ArgumentValueNode.md) \| [`ResolverValueNode`](./contextualValueNodes/ResolverValueNode.md) | The node representing how these remaining accounts are gathered. If a `ArgumentValueNode` is provided, a new argument will be used to represent this array of accounts from the provided name. Otherwise, a `ResolverValueNode` can be used as a fallback to represent more complex scenarios. |
+
+## Functions
+
+### `instructionRemainingAccountsNode(value, options?)`
+
+Helper function that creates a `InstructionRemainingAccountsNode` object from a value node and some options.
+
+```ts
+const node = instructionRemainingAccountsNode(argumentValueNode('signers'), {
+    isSigner: true,
+    isOptional: true,
+});
+```
+
+## Examples
+
+### Optional remaining signers
+
+```ts
+instructionRemainingAccountsNode(argumentValueNode('authorities'), {
+    isSigner: true,
+    isOptional: true,
+});
+```
+
+### Remaining accounts that may or may not be signers
+
+```ts
+instructionRemainingAccountsNode(argumentValueNode('authorities'), {
+    isSigner: 'either',
+});
+```
+
+### Remaining accounts using a resolver
+
+```ts
+instructionRemainingAccountsNode(
+    resolverValueNode('resolveTransferRemainingAccounts', {
+        docs: ['Provide authorities as remaining accounts if and only if the asset has a multisig set up.'],
+        dependsOn: [argumentValueNode('hasMultisig'), argumentValueNode('authorities')],
+    }),
+);
+```

+ 61 - 0
packages/nodes/docs/PdaNode.md

@@ -0,0 +1,61 @@
+# `PdaNode`
+
+This node provides a definition for a specific Program-Derived Address (PDA). It is characterized by a name and a list of seeds that can either be constant or variable.
+
+![Diagram](https://github.com/kinobi-so/kinobi/assets/3642397/4f7c9718-1ffa-4f2c-aa45-71b3ce204219)
+
+## Attributes
+
+### Data
+
+| Attribute   | Type              | Description                                                                                                                      |
+| ----------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------- |
+| `kind`      | `"pdaNode"`       | The node discriminator.                                                                                                          |
+| `name`      | `CamelCaseString` | The name of the PDA.                                                                                                             |
+| `docs`      | `string[]`        | Markdown documentation for the PDA.                                                                                              |
+| `programId` | `string`          | (Optional) The address of the program the PDA should derive from. Defaults to the address of the nearest `ProgramNode` ancestor. |
+
+### Children
+
+| Attribute | Type                                        | Description           |
+| --------- | ------------------------------------------- | --------------------- |
+| `seeds`   | [`PdaSeedNode`](./pdaSeedNodes/README.md)[] | The seeds of the PDA. |
+
+## Functions
+
+### `pdaNode(input)`
+
+Helper function that creates a `pdaNode` object from an input object.
+
+```ts
+const node = pdaNode({
+    name: 'counter',
+    seeds: [variablePdaSeedNode('authority', publicKeyTypeNode())],
+    docs: ['The counter PDA derived from its authority.'],
+});
+```
+
+## Examples
+
+### A PDA with constant and variable seeds
+
+```ts
+pdaNode({
+    name: 'ticket',
+    seeds: [
+        constantPdaSeedNodeFromString('utf8', 'raffles'),
+        variablePdaSeedNode('raffle', publicKeyTypeNode()),
+        constantPdaSeedNodeFromString('utf8', 'tickets'),
+        variablePdaSeedNode('ticketNumber', numberTypeNode('u32')),
+    ],
+});
+```
+
+### A PDA with no seeds
+
+```ts
+pdaNode({
+    name: 'seedlessPda',
+    seeds: [],
+});
+```

+ 95 - 0
packages/nodes/docs/ProgramNode.md

@@ -0,0 +1,95 @@
+# `ProgramNode`
+
+This node represents an entire program deployed on-chain. It defines all elements of a program such as accounts, instructions, PDAs, errors, etc.
+
+![Diagram](https://github.com/kinobi-so/kinobi/assets/3642397/37ec38ea-66df-4c08-81c3-822ef4388580)
+
+## Attributes
+
+### Data
+
+| Attribute   | Type                    | Description                                                                  |
+| ----------- | ----------------------- | ---------------------------------------------------------------------------- |
+| `kind`      | `"programNode"`         | The node discriminator.                                                      |
+| `name`      | `CamelCaseString`       | The name of the program.                                                     |
+| `publicKey` | `string`                | The 32-bytes address of the program base58 encoded.                          |
+| `version`   | `\d.\d.\d`              | The semantic version of the program being defined.                           |
+| `docs`      | `string[]`              | Markdown documentation for the program.                                      |
+| `origin`    | `"anchor"` \| `"shank"` | (Optional) An optional attribute tells us how this program node was created. |
+
+### Children
+
+| Attribute      | Type                                        | Description                                                   |
+| -------------- | ------------------------------------------- | ------------------------------------------------------------- |
+| `accounts`     | [`AccountNode`](./AccountNode.md)[]         | The accounts created and managed by the program.              |
+| `instructions` | [`InstructionNode`](./InstructionNode.md)[] | The instructions that allows us to interact with the program. |
+| `definedTypes` | [`DefinedTypeNode`](./DefinedTypeNode.md)[] | Some reusable types defined by the program.                   |
+| `pdas`         | [`PdaNode`](./PdaNode.md)[]                 | The Program-Derived Addresses (PDAs) used by the program.     |
+| `errors`       | [`ErrorNode`](./ErrorNode.md)[]             | The errors that can be thrown by the program.                 |
+
+## Functions
+
+### `programNode(input)`
+
+Helper function that creates a `ProgramNode` object from an input object
+
+```ts
+const node = programNode({
+    name: 'counter',
+    publicKey: '7ovtg4pFqjQdSwFAUCu8gTnh5thZHzAyJFXy3Ssnj3yK',
+    version: '1.42.6',
+    accounts: [],
+    instructions: [],
+    definedTypes: [],
+    pdas: [],
+    errors: [],
+});
+```
+
+### `getAllPrograms(node)`
+
+Helper function that returns all `ProgramNodes` under a given node. This can be a `RootNode`, a `ProgramNode` — returning itself in an array — or an array of `ProgramNode`.
+
+```ts
+const allPrograms = getAllPrograms(rootNode);
+```
+
+### `getAllPdas(node)`
+
+Helper function that returns all `PdaNodes` under a given node. This can be a `RootNode`, a `ProgramNode` or an array of `ProgramNode`.
+
+```ts
+const allPdas = getAllPdas(rootNode);
+```
+
+### `getAllAccounts(node)`
+
+Helper function that returns all `AccountNodes` under a given node. This can be a `RootNode`, a `ProgramNode` or an array of `ProgramNode`.
+
+```ts
+const allAccounts = getAllAccounts(rootNode);
+```
+
+### `getAllDefinedTypes(node)`
+
+Helper function that returns all `DefinedTypeNodes` under a given node. This can be a `RootNode`, a `ProgramNode` or an array of `ProgramNode`.
+
+```ts
+const allDefinedTypes = getAllDefinedTypes(rootNode);
+```
+
+### `getAllInstructions(node)`
+
+Helper function that returns all `InstructionNodes` under a given node. This can be a `RootNode`, a `ProgramNode` or an array of `ProgramNode`.
+
+```ts
+const allInstructions = getAllInstructions(rootNode);
+```
+
+### `getAllErrors(node)`
+
+Helper function that returns all `ErrorNodes` under a given node. This can be a `RootNode`, a `ProgramNode` or an array of `ProgramNode`.
+
+```ts
+const allErrors = getAllErrors(rootNode);
+```

+ 61 - 0
packages/nodes/docs/README.md

@@ -0,0 +1,61 @@
+# `Node` (abstract)
+
+The `Node` type helper represents all available nodes. Note that `Node` is a type alias and cannot be used directly as a node. Instead you may use any node to satisfy the `Node` type. You can [see all available nodes here](../README.md#documentation).
+
+## Functions
+
+Some helper functions are also available to work with nodes.
+
+### `isNode(node, kind)`
+
+Type guard that checks if a node is of a specific kind or part of a list of kinds. If the provided node is `null` or `undefined`, the function returns `false`.
+
+```ts
+isNode(stringTypeNode('utf8'), 'stringTypeNode'); // true.
+isNode(stringTypeNode('utf8'), 'numberTypeNode'); // false.
+isNode(stringTypeNode('utf8'), ['stringTypeNode', 'numberTypeNode']); // true.
+isNode(null, 'stringTypeNode'); // false.
+isNode(undefined, 'stringTypeNode'); // false.
+```
+
+### `assertIsNode(node, kind)`
+
+Type guard that asserts that a node is of a specific kind or part of a list of kinds. If the provided node is `null` or `undefined`, the function throws an error.
+
+```ts
+assertIsNode(stringTypeNode('utf8'), 'stringTypeNode'); // Ok.
+assertIsNode(stringTypeNode('utf8'), 'numberTypeNode'); // Throws an error.
+assertIsNode(stringTypeNode('utf8'), ['stringTypeNode', 'numberTypeNode']); // Ok.
+assertIsNode(null, 'stringTypeNode'); // Throws an error.
+assertIsNode(undefined, 'stringTypeNode'); // Throws an error.
+```
+
+### `isNodeFilter(kind)`
+
+This function returns a function that acts as the `isNode` function but with a predefined kind or list of kinds to check against. This is a useful function to use in combination with array functions like `filter`.
+
+```ts
+myNodes.filter(isNodeFilter('stringTypeNode')); // Keep only string type nodes.
+myNodes.filter(isNodeFilter(['stringTypeNode', 'numberTypeNode'])); // Keep only string and number type nodes.
+```
+
+### `assertIsNodeFilter(kind)`
+
+This function returns a function that acts as the `assertIsNode` function but with a predefined kind or list of kinds to check against. This is a useful function to use in combination with array functions like `filter`.
+
+```ts
+myNodes.filter(assertIsNodeFilter('stringTypeNode')); // Fail if there are non-string type node.
+myNodes.filter(assertIsNodeFilter(['stringTypeNode', 'numberTypeNode'])); // Fail if there are nodes that are not string or number type nodes.
+```
+
+### `removeNullAndAssertIsNodeFilter(kind)`
+
+This function acts like the `assertIsNodeFilter` function below but removes `null` and `undefined` values before asserting the kind or kinds.
+
+```ts
+const myNodes = [null, stringTypeNode('utf8'), undefined, stringTypeNode('base58')];
+
+myNodes.filter(removeNullAndAssertIsNodeFilter('stringTypeNode')); // Ok and removes null and undefined values.
+myNodes.filter(removeNullAndAssertIsNodeFilter('numberTypeNode')); // Throws an error.
+myNodes.filter(removeNullAndAssertIsNodeFilter(['stringTypeNode', 'numberTypeNode'])); // Ok and removes null and undefined values.
+```

+ 61 - 0
packages/nodes/docs/RootNode.md

@@ -0,0 +1,61 @@
+# `RootNode`
+
+This node represents the starting point of the Kinobi IDL. It contains a single `ProgramNode` which the Kinobi IDL is describing as well as any additional programs that may be referenced by the main program. This node is also responsible for setting the standard and version of the IDL.
+
+![Diagram](https://github.com/kinobi-so/kinobi/assets/3642397/96c43c75-5925-4b6b-a1e0-8b8c61317cfe)
+
+## Attributes
+
+### Data
+
+| Attribute  | Type         | Description                                                                                                                                                                                   |
+| ---------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `kind`     | `"rootNode"` | The node discriminator.                                                                                                                                                                       |
+| `standard` | `"kinobi"`   | The IDL standard used by the `RootNode` which is always `"kinobi"`. This can help other communities fork the Kinobi standard.                                                                 |
+| `version`  | `\d.\d.\d`   | The semantic version of the standard used by the `RootNode`. That is — unless a different standard is used — this will be the Kinobi version from which this entire tree of node was created. |
+
+### Children
+
+| Attribute            | Type                                | Description                                                             |
+| -------------------- | ----------------------------------- | ----------------------------------------------------------------------- |
+| `program`            | [`ProgramNode`](./ProgramNode.md)   | The main program being described.                                       |
+| `additionalPrograms` | [`ProgramNode`](./ProgramNode.md)[] | (Optional) Additional programs that are referenced by the main program. |
+
+## Functions
+
+### `rootNode(program, additionalPrograms?)`
+
+Helper function that creates a `RootNode` object from a `ProgramNode` and an optional array of additional `ProgramNodes`. Note that the `standard` is automatically set to `"kinobi"` and the `version` is set to the Kinobi version installed.
+
+```ts
+const node = rootNode(programNode({ ... }));
+```
+
+## Examples
+
+### A root node with a single program
+
+```ts
+const node = rootNode(
+    programNode({
+        name: 'counter',
+        publicKey: '2R3Ui2TVUUCyGcZdopxJauk8ZBzgAaHHZCVUhm5ifPaC',
+        version: '1.0.0',
+        accounts: [
+            accountNode({
+                name: 'counter',
+                data: structTypeNode([
+                    structFieldTypeNode({ name: 'authority', type: publicKeyTypeNode() }),
+                    structFieldTypeNode({ name: 'value', type: numberTypeNode('u32') }),
+                ]),
+            }),
+        ],
+        instructions: [
+            instructionNode({ name: 'create' /* ... */ }),
+            instructionNode({ name: 'increment' /* ... */ }),
+            instructionNode({ name: 'transferAuthority' /* ... */ }),
+            instructionNode({ name: 'delete' /* ... */ }),
+        ],
+    }),
+);
+```