🔧 Build an Escrow Program on Solana with Anchor | Full Walkthrough by Mike MacCana
By TURBIN3
Summary
## Key takeaways - **Escrow is foundational for most Solana dApps**: Building an escrow program on Solana is a crucial skill, as most decentralized applications are simply variations of this core concept, involving token handling and arbitrary data storage. [01:15] - **Solana programs replace trusted third parties**: Instead of relying on a trusted third party for transactions, Solana programs (smart contracts) act as the intermediary, ensuring users receive 100% of what's offered without fees exceeding a fraction of a penny. [08:03], [10:34] - **Anchor simplifies Solana program development**: Anchor streamlines the process of building Solana programs by providing pre-built functionalities and a clear structure, such as the use of instruction handlers and account structs, reducing boilerplate code. [19:44], [21:15] - **PDAs are key to managing on-chain data**: Program Derived Addresses (PDAs) are essential for creating accounts that store program-specific data, like offer details or token vaults, and are deterministically generated using seeds and a program ID. [11:45], [13:30] - **Atomicity ensures transaction integrity**: Solana transactions are atomic; they either succeed completely or fail entirely, meaning if any part of an instruction fails, the entire transaction is reverted, preventing partial execution and ensuring data consistency. [01:04:23] - **Lightweight testing accelerates development**: Utilizing tools like Light-SVM can drastically improve testing efficiency for Solana programs, reducing test execution times from minutes to seconds, which is crucial for rapid development cycles. [01:45:14]
Topics Covered
- Every on-chain app is just a swap app.
- Blockchain eliminates the 1-6% financial middleman tax.
- Solana's architecture enables parallel transaction processing.
- You can combine programs into a single transaction.
- Why 90% of Solana developers just use Anchor.
Full Transcript
So everybody, welcome welcome welcome
welcome to a it's becoming a tradition.
We've done this quite a few times. Mike
McCanna from Quick Node is um is a is a
turbine uh WBA grad uh and I remember
vividly you know you were so you know
inquisitive on the escrow process like
you wanted to master it. It was I
remember it vividly and you were like
trying from this TypeScript background
trying to master it and you have that we
have you back because you present it in
a way that is, you know, different than
what we do in in program and a lot of
people need that. I mean, everybody on
this call, so half our current cohort is
here.
>> Yep. It looks like about we've got like
nearly 90 people here, which is amazing.
So yeah.
>> Yeah. So, I I'm going to turn the floor
over to you. Everybody knows the drill.
Help each other in the chat. Mike will
let you know when it's time for some
questions and let's have a good time.
Thanks Mike.
>> It's all good. Thanks very much uh
audible person. Um great. So we're all
here to build the Anchor escrow app. Um
just as a little bit of background uh
this is probably the most important
class you will actually attend. There's
a saying which I heard from Jeff
originally but I'm not sure who said it
originally which is once you build a
swap app everything else is a swap app.
I'm going to use the terms swap and
escrow interchangeably. They are
effectively the same thing. Um and yeah
that that that's a that's a saying by
almost every Salana developer. If you
are going to build an auction house then
you will still need to take funds from
people. You will need to store arbitrary
data on chain. Uh you will need to uh
refund things to people etc. If you're
going to build uh something like a poly
market um betting app for example you
will need to do all these things. So
this really covers essent the handling
of tokens and arbitrary data. So today
uh you don't need I'm going to assume
you have almost no blockchain experience
and almost no Rust experience. I know
you guys have all done the vault before
um but I I'm trying to keep it really um
really just minimal in terms of the
requirements because I know you guys are
new to a lot of this stuff. And yeah, so
what we're going to be doing today is
you're going to be building instruction
handlers, uh, which are onchain
functions that process instructions.
Some sometimes people call instruction
handlers instructions. I like to
separate the thing that's doing the
actual function. I like to separate the
function from the thing that it's
processing. So I say instruction
handlers are the things that handle
instructions, much like I don't know,
like request handlers handle requests in
a in a traditional app. Um, we're going
to store tokens in our program. We're
going to store data, arbitrary data that
we create ourselves. And we're going to
control access to our program. Um, who
am I? I got started in Salana, I think
late 2021.
Yeah. Um, I won a couple of prizes in
Salana Sandstorm. Me and a buddy were
trying to build a wallet. Uh we ended up
in the kind of Nadier of crypto winter
in early 2023.
Um so that didn't work out. We we had an
investor that was about to send us a
check any day now for about four months,
which is always fun. Uh but I ended up
spending most of 2023 and 2024 at the
Salana Foundation. Um doing a bunch uh
creating educational content for uh
companies that had grants from Salana
Foundation to teach to other people. So
that's been spread out across the world
and taught everywhere from Romania to
Columbia University in New York. Um I'm
followed by everyone you all know on in
Salana on Twitter. Um uh so I you know
whatever reason I've just been in the
space for a while and and I I I know
most of the people in it. Um if you ever
used um Web 3JS version one I made the
Salana helpers library that you will see
everywhere. it still has about 30,000
downloads a week. Um, I made the
successor to it which is called Kite.
Uh, Kite just saves you a whole lot of
time when you compare it to using Salana
Kit on its own or using Gil. It's really
designed to allow you to do the most
amount of um work with the smallest
amount of code. So if you're tired of
setting up factory functions or just
boilerplate code um just using Salana
kit or Gil then kite is a higher level
library to just do things. Uh right now
I work at Salana developer relations at
QuickNote. That's actually a new job.
I've been there for about two months now
and I am um pumping out videos and
content like crazy. We we just did a big
deep dive into light SVM uh a couple of
days ago. Um including a bunch making
making a bunch of new open source code
to like work with light SVM a little bit
easier. Um uh the next thing I'm about
to do is Touktouk which Jeff is
pronounced touktouk and not tuktuk. Um
you need to spend more time in Thailand
having fun. Uh Quicknote. Quicknode
actually created the RPC provider
business. I think there was one other
company that's not around who was there
in 2016. Quicknote started in 2017 and
really like popularized the whole
concept of commercial RPC providers.
They're a YC company. YC or Y Combinator
was the first investor in Uber, Airbnb,
Dropbox, Google Docs, pretty much every
like big modern startup you've ever
heard of went through YC.
uh also the first RPC provider to
support Salana when Salana was brand new
and is used by really big things big
platforms you would have heard of before
uh like drip kraken phantom and a bunch
of others um the thing that's
particularly unique about uh quicknote
is it has a lot of highle libraries uh
most of which are actually free so uh
there's things like streams that allow
you to like pull down and modify um
Salana transactions it's if you ever
have like a finan potential app you want
to like back test it through some
previous period it's great for that and
again it like starts from like there's
generous free limits for nearly all
these things uh there's metas which is
just uh Jupyter swap APIs pumpf fun and
a bunch of other useful bits and pieces
there's a price API almost everyone
wants this and again you can get it free
for free uh KYC and and AML bits and
pieces u we have a really good ultra low
latency
uh stated quality of service uh system
called fastlane
um and yeah it's if you have a quick
node account just go into the quicknote
marketplace sort by Salana and you'll
see all these things there um it's a
really good way to kind of just get to
market faster and by having to build
less code.
Cool. So why why are we going to build a
swap program today? What does it do?
What is the equivalent in traditional
finance? Um, well, swap program handles
when somebody wants to swap something
for something else. So, in this case,
Alice has a uh 50 USDC into bonk and she
wants a little bit more bonk. Uh, and
Bob comes along and he sees that Alice
is offering to swap 10 USDC for 100 bonk
and he thinks that's great. So, they
swap.
That's all fine, but what if Bob is a
bad actor? The complexity here comes
when Alice sends her USDC to Bob and
then Bob just leaves. So, what we really
want to do here is have a situation
where neither Alice nor Bob have to
trust each other. Um, sorry, that's a
funny gift that's left over from the
last time I did this. Uh, the joke
hasn't been delivered well. Uh, if you
could imagine that I did deliver the
joke well, uh, that would be great. Uh,
and, uh, you can edit that out, please,
Jeff.
Uh so the point is how can we ensure
Alice and Bob can swap without having to
trust each other. Um so this is how they
handle that in traditional finance. Um
Alice sends her 10 USDC to a trusted
third party and then Bob will send his
100 bonk to the same trusted third party
and once that trusted third party holds
those funds in escrow which is where
this word comes from if you hadn't if
you haven't heard it before escrow means
um holding something on behalf of
someone else and then once both sides
have completed their part of the
transaction
then the third party will distribute the
funds to their destinations. What you'll
have noticed here is that third party
has grabbed uh a portion in this case 1%
of the value of the transaction.
And that's pretty much how normal
finance uh works. I bought a coffee this
morning. Um I you know gave it a tip on
that blue and white machine that
everyone has. That's from a company
called Square and they take 3.5% of
every transaction. Um, and if you're
sending money overseas, depending on the
country, that can be up to 6% of the
transaction. Um, crypto offramps, which
I have a separate rant about, you
shouldn't use. You can actually do zero,
there are 0% off ramps now. PayPal is
one. It's amazing. Um, crypto offramps
used to charge like huge amounts in
percents as well. Um yeah, this this
whole traditional finance is built on
taking these uh somewhere between 1 and
6% of the value of every transaction.
That's a huge quantity of money. And
that's what we're going to solve today.
So blockchain solves this with the swap
program. Again, you can call it an
escrow program, the same thing. Um so we
still have uh Alice and she has 50 USDC
and two Bonk and Bob and he has 10 USDC
and 500 bonk. We're going to get rid of
the trust a third party and we're going
to replace it with a Salana program
which is also called a smart contract.
Um just in the same way the people in
Salana tend to say things like mint
address rather than contract address for
a new token. We call the programs we run
on Salana Salana programs rather than
smart contracts. Um if you're new to the
space you can sound cooler on X by using
the Salana words rather than the older
words. Um, so we're going to make a swap
program and through that Alice and Bob
will swap.
Great. Well, how does it work? Um, uh,
oh yeah, and what the point, Alice and
Bob will swap and both sides are going
to receive 100% of what the other side
is offering. It's a really big deal. U,
and yes, there are transaction fees, but
those are less than a fraction of a
penny. Salana is like 0.00 something.
It's a really long amount of zeros
cents. Um, so and it doesn't change
based on the amount of money. Um, you
know, Alice could send $10 million
um to to Bob and the fees would still be
the same amount. So that's that's a huge
huge win for crypto. Um, and again, you
know, the uh the time involved here is
maybe two or three seconds for
transaction confirmation. um depending
on on the options you pick uh and Salana
is getting faster every year so that
might even go down pretty soon too. So
let's look inside this swap program. Um
here we have the Salana curve and Alice
has a basic Salana account. She has you
know a key pair she has the private key
stored on her device and she has a
public key and she has a balance of
soul. This is the most basic type of
Salana account. And Salana also Oh,
sorry. Alice also has two other accounts
that store her USDC and her bonk. Um, so
that's two token accounts. Uh the uh she
has a
pardon me um she has uh a USDC account
um whose address is made from the USDC
mint address and Alice's own address and
a bonk account made from the bonk mint
address and Alice's address. These are
program derived addresses uh by the um
uh the uh the what's it called? The um
associated token account program. Um,
you can also just call them associated
token accounts. Um, same thing. They are
token accounts that are associated with
somebody's wallet. You might know a lot
of this stuff already, but I'm I'm being
very deliberate about this stuff just to
make sure that everyone's on the same
page. And if it's new to you, it's
probably just reinforcing things that
you already know, which is always good
as well.
So, Alice still wants to swap 10 USDC
for 100 bonk.
And we're going to make a swap program
to handle this. So we're going to deploy
that um to a uh a program ID which is
also a public key um that'll be
generated when we deploy our program.
And it's going to have three instruction
handlers inside. They are make offer,
take offer, and refund offer.
So when Alice makes an offer, she's
going to run the make offer instruction
handler.
And the make offer instruction handler
is going to create an an offer account.
This is another PDA that stores a strct
inside. A strct is very similar to an
interface in Typescript. um and uh the
kind of the resulting object that you
make from that um it's just a list of
keys and values of different types. So
the strct will store things like what
Alice wants in return for her USDC.
The other thing our program will do is
take hold of the USDC that Alice is
offering.
So we're going to put that into an
account that we call the vault. Uh we'll
store that 10 USDC there. Um, the seeds
for that will just be the USDC mint
address and the offer address. We can
als we can even just store the seed just
using the offer address. We don't even
need to use the mint address, but that's
just the way I've implemented this
program. Um, here's a thing that I I'm
going to mention a couple of times
because it's really important. The owner
of the vault accounts is the offer
account. So, that data account that
where we stored information about
Alice's offer, that will actually own
that vault account. And you'll see later
on when we want to move funds out of
this vault account, we'll actually sign
those transaction as the offer. Um,
again to say the owner of the vault is
the offer account. So yes, our program
ultimately controls the vault account,
but when our program uh is uh moving
moving those funds, it will sign that
transaction as the offer account.
So Alice has made an offer and then
Alice can just go to bed at this point.
She doesn't need to be awake or online
or anything for the rest of this
process. And you know there can be a
thousand or a million Alice's. It's all
fine. Our program will make offers as
needed. They're each going to have a
unique offer ID. If someone tries to
make an offer with an existing offer ID
will be rejected. Alice can have many
offers herself there. Again, they'll
each have their own offer ID. Um, but
this is just the simplest case of uh two
users, Alice and Bob. So, Alice has made
an offer. She wants to uh swap 10 USDC
for 100 Bonk. And that's she's done all
she needs to do for this transaction at
this point. So, here's Bob. And Bob has
again a basing account with some amount
of soul and uh a USDC account and a bonk
account. And he has a lot of bonk. And
he likes Alice's offer.
Um, by the way, if this isn't obvious
for people, I hope it is. Um, if you
open up like Phantom or Soulflare, those
PDA accounts that you see underneath
Allison Bob correspond exactly to the
token accounts that you see um in
Phantom or Soulflare. Um, you can even
open up um your wallet in Salana
Explorer and you'll see the balances are
exactly the same. These these PDAs are
your your token accounts that you see in
your wallet. So, Bob has come along He
has a lot of bonk and he likes Alice's
offer. So what he wants to do is he
wants to get that 10 USDC
and he wants to um and in exchange he
has to send his 100 bonk. So if Bob runs
take offer
and again Alice doesn't need to be
online for this.
Our program will send the tokens in the
vault to Bob
and then transfer Bob's to Bob's uh bonk
directly to Alice. And that's all all
that needs to happen. It's just those
two things. And you'll actually see that
in the code later on. Um
uh what else?
Yeah, the bit the main point of this is
that each side has received 100% of the
other's offer without a middleman taking
a percentage of the transaction. You
know, Alice got her 100 bonk, Bob got
his 10 USDC at the same speed as
traditional finance. Pretty soon, I
think Salana is going to start outpacing
things like Visa, etc. And you know that
uh your crypto transactions will go
through faster than you hear than you
wait for uh that Visa um beep when you
buy a coffee. Um, and the fees are less
than a fraction of a penny.
So, the first thing I want to do is
create data accounts. And I'm going to
start getting you to code at this point.
So, I'm going to throw a um a uh little
some couple of commands into the tab
into the chat. Um, the first one's
actually important because the second
command is actually going to dump files
into this directory. So, do make an
escrow directory.
And then the second thing is do that.
Um, oh wait a sec. I'm probably
CD into escrow first.
Can I can I edit or a comment or delete
it?
In other words,
>> just wanted to check if people can hear
me. If you can speak up, if uh if those
commands will make sense. Yeah, we got
some great.
>> Well, I'm sorry. I uh I forgot to
mention the CD into the directory, but
definitely change into that directory
because DG does actually um dump all
those files straight in there for you.
What digit does is it just downloads a a
project off GitHub. Um so uh it doesn't
include any of the git history. It just
includes the files. So if you ever need
like a copy of a particular um uh you
know project and you you don't care
about the git history, you don't you
just want to download then dit is a such
dit something. I actually have a copy of
the project here. Um, and I'm gonna go
through uh I've got my many many windows
here. Give me one sec.
Yep, there we go. Um, I'm gonna go
through the structure of that um of that
project now. And I'm going to make my uh
screen nice and big as well when I do
that. Okay. Um so if you look in that um
directory that you've pulled down um
this is an anchor uh project that has
what one or more programs inside it. In
this case it just has one. It's called
escrow. Um we have our project
configuration here. None of it's
particularly interesting. that's just
like you know where you know that your
wallet is your in your salanic config
file that test using local net boring
things like that. Um the really the
really interesting action happens in the
programs escrow directory. Um the layout
I've used for this um is what you get
when you run anchoredit
d- template equals multiple. Um, I might
even type that in the chat or if someone
else can do it for me, that would be
great. Um, so rather than just having a
big um lib RS uh file, which I I kind of
think is pretty gross, um, you actually
have separate directories for each of
the instruction handlers. I renamed um
the instruction directory to handlers uh
rather than instructions uh just because
I I'm I'm very, you know, I I I have
autism. I'm very specific about the
rules and I I I don't the idea that you
have an instruction that handles an
instruction doesn't make sense. You have
an instruction handler that handles an
instruction. That that's the way my
brain works. So, I just renamed that
directory, but this is pretty much a
blank project. Um there's it's a generic
lib RS that none of these are filled in.
Um I've got some errors in there just to
do some boring stuff, but yeah, the make
offer is empty. Um all the uh account
strcts in there are empty. The state
directory is empty. The offer is empty
as well. So what we're going to do here
I'll just flip back to my notes for a
second my presentation I should say. Um
is go and create make offer.
Oh sorry. Did we let me just double
check something.
what accounts. Oh, yeah. I'm just going
to Cool. I was trying to work out if I
had any bits to show you for here, but
I'm just going to go uh straight into
it. So, sweet. So, what we're going to
do here is go and the first thing we're
going to do is create the offer account.
Um, sorry, the offer strruct, I should
say. So, this is the thing we're going
to store on chain, which stores
information about what Alice wants in
return. Um, and it's pretty simple. Uh,
I'm not going to make you type. You can
type if you want to. Um
uh but my kind of thing here is to kind
of keep this as interesting as possible.
Nearly every anchor file you'll know um
does imports what's called this prelude
at the beginning. If you're not familiar
with the term prelude uh whenever you
edit a file in Rust, there's a bunch
there's a bunch of like keywords that
Rust has loaded up before you. It's
called the Rust prelude. Um, and anchor
has its own prelude that you have to
manually load in. And yeah, it's it's
what gives you access to things like
account, for example, that comes from
Prolude. So, you probably know about
that already. I think in in WB WBA or
Turbine, they call them the goodies. Um,
so we're going to do a few things here.
Um, the first thing is to
I'll get rid of this.
>> Lots of goodies. lots of goodies. Um,
so this is uh I'll I'll paste in what's
going to be inside this strct. Um, and
these are just some really basic types
that we all got from prelude. Um, or
mill well things like pub key came from
prelude for example. U 64 is built in
rust obviously. So we have an identifier
for the offer. This is just a a number.
It's specified by the client which you
will think is really weird when you come
from kind of traditional web two
programming um or you know anything off
blockchain um but we'll actually do
checks to make sure that um we can't
create um you know people can't create
offers using IDs that are that uh
already exist. We'll store details about
who made the offer. Um uh we'll store
details about the tok about the token
being offered, what they want in return,
how much of the token they want in
return. Um and we'll store the bump,
which is just a uh because of the way
these addresses are calculated. It's
just done as a performance optimization.
It will save us some um time having to
calculate this address later. The um so
this this strct again is really similar
to an interface in Typescript. And one
of the things I'm going to actually add
to it is um because later on I'm going
to need to know how much space this
offer actually takes up on the
blockchain. And I'm not going to sit
there calculating it knowing that every
like uh pub key takes 32 bytes or
whatever else. So I'm gonna add this um
uh attribute called init space um which
actually you can read the uh um uh
implements a space trait which is
basically I think size would probably be
a nicer name than space but it's a
really nice way to get a total for what
all this um for the space requirements
or the size requirements to store all
this information. So if you want to know
um how how many bytes an offer is to
store on chain because you're creating
an offer account for example um you will
use this uh init space number in
conjunction with a um uh something
called the discriminator size which
we'll which we'll do in a sec. Um save
that file. U make sure you don't have
any uh warnings from things like um rust
analyzer etc. Um, but you should be
pretty much good to go. I'm going to
build make offer before I go through the
tests just because uh the client that is
generated needs a little bit more of
make offer to uh to to exist. Um, so let
me let me do that. I'm going to go in
and make make offer. All right. So,
we're going to do our make offer now. Um
and one of the things in uh so each
instruction handler has two parts to it.
Um it has a strct of accounts which
people need to specify as when they run
the instruction. Um and it has the
actual function which um you know does
the actual work. Um I'm going to import
a few extra things here. Um I'm going to
import my errors which I made a moment
ago.
Uh, do I error code? Cool. I'm just not
using them. Um, I'm going to import a
function called transfer tokens that I
set set up in this shared folder. This
is all generic code. Um, but it's just a
helper to transfer tokens from wherever
they need to be transferred from to
wherever they need to go to. Um,
transferring tokens involves a a call to
another Salana program. So, I've just
wrapped that in a function. Um, and
we're going to want anchor SPL. So,
let's do that. Um, I probably also, uh,
SPL tokens are the name for any token
other than soul. Um, I probably want to
make some changes here to my, um, to my
anchor config as well. Um, I will want,
where are we? Uh, cargo tunnel.
Sorry, this is a little bit zoomed in.
some uh anchor toml.
Do I have uh cargo toml? Do I have I
just want to make sure my dependencies
are correct. Um do I have cargo toml
should be in
is that the sorry I'm it's cuz my
screen's so zoomed in. It's a little bit
clumsy for me here. So programs escrow
cargo tunnel. There we are. And I just
want to make sure I've got anchor SPL
cool. So I'm using I've added anchor SPL
as a dependency. This is you will nearly
always use anchor SPL. Um it's how you
use uh any token in Salana other than
soul. So obviously we want to handle
bonk, we want to handle USDC, we want to
handle everything else. So you nearly
always want that as a dependency. um in
it if needed is the uh uh feature that
allows us to uh create an account if it
doesn't already exist. Um and we're
going to turn that on and the rest is
just uh telling anchor what version to
you or telling Rust actually what
version of anchor to use which is the
current version. Um IDL build as well.
We want anchor SPL IDL build. Um that is
uh just another feature we're going to
turn on again just to handle tokens
other than soul.
So we have um so we've got our makeoffer
instruction handler. It has the actual
function and it has our list of accounts
that people need to specify.
Um we're going to use all the normal
token programs. So or all the normal
Salana programs. So we're going to use
the associated token program. We're
going to use the token program and we're
going to use the system program. So
we're just going to specify those
already. Um uh we have this program type
which is kind of wraps around the
associated token program. Uh again we
have the program type which wraps around
the system program. Um we have this
thing called this interface type and
that's actually a way to use either the
older token program or the new token
extensions or token 22 program. Um, so
this allows us to uh like handle Alice
and Bob could be swapping to older older
um to older tokens or to newer tokens.
Um, they just have to be consistent
about the token token uh program they're
using. Um, I think it should actually
allow um swapping um uh tokens of uh a
different type in the same transaction.
um as long as they you know like Alice's
ATA is um for the alter token is owned
by the alter token program but I will
check that out and follow it up. Um we
have our maker who's the person who is
making the offer. Um it is uh this
account will also pay to make the offer.
So we need to debit the balance which is
why we add this immutable attribute. uh
they're because they're uh make because
they're creating this they're running
make offer they're signing that
transaction.
Um we have the token mint A which is the
token that they are providing. In other
words, Alice is has uh some USDC. So
this is in in this case that would be
USDC would be token mint A. Again that's
an interface account could be older
token program could be newer token
program. They're both fine. And that's
just going to wrap around the token mint
type. We apply a little check check here
to make sure that whatever the uh token
program of um the account Alice is
providing is the correct one. Um we're
going to store token mint B which is
just the token that Alice wants in
return. Um
and oh sorry I I think I mentioned
before this is Alice's token account.
That's not Alice's token account. That's
the type of token that Alice is
providing. I should have said this is a
token mint. In other words, um this is
uh USDC or yeah, this is USDC in this
case. Alice's token mint account is
actually called maker token account A.
Um and again, we're going to use an
interface account there. So, we're going
to debit Alice's token account A cuz
she's providing that USDC. We're going
to check that the mint matches token
mint A. Um, we're going to check that
that account is actually owned by Alice
and that the token program is the same
as the token program used elsewhere.
In other words, it's the same as this
token program.
Uh, we're going to use an offer account.
So, we're going to specify that. Um,
again, it's account that just wrapped
around this offer type. Um, we're going
to create the offer. So we use the init
um attribute. We're going to say that
Alice is the person who is making this
uh program uh making this account I
should say. Uh the space needed will be
the combination of these two things
which is pretty much the space needed
for any any data strct on Salana. It's
always uh at least using anchor. It's
always the discriminator the
discriminator length and the init space.
Easy for you to say, Mike.
It's like cinnamon.
>> Uh, so yeah, it's um the discriminator
is basically just a type that Anchor
actually writes out to accounts. Um,
it's it's just eight bytes and it's
actually could even be less than that.
Now you can actually it's eight bytes by
default. Um, and so the data to actually
store an offer is eight bytes. The
discriminator length plus the size for
all these things. And the way we get the
size for all these things is we use this
really neat um uh uh init space
attribute which gave us this um init
space property and that's how we got
that. So rather in in anchor many years
ago and you'll see this in old Salana
tutorials someone would go um eight
bytes for the U64 and 32 bytes for this
pub key and 32 bytes for that address
and all the rest of it. We don't do that
anymore. we just sum these two um bits
of information. So that's the type that
will be stored inside the account and
the space needed for all the data
inside. Um the way people will find an
offer is just using offer and the offer
ID. We do a little bit of extra work to
turn into bytes. Um but uh you know it's
it it really just is the text offer and
the offer ID that U64 turned into bytes.
um that becomes the address of this
program. It's an interesting thing. Um
by the way, if you are familiar with
like cryptography in general, um you'll
realize that this pub key thing is
actually misnamed. Sometimes it is
actually a public key. Like maker is a
really really a public key. Token mint a
um is actually not a public key. It's a
it's a PDA. It's it's uh it's not it
doesn't have a private key or anything
else like that. Um the Salana program
crate still calls it pub key, but I've
got an issue on GitHub to actually have
this renamed to address. And you'll see
if you use things like Salana Kit,
they've actually renamed this to address
anyway. And even if you look at the um
uh like the um docs for um the the pub
key strct, it actually says this is an
address. Some of them are public keys
and some of them are not public keys. So
I just wanted to call that out
explicitly because I know you guys are
like new to Salana and this is one of
the things that I found to be a little
bit like really kind of a little bit
misleading but yeah they called it a pub
key. Sometimes it's a pub key if it's
actually like you know a regular uh you
know public key with a with an address
you know like like your Salana wallet.
Um, sometimes it's not a pub key if it's
some kind of data account like the PDAs
that store all your token balances or
the PDA we're going to be using to uh
for this offer. So, in this case, it
will be made from just offer and an
offer ID. That's how we're going to make
the address. Um, the final account that
we need for make offer
is what we're going to call a vault
account and that's a token account.
Again, we just wrap it in this interface
account thing. So it can be token
extensions or the older token program.
We're going to make the vault. Um the
person running make offer will uh pay to
create the vault. And we're just just
going to have some uh some checks that
um the uh the mint account on that token
account is matches the token in a the
authority on that token account is the
offer. I mentioned this earlier the
vault is owned by the offer. So
authority, you'll see this word in
Salana a lot. It means like the boss,
the the the person that like is in
control. So the person or the account
that's in control of this vault account
is the offer account. Um I will just
briefly swap back to that diagram from a
second ago.
Um, so this this this guy here, this
vault account is owned by this offer
account. And when we move things from
the vault account, we'll sign that as
the offer account. And you you you might
think that's a bit weird because the
offer account doesn't have a public key.
We'll show you how signing works for
sending um things from uh token accounts
that are owned by PAS a little bit
later. Um I will go back to my notes.
Um, so we have make offer. Um, I'm going
to save that.
Uh, oh yes, we need to do a couple of
other things as well. We have a a bit of
a what's called a rust lifetime here. It
just specifies how long u it's kind of
like a generic for how long something
should be should live in memory. Um, I'm
not going to go into rust lifetimes here
because that would probably be another
lesson onto itself. Um, but if I save
that, it should be a little bit happier.
Now you can see um also uh you'll see
there should be another little error a
little bit later. Yeah. Um we uh we need
to say that um that this strruct will
have access to some of the other um
parameters from when people run make
offer. So, we're going to create a make
offer function later on and we're going
to say that this strct has access to ID
um because we're going to make our offer
account based on the ID that someone
provides when when they run the make
offer function. That's all happy. Now,
we have a couple of unused functions,
but the big thing is we have no red. So,
I'm happy with that. Um and then I'm
going to go and create make offer. I
mentioned before make offer is just
doing this. Um,
so as Alice makes an offer,
oops,
I'll move that over here. So Alice makes
an offer,
it saves details about what Alice wants
and then moves tokens into the vault
account. So that's exactly what we're
going to do now. Um the first part of
that
is to
well we're going to have a few things
that Alice is going to specify. So let's
do that first.
Um I'm going to mention a couple of
arguments. every um anchor instruction
handler always starts with the context
that allows you to do things like
there's like context accounts which is
all these accounts. So that's uh that is
where people running this function
specify all the accounts they want to
use. Um uh you can also do things like
context ID for so for the program ID. Um
I don't want to confuse that with the
next one which is ID which is actually
the offer ID. Um so yeah, context is
just basically a bunch of information
about how uh it's the first argument for
any um for any anchor instruction
handler includes all the accounts. Um
but there's other things in there as
well that you can also find useful like
the program ID. This ID here though is
the offer ID that people are about to
create. So it's um it's uh will be
specified by the client, but you'll see
we do some checks. Um in fact, you
you'll see those over here. um in it
will actually fail if uh the offer
already exists. And when we run our
tests, we'll actually do some we'll
actually go and we'll try and create
duplicate offers. Um and we'll try and
create um uh what else? Like um
yeah, we we're going to do a bunch of
like kind of uh malicious things in our
test just to make sure that they don't
work. Um we're going to you know like
we're going to be making offers for
things like um you know insufficient
balances and all that kind of stuff. Um
I'm focusing on the rust today. The
tests are done for you. That's why we
did the npxe.
Um so we're going to so people when they
run make offer they need to specify all
their accounts which are inside that
context. They need to specify the offer
ID they want to use. Um they want to
specify how much of the token they're
offering and how much they want in.
First thing we're going to do is just
check the amounts. We want to make sure
that they actually have um
uh at least some amount of that token.
So if if they say um where uh I want 10
uh I want um uh 100 bonk in exchange for
zero USDC. Uh we're going to throw up an
error. Um errors are, you know, pretty
boring here. So I've actually done them
for you. If you look in the file
error.rs RS. It's just another um it's
it's an enome very similar to a
TypeScript enom with a bunch of
different options that uh we have these
little kind of values and then the
message on top becomes the nice message
that you see in the Salana log when you
look at the you know either Salana
Explorer or um or the command line if
you're you're you know running these
things locally.
Um, so we're just going to check that
people actually have some amount of what
they're um uh people are uh they sorry
we're not checking whether they have the
amount. We're actually checking if they
are uh that they want or that they're
offering more than zero. Um next thing
is we're going to make sure that the
mints are different because nobody says
I'm going to offer 10 USDC in exchange
for 9 USDC. That would be very silly.
So, I'm going to do that. Um, again, we
just look in, we look at the accounts
they specified, and we just make sure
that token mint A and token mint B
aren't the same thing.
Then, I mentioned a second ago, this um
instruction handler only does two
things, which is move the tokens from
the makers um associated token account
into the vault. So, let's do that now.
Um, I'm running this transfer tokens
function and I'm moving it from makaker
token account A into the vault
specifying the amounts that they said uh
when they ran ran this instruction. The
mint of course is token mint A. The
authority is in the person who is owning
who owns um those accounts those tokens
that are being moved is is the maker
Alice in our example. Uh the token
program is the token program that our
specified via um the uh via the
context.ac accounts. Um and we don't
need anything for that last option cuz
it's not relevant here. Um you'll see I
I like I'm a big fan of this uh map
error stuff. Basically, whenever you do
a thing in Rust, it's going to give you
a result. And you'll actually see that
here. uh it's a result of either um
something or an error. Um and if it's an
error, we're just going to throw up an
error with a an a nice uh error message.
Uh you can use the um question mark here
if you wanted to. You could just do um
rather than map error, you could just do
question mark and it would throw up its
own error. But we kind of want to wrap
it in like a like a nice error. So in
this case, we're just saying, you know,
we kind of assume that the uh the maker
balance is insufficient um because
that's the most common cause of this
error. We might actually want to be a
little bit more detailed than that. But
yeah, and of course we have we do
actually have a question mark here, but
that's if the map error itself fails,
which is kind of unlikely. So the
question mark is okay here. The the
final thing this instruction handler
does is save the details to make that
offer count. So, we need to I just want
to kind of rewind here. We need to make
this We've just Sorry.
Oh, I can't highlight. Hang on. I'll go
back to my next. There we go. So, we've
just created this offer account when we
did this stuff here. We took the address
of the offer account that the person
running make offer specified and we've
filled it with all this information, the
ID, the maker, you know, the token A,
token B, etc. So, we've made this guy
during make offer. The next thing we
need to do is create this thing. Um,
oh, actually, did we done the Wait a
sec. Have I I've gone I' I've I've gone
in a slightly different order, but it's
okay. Um, so I've uh Yeah. So, I've made
that guy, and then I'm going to move the
tokens. So, I'm going to
So, we've done the we've created the
offer. Oh, we've already done the
transfer tokens. Sorry, you guys got to
speak up if you see me doing this. I
just realized I've completed I've
completed this already. So, we've done
the transfer tokens. That's moved them
into the vault and um we've uh saved
details about what Alice wants in
return. So, we've made this this data
account here, this PDA that uh will be
we can find just using the offer and the
offer ID.
>> Hey folks, you know, I see a lot of
people on here that are just regularly
rambling and on during the week. Feel
free to unmute.
>> Yeah, jump in. Like,
>> you can't be shy here. Like, I I I'll
call your names out as people I know are
jamming. So, don't be shy, folks. Jump
in. That's what we do. Um,
>> seriously, never mind. Since when are
you not talking, man? We love the chat.
I mean that with love, man.
>> Oh,
my joint. So, we try to be, you know,
like try to be nice, not to interrupt
him.
>> Um, I'm actually here.
>> I'm gonna run the tests and I think
after we uh run the tests and get
makeoffer working, we should have a
little bit of a like a like a Q&A type
session. Um but yeah, we've done all the
things we need to do in makeover offer.
This is actually pretty simple. Um and
you'll actually find that um like most
anchor programs are actually pretty
small like this. Um once you get the
basics of like you know writing data
accounts, you know, context accounts
offer set in go to the offer account set
this data inside it or moving tokens
around. um that handles a lot of what
you need to do in most anchor programs.
If you're going to make a betting app,
um you know, you will uh you'll have a
bunch of events that people can bet on.
You're going to have a maybe a uh
instruction handler that can only be run
by a certain account. Um and you're
going to do go like context accounts
event set inner and you'll go and like
save some details about I don't know the
upcoming election to that account. This
is how uh this is how we make data
accounts on Salana. This is how we move
tokens around on Salana. Um I am going
to go and run my tests now. Let me uh go
get my terminal back up here and clear
that and it should be good. What do we
got?
We cool. We're missing some bits. That's
all right. It's uh I don't think they
ever really like if if you get something
working like out of the box I I think
it's Oh yeah, of course. So we've we've
gone and set up a make offer but in lib
RS we haven't even like referenced make
offer at all. So we need to go and have
uh you can actually see there's that
error there. So if we go into lib RS um
we'll actually we'll give it all the
same arguments that make offer itself
has. So in other words just that normal
context
And then we'll go off to
Oops. We'll go off.
I got a little extra. There we go. Cool.
Um,
so we in our lib RS we just have like
kind of boring wrapper functions which
take all the same arguments. Context ID,
offer, offered amount, wanted amount.
Uh, you'll see that here. context, ID,
offered amount, wanted amount, um, and
pass them on to the, uh, individual
files inside our handlers directory. We
could call that instructions if you want
to. I just like the term, um, uh,
handlers as I've specified. So, we fixed
that. Let's go back to our errors.
Oh, it looks happy. Okay, cool.
I'm just just going to give it a sec to
finish running those tests. Some of them
will fail because I haven't implemented
uh take offer and I haven't implemented
refund offer. So, we'll let it do its
thing,
but you should see that. Oh, cool. Happy
things are happy things are happening.
Great. This is exactly what we wanted,
right? So, we have a bunch of tests. Um
I'm not going to spend too much time on
the TypeScript side of things um because
that's pretty boring. You've probably
seen it before. Um but all one second's
got a question.
>> Oh yeah sure. Yeah, I just wonder why uh
like let's say for transfer tokens we're
feeling too much uh like parameter there
like to so is there any practice to do
like trying to or into just to convert
the the strct we have
>> we we are creating let's say we we doing
like um so it's it's converted in
correct format so we don't fulfill it
like initially u say like we we passing
like context accounts maker and and
stuff. So,
can can we use something like trying to
is there anything in anchor or
>> um
>> I'm I'm actually I'm having trouble
understanding the question. So, I
understand you're talking about transfer
tokens. Um
>> yeah, like uh in transfer token we have
like form to mint authority. So, we need
to fill them like manually. But
actually, we have this truck. So, we
like transferring from one ST. So what I
was thinking is like
>> oh
>> like trying to just converting them into
the from the let's say uh uh how we call
it like from makeover offer strct we can
actually struck them for the transfer.
So it doesn't make sense.
>> Yeah. I get I think you're trying to
like use less parameters by just kind of
having them come like more directly. Um
uh so honestly it's like I mean the way
that transfer tokens is written um I I
guess is uh there's probably some some
word context is over overused here
some some kind of background information
that's uh that's missing here. Um, so
the real function of transfer tokens is
just to be a reusable function.
>> Um,
>> yeah.
>> So there's like this takes care of just
doing a lot of the boilerplate work of
uh of moving tokens around. So you'll
actually see in refund offer in take
offer, we're calling transfer tokens all
the time. Um, this is actually just
something I I made for myself cuz I
noticed that I was doing this work of
transferring tokens all the time. Um so
uh we could actually get a we could
actually just run this direct like we
could do all this stuff directly like
what transfer tokens actually does is it
calls the uh tokens pro the token
program has a transfer instruction
handler and all this does is make a call
or a CPI which is a cross program
invocation one Salana program running
another program um to uh you know
transfer some tokens. So it my escrow or
swap program is calling the token
programs transfer function. Um so we
have this kind of context that's set up
called a CPI context. Um and then we
have some kind of additional bits and
pieces that are needed for that. Rather
than um uh doing that directly inside uh
make offer refund offer and take offer
I've just written this reusable
function. So that that's what's going on
there. So there's there's you're right,
we could absolutely put the uh CPI,
context, new, etc. directly inside make
offer. But um I I'm a big fan of just
like I I love function libraries. I love
kind of small things that I can kind of
invoke when I when I need to um that
reduce the amount of code I need to look
at. Uh, and then I, you know, if I, if I
decide at some point in the future that
I I want to change them or fix them,
there's one place I can look. You know,
if I wanted to modify all my transfer
token functions to, I don't know, change
some error messages or add some extra
checks, um, I could do that inside this
function. So, yeah, it's um, uh, you're
right. We could do all of this stuff
directly inside each instruction handler
function.
>> Cool. Um, does anyone else have have any
other questions as well? I'm like
totally uh we've got a bunch of time
like we're really like make offer we've
done the first instruction the other two
we're kind of downhill from here.
>> Could you uh could you read them out?
I'm doing a bit of window management
here. So with this transfer function uh
oh yeah cool. Oh yeah that's Tommy
that's a really good question actually.
Um so yeah it's uh uh I can get you I
can get you two of the three arrays. Oh,
it's actually technically it is a uh
it's a a vector of a vector of a slice,
but it is a nested data structure. And
I'm pretty sure there's a really good
explanation of this on um Salana Stack
Exchange. Um but I'll I'll show you what
it is here. And it's actually it's not
as complicated as what you were
thinking. Um in uh uh what was I looking
for? Um transfer tokens.
This where am I? Oh, sorry. It's in
shared. Um, it's this guy here, right?
Um,
and actually, I want to, this is kind of
this is an important point. So, I pay
attention.
Um, I actually like renaming this thing.
This this is this is the thing that um
that Tommy was talking about is this guy
here. Um, it is a vector of a vector of
a slice of bytes, right? But really what
it is and I can kind of show you with
comments is like ser one
um ser one seed one yeah signer one seed
two and then
actually I'll I'll do it this way my
I'm going to
sorry I hate all these uh I'm being
heckled by my AI Hi. I really need to
turn this off for uh demos. I should
probably find out. Uh bytes.
Yeah. Bytes
serittes
and then uh serer two.
Yeah, that's the AI has actually helped
me here. Signer two. Yeah, cool. This is
good. So really what you actually have
is an array of signers, right? Oh, and
move that across a little bit. There you
go. Does my little asky art make sense
here? So, we have ser one. So, we have a
a vector or an array of signers. Um, and
so in this case, we have two and each
inside each serer, we have multiple
seeds. Seed one and seed two could be
seed three, seed four, whatever else,
you know, that's that's yeah, there's
however many we have. The whole point of
a vector is it will it can change every
time. Um and then uh inside each seat I
should have to actually check whether
this is a a vector or an array. It may
actually be it may actually be an array.
So I don't think it does change over
time. Yeah. Yeah. I think the amount the
amount is static but the point is that
there can be a um a uh the amount of
seeds could it could be one it could be
seven whatever else. Um inside each seed
that is stored as bytes. So bytes are
effectively again an uh a um slice of
numbers basically. Um it's uh in this
case it's a uh it's a big list of U8
numbers. So eight 8 bit 8 bit numbers.
Um so that's what you're looking at
there. And so what I'm saving you from
is really that outside one. This is
actually written just to assume you only
have one signer, which in my case is
like 99% of the time of my Salana
program, I only have one signer. Um, so
with that in mind, I hope that actually
explains
um why I've called firstly uh like this
comment here. Only one signer seed, the
PDA that owns the token account is
needed. So we create an array with the
seeds. So in this case here you'll
actually see there's only uh we've taken
out one of the levels of nesting um with
that uh that so it's just uh we have a
single PD we have a single ser which
will be a PDA I'll talk about PDA
signing in a moment and inside that
there is a big list of 8 bit numbers um
and there can be multiple multiple seeds
I actually like to call this thing's
seed seeds plural because there's
actually multiple signers and multiple
seeds inside and each seed is a uh big
list of numbers. So that's that that's
what I'm actually I mentioned before I'm
really like precise with naming. I think
that's really important. So um yeah,
there's actually multiple signers and
that's why there's multiple level levels
there. Um, apparently if you go to um
like Rust conferences, there's people
who wear this thing on their um on their
t-shirt. There's um the uh borrowed
um nested um two arrays and then a slice
of pipes. Um because uh a lot of people
are getting into Rust because of Salana
and uh Rust people um like Jeff you were
you were you ever a Unix guy like
>> I wasn't hold on I I wasn't a a Unix guy
so much you know you got to remember
when I first got into this spa into this
space it was the first time I wrote code
>> since the 80s when I wrote
>> not
like the vibe in in if you go to a Rust
event like a lot of people are lovely
but there's a there's uh more than um
their fair share of like
people who are really unwelcoming to
people new using Rust for the first
time. So um and it's it's it reminds you
of like old school Unix events you kind
of the whole like neck beard or like if
you ever met anyone that knows a
programming language called Pearl it's
the same vibe. Um, so apparently a lot
of like Rust people wear like have like
t-shirts with this uh square, you know,
like borrow two borrowed arrays and
their slice of 8bit bytes um to make fun
of Salana people that um keep asking
questions on Rust forums about what
Sinus seeds means. So
>> that's thing, Mike. I mean, yeah. I
mean, Rust is actually Rust and C++ are
my main languages and they're the two
that I've most that I've spent the last
five years on.
>> I think C++ is like the community is
slightly more chill than the C
community, but I would say also like the
C community is like Sra's Bites is
perfect by the way as well. Like that's
actually that's a great name. Um I might
even use that in future. Andrew, uh
someone had their hand up a second ago.
They had another question.
Uh, I just want to make sure I've
answered them all.
Tommy has raised a hand. Yeah, sure.
Open Q. I think I accidentally dismissed
somebody as well. So, sorry if I
dismissed you. Put your hand up again.
Tommy, what's up?
>> Oh, I just had another question. Um, so
I know in this example we are Bob is
sending tokens directly to Alice,
>> but would there be a situation where you
would ever want to send Bob's tokens to
the escrow first and then the escrow
sends the tokens to both parties as like
the intermediary holder?
>> It's like a thing called a like a like a
good example of that is there's a thing
called a fan out wallet for example.
Um, so that's actually uh uh there's a
really good example about this from the
from the tuk tuk guys um which are they
actually my um oddly enough my my cell
phone company um is is uses Salana. So
there's a company called Helium which um
they kind of have a phone network and uh
but they also give you 5G base stations
that strangers will use. they'll connect
to your your base station and they'll
reward you and then they have this like
fan out wallets, right? So, one of the
things you could do is actually you
could like accept tokens from somebody
and then distribute them out like say
like 40% goes to this account and then
20% goes to these three other accounts
or whatever else like that. Like you can
you can you kind of slice and dice this
however you want to. Um really what
we're just showing here is just an
example of how to like hold tokens in
your program and send them out to
somebody.
Does that does that answer the question?
>> Yeah, that's perfect. That makes sense.
Thank you. Uh, is there any somebody
else had their hand up before? I just
wanted to make sure that I didn't I I I
saw a little dialogue here and I went h
go away. It's probably asking about
Gemini and then I realized it was
somebody putting their hand up.
>> Yeah, I did want to ask quickly about
what actually this one topic of the
escro. So, I was imagining that the base
of the escrow is having two accounts
where you collect it. it keeps the two
tokens and then once they are both there
then it gives them away. But from your
introduction at first one is missing so
there's only one.
>> Yeah, that's totally correct. Um and
it's really we could actually do it that
way. Like we could actually kind of wait
for Bob to send his tokens. Um I I'll
pull the uh the diagram back up as well.
Um but the thing is we just we really
just don't need to do that. Like
>> Okay, I see. So it's not it's not
because it's not crucial. We we could
have like we could have vault A and we
could have vault B like we could
absolutely make this but in the kind of
general spirit of um uh like what's the
word just kind of removing unnecessary
code
that way
>> because this is as well because you're
going to reme like if any I'll I'll kind
of go into this with takeoffer in a
second but if any part of like take
offer fails so like This is you know
this is um so Bob runs take offer
and uh our program transfers tokens in
the from the vault to Bob and then maybe
this fails right here that means that
none of the changes will be made to the
blockchain
like we don't need to if any part of um
Bob running takeoffer fails there'll
never be a sit like the situation you
see on screen right now where where
we're like halfway we we've done this
But we haven't done that. That will
never happen because a Salana um
instruction is atomic. It either
succeeds or it fails. So um if say the
instruction was able to move the tokens
into um uh Bob's account but you know
moving the tokens uh that Bob's offering
to Alice failed then the whole
instruction would fail which means the
whole transaction fails which means
nothing changes. So this is kind of um
really the kind of the whole concept of
like transactions. Either the every
everything that's part of something um
completes or none of it does. A really
good example was like when you go to an
ATM machine, hopefully your balance is
deducted and you get a bunch of cash. If
you get a bunch of cash and your balance
isn't deducted, there's a problem. If
you your balance is deducted and you
don't get any cash, that's also an
issue. Um, so yeah, that's what we mean
by atomic. All of take offer must
succeed. All of make offer must succeed.
All of refund offer must succeed for
this to actually work.
Does that did that answer the question?
I just wanted to make sure.
>> Yes. Thank you.
>> Cool. Excellent. Should we should we go
on with take offer?
>> Sweet. Excellent. The vibe is let's do
take offer. So, I'm just going to remind
you like I mean you you've seen it a
second ago. All we're going to do here
is um
Bob takes the offer
and program transfers the tokens and we
move them straight back.
So, let's go back into our code and
you'll see this is actually pretty damn
similar. You just see the direction of
things is a little bit different. So
let's go to take offer. Uh we import the
anchor prelude as always. Um and we're
going to start with the tokens that
people need to the sorry the accounts
that people need to provide when they
run take offer. Um I'll also mention
some other bits and pieces we're going
to use. Um so I'm just going to pull in
my error codes because they're useful.
We're going to reference the offer uh
strct we made earlier. We already have
the anchor prelude. Um, we're going to
mention the associated token account
program and we're going to be doing more
of this token interface stuff which is
again like a little wrappers around the
older token program or the newer token
program. Um, our takeoffer um strct is
going to start with all the normal
programs. So yes, we're going to use the
associated token program and we're going
to use the system program and we're
going to use uh whichever the older or
the newer token program um depending on
uh what the user specifies.
Uh this uh take offer is invoked by Bob.
Bob is the one who's signing this
transaction. So we're going to call him
the taker. And because Bob is signing
this transaction, he'll pay the
transaction fee. That's why you have
this mutable attribute here. Um the
maker will also be involved. So we're
going to um put that there. Well, I'll
also get rid of um this warning about uh
the in the lifetime not being there.
Info, by the way, is um basically a raw
Salana account. Salana calls it the the
the kind of the like the Salana program
library that sits underneath anchor
calls um like a raw Salana account and
account info object. Um I hate the name
account info. I hate don't ever program
anything with the word info. It means
nothing. Like you it could just call it
account or raw account. I would love
that. Um info is like so meaningless. Um
>> reference to bytes. No, you don't like
that.
>> Yeah. I don't know. Like it's it's it's
yeah it's it's
feel like
yeah it's it's I I get that it's the
data inside an account but like it's
still just like just call it an account
or an account data or something like
that. Um
we're referring to the token mints um of
uh in other words USDC and bonk or
whatever else. Um we're going to have
the takers token account A. So, this is
where Bob is going to receive the tokens
that Alice is offering. And that account
may not already exist. So, we're going
to run in it if needed. And um Bob,
who's the taker in this case, will pay
to create it. So, he's going to pay to
make an account where he's going to
receive his tokens from Alice. And we're
just going to check that the um the mint
for that token account is the um the
mint specified and the authority um is
is Bob and the token program is the same
token program that uh whose account you
specified.
Um
we have the takers token account B.
Um this is um where uh Bob is going to
send his tokens to Alice for example. Um
and again uh this is going to be mutable
because we are going to change the
balance of it. Um and what else? We're
just going to check that it is indeed
using token B that it is in fact you
know like Bob's bonk count in this in
this case that the token program is
either the older or the newer
programmed. As long as it's consistent
that's fine. Um now Alice is going to
need to receive her tokens from Bob. So,
we're going to call that maker token
account B. That is if this is uh all
confusing. I'll just I'll just get back
to the diagram for one second. Uh
keynote.
This one here is So, that's Alice. She's
she's the maker. This is Alice. Uh uh
maker token account A. And this is maker
token account B. This is Bob. He's the
taker. This is um taker token account A
and this is taker token account B. So um
I hope that is uh is clear. Um if not
you can replay that part of the video.
Um but so maker token account B is this
one here. And um we're going to create
it because maybe Alice didn't have any
bonk. Maybe she had 10 USDC and she
never has had any bonk before. So we're
going to create that account if we need
it. Bob's going to pay to create the
account. And we're going to make sure
that account is in fact a um uh a bonk
account that the mint is sent to the
bonk mint. The authority is Alice.
That's going to be Alice's account. And
the token program is the same token
program consistently that we've used
elsewhere that matches the uh token
program that uh Bob specified.
Um
what else? Oh, we'll actually need to
reference the offer as well. So, that
will be involved in this transaction. By
the way, another thing that I I didn't
realize when I was like really early in
my Salana journey is
why or the benefit of us having to
specify the accounts we're going to use
for every single transaction. Because in
other blockchains, you don't have to do
that. You can just, you know, just move
stuff around and it's great. Um the
really cool thing about this is that um
while
you know uh say Bob also has I don't
know some PYUSD right and there's a
separate transaction where somebody's
sending Bob some PYUSD
at the same time we're modifying
this while while Bob running uh the
takeoffer um uh the transaction with Bob
running takeoffer is modifying his USDC
and bonk account a separate transaction
could be modifying Bomb's PYUSD account.
The um the reason why we specify the
accounts when we run Salana transactions
is so that Salana can modify different
accounts at the same time. That's is
also the same reason why Salana stores
different information in different
accounts. So it can be modified in
parallel at the same time. So one of the
things those validators do when they're
processing transactions is look and find
out whether transactions are overlapping
or not. I.e. whether they include any of
the same accounts. And if they're um not
modifying the same transa if they're not
modifying the same accounts they can
actually be run at the same time which
is one of the reasons why Salana is
fast. Um so yeah it's a basically a
little bit of extra work when you're
calling um these functions because you
need to specify all the accounts as part
of the parameters you know context
accounts. Um but um there is a huge
benefit which is that Salana is really
fast. Um so we have the offer account.
We're going to change it because we're
actually going to close it down once
finished with it. Going to just do some
checks on it. Um and we we can find um
the offer count by just using the offer
the the the text offer and the offer ID.
And again u the bump is the offer bump.
Um the final thing we'll do is because
we're also using the account when Bob
runs take offer
is we'll specify that. I'm conscious of
time here so I'm going to speed up but
you've seen most of these checks
already. Obviously this is mutable
because we're taking the we're taking
the tokens out of the vault.
Um now this is ties in with some of the
stuff you were asking during um after we
finish make offer which is um to do with
the assigners seeds. Um so the first
thing I'm going to do is set um I need
to sign a transaction
um as the offer. So even though this
program is our swap or esco program, um
it's actually it doesn't own the vault,
the offer owns the vault.
So the account seeds for the offer vault
is just simply the text offer and the
offer ID and also you specify the bump
that was used to create the uh the the
address for the offer account. Uh all
that extra work there is just like the B
and this twole bytes, it's just
converting that into bytes. So it's it's
basically saying the offer account seeds
are the text offer and the offer ID as
bytes. And we're also going to specify
the bump with that.
Um we're going to wrap this in a sum.
This is basically just kind of a little
um a way of um uh we're going to use
this effectively. You'll see it in the
transfer token section in in the next
moment. we need to have a um uh rust
handles uh optional parameters in a
slightly different way than TypeScript.
So that's the that's what the sum is
doing that there. It's just effectively
saying this is a value we're actually
going to provide this time. Um it's used
for calling transfer tokens. Then we
actually call transfer tokens to give
the tokens um in the vault to the person
running um take offer. um specify
they're coming from the vault. They're
going to Bob's um uh USD uh USDC account
by taking the the amount from the vault.
The the the mint is the USDC. Um and the
uh the owner of the vault is the offer
uh and the seeds are the seeds we've
specified. Um,
and we're going to close the vault cuz
we don't need it anymore. I'm going to
call another helper here, which is
called close token account. You'll see
it in shared. It's not particularly
interesting. It just takes care of doing
some extra work for uh for closing token
accounts. Um, where is it?
What does it do? So yeah, it runs close
accounts and does some little checks and
it can close like um PDA accounts owned
by PDAs and accounts owned by regular
users. It's kind of nice. Um but it just
it's generic code. So it's not you know
you can cut and paste it and um you know
it's uh what's the word? like it's not
particularly important to understanding
the uh the the syntax of calls to close
an account isn't particularly important
um uh to learning an escrow and you can
next time you need to you know close an
account you can use the same code um and
then finally so we've um we've
transferred the tokens out and we've
closed the token accounts uh so oh so
we've uh so let me hold on a sec let
because there's two transfers here one
is from the makers associated token
account to oh the makers associated
token account to the vault is that from
makers token account a
uh it's moving it to the oh sorry I'm in
the wrong I'm in the wrong file sorry I
hope I haven't editing the wrong file
have I sorry oh you know I think edit
sorry I was just in the shift up zed zed
let's say that that looks correct cool
sorry I was just I I opened make offer
rather than take offer there So, we've
transferred the tokens from the vault to
the taker and we've closed the token
account. Uh, the final thing we need to
do is do that last part which uh
somebody asked about during the break,
which is transfer the tokens from the uh
from the uh taker straight to the maker.
Um, and that should be it. There's a
little bunch of red there that I'm going
to fix in a second. Oh, I've got to
specify my options here for take offer.
So take offer is Oh, it's just literally
context.
Here you go. Cool. Underscore context
versus context. And did I import all my
uh No, I need to import transfer tokens.
Where are we? I could just do yoink.
There we go. Fixed. And then yoink. Uh I
could use fix with AI, but I actually
know where it's coming from, which is um
my error code.
Uh
has error code has transit tokens.
What's that complaining about? Transit
uh error code failed vault withdrawal.
Oh, maybe maybe I actually added an
error code. Hold on a sec. I'm going to
go check my errors.
Oh, I got Yeah, I've got some extra
error codes I've added. I can see that.
Hold on a sec. I'll um I'll send you a
repo after this, but it's literally you
can just where you can even just create
these yourself. Um I've added a couple
of extra errors um for failed to
withdraw tokens from vault. I've just
made a pretty error message there. So
I'll save that. That should be happy.
Close token account. Import that.
And no more red. So that looks good. So
I'm going to run our
tests again. Um before we ran make
offer, we firstly made sure that we can
actually create an offer. We made sure
that it didn't work if we tried to reuse
an existing offer ID. That's just just
checking um that uh that in it works
because init will always fail if you try
and create an account that already
exists. Um that it fails when it has
insufficient token balance, etc. Um, if
somebody tries to say, I I'm I want USDC
and I'm giving USDC. That that that
seems wrong. Um, you can just give
someone USDC if you feel like throwing
some away. Um, uh, and if you know
somebody specifies silly amounts as what
they want. Um, so what we're going to do
now is run the test for take offer. Um,
so that's going to firstly create an
offer and then try and take it and then
check the balance of the account. Um,
and also we're going to check we're
going to try and um create an offer and
try and take it when we don't have the
right amount of tokens. So we'll run
anchor test that will build our program
and then run our test. This will take a
moment
and I'm going to that sounded like a
little thing there. So I'm going to jump
back to the chat for a sec. Where are
we? Zoom should be no
Sorry, I'm on uh not my normal desktop,
so I'm doing a little bit of extra
window management today. Where are we?
We I mean, no, this is uh this is Google
chat. Was there did somebody have a
question? I heard a little alert there.
>> Yeah. Yeah. I thought while it's loading
uh in terms of opportunity to ask a
question. So, uh as we know like in
talking 2022, uh we have additional
hooks which are runnable. Yeah.
>> So do we need like u additional
validation or assertion to be done
>> uh on the take because like uh it it
fires something. So I'm not sure how
it's working but
it could do something unexpected.
Definitely like that that if you had a
transfer hook, you would absolutely want
to check that the transfer hook is uh
basically you would check that the the
accounts that the transfer hook is
modifying have been modified in terms of
how you expect. It's um you know that
that's entirely you know that's entirely
reasonable. It's just really another
extension of the existing tests. you
know, you you you'll go and um uh
calculate the uh addresses of the
accounts that the transfer hook will be
modifying and then you'll check the
balances of if they're token accounts or
the data inside if they're data
accounts.
>> So like you remember we we have like a
require assertion.
>> Mhm.
>> Before we get into like we assert the
context and then we do the trans
transfer. So is there anything we can do
to check about the hooks at least if
there is a hook then we will do like
additional assertion.
>> Um let me think uh if the cuz uh
you would check that in the token mint
account because a transfer hook is
enabled on the token mint account. Um
I don't know what a transfer hook would
look like on the uh like on on a token
on a token mint. I just haven't done
that much with transfer hooks before but
it would be another aspect of you would
you could check it with require or any
other like normal like rust mechanism
and it would be some aspect of the token
mint um in the same way that any other
extension is. So you know it's uh if
you're doing uh token metadata or
whatever else um so it would be a
property of the token mint. I'm not sure
on the exact syntax but I can go and
chase it down. There's probably some
good docs on um I I know if you go to
salana.com
uh uh courses developers they have one
on transfer hooks I'm pretty sure for
token extensions. Quicknode has a bunch
of documentation on transfer hooks as
well but it will be a property on the
mint like any other token extension.
>> Awesome. Thanks. Cool.
>> Anyone else? Any any more questions?
>> Hi Mike. Uh can I speak? Yeah sure.
>> Uh okay. So based on my understanding uh
the taker is taking uh the token from
the vault and in the other transaction
uh sorry in the other instruction in the
same transaction he sends the the other
token directly to
>> just one um instruction. So there's
multiple.
>> So the it's it's really it's um uh so
each um so look at take offer for
example. Um so that's the actual that's
the account strct which is pretty
boring. Um this is just a like each
instruction handler. This could be this
directory could be called instructions.
Again I like calling the functions
handler. So the each of these
instruction handlers has multiple
functions inside but they are still one
Salana um instruction. So, uh, when I'm
actually, in fact, if you go into the
tests, um, these are like you can go see
Alice has some amount of token A and all
the rest of it. It's all pretty boring.
Um,
uh, we're making some token mints, you
know, uh, we're minting some tokens so
they can have some initial balances. Um,
and you'll see, uh, in say create test
offer, that's a good example, that's
just a test helper. we go and make our
um we get a make offer instruction
which is literally just um uh using the
client that I I use kadama you could use
anchor you could use whatever else um so
we're creating a make offer instruction
and we only have one uh when we run our
transaction we only have one instruction
inside which is our make offer so we can
actually have a separate instruction
inside for say the memo program and we
could like write something out to the
Salana logs describing the transaction.
Um, we could add um there's actually an
interesting thing recently which is um
uh I I read about yesterday um somebody
has a uh like you can add an instruction
um at the beginning of your transaction
um and all so the really cool thing
about Salana is all these instructions
can be to completely different programs.
So you can actually make a a transaction
that calls the token transfer uh program
that then goes and calls the memo
program then then calls like lighthouse
to check the balances that are what you
expect and make sure you didn't get
rugged. I was reading about something
yesterday that actually is an
instruction you can put at the front of
your list of instructions. Um, which
says that if this transaction is being
processed at the time when a validator
that I don't like is the leader, then
fail. Um,
>> wow. And that it's like basically
there's some people uh who like
basically listen there's some word
there's there's you know I I don't want
to badmouth anyone on video but there's
some uh people feel that some of the
validators um are doing like sandwich
attacks or front running etc. Um
>> yes exactly that that was actually I was
thinking about
>> yeah it's actually
>> if instructions are separate I can like
for example I can take that instruction
and use it for my advantage because it's
signed already so I can actually
>> use it in another transaction before
that transaction executes
>> the signature is unique and um you can't
reuse signatures across each uh the
signature is a signed version of that uh
transaction and you can't reuse the same
signature across multiple transactions.
>> So there is there is a a thing called a
a durable nons uh which is if anyone is
from Britain you're laughing now and we
can just keep that as a private joke
amongst amongst ourselves. Um but
there's thing called a durable nons
which is like permission. It's like a
it's a forever signature, but everyone's
moving away from them because they're a
terrible idea. And I think wallets are
even like starting to tell people don't
create a durable nod. Um
it it really was people used to do it to
like to make like Salana sizes where you
can have like repeat billing etc. Um now
but um I think yeah like there there's
better technologies out that
out there for repeat billing. Um Sphere
is is uh has some cool tech for that. Um
but yeah generally uh like well not as a
rule um uh
uh signatures are not reusable across
transactions.
>> Oh okay that's that's durable the only
the durable nons is the only like
exception to that. Um but yeah the the
the kind of the cool thing that uh
people are talking about here is this
idea that you can have a single
instruction to multiple programs and a
lot of the security programs like
lighthouse and like the one I was
reading about yesterday whose name I
can't remember I think it's called
gateway or something like that or to
something like that um uh it uh or
validator gateway or something like that
but you can actually have um like you
have an instruction that uh you know
before your other instructions that
checks the validator and fails. Then you
have an instruction after your other
instructions that checks the uh balances
your token accounts and make sure
they're what what you expect. You can
actually combine functionality from
different programs to do cool things. Um
and so you have a lot of uh like
transactions that reuse existing um
programs that are good at what they're
doing to perform particular tasks and
then add you know um uh instructions to
you know your program to do the things
that are unique to you. Um I might want
to do some cool things like uh make a um
maybe I want to make a multisig account
with squads. So, I'll have an
instruction that makes a multi-IG
account with squads and then maybe
another one to the token programs
transfer instruction to go and put some
tokens in that account or something
similar.
>> But, but I was not thinking to reuse it.
I was thinking to use it before the
transaction gets executed. Like I I I
pretend I'm a validator and can use that
instruction already in a separate
transaction before the trans the
legitimate transaction gets used.
>> Yeah. So there's Salana like so that
people like validators do actually use
transaction information to like do um
you know like there are bad validators
out there who are front running again I
don't want to name it but there is a
there there's actually which you
probably find on my Twitter account
retweeted by somebody else um but yeah
so there's there is definitely like
people who do me and they can see that
you know incoming transactions etc and
and basically uh effectively front run
them Um and there there's also a thing
called back running which is uh looking
at transactions as a form of market data
and uh effectively looking at as like
low latency access to to what's
happening on the market. Um Salana
doesn't have what's called a shared
mempool like Ethereum had. So it happens
less on Salana but it does definitely
happen. Um this thing I was talking
about yesterday it's in my Twitter
account. It's called like uh validated
gateway. That's one way to actually
ensure that your transaction is not
processed by that validator for example.
Um so yeah and that works by injecting a
new um uh like effectively a uh a
validated check instruction that runs
before the other instructions in your
transaction. And again the rule for if
any instruction fails the whole
transaction fails.
>> Yeah. Thank you so much.
>> No worries. Anyone else?
>> Yeah I had another question. Um
in make offer when we are initializing
the offer account
>> and we are deriving
um the account with the with the seeds
and the ID
>> um or the offer bytes. Um, can we also
use the third field to use the maker key
to derive it and that way?
>> Yeah. Yeah, we could. I think
>> the the person making it
>> originally I actually had the maker in
there. Um the thing is uh like it really
depends whether you want to have like um
offer one Mike's address and then like
offer to Tommy's address like could
those could be separate offer accounts
or you can just have offer one and offer
two like it's really like the whole of
Salana PDAs is a type of key value
store. These seeds are how you create
the key. Um, so it's really a program
design thing. My mentality with all any
kind of programming is if it can be
removed, remove it. Um, it's a from the
guy that wrote the little prince and
descentup. Um, and it's like perfection
is achieved when there's nothing more to
remove. So I think originally the first
time I wrote it, I actually had the
maker's key in there. Um, but then I
thought I don't really need it anymore.
Um you'll also see as well like some
people make indexes like people make
PDAs that are also indexes um where they
just like store um maybe you want a big
list of um all the offers that have been
made by a particular account or here's a
better example maybe you're making like
poly market and you wanted um you know
you have uh events which have lots of
outcomes and outcomes have lots of um
bets, right? So you have an event strct
and it has outcomes which is a ve of
addresses pub keys um and then you each
uh outcome you know Trump wins Biden
wins whatever is its own is is there's
an outcome strct for all of those and
then for all the people that bet on
Trump or for Biden you have another um
ve of pub keys or aggressors which are
you know the fact that you know Tommy
placed a bet on who whoever he bet
Um you that's cool. You have this like
um uh events
one event contains many outcomes. Each
outcome contains um many bets. But you
might want to look up the bets um by the
by the individual. You want might want
to quickly access all the bets by an
individual. So um like uh RPC providers
like quick node have like cool indexing
systems you can use but you can also
just build your own indexes using PDA.
So some people do that as well or you
can actually index using like Postgress
if you really like Postgress. Um people
are used to that on all the blockchains
because they're a little bit slower. Um
but you can also just do onchain
indexing in Salana. like literally just
making a PDA of like um bets for Tommy
and I can see that you bet on the
election then you bet on the pope and
that's the you know different bet IDs
etc. So uh it's really just a program
design consideration the seeds you use
for a particular account.
>> Um okay yeah that totally makes sense.
So in this system where we have like the
global ids basically is there any risk
of like uh like race conditions where
>> yeah like collisions etc race conditions
yeah um so these are uh a PDA is always
specific to our program so this is just
inside the program ID of uh whatever my
uh inside this inside this program. So,
they're all they're not quite globals.
They're globals for my program. Um, if
somebody does try and create an offer
that has an existing offer ID, it will
fail. And the offer ID on the client
side is just generated by a random
number. But if it wasn't generated by a
random number, you know, someone
my offer ID is one, um, it's actually
going to throw an error. So that's
actually the the one of the first things
I test for and that's actually given to
us for free by anchor. When we added
that init um attribute um to the offer
ID it said make this and it fail if it
doesn't exist fail if it doesn't exist
already. Um that's one of the rules for
in it. So uh we kind of get it for free
just by using anchor. is like there's a
lot of things that you kind of um would
otherwise be building yourself that you
get out of the box with anchor. Um
actually there's Jacob Creature had a
great tweet about this yesterday saying
like everyone has their own stuff they
prefer. Some people like web3js, some
people like raw salana kit, some people
like high level libraries like kite, uh
some people like um light SVM for
testing um you know whatever else. I I
recently got into light SVM. I really
like it. Um but um uh one thing that we
all do is we like I'd say maybe 90% plus
people use anchor because no one wants
to write des serialization and
serialization.
No one wants to write uh like the thing
that takes an incoming instruction and
finds the right instruction handler to
run it. Make offer take offer refund
offer etc. Um it's called an entry point
function and it's boring. Um, no one
wants to, you know, write their own
version of in it that goes and makes a
nice failure if the account already
exists. Um, because if you did write
that yourself, unless you're really
good, you it probably won't be good as
what Anchor gives you for free. So like
um you know use anchor like two years
ago people were like having I had this
discussion with colleagues at Salana
Foundation like all our docs say here's
how to use do native salana and then
they would like two chapters later be
like oh by the way you didn't need to do
any of that because you could just use
anchor like why don't we lead with
anchor and like literally all of them
were personally using anchor by default
and then we decided to like lead with
anchor and I think one things that
foundation's done really well recently
has been realizing that you know like
foundation, you know, like foundation
don't make Ankerch. Aza doesn't make
Ankor. It's made by a guy called Acaron
who's essentially an open source
developer. Um but um it's like it's not
a project of a particular company or
anything else like that. Um but it is it
it's the thing that people use. So we
need to kind of you know like all
foundation and and and and everyone
who's making content on on Salana needs
to needs to meet people where they're
at. Now there's really cool things about
Pinocchio, but Pinocchio still does less
things than Anchor. No one wants to
generate a TypeScript client to, you
know, uh, based on an IDL. That's
boring. Um, you know, Pinocchio might
have that now. I didn't have it a couple
of months ago when I looked. So I I like
Anchor is great. It gives you a lot of
things for free. And um, making sure
that you can't um, reuse an existing
offer is one of them. So that's a very
long answer to a simple question. U, but
I hope it was a good one.
Yeah, I mean look, one thing the one
thing that's important to know about
like the Pinocchio anchor thing is this.
You know, anchor makes sense for most
use cases.
Pinocchio makes sense for fewer. You're
going to start to see a lot more
Pinocchio
um concepts and tools in Ankor. Anchor
v2 is going to have a lot of Pinocchio
in it. Mhm.
>> I mean the one thing that that about
Pinocchio is as soon as you use the
entry point you're saving about 70 to
80% of cus just from the entry point.
>> Yeah. That is like it is you know like
it it's it is what I hope is that Dino
will be there in like maybe like 12
months or 18 months. That would be
amazing. There is a lot of work on it
and it's an ANZA project. So I think you
know I think Ans would probably want to
control more like Anza now had their own
like Devril team. I think Ans would
probably want to uh if I were Anza I
would want to control more more of the
Salana developer experience rather than
having like the Salana program crate be
like a side effect of anchor which is
the thing people actually use. So what I
what I would want to do if I were Anza
was make Pinocchio as accessible as
possible and kind of do more things out
of the box and you know make them all
optional. So if you don't want those
things or if you want to replace them,
you can which feels very Anza.
>> That is the that is the path they're
taking. I mean we're working with FIBO
and we actually will be running our
second Pinocchio program starting on
Monday. So and a lot of the focus is on
that Devax and that optionality.
>> Yeah, I mean I mean I'd even love to
join him because I think you know I I I
like the idea of being 10x faster. I
don't actually mind writing my own code
and I can like I've started publishing
Rust modules recently. Um it's like what
I would do if I if I was learning
Salana, I would probably not just stick
with Ankor. Um uh I the and I like you
have a limited amount of time. Um and I
would make sure that you know anchor
very very well before you push into
anything else. Um that's I think it's
probably the most efficient use of your
time. It's the same way as like you know
you could if you're writing some front
end code you could you know write your
own front-end framework or you could
just write React and you know maybe
React is pretty old and dated at this
point. Virtual DOMs every kind of one
knows they're a little bit slow. Um but
um it's like you know you have a limited
amount of time. Spend it on the thing
you're building. Don't spend it on you
know like recreating a lot of
boilerplate stuff. I I I I I I want
better like I want better Salana
programs. I want more efficient Salana
programs. So I I personally like I I
I'll keep an eye on Pinocchio. I might
contribute to to Pinocchio if I if I you
know feel that it's worth it. Um but if
I was learning Salana, I would just
stick with anger for now.
>> Cool. I want to point out as well, I
think I was scrolled up to the wrong
part, but yeah, all those takeoffer like
success uh all those takeover tests are
passing refund offer. Um I'll just go
through real real quickly for you. Um
because it's boring. Um and you've seen
90% of it already. Um we're going to do
our imports. We have our token program
and our system program because we're
using them. Um, refund offer is if
Alice, by the way, like makes her um
makes her offer and and no one comes
along to take it. So Alice is going to
sign this transaction.
Um, we're going to deal with the uh I
think in this case USDC would be token
mint A. Uh Alice's has a maker token
account A which is where we're going to
refund the tokens back to. Um, we're
going to look at the offer account and
we're going to use the vault. And um,
all refund offer does is return the
tokens from the vault to the makaker's
account and close the vault and return
the uh, the tiny bit of Salana um, back
to the maker. So, it's just another
transfer from the vault, but you'll see
the destination is um, Alice's um, maker
token account. A then we close the token
account and then we're done. We we have
some nice like um you know failed refund
transfer and failed refund clo like just
some some nice kind of um error messages
which expand into like uh more
descriptive things you know like failed
to close vault during refund etc. Um
that's all refund is uh is there we'll
also need to jump into um where are we
lib RS and just make sure is there
anything else we need to specify other
no we don't actually we don't need to
specify there's no extra options for
refund offer um I'll also point out to
the the crowd this is one of the other
things that I didn't find um intuitive
like if I think I was running a function
called refund offer Um, I would go,
well, what's the offer I'm refunding?
Where am I specifying that? And the
answer to that is in context. It's
inside context.ac accounts. I'm
specifying the offer account that I want
refunded. So, like if you don't see a
parameter that you would expect in an
instruction handler, the answer is it's
actually inside the accounts that um you
need that uh people specify when they
run that instruction handler. So when
people run refund offer the offer that
is being refunded is determined by
whatever account they specify right
here.
Um if I run the tests now
give it a sec. And these are uh by the
way I have um
uh I have uh light SVM tests. Um I made
a video about this recently. By the way,
subscribe to QuickNotes YouTube channel.
I'll show you something really cool. Um
this is actually uh this is
uh
when did I do this recently?
This is um Hey, all all the tests have
passed. I just did this stupid confetti
thing. that if I scroll up for all the
confetti, in fact, I'll remove the
confetti. Give me a sec.
Is it anchor.com? I'll get rid of the uh
get rid of the uh confetti on passing
all the tests and you'll see it runs. Um
it runs and they all pass. Now, um I
have a really good video called 25 times
faster anchor testing with light SVM and
I'll I'll turn the sound off just to
give you a demonstration here. Um, so I
had a repo that originally took 93
seconds with um, using web3js and I'd
already ported it to Salana Kit because
Salanakit uses things like web crypto
and big ants and all these things are
like built into JavaScript now. Um, it
is a lot faster. So I was already
starting from 25 seconds. Um, the first
time I used light SVM, those tests went
down from 25 seconds to I think about 3
seconds.
Um,
and then after that I got rid of a bunch
of duplicate code and the results were
0.9 seconds. So light SVM like I'm not a
big if someone tells me something's
going to be a little bit faster, I don't
normally care, but light SVM is 25 times
faster. I have a copy of this repo which
is linked to from this video. Um, and
like it it is it is the anchor escrow.
Um, but the tests complete in 0.9
seconds. Um, so anything that's an order
of magnitude has me immediately
interested. That's kind of my hope for
Pinocchio that it's basically as good as
an it does all the things anchor does
and is like 10 times fast or 10 times
more efficient. Um, and uh yeah, like if
you if you're interested in this stuff
like we like my role at QuickNote is
just entirely producing really useful
Salana content. So if you like that kind
of stuff, you can always find more of it
here as well. Awesome.
>> Cool. Um, yeah. Is anyone have any more
questions? Um, I think we've got a
couple couple minutes left or uh
>> some love hearts. Thank you very much.
Uh, if you if you want any uh if you're
interested in finding out what the name
of that thing to uh kind of uh blacklist
bad validators or you want to see cool
things about light SBM or Pinocchio,
um, I'm on X. Um, this is me. Um, you
can also send me feedback about this
session. Um, I'm always interested like
the escrow program as we said before is
really like the key to learning anchor.
Um, so I always want to get better at
it. I I've taught this to a lot of
people at this point. Um, but I always I
I always think there's like more to do
like things that we can kind of get rid
of in our explanations or things that
can kind of take us there faster or
better names we can use for things. Um,
so if you uh follow me on X, DM me, my
DMs are open. I would love uh feedback
for this. Um, and yeah, if you also
follow me on X, you'll see everything
that QuickNote is doing in the Salana
space. Um, you know, I can get you promo
codes. I can get you uh you know like a
lot of you know like first access to a
lot of cool tech that doesn't have
documentation or videos yet. Um and I
promise everything will be animated.
Everything will have like a equivalent
in you know tradi so you actually
understand what it is you're building.
Um and yeah I want to thank Jeff for
this opportunity to present you all. Um
there's a as I said before there's a lot
of talent that has come through WBA and
you guys are part of that. So that's
amazing. Thanks, Mike. And look, let me
give a shout out to QuickNote because I
mean, we uh we have a lot of our people
with it once they graduate and they're
starting to look at getting full-time
jobs and getting some of those wild
take-home tasks that you know about.
>> Yeah.
>> Um who um who need a free tier to be
able to do these tasks. And I'm going to
tell you right now, folks, there is no
better free tier. And look, the the paid
tiers and all that stuff beyond are are
excellent as well. They've been around
since day one. They're massive. They
are, you know, the quality of their
tooling means they're that their tagline
isn't how great their customer service
is. Um, you know, the
the free tier is the best free tier on
Salana for devs that need to not be rate
limited
um and have to go buy something that
that they maybe need once or twice.
>> Yeah. It's also just like when you're
making something new, just I need prices
for tokens. Like come on, guys. like um
there's so much like you can literally
just go into this um this marketplace
inside the QuickNote dashboard and there
is so many things you can enable for
free. We're really like uh we have a bit
of a reputation for like generous free
tiers, not just for the for the actual
like RPC product, but for all for most
of these things you see in um in the uh
in the marketplace like prices or
anti-me tech or uh what else? Like um
just token data or swaps
um you know, anything there. you can
just flip things on inside the quick
node marketplace and get um a bunch of
extra APIs that'll mean that will solve
you from that will mean that you don't
have to build those things yourself
which means you can get to market
faster. Um if you are like my other
recommendation to people because I know
that um uh when you come to with a salar
and you don't really know anyone it's
kind of hard to kind of raise funding
etc. Uh if it's not clear already, um I
think Jeff probably made this apparent.
Uh finish WBA, build a thing, win a
hackathon, get funding. Um when I was
trying to like do this, why I won a
hackathon three years ago and the
funding kind of wasn't there at the
time. It was in this kind of you know
crypto winter. Um but it is now like if
you go and if you like get a place um at
um at breakout then like coliseum will
just take you into their accelerator and
start introducing you to investors and
uh investors are starting to come to
these accelerators to be like cool this
is like deal flow for the smartest in
Salana. So, if you want to make crypto
your full-time job,
learn how to build the escro app so you
know how to make make things on chain.
>> Everything
uh build something for a hackathon
project and win.
>> Yeah.
>> Um, cool. All right, let's wrap this
folks. Mike, thanks so much. And this
was last minute and you are usually very
hard to nail down. So, thank you and
thanks to the QuickNote team for freeing
you up today. Good. If I don't see you,
uh, good luck in October, but I'm sure
I'll probably bump into you. But before
then, everybody, enjoy the weekend. Uh,
you know me, touch some grass, eat some
good food, hang out with some friends,
and we'll see you on the flip side on
Tuesday.
>> Excellent. uh this if you uh by the way
if you take that address from um from
the MPXD getit as well um and if you
remove the like beginning kind of the
the end part of it which is like the
branch name you'll see the completed
project as well so you can get the whole
thing on GitHub um I think the one on
GitHub as well has the light SVM tests
so um yeah go subscribe to Quicknot
Quicknot's uh YouTube channel I go
through like why light SVM is amazing um
it's it's good fun. We're doing
something with tuk tuk next. I think
touktouk almost deserves to be like part
of like the standard learning process
for people on Salana. Um I love having
like automated tasks, etc. It's a really
good time to learn things on Salana as
well. Like it's there's so much amazing
tech that's coming out. Um yeah.
>> Awesome.
>> Cool. Have a good one, guys. Take care.
Loading video analysis...