Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
@certusone/wormhole-sdk
Advanced tools
Note: This is a pre-alpha release and in active development. Function names and signatures are subject to change.
Wormhole allows for the transmission of arbitrary data across multiple blockchains. Wormhole currently supports the following platforms:
Wormhole is, at its base layer, a very simple protocol. A Wormhole smart contract has been deployed on each of the supported blockchains, and users can emit messages in the Wormhole Network by submitting data to the smart contracts. These messages are quite simple and only have the following six fields.
Whenever a wormhole contract processes one of these messages, participants in the Wormhole Network ( individually known as Guardians ), will observe the transaction and create a SignedVAA (Signed Verifiable Action Approval) once the transaction has reached the specified confirmation time on the emitter chain.
The SignedVAA is essentially an affirmation from the Wormhole Network that a transaction has been finalized on the emitter chain, and that any dependent actions on other chains may proceed.
While simple, the Wormhole Protocol provides a powerful base layer upon which many 'bridge' applications can be built. Because Wormhole is capable of verifying arbitrary data, bridges utilizing it are able to transfer native currencies, tokens, NFTs, oracle data, governance votes, and a whole host of other forms of decentralized data.
The core Wormhole bridge operates by running smart contracts on both the Source Chain (where the data currently resides) and the Target Chain (where the data will be moved), and generally follows this workflow:
1) An end user or another smart contract publishes a message using the Bridge Contract on the Source Chain.
2) The Wormhole Network observes this transaction and issues a SignedVAA once it crosses its confirmation threshold.
3) An off-chain process collects the SignedVAA and submits it in a transaction to the Bridge Contract on the Target Chain, which can parse and verify the message.
It is important to note that the Wormhole Token Bridge is not, strictly speaking, part of the Wormhole protocol, but rather a bridge on top of it. However, as token transfers are such an important use-case of the bridge, it is built and packaged as part of the Wormhole SDK.
The Token Bridge works in the same fashion as above, leveraging the Core Bridge to publish messages. However, there are actually two different functions in the token bridge: Attest and Transfer.
Attestation is the process by which a token is 'registered' with the token bridge. Before being transferred, tokens must first be attested on their Origin Chain and have corresponding wrapped tokens created on the Foreign Chain to which they will be transferred. Attesting on the Origin Chain will create requisite addresses and metadata that will allow the wrapped asset to exist on Foreign Chains.
Once attested, tokens are mapped from their Native Chain to 'wrapped' assets on the Foreign Chains. Transferring an Ethereum-native token to Solana will result in a 'wrapped asset' on Solana, and transferring that same asset back to Ethereum will restore the native token.
It is important to note that Wormhole wrapped tokens are distinct from and incompatible with tokens wrapped by other bridges. Transferring a token which was wrapped by a different bridge will not redeem the native token, but rather will result in a 'double-wrapped' token.
The integration tests in the source code have many full-path examples, while the example Token Bridge UI demonstrates how to integrate it.
// Submit transaction - results in a Wormhole message being published
const transaction = await attestFromSolana(
connection,
SOL_BRIDGE_ADDRESS,
SOL_TOKEN_BRIDGE_ADDRESS,
payerAddress,
mintAddress
);
const signed = await wallet.signTransaction(transaction);
const txid = await connection.sendRawTransaction(signed.serialize());
await connection.confirmTransaction(txid);
// Get the sequence number and emitter address required to fetch the signedVAA of our message
const info = await connection.getTransaction(txid);
const sequence = parseSequenceFromLogSolana(info);
const emitterAddress = await getEmitterAddressSolana(SOL_TOKEN_BRIDGE_ADDRESS);
// Fetch the signedVAA from the Wormhole Network (this may require retries while you wait for confirmation)
const { signedVAA } = await getSignedVAA(
WORMHOLE_RPC_HOST,
CHAIN_ID_SOLANA,
emitterAddress,
sequence
);
// Create the wrapped token on Ethereum
await createWrappedOnEth(ETH_TOKEN_BRIDGE_ADDRESS, signer, signedVAA);
// Submit transaction - results in a Wormhole message being published
const receipt = await attestFromEth(
ETH_TOKEN_BRIDGE_ADDRESS,
signer,
tokenAddress
);
// Get the sequence number and emitter address required to fetch the signedVAA of our message
const sequence = parseSequenceFromLogEth(receipt, ETH_BRIDGE_ADDRESS);
const emitterAddress = getEmitterAddressEth(ETH_TOKEN_BRIDGE_ADDRESS);
// Fetch the signedVAA from the Wormhole Network (this may require retries while you wait for confirmation)
const { signedVAA } = await getSignedVAA(
WORMHOLE_RPC_HOST,
CHAIN_ID_ETH,
emitterAddress,
sequence
);
// On Solana, we have to post the signedVAA ourselves
await postVaaSolana(
connection,
wallet,
SOL_BRIDGE_ADDRESS,
payerAddress,
signedVAA
);
// Finally, create the wrapped token
const transaction = await createWrappedOnSolana(
connection,
SOL_BRIDGE_ADDRESS,
SOL_TOKEN_BRIDGE_ADDRESS,
payerAddress,
signedVAA
);
const signed = await wallet.signTransaction(transaction);
const txid = await connection.sendRawTransaction(signed.serialize());
await connection.confirmTransaction(txid);
// Submit transaction - results in a Wormhole message being published
const transaction = await transferFromSolana(
connection,
SOL_BRIDGE_ADDRESS,
SOL_TOKEN_BRIDGE_ADDRESS,
payerAddress,
fromAddress,
mintAddress,
amount,
targetAddress,
CHAIN_ID_ETH,
originAddress,
originChain
);
const signed = await wallet.signTransaction(transaction);
const txid = await connection.sendRawTransaction(signed.serialize());
await connection.confirmTransaction(txid);
// Get the sequence number and emitter address required to fetch the signedVAA of our message
const info = await connection.getTransaction(txid);
const sequence = parseSequenceFromLogSolana(info);
const emitterAddress = await getEmitterAddressSolana(SOL_TOKEN_BRIDGE_ADDRESS);
// Fetch the signedVAA from the Wormhole Network (this may require retries while you wait for confirmation)
const { signedVAA } = await getSignedVAA(
WORMHOLE_RPC_HOST,
CHAIN_ID_SOLANA,
emitterAddress,
sequence
);
// Redeem on Ethereum
await redeemOnEth(ETH_TOKEN_BRIDGE_ADDRESS, signer, signedVAA);
// determine destination address - an associated token account
const solanaMintKey = new PublicKey(
(await getForeignAssetSolana(
connection,
SOLANA_TOKEN_BRIDGE_ADDRESS,
CHAIN_ID_ETH,
hexToUint8Array(nativeToHexString(tokenAddress, CHAIN_ID_ETH) || "")
)) || ""
);
const recipientAddress = await Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
solanaMintKey,
walletAddress
);
// Submit transaction - results in a Wormhole message being published
const receipt = await transferFromEth(
ETH_TOKEN_BRIDGE_ADDRESS,
signer,
tokenAddress,
amount,
CHAIN_ID_SOLANA,
recipientAddress
);
// Get the sequence number and emitter address required to fetch the signedVAA of our message
const sequence = parseSequenceFromLogEth(receipt, ETH_BRIDGE_ADDRESS);
const emitterAddress = getEmitterAddressEth(ETH_TOKEN_BRIDGE_ADDRESS);
// Fetch the signedVAA from the Wormhole Network (this may require retries while you wait for confirmation)
const { signedVAA } = await getSignedVAA(
WORMHOLE_RPC_HOST,
CHAIN_ID_ETH,
emitterAddress,
sequence
);
// On Solana, we have to post the signedVAA ourselves
await postVaaSolana(
connection,
wallet,
SOL_BRIDGE_ADDRESS,
payerAddress,
signedVAA
);
// Finally, redeem on Solana
const transaction = await redeemOnSolana(
connection,
SOL_BRIDGE_ADDRESS,
SOL_TOKEN_BRIDGE_ADDRESS,
payerAddress,
signedVAA,
isSolanaNative,
mintAddress
);
const signed = await wallet.signTransaction(transaction);
const txid = await connection.sendRawTransaction(signed.serialize());
await connection.confirmTransaction(txid);
FAQs
SDK for interacting with Wormhole
The npm package @certusone/wormhole-sdk receives a total of 4,990 weekly downloads. As such, @certusone/wormhole-sdk popularity was classified as popular.
We found that @certusone/wormhole-sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.