Skip to content

Commit

Permalink
Merge pull request #42 from sunrise-stake/chore/script-fixes
Browse files Browse the repository at this point in the history
Script fixes
  • Loading branch information
dankelleher committed Sep 11, 2024
2 parents 988b521 + aabcd87 commit f6e3121
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 133 deletions.
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
POLYGON_NODE_URL=
SOLANA_RPC_ENDPOINT=
POLYGON_PRIVATE_KEY=
2 changes: 1 addition & 1 deletion scripts/bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ async function bridge() {
const txSig = await solanaProgram.methods.bridge(new BN(amount.toString()), instruction.data).accounts({
state: STATE_ADDRESS,
bridgeAuthority,
tokenAccount: bridgeInputTokenAccount,
tokenAccount: bridgeInputTokenAccount(STATE_ADDRESS),
}).remainingAccounts(instruction.keys)
.signers([message])
.rpc();
Expand Down
12 changes: 9 additions & 3 deletions scripts/createATAs.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { ConfirmOptions, Connection, PublicKey, sendAndConfirmTransaction, Signer, Transaction } from "@solana/web3.js";
import { WRAPPED_SOL_TOKEN_MINT, BRIDGE_INPUT_MINT_ADDRESS, SOLANA_RPC_ENDPOINT, USER_KEYPAIR } from "./constants";
import {
WRAPPED_SOL_TOKEN_MINT,
BRIDGE_INPUT_MINT_ADDRESS,
SOLANA_RPC_ENDPOINT,
USER_KEYPAIR,
STATE_ADDRESS
} from "./constants";
import { createAssociatedTokenAccountInstruction, getAssociatedTokenAddressSync, ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } from "spl-token-latest";
import { tokenAuthority } from "./util";

Expand Down Expand Up @@ -36,8 +42,8 @@ async function createAssociatedTokenAccount(
(async () => {
const connection = new Connection(SOLANA_RPC_ENDPOINT);

const inputMintATA = await createAssociatedTokenAccount(connection, USER_KEYPAIR, new PublicKey(WRAPPED_SOL_TOKEN_MINT), tokenAuthority);
const outputMintATA = await createAssociatedTokenAccount(connection, USER_KEYPAIR, new PublicKey(BRIDGE_INPUT_MINT_ADDRESS), tokenAuthority);
const inputMintATA = await createAssociatedTokenAccount(connection, USER_KEYPAIR, new PublicKey(WRAPPED_SOL_TOKEN_MINT), tokenAuthority(STATE_ADDRESS));
const outputMintATA = await createAssociatedTokenAccount(connection, USER_KEYPAIR, new PublicKey(BRIDGE_INPUT_MINT_ADDRESS), tokenAuthority(STATE_ADDRESS));

console.log("inputMintATA", inputMintATA.toBase58());
console.log("outputMintATA", outputMintATA.toBase58());
Expand Down
4 changes: 2 additions & 2 deletions scripts/depositUSDC.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
Connection, PublicKey,
} from "@solana/web3.js";
import {SOLANA_RPC_ENDPOINT, USER_KEYPAIR, USDC_TOKEN_SOLANA} from "./constants";
import {SOLANA_RPC_ENDPOINT, USER_KEYPAIR, USDC_TOKEN_SOLANA, STATE_ADDRESS} from "./constants";
import {getAssociatedTokenAddressSync, transfer} from "spl-token-latest";
import {tokenAuthority} from "./util";

Expand All @@ -10,7 +10,7 @@ const usdcToSend = 1_000_000; // 1 USDC
(async () => {
const connection = new Connection(SOLANA_RPC_ENDPOINT);
const from = getAssociatedTokenAddressSync(new PublicKey(USDC_TOKEN_SOLANA), USER_KEYPAIR.publicKey);
const to = getAssociatedTokenAddressSync(new PublicKey(USDC_TOKEN_SOLANA), tokenAuthority, true);
const to = getAssociatedTokenAddressSync(new PublicKey(USDC_TOKEN_SOLANA), tokenAuthority(STATE_ADDRESS), true);
const tx= await transfer(connection, USER_KEYPAIR, from, to, USER_KEYPAIR.publicKey, usdcToSend);
console.log("tx: ", tx);
})().catch((error) => {
Expand Down
21 changes: 14 additions & 7 deletions scripts/getState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet";
import {BigNumber, ethers} from "ethers";
import {HOLDING_CONTRACT_ABI} from "../ui/src/lib/abi/holdingContract";
import {ERC20_ABI} from "../ui/src/lib/abi/erc20";
import {tokenAuthority} from "./util";

const POLYGON_NODE_URL = process.env.POLYGON_NODE_URL;
const ethProvider = new ethers.providers.JsonRpcProvider(POLYGON_NODE_URL);
Expand All @@ -26,7 +27,7 @@ const isValidPublicKey = (publicKey: string) => {
}

// read the state address from the command line
const stateAddress = process.argv[2];
const stateAddress = process.argv[2] ?? "4U6vxUjMGhiaM8GzmH8KKvs8q7L3zxjDV5eRJnyfAtgF";
// ensure the state address is provided and is a valid PublicKey
if (!stateAddress || !isValidPublicKey(stateAddress)) {
console.error('Usage: bun run scripts/getState.ts <stateAddress>');
Expand All @@ -44,18 +45,24 @@ if (!stateAddress || !isValidPublicKey(stateAddress)) {

const state = await program.account.state.fetch(new PublicKey(stateAddress));

console.log("Output Mint Address: ", state.outputMint.toBase58());
console.log("Chain ID: ", state.tokenChainId);
console.log("Holding Contract", state.holdingContract);
console.log("Upgrade Authority", state.updateAuthority.toBase58())
console.log("State Address:", stateAddress);
console.log("Output Mint Address:", state.outputMint.toBase58());
console.log("Chain ID:", state.tokenChainId);
console.log("Holding Contract:", state.holdingContract);
console.log("Upgrade Authority:", state.updateAuthority.toBase58())

console.log("Token Authority", tokenAuthority(new PublicKey(stateAddress)).toBase58())

console.log("Fetching holding contract state on Polygon...")
const holdingContract = new ethers.Contract(state.holdingContract, HOLDING_CONTRACT_ABI, ethProvider);
const owner = await holdingContract.owner();
console.log("Owner:", owner);

const retirementContract = await holdingContract.retireContract();
console.log("Retirement Contract", retirementContract);
console.log("Retirement Contract:", retirementContract);

const tco2ContractAddress = await holdingContract.tco2();
console.log("TCO2 Contract Address", tco2ContractAddress);
console.log("TCO2 Contract Address:", tco2ContractAddress);
const tco2Contract = new ethers.Contract(tco2ContractAddress, ERC20_ABI, ethProvider);
const result = await tco2Contract.balanceOf(NCT_POOL_ADDRESS);
const decimals = await tco2Contract.decimals();
Expand Down
4 changes: 2 additions & 2 deletions scripts/getStateAddresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import {WRAPPED_SOL_TOKEN_MINT, STATE_ADDRESS} from "./constants";
import {getAssociatedTokenAddressSync} from "spl-token-latest";
import {tokenAuthority} from "./util";

const wrappedSolATA = getAssociatedTokenAddressSync(new PublicKey(WRAPPED_SOL_TOKEN_MINT), tokenAuthority, true);
const wrappedSolATA = getAssociatedTokenAddressSync(new PublicKey(WRAPPED_SOL_TOKEN_MINT), tokenAuthority(STATE_ADDRESS), true);

console.log("state address: ", STATE_ADDRESS.toBase58())
console.log("tokenAuthority: ", tokenAuthority.toBase58())
console.log("tokenAuthority: ", tokenAuthority(STATE_ADDRESS).toBase58())
console.log("wrappedSolATA", wrappedSolATA.toBase58());
93 changes: 30 additions & 63 deletions scripts/types/swap_bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* IDL can be found at `target/idl/swap_bridge.json`.
*/
export type SwapBridge = {
"address": "suobUdMc9nSaQ1TjRkQA4K6CR9CmDiU9QViN7kVw74T",
"address": "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",
"metadata": {
"name": "swapBridge",
"version": "0.1.0",
Expand All @@ -29,8 +29,8 @@ export type SwapBridge = {
{
"name": "state",
"docs": [
"The state account that identifies the mint of the token being transferred through the bridge",
"and is also the token account authority"
"State account specifying the mint of the token being transferred through the bridge",
"and the recipient address on the target chain"
]
},
{
Expand Down Expand Up @@ -113,6 +113,9 @@ export type SwapBridge = {
"accounts": [
{
"name": "state",
"docs": [
"Initialize the state account"
],
"writable": true,
"pda": {
"seeds": [
Expand Down Expand Up @@ -239,66 +242,6 @@ export type SwapBridge = {
}
}
]
},
{
"name": "wrap",
"discriminator": [
178,
40,
10,
189,
228,
129,
186,
140
],
"accounts": [
{
"name": "state"
},
{
"name": "tokenAccountAuthority",
"pda": {
"seeds": [
{
"kind": "const",
"value": [
116,
111,
107,
101,
110,
95,
97,
117,
116,
104,
111,
114,
105,
116,
121
]
},
{
"kind": "account",
"path": "state"
}
]
}
},
{
"name": "tokenAccount",
"docs": [
"The account containing tokens that will be transferred through the bridge"
]
},
{
"name": "tokenProgram",
"address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
}
],
"args": []
}
],
"accounts": [
Expand Down Expand Up @@ -336,18 +279,30 @@ export type SwapBridge = {
"fields": [
{
"name": "outputMint",
"docs": [
"Mint of the wrapped USDC token to be bridged over to the target chain"
],
"type": "pubkey"
},
{
"name": "holdingContract",
"docs": [
"Holding contract on the target chain to receive the bridged tokens"
],
"type": "string"
},
{
"name": "tokenChainId",
"docs": [
"Wormhole ID specifying the target chain"
],
"type": "string"
},
{
"name": "updateAuthority",
"docs": [
"Authority who can update the data in the state account"
],
"type": "pubkey"
}
]
Expand All @@ -360,18 +315,30 @@ export type SwapBridge = {
"fields": [
{
"name": "outputMint",
"docs": [
"Mint of the wrapped USDC token to be bridged over to the target chain"
],
"type": "pubkey"
},
{
"name": "holdingContract",
"docs": [
"Holding contract on the target chain to receive the bridged tokens"
],
"type": "string"
},
{
"name": "tokenChainId",
"docs": [
"Wormhole ID specifying the target chain"
],
"type": "string"
},
{
"name": "updateAuthority",
"docs": [
"Authority who can update the data in the state account"
],
"type": "pubkey"
}
]
Expand Down
4 changes: 2 additions & 2 deletions scripts/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ const getPossiblePairsTokenInfo = ({

export const solanaAddressToHex = (address: PublicKey) => `0x${address.toBuffer().toString("hex")}` as const;

export const tokenAuthority = PublicKey.findProgramAddressSync([Buffer.from("token_authority"), STATE_ADDRESS.toBuffer()], PROGRAM_ID)[0];
export const tokenAuthority = (stateAddress: PublicKey) => PublicKey.findProgramAddressSync([Buffer.from("token_authority"), stateAddress.toBuffer()], PROGRAM_ID)[0];
export const bridgeAuthority = PublicKey.findProgramAddressSync([Buffer.from("authority_signer")], new PublicKey(SOL_TOKEN_BRIDGE_ADDRESS))[0];
export const bridgeInputTokenAccount = getAssociatedTokenAddressSync(new PublicKey(BRIDGE_INPUT_MINT_ADDRESS), tokenAuthority, true);
export const bridgeInputTokenAccount = (stateAddress: PublicKey) => getAssociatedTokenAddressSync(new PublicKey(BRIDGE_INPUT_MINT_ADDRESS), tokenAuthority(stateAddress), true);

const SEED_INDEX = Buffer.from([0]);
export const deriveStateAddress = (owner: PublicKey) => PublicKey.findProgramAddressSync([Buffer.from("state_address"), owner.toBuffer(), SEED_INDEX], PROGRAM_ID)[0];
4 changes: 2 additions & 2 deletions scripts/wrapSOL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import {
SystemProgram,
Transaction
} from "@solana/web3.js";
import {WRAPPED_SOL_TOKEN_MINT, SOLANA_RPC_ENDPOINT, USER_KEYPAIR} from "./constants";
import {WRAPPED_SOL_TOKEN_MINT, SOLANA_RPC_ENDPOINT, USER_KEYPAIR, STATE_ADDRESS} from "./constants";
import {createSyncNativeInstruction, getAssociatedTokenAddressSync} from "spl-token-latest";
import {tokenAuthority} from "./util";

const lamportsToSend = 1_000_000; // 0.1 SOL

(async () => {
const connection = new Connection(SOLANA_RPC_ENDPOINT);
const wrappedSolATA = getAssociatedTokenAddressSync(new PublicKey(WRAPPED_SOL_TOKEN_MINT), tokenAuthority, true);
const wrappedSolATA = getAssociatedTokenAddressSync(new PublicKey(WRAPPED_SOL_TOKEN_MINT), tokenAuthority(STATE_ADDRESS), true);

const tx = new Transaction().add(
SystemProgram.transfer({
Expand Down
32 changes: 1 addition & 31 deletions solana-contract/programs/swap-bridge/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ mod util;
use crate::util::bridge::Wormhole;
use crate::util::errors::ErrorCode;
use crate::util::swap::Jupiter;
use crate::util::token::wrapped_sol::ID as WRAPPED_SOL;
use anchor_lang::prelude::*;
use anchor_spl::token::{Token, TokenAccount};

Expand All @@ -16,7 +15,7 @@ pub mod swap_bridge {
use super::*;
use crate::util::bridge::call_bridge;
use crate::util::errors::ErrorCode;
use crate::util::token::{approve_delegate, wrap_sol};
use crate::util::token::approve_delegate;
use anchor_lang::solana_program::instruction::Instruction;
use anchor_lang::solana_program::program;

Expand Down Expand Up @@ -65,20 +64,6 @@ pub mod swap_bridge {
Ok(())
}

pub fn wrap(ctx: Context<Wrap>) -> Result<()> {
let state_address = ctx.accounts.state.key();
let authority_seeds = [
State::TOKEN_AUTHORITY_SEED,
state_address.as_ref(),
&[ctx.bumps.token_account_authority],
];
wrap_sol(
&ctx.accounts.token_account.to_account_info(),
&ctx.accounts.token_program,
&authority_seeds[..],
)
}

pub fn swap(ctx: Context<Swap>, route_info: Vec<u8>) -> Result<()> {
/* Swap SOL for wrapped USDC for the target chain using Jupiter
Expand Down Expand Up @@ -199,21 +184,6 @@ pub struct Swap<'info> {
pub jupiter_program: Program<'info, Jupiter>,
}

#[derive(Accounts)]
pub struct Wrap<'info> {
pub state: Account<'info, State>,
#[account(
seeds = [State::TOKEN_AUTHORITY_SEED, state.key().as_ref()],
bump
)]
/// CHECK: Derived from the state account
pub token_account_authority: UncheckedAccount<'info>,
/// The account containing tokens that will be transferred through the bridge
#[account(token::authority = token_account_authority.key(), token::mint = WRAPPED_SOL)]
pub token_account: Account<'info, TokenAccount>,
pub token_program: Program<'info, Token>,
}

#[derive(Accounts)]
pub struct Bridge<'info> {
/// State account specifying the mint of the token being transferred through the bridge
Expand Down
21 changes: 1 addition & 20 deletions solana-contract/programs/swap-bridge/src/util/token.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use anchor_lang::prelude::*;
use anchor_spl::token;
use anchor_spl::token::{sync_native, Approve, SyncNative, Token};
use anchor_spl::token::{Approve, Token};

pub fn approve_delegate<'a>(
amount: u64,
Expand Down Expand Up @@ -34,22 +34,3 @@ pub fn approve_delegate<'a>(

Ok(())
}

pub fn wrap_sol<'a>(
token_account: &AccountInfo<'a>,
token_program: &Program<'a, Token>,
signer_seeds: &[&[u8]],
) -> Result<()> {
let cpi_program = token_program.to_account_info();
let cpi_accounts = SyncNative {
account: token_account.to_account_info(),
};
let seeds = [signer_seeds];
let cpi_ctx = CpiContext::new_with_signer(cpi_program, cpi_accounts, &seeds);
sync_native(cpi_ctx)
}

pub(crate) mod wrapped_sol {
use super::*;
declare_id!("So11111111111111111111111111111111111111112");
}

0 comments on commit f6e3121

Please sign in to comment.