Skip to content

Commit

Permalink
Update serializers documentation (#69)
Browse files Browse the repository at this point in the history
  • Loading branch information
lorisleiva authored Jun 20, 2023
1 parent cd243ca commit 1e2ab1a
Show file tree
Hide file tree
Showing 8 changed files with 213 additions and 177 deletions.
13 changes: 8 additions & 5 deletions docs/accounts.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Fetching accounts

Let's see how we can fetch account data from the Solana blockchain using Umi. For that, we will need the [`RpcInterface`](https://umi-docs.vercel.app/interfaces/umi.RpcInterface.html) to fetch accounts with serialized data and the [`SerializerInterface`](https://umi-docs.vercel.app/interfaces/umi.SerializerInterface.html) to help deserialize them.
Let's see how we can fetch account data from the Solana blockchain using Umi. For that, we will need the [`RpcInterface`](https://umi-docs.vercel.app/interfaces/umi.RpcInterface.html) to fetch accounts with serialized data and [serializers](./serializers.md) to help deserialize them.

## Account definitions

Expand Down Expand Up @@ -87,15 +87,18 @@ Note that when fetching program accounts, you might be interested in [`GpaBuilde
In order to turn a `RpcAccount` into a deserialized `Account<T>`, we simply need the `deserializeAccount` function and a `Serializer` that knows how to deserialize the account's data. You can read more about `Serializer`s in the [Serializers page](./serializers.md) but here's a quick example assuming the data is composed of two public keys and one `u64` number.

```ts
import { assertAccountExists, deserializeAccount } from '@metaplex-foundation/umi';
import { struct, publicKey, u64 } from '@metaplex-foundation/umi/serializers';

// Given an existing RPC account.
const myRpcAccount = await umi.rpc.getAccount(myPublicKey);
assertAccountExists(myRpcAccount);

// And an account data serializer.
const myDataSerializer = umi.serializer.struct([
['source', umi.serializer.publicKey()],
['destination', umi.serializer.publicKey()],
['amount', umi.serializer.u64()],
const myDataSerializer = struct([
['source', publicKey()],
['destination', publicKey()],
['amount', u64()],
]);

// We can deserialize the account like so.
Expand Down
7 changes: 5 additions & 2 deletions docs/helpers.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,13 @@ const accounts: Metadata[] = await metadataGpaBuilder.getDeserialized();
Additionally, we can pass a set of fields with their offsets to a `GpaBuilder` to improve the developer experience around filtering and slicing data. To do so, we can use the `registerFields` method. For instance, say we know that starting from byte 16, the next 32 bytes represent a `name` via a fixed size string and the next 4 bytes after that represent an `age`. Here's how we could register those fields.

```ts
import { gpaBuilder } from '@metaplex-foundation/umi';
import { string, u32 } from '@metaplex-foundation/umi/serializers';

const myGpaBuilderWithFields = gpaBuilder(umi, programId)
.registerFields<{ name: string; age: number; }>({
name: [16, umi.serializer.string({ size: 32 })],
age: [48, umi.serializer.u32()],
name: [16, string({ size: 32 })],
age: [48, u32()],
})
```

Expand Down
8 changes: 1 addition & 7 deletions docs/implementations.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,14 @@ The page aims to list all the available implementations of [the interfaces defin
| Description | Maintainer | Links |
| --- | --- | --- |
| Use Solana's web3.js | Metaplex | [GitHub](https://github.com/metaplex-foundation/umi/tree/main/packages/umi-rpc-web3js) / [NPM](https://www.npmjs.com/package/@metaplex-foundation/umi-rpc-web3js) |
| An RPC decorator that chunks `getAccounts` requests into batches of a given size, and run them in parallel to abstract API limitations to the end-user. | Metaplex | [GitHub](https://github.com/metaplex-foundation/umi/tree/main/packages/umi-rpc-chunk-get-accounts) / [NPM](https://www.npmjs.com/package/@metaplex-foundation/umi-rpc-chunk-get-accounts) |

## Transaction Factory Interface

| Description | Maintainer | Links |
| --- | --- | --- |
| Use Solana's web3.js | Metaplex | [GitHub](https://github.com/metaplex-foundation/umi/tree/main/packages/umi-transaction-factory-web3js) / [NPM](https://www.npmjs.com/package/@metaplex-foundation/umi-transaction-factory-web3js) |

## Serializer Interface

| Description | Maintainer | Links |
| --- | --- | --- |
| Uses JavaScript's native `DataView` API | Metaplex | [GitHub](https://github.com/metaplex-foundation/umi/tree/main/packages/umi-serializer-data-view) / [NPM](https://www.npmjs.com/package/@metaplex-foundation/umi-serializer-data-view) |
| Uses Metaplex's Beet library | Metaplex | [GitHub](https://github.com/metaplex-foundation/umi/tree/main/packages/umi-serializer-beet) / [NPM](https://www.npmjs.com/package/@metaplex-foundation/umi-serializer-beet) |

## Uploader Interface

| Description | Maintainer | Links |
Expand Down
5 changes: 3 additions & 2 deletions docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,15 @@ You can then use Umi's `Context` object or a subset of it to inject any interfac

```ts
import type { Context, PublicKey } from '@metaplex-foundation/umi';
import { u32 } from '@metaplex-foundation/umi/serializers';

export async function myFunction(
context: Pick<Context, 'rpc' | 'serializer'>, // <-- Inject the interfaces you need.
context: Pick<Context, 'rpc'>, // <-- Inject the interfaces you need.
publicKey: PublicKey
): number {
const rawAccount = await context.rpc.getAccount(publicKey);
if (!rawAccount.exists) return 0;
return context.serializer.u32().deserialize(rawAccount.data)[0];
return u32().deserialize(rawAccount.data)[0];
}
```

Expand Down
2 changes: 0 additions & 2 deletions docs/interfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ Umi defines a set of core interfaces that makes it easy to interact with the Sol
- [`EddsaInterface`](https://umi-docs.vercel.app/interfaces/umi.EddsaInterface.html): An interface to create keypairs, find PDAs and sign/verify messages using the EdDSA algorithm.
- [`RpcInterface`](https://umi-docs.vercel.app/interfaces/umi.RpcInterface.html): An interface representing a Solana RPC client.
- [`TransactionFactoryInterface`](https://umi-docs.vercel.app/interfaces/umi.TransactionFactoryInterface.html): An interface allowing us to create and serialize transactions.
- [`SerializerInterface`](https://umi-docs.vercel.app/interfaces/umi.SerializerInterface.html): An interface providing a vast range of serializers for any Solana types.
- [`UploaderInterface`](https://umi-docs.vercel.app/interfaces/umi.UploaderInterface.html): An interface allowing us to upload files and get a URI to access them.
- [`DownloaderInterface`](https://umi-docs.vercel.app/interfaces/umi.DownloaderInterface.html): An interface allowing us to download files from a given URI.
- [`HttpInterface`](https://umi-docs.vercel.app/interfaces/umi.HttpInterface.html): An interface allowing us to send HTTP requests.
Expand All @@ -26,7 +25,6 @@ interface Context {
payer: Signer;
programs: ProgramRepositoryInterface;
rpc: RpcInterface;
serializer: SerializerInterface;
transactions: TransactionFactoryInterface;
uploader: UploaderInterface;
};
Expand Down
8 changes: 4 additions & 4 deletions docs/kinobi.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ Now that we know how to generate Umi-compatible libraries via Kinobi, let's take
Kinobi-generated libraries provide a serializer for each type, account and instruction defined on the program. It also exports the two TypeScript types required to create the serializer — i.e. its `From` and `To` type parameters. It will suffix the `From` type with `Args` to distinguish the two. For instance, if you have a `MyType` type defined in your IDL, you can use the following code to serialize and deserialize it.

```ts
const serializer: Serializer<MyTypeArgs, MyType> = getMyTypeSerializer(umi);
const serializer: Serializer<MyTypeArgs, MyType> = getMyTypeSerializer();
serializer.serialize(myType);
serializer.deserialize(myBuffer);
```
Expand All @@ -67,12 +67,12 @@ For instructions, the name of the type is suffixed with `InstructionData` and, f
type Token = Account<TokenAccountData>;
type TokenAccountData = {...};
type TokenAccountDataArgs = {...};
const tokenDataSerializer = getTokenAccountDataSerializer(umi);
const tokenDataSerializer = getTokenAccountDataSerializer();

// For instructions.
type TransferInstructionData = {...};
type TransferInstructionDataArgs = {...};
const transferDataSerializer = getTransferInstructionDataSerializer(umi);
const transferDataSerializer = getTransferInstructionDataSerializer();
```

### Data enum helpers
Expand Down Expand Up @@ -102,7 +102,7 @@ Kinobi will also provide additional helper methods for accounts, providing us wi

```ts
// Deserialize a raw account into a parsed account.
deserializeMetadata(umi, rawAccount); // -> Metadata
deserializeMetadata(rawAccount); // -> Metadata

// Fetch an deserialized account from its public key.
await fetchMetadata(umi, publicKey); // -> Metadata or fail
Expand Down
9 changes: 6 additions & 3 deletions docs/publickeys-signers.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,14 @@ const pda = umi.eddsa.findPda(programId, seeds);
Each seed must be serialized as a `Uint8Array`. You can learn more about serializers on [the Serializers page](./serializers.md) but here is a quick example showing how to find the metadata PDA of a given mint address.

```ts
import { publicKey } from '@metaplex-foundation/umi';
import { publicKey as publicKeySerializer, string } from '@metaplex-foundation/umi/serializers';

const tokenMetadataProgramId = publicKey('metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s');
const metadata = umi.eddsa.findPda(tokenMetadataProgramId, [
umi.serializer.string({ size: 'variable' }).serialize('metadata'),
umi.serializer.publicKey().serialize(tokenMetadataProgramId),
umi.serializer.publicKey().serialize(mint),
string({ size: 'variable' }).serialize('metadata'),
publicKeySerializer().serialize(tokenMetadataProgramId),
publicKeySerializer().serialize(mint),
]);
```

Expand Down
Loading

0 comments on commit 1e2ab1a

Please sign in to comment.