LongCut logo

🔧 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...

Loading video analysis...