Build token migration program
Change-Id: I78b10931fb09f5bca457c1fb36095fdbcea9e65f
This commit is contained in:
parent
c116b3c813
commit
88933d13e2
|
@ -59,6 +59,9 @@ spec:
|
|||
- --bpf-program
|
||||
- P2WH424242424242424242424242424242424242424
|
||||
- /opt/solana/deps/pyth2wormhole.so
|
||||
- --bpf-program
|
||||
- Ex9bCdVMSfx7EzB3pgSi2R4UHwJAXvTw18rBQm5YQ8gK
|
||||
- /opt/solana/deps/wormhole_migration.so
|
||||
- --log
|
||||
ports:
|
||||
- containerPort: 8001
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
| Bridge Core | SOL | Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o | |
|
||||
| Token Bridge | SOL | B6RHG3mfcckmrYN1UhmJzyS1XX3fZKbkeUcpJe9Sy3FE | |
|
||||
| NFT Bridge | SOL | NFTWqJR8YnRVqPDvTJrYuLrQDitTG5AScqbeghi4zSA | |
|
||||
| Migration Contract | SOL | Ex9bCdVMSfx7EzB3pgSi2R4UHwJAXvTw18rBQm5YQ8gK | |
|
||||
| Test Wallet | Terra | terra1x46rqay4d3cssq8gxxvqz8xt6nwlz4td20k38v | Mnemonic: `notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius` |
|
||||
| Example Token | Terra | terra13nkgqrfymug724h8pprpexqj9h629sa3ncw7sh | Tokens minted to Test Wallet |
|
||||
| Bridge Core | Terra | terra18eezxhys9jwku67cm4w84xhnzt4xjj77w2qt62 | |
|
||||
|
|
|
@ -48,13 +48,16 @@ RUN --mount=type=cache,target=bridge/target \
|
|||
--mount=type=cache,target=modules/token_bridge/target \
|
||||
--mount=type=cache,target=modules/nft_bridge/target \
|
||||
--mount=type=cache,target=pyth2wormhole/target \
|
||||
--mount=type=cache,target=migration/target \
|
||||
cargo build-bpf --manifest-path "bridge/program/Cargo.toml" && \
|
||||
cargo build-bpf --manifest-path "bridge/cpi_poster/Cargo.toml" && \
|
||||
cargo build-bpf --manifest-path "modules/token_bridge/program/Cargo.toml" && \
|
||||
cargo build-bpf --manifest-path "pyth2wormhole/program/Cargo.toml" && \
|
||||
cargo build-bpf --manifest-path "modules/nft_bridge/program/Cargo.toml" && \
|
||||
cargo build-bpf --manifest-path "migration/Cargo.toml" && \
|
||||
cp bridge/target/deploy/bridge.so /opt/solana/deps/bridge.so && \
|
||||
cp bridge/target/deploy/cpi_poster.so /opt/solana/deps/cpi_poster.so && \
|
||||
cp migration/target/deploy/wormhole_migration.so /opt/solana/deps/wormhole_migration.so && \
|
||||
cp modules/token_bridge/target/deploy/token_bridge.so /opt/solana/deps/token_bridge.so && \
|
||||
cp modules/nft_bridge/target/deploy/nft_bridge.so /opt/solana/deps/nft_bridge.so && \
|
||||
cp modules/token_bridge/token-metadata/spl_token_metadata.so /opt/solana/deps/spl_token_metadata.so && \
|
||||
|
|
|
@ -16,6 +16,7 @@ ENV BRIDGE_ADDRESS="Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o"
|
|||
COPY bridge bridge
|
||||
COPY modules modules
|
||||
COPY solitaire solitaire
|
||||
COPY migration migration
|
||||
|
||||
# Compile Wormhole
|
||||
RUN --mount=type=cache,target=/root/.cache \
|
||||
|
@ -35,6 +36,11 @@ RUN --mount=type=cache,target=/root/.cache \
|
|||
--mount=type=cache,target=modules/token_bridge/target \
|
||||
cd modules/token_bridge/program && /usr/local/cargo/bin/wasm-pack build --target nodejs -d nodejs -- --features wasm
|
||||
|
||||
# Compile Migration
|
||||
RUN --mount=type=cache,target=/root/.cache \
|
||||
--mount=type=cache,target=migration/target \
|
||||
cd migration && /usr/local/cargo/bin/wasm-pack build --target bundler -d bundler -- --features wasm
|
||||
|
||||
# Compile NFT Bridge
|
||||
RUN --mount=type=cache,target=/root/.cache \
|
||||
--mount=type=cache,target=modules/nft_bridge/target \
|
||||
|
@ -48,6 +54,7 @@ FROM scratch AS export
|
|||
|
||||
COPY --from=build /usr/src/bridge/bridge/program/bundler sdk/js/src/solana/core
|
||||
COPY --from=build /usr/src/bridge/modules/token_bridge/program/bundler sdk/js/src/solana/token
|
||||
COPY --from=build /usr/src/bridge/migration/bundler sdk/js/src/solana/migration
|
||||
COPY --from=build /usr/src/bridge/modules/nft_bridge/program/bundler sdk/js/src/solana/nft
|
||||
|
||||
COPY --from=build /usr/src/bridge/bridge/program/nodejs clients/solana/pkg
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
[package]
|
||||
name = "wormhole-migration"
|
||||
version = "0.1.0"
|
||||
description = "Created with Rocksalt"
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "lib"]
|
||||
name = "wormhole_migration"
|
||||
|
||||
[features]
|
||||
no-entrypoint = ["solitaire/no-entrypoint", "rand"]
|
||||
trace = ["solitaire/trace"]
|
||||
wasm = ["no-entrypoint"]
|
||||
client = ["solitaire-client", "solitaire/client", "no-entrypoint"]
|
||||
cpi = ["no-entrypoint"]
|
||||
default = []
|
||||
|
||||
[dependencies]
|
||||
borsh = "0.8.1"
|
||||
byteorder = "1.4.3"
|
||||
rocksalt = { path = "../solitaire/rocksalt" }
|
||||
solitaire = { path = "../solitaire/program" }
|
||||
sha3 = "0.9.1"
|
||||
solana-program = "*"
|
||||
spl-token = { version = "=3.1.0", features = ["no-entrypoint"] }
|
||||
solitaire-client = { path = "../solitaire/client", optional = true }
|
||||
wasm-bindgen = { version = "0.2.74", features = ["serde-serialize"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
rand = { version = "0.7.3", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
hex = "*"
|
||||
hex-literal = "0.3.1"
|
||||
libsecp256k1 = { version = "0.3.5", features = [] }
|
||||
solana-client = "1.7.0"
|
||||
solana-sdk = "=1.7.0"
|
||||
spl-token = { version = "=3.1.0", features = ["no-entrypoint"] }
|
||||
|
||||
[patch.crates-io]
|
||||
memmap2 = { path = "../bridge/memmap2-rs" }
|
|
@ -0,0 +1,11 @@
|
|||
# Merge similar crates together to avoid multiple use statements.
|
||||
imports_granularity = "Crate"
|
||||
|
||||
# Consistency in formatting makes tool based searching/editing better.
|
||||
empty_item_single_line = false
|
||||
|
||||
# Easier editing when arbitrary mixed use statements do not collapse.
|
||||
imports_layout = "Vertical"
|
||||
|
||||
# Default rustfmt formatting of match arms with branches is awful.
|
||||
match_arm_leading_pipes = "Preserve"
|
|
@ -0,0 +1,84 @@
|
|||
use crate::types::{
|
||||
PoolData,
|
||||
SplAccount,
|
||||
SplMint,
|
||||
};
|
||||
use solana_program::pubkey::Pubkey;
|
||||
use solitaire::{
|
||||
processors::seeded::Seeded,
|
||||
AccountState,
|
||||
Data,
|
||||
Derive,
|
||||
Info,
|
||||
};
|
||||
|
||||
pub type ShareMint<'a, const STATE: AccountState> = Data<'a, SplMint, { STATE }>;
|
||||
|
||||
pub struct ShareMintDerivationData {
|
||||
pub pool: Pubkey,
|
||||
}
|
||||
|
||||
impl<'b, const STATE: AccountState> Seeded<&ShareMintDerivationData> for ShareMint<'b, { STATE }> {
|
||||
fn seeds(accs: &ShareMintDerivationData) -> Vec<Vec<u8>> {
|
||||
vec![
|
||||
String::from("share_mint").as_bytes().to_vec(),
|
||||
accs.pool.to_bytes().to_vec(),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
pub type FromCustodyTokenAccount<'a, const STATE: AccountState> = Data<'a, SplAccount, { STATE }>;
|
||||
|
||||
pub struct FromCustodyTokenAccountDerivationData {
|
||||
pub pool: Pubkey,
|
||||
}
|
||||
|
||||
impl<'b, const STATE: AccountState> Seeded<&FromCustodyTokenAccountDerivationData>
|
||||
for FromCustodyTokenAccount<'b, { STATE }>
|
||||
{
|
||||
fn seeds(accs: &FromCustodyTokenAccountDerivationData) -> Vec<Vec<u8>> {
|
||||
vec![
|
||||
String::from("from_custody").as_bytes().to_vec(),
|
||||
accs.pool.to_bytes().to_vec(),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
pub type ToCustodyTokenAccount<'a, const STATE: AccountState> = Data<'a, SplAccount, { STATE }>;
|
||||
|
||||
pub struct ToCustodyTokenAccountDerivationData {
|
||||
pub pool: Pubkey,
|
||||
}
|
||||
|
||||
impl<'b, const STATE: AccountState> Seeded<&ToCustodyTokenAccountDerivationData>
|
||||
for ToCustodyTokenAccount<'b, { STATE }>
|
||||
{
|
||||
fn seeds(accs: &ToCustodyTokenAccountDerivationData) -> Vec<Vec<u8>> {
|
||||
vec![
|
||||
String::from("to_custody").as_bytes().to_vec(),
|
||||
accs.pool.to_bytes().to_vec(),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
pub type MigrationPool<'a, const STATE: AccountState> = Data<'a, PoolData, { STATE }>;
|
||||
|
||||
pub struct MigrationPoolDerivationData {
|
||||
pub from: Pubkey,
|
||||
pub to: Pubkey,
|
||||
}
|
||||
|
||||
impl<'b, const STATE: AccountState> Seeded<&MigrationPoolDerivationData>
|
||||
for MigrationPool<'b, { STATE }>
|
||||
{
|
||||
fn seeds(accs: &MigrationPoolDerivationData) -> Vec<Vec<u8>> {
|
||||
vec![
|
||||
String::from("pool").as_bytes().to_vec(),
|
||||
accs.from.to_bytes().to_vec(),
|
||||
accs.to.to_bytes().to_vec(),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
pub type CustodySigner<'a> = Derive<Info<'a>, "custody_signer">;
|
||||
pub type AuthoritySigner<'a> = Derive<Info<'a>, "authority_signer">;
|
|
@ -0,0 +1,4 @@
|
|||
pub mod add_liquidity;
|
||||
pub mod claim_shares;
|
||||
pub mod create_pool;
|
||||
pub mod migrate_tokens;
|
|
@ -0,0 +1,112 @@
|
|||
use crate::{
|
||||
accounts::{
|
||||
AuthoritySigner,
|
||||
CustodySigner,
|
||||
MigrationPool,
|
||||
ShareMint,
|
||||
ShareMintDerivationData,
|
||||
ToCustodyTokenAccount,
|
||||
ToCustodyTokenAccountDerivationData,
|
||||
},
|
||||
types::{
|
||||
SplAccount,
|
||||
SplMint,
|
||||
},
|
||||
MigrationError::WrongMint,
|
||||
};
|
||||
use borsh::{
|
||||
BorshDeserialize,
|
||||
BorshSerialize,
|
||||
};
|
||||
|
||||
use crate::accounts::MigrationPoolDerivationData;
|
||||
use solitaire::*;
|
||||
|
||||
#[derive(FromAccounts)]
|
||||
pub struct AddLiquidity<'b> {
|
||||
pub pool: Mut<MigrationPool<'b, { AccountState::Initialized }>>,
|
||||
pub from_mint: Data<'b, SplMint, { AccountState::Initialized }>,
|
||||
pub to_mint: Data<'b, SplMint, { AccountState::Initialized }>,
|
||||
pub to_token_custody: Mut<ToCustodyTokenAccount<'b, { AccountState::Initialized }>>,
|
||||
pub share_mint: Mut<ShareMint<'b, { AccountState::Initialized }>>,
|
||||
|
||||
pub to_lp_acc: Mut<Data<'b, SplAccount, { AccountState::Initialized }>>,
|
||||
pub lp_share_acc: Mut<Data<'b, SplAccount, { AccountState::Initialized }>>,
|
||||
pub custody_signer: CustodySigner<'b>,
|
||||
pub authority_signer: AuthoritySigner<'b>,
|
||||
}
|
||||
|
||||
#[derive(BorshDeserialize, BorshSerialize, Default)]
|
||||
pub struct AddLiquidityData {
|
||||
pub amount: u64,
|
||||
}
|
||||
|
||||
pub fn add_liquidity(
|
||||
ctx: &ExecutionContext,
|
||||
accs: &mut AddLiquidity,
|
||||
data: AddLiquidityData,
|
||||
) -> Result<()> {
|
||||
if *accs.from_mint.info().key != accs.pool.from {
|
||||
return Err(WrongMint.into());
|
||||
}
|
||||
if *accs.to_mint.info().key != accs.pool.to {
|
||||
return Err(WrongMint.into());
|
||||
}
|
||||
if accs.lp_share_acc.mint != *accs.share_mint.info().key {
|
||||
return Err(WrongMint.into());
|
||||
}
|
||||
accs.to_token_custody.verify_derivation(
|
||||
ctx.program_id,
|
||||
&ToCustodyTokenAccountDerivationData {
|
||||
pool: *accs.pool.info().key,
|
||||
},
|
||||
)?;
|
||||
accs.share_mint.verify_derivation(
|
||||
ctx.program_id,
|
||||
&ShareMintDerivationData {
|
||||
pool: *accs.pool.info().key,
|
||||
},
|
||||
)?;
|
||||
accs.pool.verify_derivation(
|
||||
ctx.program_id,
|
||||
&MigrationPoolDerivationData {
|
||||
from: accs.pool.from,
|
||||
to: accs.pool.to,
|
||||
},
|
||||
)?;
|
||||
|
||||
// Transfer out-tokens in
|
||||
let transfer_ix = spl_token::instruction::transfer(
|
||||
&spl_token::id(),
|
||||
accs.to_lp_acc.info().key,
|
||||
accs.to_token_custody.info().key,
|
||||
accs.authority_signer.key,
|
||||
&[],
|
||||
data.amount,
|
||||
)?;
|
||||
invoke_seeded(&transfer_ix, ctx, &accs.authority_signer, None)?;
|
||||
|
||||
// The share amount should be equal to the amount of from tokens an lp would be getting
|
||||
let share_amount = if accs.from_mint.decimals > accs.to_mint.decimals {
|
||||
data.amount
|
||||
.checked_mul(10u64.pow((accs.from_mint.decimals - accs.to_mint.decimals) as u32))
|
||||
.unwrap()
|
||||
} else {
|
||||
data.amount
|
||||
.checked_div(10u64.pow((accs.to_mint.decimals - accs.from_mint.decimals) as u32))
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
// Mint LP shares
|
||||
let mint_ix = spl_token::instruction::mint_to(
|
||||
&spl_token::id(),
|
||||
accs.from_mint.info().key,
|
||||
accs.lp_share_acc.info().key,
|
||||
accs.custody_signer.key,
|
||||
&[],
|
||||
share_amount,
|
||||
)?;
|
||||
invoke_seeded(&mint_ix, ctx, &accs.custody_signer, None)?;
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
use crate::{
|
||||
accounts::{
|
||||
AuthoritySigner,
|
||||
CustodySigner,
|
||||
FromCustodyTokenAccountDerivationData,
|
||||
MigrationPool,
|
||||
ShareMint,
|
||||
ShareMintDerivationData,
|
||||
ToCustodyTokenAccount,
|
||||
},
|
||||
types::{
|
||||
SplAccount,
|
||||
SplMint,
|
||||
},
|
||||
MigrationError::WrongMint,
|
||||
};
|
||||
use borsh::{
|
||||
BorshDeserialize,
|
||||
BorshSerialize,
|
||||
};
|
||||
|
||||
use crate::accounts::MigrationPoolDerivationData;
|
||||
use solitaire::{
|
||||
processors::seeded::{
|
||||
invoke_seeded,
|
||||
Seeded,
|
||||
},
|
||||
*,
|
||||
};
|
||||
|
||||
#[derive(FromAccounts)]
|
||||
pub struct ClaimShares<'b> {
|
||||
pub pool: Mut<MigrationPool<'b, { AccountState::Initialized }>>,
|
||||
pub to_mint: Data<'b, SplMint, { AccountState::Initialized }>,
|
||||
pub from_token_custody: Mut<ToCustodyTokenAccount<'b, { AccountState::Initialized }>>,
|
||||
pub share_mint: Mut<ShareMint<'b, { AccountState::Initialized }>>,
|
||||
|
||||
pub from_lp_acc: Mut<Data<'b, SplAccount, { AccountState::Initialized }>>,
|
||||
pub lp_share_acc: Mut<Data<'b, SplAccount, { AccountState::Initialized }>>,
|
||||
pub custody_signer: CustodySigner<'b>,
|
||||
pub authority_signer: AuthoritySigner<'b>,
|
||||
}
|
||||
|
||||
#[derive(BorshDeserialize, BorshSerialize, Default)]
|
||||
pub struct ClaimSharesData {
|
||||
pub amount: u64,
|
||||
}
|
||||
|
||||
pub fn claim_shares(
|
||||
ctx: &ExecutionContext,
|
||||
accs: &mut ClaimShares,
|
||||
data: ClaimSharesData,
|
||||
) -> Result<()> {
|
||||
if *accs.to_mint.info().key != accs.pool.to {
|
||||
return Err(WrongMint.into());
|
||||
}
|
||||
if accs.lp_share_acc.mint != *accs.share_mint.info().key {
|
||||
return Err(WrongMint.into());
|
||||
}
|
||||
accs.from_token_custody.verify_derivation(
|
||||
ctx.program_id,
|
||||
&FromCustodyTokenAccountDerivationData {
|
||||
pool: *accs.pool.info().key,
|
||||
},
|
||||
)?;
|
||||
accs.share_mint.verify_derivation(
|
||||
ctx.program_id,
|
||||
&ShareMintDerivationData {
|
||||
pool: *accs.pool.info().key,
|
||||
},
|
||||
)?;
|
||||
accs.pool.verify_derivation(
|
||||
ctx.program_id,
|
||||
&MigrationPoolDerivationData {
|
||||
from: accs.pool.from,
|
||||
to: accs.pool.to,
|
||||
},
|
||||
)?;
|
||||
|
||||
// Transfer claimed tokens to LP
|
||||
let transfer_ix = spl_token::instruction::transfer(
|
||||
&spl_token::id(),
|
||||
accs.from_token_custody.info().key,
|
||||
accs.from_lp_acc.info().key,
|
||||
accs.custody_signer.key,
|
||||
&[],
|
||||
data.amount,
|
||||
)?;
|
||||
invoke_seeded(&transfer_ix, ctx, &accs.custody_signer, None)?;
|
||||
|
||||
// Burn LP shares
|
||||
let mint_ix = spl_token::instruction::burn(
|
||||
&spl_token::id(),
|
||||
accs.lp_share_acc.info().key,
|
||||
accs.share_mint.info().key,
|
||||
accs.authority_signer.key,
|
||||
&[],
|
||||
data.amount,
|
||||
)?;
|
||||
invoke_seeded(&mint_ix, ctx, &accs.authority_signer, None)?;
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
use crate::{
|
||||
accounts::{
|
||||
CustodySigner,
|
||||
FromCustodyTokenAccount,
|
||||
FromCustodyTokenAccountDerivationData,
|
||||
MigrationPool,
|
||||
MigrationPoolDerivationData,
|
||||
ShareMint,
|
||||
ShareMintDerivationData,
|
||||
ToCustodyTokenAccount,
|
||||
ToCustodyTokenAccountDerivationData,
|
||||
},
|
||||
types::SplMint,
|
||||
};
|
||||
use borsh::{
|
||||
BorshDeserialize,
|
||||
BorshSerialize,
|
||||
};
|
||||
use solana_program::program::invoke_signed;
|
||||
use solitaire::{
|
||||
processors::seeded::Seeded,
|
||||
CreationLamports::Exempt,
|
||||
*,
|
||||
};
|
||||
|
||||
#[derive(FromAccounts)]
|
||||
pub struct CreatePool<'b> {
|
||||
pub payer: Mut<Signer<Info<'b>>>,
|
||||
|
||||
pub pool: Mut<MigrationPool<'b, { AccountState::Uninitialized }>>,
|
||||
pub from_mint: Data<'b, SplMint, { AccountState::Initialized }>,
|
||||
pub to_mint: Data<'b, SplMint, { AccountState::Initialized }>,
|
||||
pub from_token_custody: Mut<FromCustodyTokenAccount<'b, { AccountState::Uninitialized }>>,
|
||||
pub to_token_custody: Mut<ToCustodyTokenAccount<'b, { AccountState::Uninitialized }>>,
|
||||
pub pool_mint: Mut<ShareMint<'b, { AccountState::Uninitialized }>>,
|
||||
|
||||
pub custody_signer: CustodySigner<'b>,
|
||||
}
|
||||
|
||||
#[derive(BorshDeserialize, BorshSerialize, Default)]
|
||||
pub struct CreatePoolData {}
|
||||
|
||||
pub fn create_pool(
|
||||
ctx: &ExecutionContext,
|
||||
accs: &mut CreatePool,
|
||||
_data: CreatePoolData,
|
||||
) -> Result<()> {
|
||||
// Create from custody account
|
||||
accs.from_token_custody.create(
|
||||
&FromCustodyTokenAccountDerivationData {
|
||||
pool: *accs.pool.info().key,
|
||||
},
|
||||
ctx,
|
||||
accs.payer.key,
|
||||
Exempt,
|
||||
)?;
|
||||
|
||||
let init_ix = spl_token::instruction::initialize_account(
|
||||
&spl_token::id(),
|
||||
accs.from_token_custody.info().key,
|
||||
accs.from_mint.info().key,
|
||||
accs.custody_signer.info().key,
|
||||
)?;
|
||||
invoke_signed(&init_ix, ctx.accounts, &[])?;
|
||||
|
||||
// Create to custody account
|
||||
accs.to_token_custody.create(
|
||||
&ToCustodyTokenAccountDerivationData {
|
||||
pool: *accs.pool.info().key,
|
||||
},
|
||||
ctx,
|
||||
accs.payer.key,
|
||||
Exempt,
|
||||
)?;
|
||||
|
||||
let init_ix = spl_token::instruction::initialize_account(
|
||||
&spl_token::id(),
|
||||
accs.to_token_custody.info().key,
|
||||
accs.to_mint.info().key,
|
||||
accs.custody_signer.info().key,
|
||||
)?;
|
||||
invoke_signed(&init_ix, ctx.accounts, &[])?;
|
||||
|
||||
// Create to pool mint
|
||||
accs.pool_mint.create(
|
||||
&ShareMintDerivationData {
|
||||
pool: *accs.pool.info().key,
|
||||
},
|
||||
ctx,
|
||||
accs.payer.key,
|
||||
Exempt,
|
||||
)?;
|
||||
|
||||
let init_ix = spl_token::instruction::initialize_mint(
|
||||
&spl_token::id(),
|
||||
accs.pool_mint.info().key,
|
||||
accs.custody_signer.info().key,
|
||||
None,
|
||||
accs.from_mint.decimals,
|
||||
)?;
|
||||
invoke_signed(&init_ix, ctx.accounts, &[])?;
|
||||
|
||||
// Set fields on pool
|
||||
accs.pool.from = *accs.from_mint.info().key;
|
||||
accs.pool.to = *accs.to_mint.info().key;
|
||||
|
||||
// Create pool
|
||||
accs.pool.create(
|
||||
&MigrationPoolDerivationData {
|
||||
from: *accs.from_mint.info().key,
|
||||
to: *accs.to_mint.info().key,
|
||||
},
|
||||
ctx,
|
||||
accs.payer.key,
|
||||
Exempt,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
use crate::{
|
||||
accounts::{
|
||||
AuthoritySigner,
|
||||
CustodySigner,
|
||||
FromCustodyTokenAccount,
|
||||
FromCustodyTokenAccountDerivationData,
|
||||
MigrationPool,
|
||||
ToCustodyTokenAccount,
|
||||
ToCustodyTokenAccountDerivationData,
|
||||
},
|
||||
types::{
|
||||
SplAccount,
|
||||
SplMint,
|
||||
},
|
||||
MigrationError::WrongMint,
|
||||
};
|
||||
use borsh::{
|
||||
BorshDeserialize,
|
||||
BorshSerialize,
|
||||
};
|
||||
|
||||
use crate::accounts::MigrationPoolDerivationData;
|
||||
use solitaire::{
|
||||
processors::seeded::{
|
||||
invoke_seeded,
|
||||
Seeded,
|
||||
},
|
||||
*,
|
||||
};
|
||||
|
||||
#[derive(FromAccounts)]
|
||||
pub struct MigrateTokens<'b> {
|
||||
pub pool: Mut<MigrationPool<'b, { AccountState::Initialized }>>,
|
||||
pub from_mint: Data<'b, SplMint, { AccountState::Initialized }>,
|
||||
pub to_mint: Data<'b, SplMint, { AccountState::Initialized }>,
|
||||
pub to_token_custody: Mut<ToCustodyTokenAccount<'b, { AccountState::Initialized }>>,
|
||||
pub from_token_custody: Mut<FromCustodyTokenAccount<'b, { AccountState::Initialized }>>,
|
||||
|
||||
pub user_from_acc: Mut<Data<'b, SplAccount, { AccountState::Initialized }>>,
|
||||
pub user_to_acc: Mut<Data<'b, SplAccount, { AccountState::Initialized }>>,
|
||||
pub custody_signer: CustodySigner<'b>,
|
||||
pub authority_signer: AuthoritySigner<'b>,
|
||||
}
|
||||
|
||||
#[derive(BorshDeserialize, BorshSerialize, Default)]
|
||||
pub struct MigrateTokensData {
|
||||
pub amount: u64,
|
||||
}
|
||||
|
||||
pub fn migrate_tokens(
|
||||
ctx: &ExecutionContext,
|
||||
accs: &mut MigrateTokens,
|
||||
data: MigrateTokensData,
|
||||
) -> Result<()> {
|
||||
if *accs.from_mint.info().key != accs.pool.from {
|
||||
return Err(WrongMint.into());
|
||||
}
|
||||
if *accs.to_mint.info().key != accs.pool.to {
|
||||
return Err(WrongMint.into());
|
||||
}
|
||||
if accs.user_from_acc.mint != accs.pool.from {
|
||||
return Err(WrongMint.into());
|
||||
}
|
||||
if accs.user_to_acc.mint != accs.pool.to {
|
||||
return Err(WrongMint.into());
|
||||
}
|
||||
accs.to_token_custody.verify_derivation(
|
||||
ctx.program_id,
|
||||
&ToCustodyTokenAccountDerivationData {
|
||||
pool: *accs.pool.info().key,
|
||||
},
|
||||
)?;
|
||||
accs.from_token_custody.verify_derivation(
|
||||
ctx.program_id,
|
||||
&FromCustodyTokenAccountDerivationData {
|
||||
pool: *accs.pool.info().key,
|
||||
},
|
||||
)?;
|
||||
accs.pool.verify_derivation(
|
||||
ctx.program_id,
|
||||
&MigrationPoolDerivationData {
|
||||
from: accs.pool.from,
|
||||
to: accs.pool.to,
|
||||
},
|
||||
)?;
|
||||
|
||||
// Transfer in-tokens in
|
||||
let transfer_ix = spl_token::instruction::transfer(
|
||||
&spl_token::id(),
|
||||
accs.user_from_acc.info().key,
|
||||
accs.from_token_custody.info().key,
|
||||
accs.authority_signer.key,
|
||||
&[],
|
||||
data.amount,
|
||||
)?;
|
||||
invoke_seeded(&transfer_ix, ctx, &accs.authority_signer, None)?;
|
||||
|
||||
// The share amount should be equal to the amount of from tokens an lp would be getting
|
||||
let out_amount = if accs.from_mint.decimals > accs.to_mint.decimals {
|
||||
data.amount
|
||||
.checked_div(10u64.pow((accs.from_mint.decimals - accs.to_mint.decimals) as u32))
|
||||
.unwrap()
|
||||
} else {
|
||||
data.amount
|
||||
.checked_mul(10u64.pow((accs.to_mint.decimals - accs.from_mint.decimals) as u32))
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
// Transfer out-tokens to user
|
||||
let transfer_ix = spl_token::instruction::transfer(
|
||||
&spl_token::id(),
|
||||
accs.to_token_custody.info().key,
|
||||
accs.user_to_acc.info().key,
|
||||
accs.custody_signer.key,
|
||||
&[],
|
||||
out_amount,
|
||||
)?;
|
||||
invoke_seeded(&transfer_ix, ctx, &accs.custody_signer, None)?;
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -0,0 +1,242 @@
|
|||
use crate::{
|
||||
accounts::{
|
||||
AuthoritySigner,
|
||||
CustodySigner,
|
||||
FromCustodyTokenAccount,
|
||||
FromCustodyTokenAccountDerivationData,
|
||||
MigrationPool,
|
||||
MigrationPoolDerivationData,
|
||||
ShareMint,
|
||||
ShareMintDerivationData,
|
||||
ToCustodyTokenAccount,
|
||||
ToCustodyTokenAccountDerivationData,
|
||||
},
|
||||
api::{
|
||||
add_liquidity::AddLiquidityData,
|
||||
claim_shares::ClaimSharesData,
|
||||
create_pool::CreatePoolData,
|
||||
migrate_tokens::MigrateTokensData,
|
||||
},
|
||||
};
|
||||
use borsh::BorshSerialize;
|
||||
use solana_program::{
|
||||
instruction::{
|
||||
AccountMeta,
|
||||
Instruction,
|
||||
},
|
||||
pubkey::Pubkey,
|
||||
};
|
||||
use solitaire::{
|
||||
processors::seeded::Seeded,
|
||||
AccountState,
|
||||
};
|
||||
|
||||
pub fn add_liquidity(
|
||||
program_id: Pubkey,
|
||||
from_mint: Pubkey,
|
||||
to_mint: Pubkey,
|
||||
liquidity_token_account: Pubkey,
|
||||
lp_share_token_account: Pubkey,
|
||||
amount: u64,
|
||||
) -> solitaire::Result<Instruction> {
|
||||
let pool = MigrationPool::<'_, { AccountState::Initialized }>::key(
|
||||
&MigrationPoolDerivationData {
|
||||
from: from_mint,
|
||||
to: to_mint,
|
||||
},
|
||||
&program_id,
|
||||
);
|
||||
Ok(Instruction {
|
||||
program_id,
|
||||
accounts: vec![
|
||||
AccountMeta::new(pool, false),
|
||||
AccountMeta::new_readonly(from_mint, false),
|
||||
AccountMeta::new_readonly(to_mint, false),
|
||||
AccountMeta::new(
|
||||
ToCustodyTokenAccount::<'_, { AccountState::Uninitialized }>::key(
|
||||
&ToCustodyTokenAccountDerivationData { pool },
|
||||
&program_id,
|
||||
),
|
||||
false,
|
||||
),
|
||||
AccountMeta::new(
|
||||
ShareMint::<'_, { AccountState::Uninitialized }>::key(
|
||||
&ShareMintDerivationData { pool },
|
||||
&program_id,
|
||||
),
|
||||
false,
|
||||
),
|
||||
AccountMeta::new(liquidity_token_account, false),
|
||||
AccountMeta::new(lp_share_token_account, false),
|
||||
AccountMeta::new_readonly(CustodySigner::key(None, &program_id), false),
|
||||
AccountMeta::new_readonly(AuthoritySigner::key(None, &program_id), false),
|
||||
// Dependencies
|
||||
AccountMeta::new(solana_program::sysvar::rent::id(), false),
|
||||
AccountMeta::new(solana_program::system_program::id(), false),
|
||||
AccountMeta::new_readonly(spl_token::id(), false),
|
||||
],
|
||||
data: (
|
||||
crate::instruction::Instruction::AddLiquidity,
|
||||
AddLiquidityData { amount },
|
||||
)
|
||||
.try_to_vec()?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn claim_shares(
|
||||
program_id: Pubkey,
|
||||
from_mint: Pubkey,
|
||||
to_mint: Pubkey,
|
||||
output_token_account: Pubkey,
|
||||
lp_share_token_account: Pubkey,
|
||||
amount: u64,
|
||||
) -> solitaire::Result<Instruction> {
|
||||
let pool = MigrationPool::<'_, { AccountState::Initialized }>::key(
|
||||
&MigrationPoolDerivationData {
|
||||
from: from_mint,
|
||||
to: to_mint,
|
||||
},
|
||||
&program_id,
|
||||
);
|
||||
Ok(Instruction {
|
||||
program_id,
|
||||
accounts: vec![
|
||||
AccountMeta::new(pool, false),
|
||||
AccountMeta::new_readonly(to_mint, false),
|
||||
AccountMeta::new(
|
||||
FromCustodyTokenAccount::<'_, { AccountState::Uninitialized }>::key(
|
||||
&FromCustodyTokenAccountDerivationData { pool },
|
||||
&program_id,
|
||||
),
|
||||
false,
|
||||
),
|
||||
AccountMeta::new(
|
||||
ShareMint::<'_, { AccountState::Uninitialized }>::key(
|
||||
&ShareMintDerivationData { pool },
|
||||
&program_id,
|
||||
),
|
||||
false,
|
||||
),
|
||||
AccountMeta::new(output_token_account, false),
|
||||
AccountMeta::new(lp_share_token_account, false),
|
||||
AccountMeta::new_readonly(CustodySigner::key(None, &program_id), false),
|
||||
AccountMeta::new_readonly(AuthoritySigner::key(None, &program_id), false),
|
||||
// Dependencies
|
||||
AccountMeta::new(solana_program::sysvar::rent::id(), false),
|
||||
AccountMeta::new(solana_program::system_program::id(), false),
|
||||
AccountMeta::new_readonly(spl_token::id(), false),
|
||||
],
|
||||
data: (
|
||||
crate::instruction::Instruction::ClaimShares,
|
||||
ClaimSharesData { amount },
|
||||
)
|
||||
.try_to_vec()?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn create_pool(
|
||||
program_id: Pubkey,
|
||||
payer: Pubkey,
|
||||
from_mint: Pubkey,
|
||||
to_mint: Pubkey,
|
||||
) -> solitaire::Result<Instruction> {
|
||||
let pool = MigrationPool::<'_, { AccountState::Initialized }>::key(
|
||||
&MigrationPoolDerivationData {
|
||||
from: from_mint,
|
||||
to: to_mint,
|
||||
},
|
||||
&program_id,
|
||||
);
|
||||
Ok(Instruction {
|
||||
program_id,
|
||||
accounts: vec![
|
||||
AccountMeta::new(payer, true),
|
||||
AccountMeta::new(pool, false),
|
||||
AccountMeta::new_readonly(from_mint, false),
|
||||
AccountMeta::new_readonly(to_mint, false),
|
||||
AccountMeta::new(
|
||||
FromCustodyTokenAccount::<'_, { AccountState::Uninitialized }>::key(
|
||||
&FromCustodyTokenAccountDerivationData { pool },
|
||||
&program_id,
|
||||
),
|
||||
false,
|
||||
),
|
||||
AccountMeta::new(
|
||||
ToCustodyTokenAccount::<'_, { AccountState::Uninitialized }>::key(
|
||||
&ToCustodyTokenAccountDerivationData { pool },
|
||||
&program_id,
|
||||
),
|
||||
false,
|
||||
),
|
||||
AccountMeta::new(
|
||||
ShareMint::<'_, { AccountState::Uninitialized }>::key(
|
||||
&ShareMintDerivationData { pool },
|
||||
&program_id,
|
||||
),
|
||||
false,
|
||||
),
|
||||
AccountMeta::new_readonly(CustodySigner::key(None, &program_id), false),
|
||||
// Dependencies
|
||||
AccountMeta::new(solana_program::sysvar::rent::id(), false),
|
||||
AccountMeta::new(solana_program::system_program::id(), false),
|
||||
AccountMeta::new_readonly(spl_token::id(), false),
|
||||
],
|
||||
data: (
|
||||
crate::instruction::Instruction::CreatePool,
|
||||
CreatePoolData {},
|
||||
)
|
||||
.try_to_vec()?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn migrate_tokens(
|
||||
program_id: Pubkey,
|
||||
from_mint: Pubkey,
|
||||
to_mint: Pubkey,
|
||||
input_token_account: Pubkey,
|
||||
output_token_account: Pubkey,
|
||||
amount: u64,
|
||||
) -> solitaire::Result<Instruction> {
|
||||
let pool = MigrationPool::<'_, { AccountState::Initialized }>::key(
|
||||
&MigrationPoolDerivationData {
|
||||
from: from_mint,
|
||||
to: to_mint,
|
||||
},
|
||||
&program_id,
|
||||
);
|
||||
Ok(Instruction {
|
||||
program_id,
|
||||
accounts: vec![
|
||||
AccountMeta::new(pool, false),
|
||||
AccountMeta::new_readonly(from_mint, false),
|
||||
AccountMeta::new_readonly(to_mint, false),
|
||||
AccountMeta::new(
|
||||
ToCustodyTokenAccount::<'_, { AccountState::Uninitialized }>::key(
|
||||
&ToCustodyTokenAccountDerivationData { pool },
|
||||
&program_id,
|
||||
),
|
||||
false,
|
||||
),
|
||||
AccountMeta::new(
|
||||
FromCustodyTokenAccount::<'_, { AccountState::Uninitialized }>::key(
|
||||
&FromCustodyTokenAccountDerivationData { pool },
|
||||
&program_id,
|
||||
),
|
||||
false,
|
||||
),
|
||||
AccountMeta::new(input_token_account, false),
|
||||
AccountMeta::new(output_token_account, false),
|
||||
AccountMeta::new_readonly(CustodySigner::key(None, &program_id), false),
|
||||
AccountMeta::new_readonly(AuthoritySigner::key(None, &program_id), false),
|
||||
// Dependencies
|
||||
AccountMeta::new(solana_program::sysvar::rent::id(), false),
|
||||
AccountMeta::new(solana_program::system_program::id(), false),
|
||||
AccountMeta::new_readonly(spl_token::id(), false),
|
||||
],
|
||||
data: (
|
||||
crate::instruction::Instruction::MigrateTokens,
|
||||
MigrateTokensData { amount },
|
||||
)
|
||||
.try_to_vec()?,
|
||||
})
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
#![allow(incomplete_features)]
|
||||
#![feature(const_generics)]
|
||||
|
||||
use api::{
|
||||
add_liquidity::*,
|
||||
claim_shares::*,
|
||||
create_pool::*,
|
||||
migrate_tokens::*,
|
||||
};
|
||||
use solitaire::{
|
||||
solitaire,
|
||||
SolitaireError,
|
||||
};
|
||||
|
||||
pub mod accounts;
|
||||
pub mod api;
|
||||
pub mod types;
|
||||
|
||||
#[cfg(feature = "no-entrypoint")]
|
||||
pub mod instructions;
|
||||
|
||||
#[cfg(feature = "wasm")]
|
||||
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
|
||||
extern crate wasm_bindgen;
|
||||
|
||||
#[cfg(feature = "wasm")]
|
||||
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
|
||||
pub mod wasm;
|
||||
|
||||
pub enum MigrationError {
|
||||
WrongMint,
|
||||
}
|
||||
|
||||
impl From<MigrationError> for SolitaireError {
|
||||
fn from(t: MigrationError) -> SolitaireError {
|
||||
SolitaireError::Custom(t as u64)
|
||||
}
|
||||
}
|
||||
|
||||
solitaire! {
|
||||
AddLiquidity(AddLiquidityData) => add_liquidity,
|
||||
ClaimShares(ClaimSharesData) => claim_shares,
|
||||
CreatePool(CreatePoolData) => create_pool,
|
||||
MigrateTokens(MigrateTokensData) => migrate_tokens,
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
use borsh::{
|
||||
BorshDeserialize,
|
||||
BorshSerialize,
|
||||
};
|
||||
use serde::{
|
||||
Deserialize,
|
||||
Serialize,
|
||||
};
|
||||
use solana_program::pubkey::Pubkey;
|
||||
use solitaire::{
|
||||
pack_type,
|
||||
processors::seeded::{
|
||||
AccountOwner,
|
||||
Owned,
|
||||
},
|
||||
};
|
||||
use spl_token::state::{
|
||||
Account,
|
||||
Mint,
|
||||
};
|
||||
|
||||
#[derive(Default, Clone, Copy, BorshDeserialize, BorshSerialize, Serialize, Deserialize)]
|
||||
pub struct PoolData {
|
||||
pub from: Pubkey,
|
||||
pub to: Pubkey,
|
||||
}
|
||||
|
||||
impl Owned for PoolData {
|
||||
fn owner(&self) -> AccountOwner {
|
||||
AccountOwner::This
|
||||
}
|
||||
}
|
||||
|
||||
pack_type!(SplMint, Mint, AccountOwner::Other(spl_token::id()));
|
||||
pack_type!(SplAccount, Account, AccountOwner::Other(spl_token::id()));
|
|
@ -0,0 +1,194 @@
|
|||
use crate::{
|
||||
accounts::{
|
||||
AuthoritySigner,
|
||||
FromCustodyTokenAccount,
|
||||
FromCustodyTokenAccountDerivationData,
|
||||
MigrationPool,
|
||||
MigrationPoolDerivationData,
|
||||
ShareMint,
|
||||
ShareMintDerivationData,
|
||||
ToCustodyTokenAccount,
|
||||
ToCustodyTokenAccountDerivationData,
|
||||
},
|
||||
instructions,
|
||||
types::PoolData,
|
||||
};
|
||||
use borsh::BorshDeserialize;
|
||||
use solana_program::pubkey::Pubkey;
|
||||
use solitaire::{
|
||||
processors::seeded::Seeded,
|
||||
AccountState,
|
||||
};
|
||||
use std::str::FromStr;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn add_liquidity(
|
||||
program_id: String,
|
||||
from_mint: String,
|
||||
to_mint: String,
|
||||
liquidity_token_account: String,
|
||||
lp_share_token_account: String,
|
||||
amount: u64,
|
||||
) -> JsValue {
|
||||
let program_id = Pubkey::from_str(program_id.as_str()).unwrap();
|
||||
let from_mint = Pubkey::from_str(from_mint.as_str()).unwrap();
|
||||
let to_mint = Pubkey::from_str(to_mint.as_str()).unwrap();
|
||||
let liquidity_token_account = Pubkey::from_str(liquidity_token_account.as_str()).unwrap();
|
||||
let lp_share_token_account = Pubkey::from_str(lp_share_token_account.as_str()).unwrap();
|
||||
|
||||
let ix = instructions::add_liquidity(
|
||||
program_id,
|
||||
from_mint,
|
||||
to_mint,
|
||||
liquidity_token_account,
|
||||
lp_share_token_account,
|
||||
amount,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
JsValue::from_serde(&ix).unwrap()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn claim_shares(
|
||||
program_id: String,
|
||||
from_mint: String,
|
||||
to_mint: String,
|
||||
output_token_account: String,
|
||||
lp_share_token_account: String,
|
||||
amount: u64,
|
||||
) -> JsValue {
|
||||
let program_id = Pubkey::from_str(program_id.as_str()).unwrap();
|
||||
let from_mint = Pubkey::from_str(from_mint.as_str()).unwrap();
|
||||
let to_mint = Pubkey::from_str(to_mint.as_str()).unwrap();
|
||||
let output_token_account = Pubkey::from_str(output_token_account.as_str()).unwrap();
|
||||
let lp_share_token_account = Pubkey::from_str(lp_share_token_account.as_str()).unwrap();
|
||||
|
||||
let ix = instructions::claim_shares(
|
||||
program_id,
|
||||
from_mint,
|
||||
to_mint,
|
||||
output_token_account,
|
||||
lp_share_token_account,
|
||||
amount,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
JsValue::from_serde(&ix).unwrap()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn create_pool(
|
||||
program_id: String,
|
||||
payer: String,
|
||||
from_mint: String,
|
||||
to_mint: String,
|
||||
) -> JsValue {
|
||||
let program_id = Pubkey::from_str(program_id.as_str()).unwrap();
|
||||
let payer = Pubkey::from_str(payer.as_str()).unwrap();
|
||||
let from_mint = Pubkey::from_str(from_mint.as_str()).unwrap();
|
||||
let to_mint = Pubkey::from_str(to_mint.as_str()).unwrap();
|
||||
|
||||
let ix = instructions::create_pool(program_id, payer, from_mint, to_mint).unwrap();
|
||||
|
||||
JsValue::from_serde(&ix).unwrap()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn migrate_tokens(
|
||||
program_id: String,
|
||||
from_mint: String,
|
||||
to_mint: String,
|
||||
input_token_account: String,
|
||||
output_token_account: String,
|
||||
amount: u64,
|
||||
) -> JsValue {
|
||||
let program_id = Pubkey::from_str(program_id.as_str()).unwrap();
|
||||
let from_mint = Pubkey::from_str(from_mint.as_str()).unwrap();
|
||||
let to_mint = Pubkey::from_str(to_mint.as_str()).unwrap();
|
||||
let input_token_account = Pubkey::from_str(input_token_account.as_str()).unwrap();
|
||||
let output_token_account = Pubkey::from_str(output_token_account.as_str()).unwrap();
|
||||
|
||||
let ix = instructions::migrate_tokens(
|
||||
program_id,
|
||||
from_mint,
|
||||
to_mint,
|
||||
input_token_account,
|
||||
output_token_account,
|
||||
amount,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
JsValue::from_serde(&ix).unwrap()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn pool_address(program_id: String, from_mint: String, to_mint: String) -> Vec<u8> {
|
||||
let program_id = Pubkey::from_str(program_id.as_str()).unwrap();
|
||||
let from_mint_key = Pubkey::from_str(from_mint.as_str()).unwrap();
|
||||
let to_mint_key = Pubkey::from_str(to_mint.as_str()).unwrap();
|
||||
|
||||
let pool_addr = MigrationPool::<'_, { AccountState::Initialized }>::key(
|
||||
&MigrationPoolDerivationData {
|
||||
from: from_mint_key,
|
||||
to: to_mint_key,
|
||||
},
|
||||
&program_id,
|
||||
);
|
||||
|
||||
pool_addr.to_bytes().to_vec()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn authority_address(program_id: String) -> Vec<u8> {
|
||||
let program_id = Pubkey::from_str(program_id.as_str()).unwrap();
|
||||
|
||||
let authority_addr = AuthoritySigner::key(None, &program_id);
|
||||
|
||||
authority_addr.to_bytes().to_vec()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn share_mint_address(program_id: String, pool: String) -> Vec<u8> {
|
||||
let program_id = Pubkey::from_str(program_id.as_str()).unwrap();
|
||||
let pool_key = Pubkey::from_str(pool.as_str()).unwrap();
|
||||
|
||||
let share_mint_addr = ShareMint::<'_, { AccountState::Initialized }>::key(
|
||||
&ShareMintDerivationData { pool: pool_key },
|
||||
&program_id,
|
||||
);
|
||||
|
||||
share_mint_addr.to_bytes().to_vec()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn from_custody_address(program_id: String, pool: String) -> Vec<u8> {
|
||||
let program_id = Pubkey::from_str(program_id.as_str()).unwrap();
|
||||
let pool_key = Pubkey::from_str(pool.as_str()).unwrap();
|
||||
|
||||
let from_custody_addr = FromCustodyTokenAccount::<'_, { AccountState::Initialized }>::key(
|
||||
&FromCustodyTokenAccountDerivationData { pool: pool_key },
|
||||
&program_id,
|
||||
);
|
||||
|
||||
from_custody_addr.to_bytes().to_vec()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn to_custody_address(program_id: String, pool: String) -> Vec<u8> {
|
||||
let program_id = Pubkey::from_str(program_id.as_str()).unwrap();
|
||||
let pool_key = Pubkey::from_str(pool.as_str()).unwrap();
|
||||
|
||||
let to_custody_addr = ToCustodyTokenAccount::<'_, { AccountState::Initialized }>::key(
|
||||
&ToCustodyTokenAccountDerivationData { pool: pool_key },
|
||||
&program_id,
|
||||
);
|
||||
|
||||
to_custody_addr.to_bytes().to_vec()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn parse_pool(data: Vec<u8>) -> JsValue {
|
||||
JsValue::from_serde(&PoolData::try_from_slice(data.as_slice()).unwrap()).unwrap()
|
||||
}
|
Loading…
Reference in New Issue