Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions tokens/escrow/steel/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
target
test-ledger
node_modules
25 changes: 25 additions & 0 deletions tokens/escrow/steel/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[workspace]
resolver = "2"
members = ["api", "program"]

[workspace.package]
version = "0.1.0"
edition = "2021"
license = "Apache-2.0"
homepage = ""
documentation = ""
respository = "https://www.github.com/Ovodo"
readme = "./README.md"
keywords = ["solana","steel","escrow"]

[workspace.dependencies]
escrow-api = { path = "./api", version = "0.1.0" }
bytemuck = "1.14"
num_enum = "0.7"
solana-program = "1.18"
steel = { version = "2.1.1", features = ["spl"] }
thiserror = "1.0"
spl-token = { features = ["no-entrypoint"], version = "^4" }
spl-associated-token-account = { features = [ "no-entrypoint" ], version = "^2.3" }


51 changes: 51 additions & 0 deletions tokens/escrow/steel/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Escrow

**Escrow** is a an example of an escrow holding tokens on behalf of a user.

## API

- [`Consts`](api/src/consts.rs) – Program constants.
- [`Error`](api/src/error.rs) – Custom program errors.
- [`Instruction`](api/src/instruction.rs) – Declared instructions.

## Instructions

- [`MakeOffer`](program/src/make_offer.rs) Makes an offer ...
- [`TakeOfferr`](program/src/take_offer.rs) Takes an offer ...
- [`Refund`](program/src/refund.rs) Refunds an offer to the ochestrator ...

## State

- [`Offer`](api/src/state/offer.rs) – Offer ...

## Get started

Compile your program:

```sh
steel build
```

Install dependencies:

```sh
pnpm install
```

Run unit and integration tests (native):

```sh
steel test
```

Run unit and integration tests (bankrun):

```sh
pnpm build-and-test
```

Run unit and integration tests without logs for a cleaner output (bankrun):

```sh
pnpm test-no-log
```
13 changes: 13 additions & 0 deletions tokens/escrow/steel/api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "escrow-api"
version = "0.1.0"
edition = "2021"

[dependencies]
bytemuck.workspace = true
num_enum.workspace = true
spl-associated-token-account.workspace = true
solana-program.workspace = true
steel.workspace = true
spl-token.workspace = true
thiserror.workspace = true
2 changes: 2 additions & 0 deletions tokens/escrow/steel/api/src/consts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/// Seed of the offer account PDA.
pub const OFFER: &[u8] = b"offer";
10 changes: 10 additions & 0 deletions tokens/escrow/steel/api/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use steel::*;

#[derive(Debug, Error, Clone, Copy, PartialEq, Eq, IntoPrimitive)]
#[repr(u32)]
pub enum AccountError {
#[error("This is a dummy error")]
Dummy = 0,
}

error!(AccountError);
30 changes: 30 additions & 0 deletions tokens/escrow/steel/api/src/instruction.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use steel::*;

#[repr(u8)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, TryFromPrimitive)]
pub enum AccountInstruction {
MakeOffer = 0,
TakeOffer = 1,
Refund = 2,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct MakeOffer {
pub id: [u8; 8],
pub token_a_offered_amount: [u8; 8],
pub token_b_wanted_amount: [u8; 8],
pub bump: [u8; 1],
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct TakeOffer {}

#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct Refund {}

instruction!(AccountInstruction, MakeOffer);
instruction!(AccountInstruction, TakeOffer);
instruction!(AccountInstruction, Refund);
18 changes: 18 additions & 0 deletions tokens/escrow/steel/api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
pub mod consts;
pub mod error;
pub mod instruction;
pub mod sdk;
pub mod state;

pub mod prelude {
pub use crate::consts::*;
pub use crate::error::*;
pub use crate::instruction::*;
pub use crate::sdk::*;
pub use crate::state::*;
}

use steel::*;

// TODO Set program id
declare_id!("z7msBPQHDJjTvdQRoEcKyENgXDhSRYeHieN1ZMTqo35");
91 changes: 91 additions & 0 deletions tokens/escrow/steel/api/src/sdk.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
use steel::*;

use crate::prelude::*;

pub fn make_offer(
signer: Pubkey,
token_mint_a: Pubkey,
token_mint_b: Pubkey,
maker_token_account_a: Pubkey,
vault: Pubkey,
token_a_offered_amount: u64,
token_b_wanted_amount: u64,
id: u64,
bump: u8,
) -> Instruction {
Instruction {
program_id: crate::ID,
accounts: vec![
AccountMeta::new(signer, true),
AccountMeta::new(token_mint_a, false),
AccountMeta::new(token_mint_b, false),
AccountMeta::new(maker_token_account_a, false),
AccountMeta::new(offer_pda(signer, id).0, false),
AccountMeta::new(vault, false),
AccountMeta::new_readonly(spl_token::ID, false),
AccountMeta::new_readonly(spl_associated_token_account::ID, false),
AccountMeta::new_readonly(system_program::ID, false),
],
data: MakeOffer {
token_a_offered_amount: token_a_offered_amount.to_le_bytes(),
token_b_wanted_amount: token_b_wanted_amount.to_le_bytes(),
id: id.to_le_bytes(),
bump: bump.to_le_bytes(),
}
.to_bytes(),
}
}

pub fn take_offer(
signer: Pubkey,
maker: Pubkey,
token_mint_a: Pubkey,
token_mint_b: Pubkey,
taker_token_account_a: Pubkey,
taker_token_account_b: Pubkey,
maker_token_account_b: Pubkey,
vault: Pubkey,
id: u64,
) -> Instruction {
Instruction {
program_id: crate::ID,
accounts: vec![
AccountMeta::new(signer, true),
AccountMeta::new(maker, false),
AccountMeta::new(token_mint_a, false),
AccountMeta::new(token_mint_b, false),
AccountMeta::new(taker_token_account_a, false),
AccountMeta::new(taker_token_account_b, false),
AccountMeta::new(maker_token_account_b, false),
AccountMeta::new(offer_pda(maker, id).0, false),
AccountMeta::new(vault, false),
AccountMeta::new_readonly(spl_token::ID, false),
AccountMeta::new_readonly(spl_associated_token_account::ID, false),
AccountMeta::new_readonly(system_program::ID, false),
],
data: TakeOffer {}.to_bytes(),
}
}

pub fn refund(
maker: Pubkey,
token_mint_a: Pubkey,
maker_token_account_a: Pubkey,
vault: Pubkey,
id: u64,
) -> Instruction {
Instruction {
program_id: crate::ID,
accounts: vec![
AccountMeta::new(maker, true),
AccountMeta::new(token_mint_a, false),
AccountMeta::new(maker_token_account_a, false),
AccountMeta::new(offer_pda(maker, id).0, false),
AccountMeta::new(vault, false),
AccountMeta::new_readonly(spl_token::ID, false),
AccountMeta::new_readonly(spl_associated_token_account::ID, false),
AccountMeta::new_readonly(system_program::ID, false),
],
data: Refund {}.to_bytes(),
}
}
19 changes: 19 additions & 0 deletions tokens/escrow/steel/api/src/state/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
mod offer;

use crate::consts::*;
pub use offer::*;
use steel::*;

#[repr(u8)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, IntoPrimitive, TryFromPrimitive)]
pub enum SteelAccount {
Offer = 0,
}

/// Fetch PDA of the offer account.
pub fn offer_pda(maker: Pubkey, id: u64) -> (Pubkey, u8) {
Pubkey::find_program_address(
&[OFFER, maker.as_ref(), id.to_le_bytes().as_ref()],
&crate::id(),
)
}
16 changes: 16 additions & 0 deletions tokens/escrow/steel/api/src/state/offer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use steel::*;

use super::SteelAccount;

#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]
pub struct Offer {
pub id: u64,
pub maker: Pubkey,
pub token_mint_a: Pubkey,
pub token_mint_b: Pubkey,
pub token_b_wanted_amount: u64,
pub bump: u64,
}

account!(SteelAccount, Offer);
38 changes: 38 additions & 0 deletions tokens/escrow/steel/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "escrow",
"version": "1.0.0",
"description": "**Account** is a ...",
"main": "index.js",
"scripts": {
"test-no-log": "RUST_LOG=error pnpm ts-mocha -p ./tsconfig.json -t 1000000 ./tests/*.test.ts",
"test": "pnpm ts-mocha -p ./tsconfig.json -t 1000000 ./tests/*.test.ts",
"build-and-test": "cargo build-sbf --manifest-path=./program/Cargo.toml --sbf-out-dir=./tests/fixtures && pnpm test",
"build": "cargo build-sbf --manifest-path=./program/Cargo.toml --sbf-out-dir=./program/target/so",
"deploy": "solana program deploy ./program/target/so/program.so"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@types/bn.js": "^5.1.6",
"@types/chai": "^5.0.0",
"@types/mocha": "^10.0.9",
"@types/node": "^22.7.9",
"anchor-bankrun": "^0.5.0",
"chai": "^4.5.0",
"mocha": "^10.7.3",
"solana-bankrun": "^0.4.0",
"ts-mocha": "^10.0.0",
"ts-node": "^10.9.2",
"typescript": "^5.6.3"
},
"dependencies": {
"@coral-xyz/anchor": "^0.30.1",
"@solana-developers/helpers": "^2.5.6",
"@solana/buffer-layout": "^4.0.1",
"@solana/buffer-layout-utils": "^0.2.0",
"@solana/spl-token": "^0.4.9",
"@solana/web3.js": "^1.95.4",
"borsh": "^2.0.0"
}
}
Loading