Deserialize instructions in JS/TS clients to send to your native program.
findProgramAddress(seeds, programid)
method.getProgramAccounts(programId)
.@coral-xyz/borsh
to create a schema.findProgramAddress()
function.
Let’s have a look at some examples…
"GLOBAL_STATE"
. If
the client wanted to read data from this PDA, it could derive the address using
the program ID and this same seed.
connection.getProgramAccounts(programId)
. This returns an array
of objects where each object has pubkey
property representing the public key
of the account and an account
property of type AccountInfo
. You can use the
account
property to get the account data.
data
property on an AccountInfo
object is a buffer. To use it
efficiently, you’ll need to write code that deserializes it into something more
usable. This is similar to the serialization process we covered last lesson.
Just as before, we’ll use Borsh and @coral-xyz/borsh
. If
you need a refresher on either of these, have a look at the previous lesson.
Deserializing requires knowledge of the account layout ahead of time. When
creating your own programs, you will define how this is done as part of that
process. Many programs also have documentation on how to deserialize the account
data. Otherwise, if the program code is available you can look at the source and
determine the structure that way.
To properly deserialize data from an onchain program, you will have to create a
client-side schema mirroring how the data is stored in the account. For example,
the following might be the schema for an account storing metadata about a player
in an onchain game.
.decode(buffer)
on the schema.
WalletContextProvider
we created in the Wallets lesson, a Card
component for
displaying a movie review, a MovieList
component that displays reviews in a
list, a Form
component for submitting a new review, and a Movie.ts
file that
contains a class definition for a Movie
object.
Note that when you run npm run dev
, the reviews displayed on the page are
mocks. We’ll be swapping those out for the real deal.
findProgramAddress()
to create a PDA that’s unique
for every wallet, for every film title. We’ll store the following data in the
PDA’s data
:
initialized
as a boolean representing whether or not the account has been
initialized.rating
as an unsigned, 8-bit integer representing the rating out of 5 that
the reviewer gave the movie.title
as a string representing the title of the reviewed movie.description
as a string representing the written portion of the review.borsh
layout in the Movie
class to represent the movie
account data layout. Start by importing @coral-xyz/borsh
. Next, create a
borshAccountSchema
static property and set it to the appropriate borsh
struct containing the properties listed above.
Movie
called deserialize
that will take an optional Buffer
and return a
Movie
object or null
.
null
if
it doesn’t. Next, it uses the layout we created to decode the buffer, then uses
the data to construct and return an instance of Movie
. If the decoding fails,
the method logs the error and returns null
.
MovieList.tsx
and import @nexis-network/web3.js
. Then, create a
new Connection
inside the MovieList
component. Finally, replace the line
setMovies(Movie.mocks)
inside useEffect
with a call to
connection.getProgramAccounts
. Take the resulting array and convert it into an
array of movies and call setMovies
.
HdE95RSVsdb315jfJtaykXhXY478h53X6okDupVfY9yf
.
StudentIntro.ts
. The account data
contains:
initialized
as an unsigned, 8-bit integer representing the instruction
to run (should be 1).name
as a string representing the student’s name.message
as a string representing the message the student shared about
their Nexis Native Chain journey.StudentIntro.ts
that will use the buffer layout
to deserialize an account data buffer into a StudentIntro
object.StudentIntroList
component’s useEffect
, get the program’s accounts
and deserialize their data into a list of StudentIntro
objects.