Skip to content

Commit

Permalink
Merge pull request #94 from XLabs/solana-transfer-test
Browse files Browse the repository at this point in the history
Solana tests and SDK update
  • Loading branch information
scnale authored Nov 27, 2024
2 parents 08cc37f + f118be8 commit 3868b66
Show file tree
Hide file tree
Showing 32 changed files with 1,659 additions and 1,330 deletions.
147 changes: 70 additions & 77 deletions .pnp.cjs

Large diffs are not rendered by default.

Binary file not shown.
5 changes: 5 additions & 0 deletions Anchor.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ name = "wormhole-bridge"
address = "DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe" # Testnet in lib.rs
program = "solana/tests/token_bridge.so"

[[test.genesis]]
name = "mpl-token-metadata"
address = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"
program = "solana/tests/token_metadata.so"

[registry]
url = "https://api.apr.dev"

Expand Down
72 changes: 21 additions & 51 deletions connect/platforms/solana/src/automatic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
PublicKey,
SystemProgram,
Transaction,
TransactionInstruction,
VersionedTransaction,
} from '@solana/web3.js';
import { Chain, Network, amount as sdkAmount } from '@wormhole-foundation/sdk-base';
Expand Down Expand Up @@ -81,7 +80,7 @@ export class AutomaticTokenBridgeV3Solana<N extends Network, C extends SolanaCha
this.chain = new SolanaChain(chainName, new SolanaPlatform(this.network));
this.oracleClient = new SolanaPriceOracle(connection, new PublicKey(priceOracleAddress));
this.client = new SolanaTokenBridgeRelayer(
{ connection },
connection,
network,
new PublicKey(address),
this.oracleClient,
Expand Down Expand Up @@ -168,37 +167,19 @@ export class AutomaticTokenBridgeV3Solana<N extends Network, C extends SolanaCha
const senderPk = new PublicKey(params.sender.toNative('Solana').toString());
const gasDropoffAmount = Number(sdkAmount.display(params.gasDropOff));

if (token.chain === 'Solana') {
transaction.add(
await this.client.transferNativeTokens(senderPk, {
recipient: {
chain: params.recipient.chain,
address: params.recipient.address.toUniversalAddress(),
},
transferredAmount: BigInt(params.amount.toString()),
maxFeeLamports: BigInt(params.fee.toString() || 0),
gasDropoffAmount,
tokenAccount: ata,
mint,
unwrapIntent: params.unwrapIntent,
}),
);
} else {
transaction.add(
await this.client.transferWrappedTokens(senderPk, {
recipient: {
chain: params.recipient.chain,
address: params.recipient.address.toUniversalAddress(),
},
userTokenAccount: ata,
transferredAmount: BigInt(params.amount.toString()),
gasDropoffAmount,
maxFeeLamports: BigInt(params.fee.toString() || 0),
unwrapIntent: params.unwrapIntent,
token,
}),
);
}
transaction.add(
await this.client.transferTokens(senderPk, {
recipient: {
chain: params.recipient.chain,
address: params.recipient.address.toUniversalAddress(),
},
userTokenAccount: ata,
transferredAmount: BigInt(params.amount.toString()),
gasDropoffAmount,
maxFeeLamports: BigInt(params.fee.toString() || 0),
unwrapIntent: params.unwrapIntent,
}),
);

const { blockhash } = await this.connection.getLatestBlockhash('finalized');
transaction.recentBlockhash = blockhash;
Expand Down Expand Up @@ -227,24 +208,13 @@ export class AutomaticTokenBridgeV3Solana<N extends Network, C extends SolanaCha
const transaction = new Transaction();
transaction.feePayer = signer;

if (vaa.payload.token.chain === 'Solana') {
transaction.add(
await this.client.completeNativeTransfer(
signer,
// @ts-expect-error
vaa, // TODO: fix at solana sdk
ata,
),
);
} else {
transaction.add(
await this.client.completeWrappedTransfer(
signer,
// @ts-expect-error
vaa, // TODO: fix at solana sdk
ata,
),
);
const instructions = await this.client.completeTransfer(
signer,
// @ts-expect-error
vaa, // TODO: fix at solana sdk
);
for (const instruction of instructions) {
transaction.add(instruction);
}

const { blockhash } = await this.connection.getLatestBlockhash('finalized');
Expand Down
27 changes: 13 additions & 14 deletions deployment/solana/configure.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,23 @@
import { BN } from '@coral-xyz/anchor';
import { SolanaTokenBridgeRelayer } from '@xlabs-xyz/solana-arbitrary-token-transfers';
import { runOnSolana, ledgerSignAndSend, getConnection, SolanaSigner } from '../helpers/solana.js';
import { SolanaChainInfo, LoggerFn } from '../helpers/interfaces.js';
import { runOnSolana, ledgerSignAndSend, getConnection } from '../helpers/solana.js';
import { SolanaScriptCb } from '../helpers/interfaces.js';
import { dependencies } from '../helpers/env.js';
import { PublicKey } from '@solana/web3.js';
import { getChainConfig, getChainInfo } from '../helpers/env';
import { getChainConfig } from '../helpers/env';
import { SolanaTbrV3Config } from '../config/config.types.js';

runOnSolana('configure-tbr', configureSolanaTbr).catch((error) => {
console.error('Error executing script: ', error);
});

async function configureSolanaTbr(
chain: SolanaChainInfo,
signer: SolanaSigner,
log: LoggerFn,
): Promise<void> {
const configureSolanaTbr: SolanaScriptCb = async function (
chain,
signer,
log,
) {
const signerKey = new PublicKey(await signer.getAddress());
const connection = getConnection(chain);
const solanaDependencies = dependencies.find((d) => d.chainId === chain.chainId);
if (solanaDependencies === undefined) {
throw new Error(`No dependencies found for chain ${chain.chainId}`);
}
const tbr = await SolanaTokenBridgeRelayer.create({ connection });
const tbr = await SolanaTokenBridgeRelayer.create(connection);

const config = await getChainConfig<SolanaTbrV3Config>('tbr-v3', chain.chainId);

Expand Down Expand Up @@ -56,3 +51,7 @@ async function configureSolanaTbr(
await ledgerSignAndSend(connection, [ix], []);
}
}

runOnSolana('configure-tbr', configureSolanaTbr).catch((error) => {
console.error('Error executing script: ', error);
});
25 changes: 12 additions & 13 deletions deployment/solana/initialize.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
import { SolanaTokenBridgeRelayer } from '@xlabs-xyz/solana-arbitrary-token-transfers';
import { runOnSolana, ledgerSignAndSend, getConnection, SolanaSigner } from '../helpers/solana.js';
import { SolanaChainInfo, LoggerFn } from '../helpers/interfaces.js';
import { runOnSolana, ledgerSignAndSend, getConnection } from '../helpers/solana.js';
import { SolanaScriptCb } from '../helpers/interfaces.js';
import { PublicKey } from '@solana/web3.js';
import { loadSolanaTbrInitParams } from '../helpers/env.js';

runOnSolana('initialize-tbr', initializeSolanaTbr).catch((e) => {
console.error('Error executing script: ', e);
});

async function initializeSolanaTbr(
chain: SolanaChainInfo,
signer: SolanaSigner,
log: LoggerFn,
): Promise<void> {
const signerKey = new PublicKey(await signer.getAddress());
const initializeSolanaTbr: SolanaScriptCb = async function (
chain,
// signer,
// log,
) {
const connection = getConnection(chain);
const tbr = await SolanaTokenBridgeRelayer.create({ connection });
const tbr = await SolanaTokenBridgeRelayer.create(connection);

const tbrInitParams = loadSolanaTbrInitParams();

Expand All @@ -35,3 +30,7 @@ async function initializeSolanaTbr(

await ledgerSignAndSend(connection, [initializeIx], []);
}

runOnSolana('initialize-tbr', initializeSolanaTbr).catch((e) => {
console.error('Error executing script: ', e);
});
2 changes: 1 addition & 1 deletion deployment/solana/read-configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const readChainConfig: SolanaScriptCb = async function (
if (solanaDependencies === undefined) {
throw new Error(`No dependencies found for chain ${operatingChain.chainId}`);
}
const tbr = await SolanaTokenBridgeRelayer.create({ connection });
const tbr = await SolanaTokenBridgeRelayer.create(connection);

let allChainConfigs: ChainConfigEntry[];
try {
Expand Down
27 changes: 13 additions & 14 deletions deployment/solana/register-peers.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { BN } from '@coral-xyz/anchor';
import { chainIdToChain } from '@wormhole-foundation/sdk-base';
import { UniversalAddress } from '@wormhole-foundation/sdk-definitions';
import { SolanaTokenBridgeRelayer } from '@xlabs-xyz/solana-arbitrary-token-transfers';
import { runOnSolana, ledgerSignAndSend, getConnection, SolanaSigner } from '../helpers/solana.js';
import { SolanaChainInfo, LoggerFn } from '../helpers/interfaces.js';
import { runOnSolana, ledgerSignAndSend, getConnection } from '../helpers/solana.js';
import { SolanaScriptCb } from '../helpers/interfaces.js';
import { dependencies } from '../helpers/env.js';
import { PublicKey } from '@solana/web3.js';
import { contracts } from '../helpers';
Expand All @@ -18,23 +17,18 @@ type ChainConfigEntry = {
canonicalPeer: UniversalAddress;
};

runOnSolana('configure-tbr', configureSolanaTbr).catch((error) => {
console.error('Error executing script: ', error);
console.log('extra logs', error.getLogs());
});

async function configureSolanaTbr(
chain: SolanaChainInfo,
signer: SolanaSigner,
log: LoggerFn,
): Promise<void> {
const configureSolanaTbr: SolanaScriptCb = async function (
chain,
signer,
log,
) {
const signerKey = new PublicKey(await signer.getAddress());
const connection = getConnection(chain);
const solanaDependencies = dependencies.find((d) => d.chainId === chain.chainId);
if (solanaDependencies === undefined) {
throw new Error(`No dependencies found for chain ${chain.chainId}`);
}
const tbr = await SolanaTokenBridgeRelayer.create({ connection });
const tbr = await SolanaTokenBridgeRelayer.create(connection);

for (const tbrDeployment of contracts['TbrV3Proxies']) {
if (tbrDeployment.chainId === chain.chainId) continue; // skip self;
Expand Down Expand Up @@ -113,3 +107,8 @@ async function configureSolanaTbr(
}
}
}

runOnSolana('configure-tbr', configureSolanaTbr).catch((error) => {
console.error('Error executing script: ', error);
console.log('extra logs', error.getLogs());
});
24 changes: 12 additions & 12 deletions deployment/solana/unpause-contract.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
import { SolanaTokenBridgeRelayer } from '@xlabs-xyz/solana-arbitrary-token-transfers';
import { runOnSolana, ledgerSignAndSend, getConnection, SolanaSigner } from '../helpers/solana.js';
import { SolanaChainInfo, LoggerFn } from '../helpers/interfaces.js';
import { runOnSolana, ledgerSignAndSend, getConnection } from '../helpers/solana.js';
import { SolanaScriptCb } from '../helpers/interfaces.js';
import { dependencies } from '../helpers/env.js';
import { PublicKey } from '@solana/web3.js';

runOnSolana('unpause-contract', unpauseContract).catch((e) => {
console.error('Error executing script: ', e);
});

async function unpauseContract(
chain: SolanaChainInfo,
signer: SolanaSigner,
log: LoggerFn,
): Promise<void> {
const unpauseContract: SolanaScriptCb = async function (
chain,
signer,
// log,
) {
const signerKey = new PublicKey(await signer.getAddress());
const connection = getConnection(chain);
const solanaDependencies = dependencies.find((d) => d.chainId === chain.chainId);
if (solanaDependencies === undefined) {
throw new Error(`No dependencies found for chain ${chain.chainId}`);
}
const tbr = await SolanaTokenBridgeRelayer.create({ connection });
const tbr = await SolanaTokenBridgeRelayer.create(connection);

const initializeIx = await tbr.setPauseForOutboundTransfers(signerKey, 'Sepolia', false);

await ledgerSignAndSend(connection, [initializeIx], []);
}

runOnSolana('unpause-contract', unpauseContract).catch((e) => {
console.error('Error executing script: ', e);
});
53 changes: 15 additions & 38 deletions deployment/test/test-transfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ import { EvmAddress } from '@wormhole-foundation/sdk-evm';
import { PublicKey, SystemProgram, TransactionInstruction } from '@solana/web3.js';
import {
SolanaTokenBridgeRelayer,
TransferNativeParameters,
TransferWrappedParameters,
TransferParameters,
} from '@xlabs-xyz/solana-arbitrary-token-transfers';
import {
createAssociatedTokenAccountIdempotentInstruction,
Expand Down Expand Up @@ -304,48 +303,26 @@ async function sendSolanaTestTransaction(
throw new Error(`No dependencies found for chain ${chain.chainId}`);
}

const tbr = await SolanaTokenBridgeRelayer.create({ connection });
const tbr = await SolanaTokenBridgeRelayer.create(connection);

const evmAddress = getEnv('RECIPIENT_EVM_ADDRESS');
const maxFeeLamports = BigInt(getEnvOrDefault('MAX_FEE_KLAMPORTS', '5000000'));

let transferIx: TransactionInstruction;

if (testTransfer.tokenChain !== "Solana") {
const tokenChain = testTransfer.tokenChain ?? getEnvOrDefault('TOKEN_CHAIN', 'Sepolia') as Chain;
const params = {
recipient: {
chain: targetChain.name as Chain,
address: toUniversal(targetChain.name as Chain, evmAddress),
},
token: {
chain: tokenChain,
address: toUniversal(testTransfer.tokenChain, testTransfer.sourceTokenAddress ?? testTransfer.tokenAddress!),
},
userTokenAccount: tokenAccount,
transferredAmount,
gasDropoffAmount,
maxFeeLamports,
unwrapIntent,
} satisfies TransferWrappedParameters;

transferIx = await tbr.transferWrappedTokens(signerKey, params);
} else {
const params = {
recipient: {
chain: targetChain.name as Chain,
address: toUniversal(targetChain.name as Chain, evmAddress),
},
mint,
tokenAccount,
transferredAmount,
gasDropoffAmount,
maxFeeLamports,
unwrapIntent,
} satisfies TransferNativeParameters;

transferIx = await tbr.transferNativeTokens(signerKey, params);
}
const params = {
recipient: {
chain: targetChain.name as Chain,
address: toUniversal(targetChain.name as Chain, evmAddress),
},
userTokenAccount: tokenAccount,
transferredAmount,
gasDropoffAmount,
maxFeeLamports,
unwrapIntent,
} satisfies TransferParameters;

transferIx = await tbr.transferTokens(signerKey, params);
const ixs: TransactionInstruction[] = [];

// if transferring SOL first we have to wrap it
Expand Down
4 changes: 2 additions & 2 deletions sdk/solana/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@
},
"dependencies": {
"@coral-xyz/anchor": "^0.30.1",
"@solana/spl-token": "^0.4.9",
"@solana/web3.js": "^1.95.3",
"@wormhole-foundation/sdk-base": "^0.12.0",
"@wormhole-foundation/sdk-definitions": "^0.12.0",
"@wormhole-foundation/sdk-solana": "^0.12.0",
"@wormhole-foundation/sdk-solana-tokenbridge": "^0.12.0",
"@xlabs-xyz/solana-price-oracle-sdk": "0.0.16",
"borsh": "^2.0.0"
"@xlabs-xyz/solana-price-oracle-sdk": "0.0.16"
},
"devDependencies": {
"@types/node": "20.17.5",
Expand Down
Loading

0 comments on commit 3868b66

Please sign in to comment.