Skip to content
This repository was archived by the owner on Jun 16, 2025. It is now read-only.

Commit 925b755

Browse files
AgusVelez5scnale
authored andcommitted
Add solana programs helpers
1 parent 78539b0 commit 925b755

File tree

8 files changed

+71
-33
lines changed

8 files changed

+71
-33
lines changed

deployment/helpers/env.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,24 @@ export function getEnv(env: string): string {
4545
return v;
4646
}
4747

48+
export function getChainInfo(chainId: ChainId): ChainInfo {
49+
if (ecosystemChains.solana.networks.length > 1) {
50+
throw Error("Unexpected number of Solana networks.");
51+
}
52+
53+
const chains = [
54+
...ecosystemChains.evm.networks,
55+
...ecosystemChains.solana.networks,
56+
];
57+
58+
const chain = chains.find((c) => c.chainId === chainId);
59+
if (chain === undefined) {
60+
throw Error(`Failed to find chain info for chain id: ${chainId}`);
61+
}
62+
63+
return chain;
64+
}
65+
4866
export async function getChainConfig<T extends ChainConfig>(filename: string, whChainId: ChainId): Promise<T> {
4967
const scriptConfig: T[] = await loadJson(filename);
5068

deployment/helpers/interfaces.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { Commitment } from "@solana/web3.js";
12
import { ChainId, Network } from "@wormhole-foundation/sdk-base";
23
import { SolanaLedgerSigner } from "@xlabs-xyz/ledger-signer-solana";
34
import { BytesLike, ethers } from "ethers";
@@ -19,6 +20,7 @@ export type ChainInfo = {
1920
*/
2021
externalId?: string;
2122
network: Network;
23+
commitmentLevel?: Commitment;
2224
};
2325

2426
export type Deployment = {

deployment/helpers/solana.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@ import {
77
Commitment
88
} from "@solana/web3.js";
99
import { SolanaLedgerSigner } from "@xlabs-xyz/ledger-signer-solana";
10-
import { ecosystemChains, getEnv } from "./env";
10+
import { ecosystemChains, env, getContractAddress, getEnv } from "./env";
1111
import type { SolanaScriptCb } from "./interfaces";
1212
import { inspect } from "util";
13+
import { circle, toChainId } from "@wormhole-foundation/sdk-base";
14+
import { MatchingEngineProgram, ProgramId as MatchingEngineProgramId } from "@wormhole-foundation/example-liquidity-layer-solana/matchingEngine";
15+
import { TokenRouterProgram, ProgramId as TokenRouterProgramId } from "@wormhole-foundation/example-liquidity-layer-solana/tokenRouter";
1316

1417
export const connectionCommitmentLevel = (process.env.SOLANA_COMMITMENT || "confirmed") as Commitment;
1518
export const priorityMicrolamports = process.env.PRIORITY_MICROLAMPORTS !== "undefined" ? Number(process.env.PRIORITY_MICROLAMPORTS) : 1;
@@ -89,4 +92,20 @@ export async function ledgerSignAndSend(connection: Connection, instructions: Tr
8992
async function addLedgerSignature(tx: Transaction, signer: SolanaLedgerSigner, signerPk: PublicKey) {
9093
const signedByPayer = await signer.signTransaction(tx.compileMessage().serialize());
9194
tx.addSignature(signerPk, signedByPayer);
92-
}
95+
}
96+
97+
export function getMatchingEngineProgram(connection: Connection) {
98+
const matchingEngineId = getContractAddress("MatchingEngine", toChainId("Solana")) as MatchingEngineProgramId;
99+
const network = env === "mainnet" ? "Mainnet" : "Testnet";
100+
101+
const usdcMint = new PublicKey(circle.usdcContract(network, "Solana"));
102+
return new MatchingEngineProgram(connection, matchingEngineId, usdcMint);
103+
};
104+
105+
export function getTokenRouterProgram(connection: Connection) {
106+
const tokenRouterId = getContractAddress("TokenRouter", toChainId("Solana")) as TokenRouterProgramId;
107+
const network = env === "mainnet" ? "Mainnet" : "Testnet";
108+
109+
const usdcMint = new PublicKey(circle.usdcContract(network, "Solana"));
110+
return new TokenRouterProgram(connection, tokenRouterId, usdcMint);
111+
};

deployment/helpers/utils.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import chalk from 'chalk';
22
import { ChainInfo, LoggerFn, ValueDiff } from '.';
3-
import { UniversalAddress } from '@wormhole-foundation/sdk-definitions';
43

54
export const someoneIsDifferent = (values: ValueDiff[]) => values.some((value) => value.onChain.toString() !== value.offChain.toString() && Number(value.onChain) !== Number(value.offChain));
65

deployment/scripts/evm/TokenRouter/cross-registration-token-router.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import { evm, getContractInstance, getContractAddress, contracts } from "../../../helpers";
1+
import { evm, getContractInstance, getContractAddress, contracts, getChainInfo } from "../../../helpers";
22
import { TokenRouter } from "../../../contract-bindings";
3-
import { circle, toChain } from "@wormhole-foundation/sdk-base";
3+
import { circle, toChain, toChainId } from "@wormhole-foundation/sdk-base";
44
import { toUniversal } from "@wormhole-foundation/sdk-definitions";
5+
import { getTokenRouterProgram } from "../../../helpers/solana";
6+
import { Connection } from "@solana/web3.js";
57

68
evm.runOnEvms("cross-registration-token-router", async (chain, _, log) => {
79
const tokenRouterAddress = getContractAddress("TokenRouterProxy", chain.chainId);
@@ -10,11 +12,12 @@ evm.runOnEvms("cross-registration-token-router", async (chain, _, log) => {
1012

1113
for (const router of deployedTokenRouters) {
1214
const circleDomain = circle.toCircleChainId(chain.network, toChain(router.chainId));
13-
// TODO: handle Solana registrations correctly in regards to mintRecipient
1415
const routerChain = toChain(router.chainId);
16+
const routerAddress = toUniversal(routerChain, router.address).toString();
17+
const mintRecipient = routerChain === "Solana" ? getSolanaMintRecipient() : routerAddress;
1518
const endpoint = {
16-
router: toUniversal(routerChain, router.address).toString(),
17-
mintRecipient: toUniversal(routerChain, router.address).toString()
19+
router: routerAddress,
20+
mintRecipient
1821
};
1922

2023
if (router.chainId === 0)
@@ -33,3 +36,13 @@ evm.runOnEvms("cross-registration-token-router", async (chain, _, log) => {
3336
log(`Router endpoint added for chainId ${router.chainId}`);
3437
}
3538
});
39+
40+
41+
function getSolanaMintRecipient(): string {
42+
const chain = "Solana";
43+
const chainInfo = getChainInfo(toChainId(chain));
44+
const connection = new Connection(chainInfo.rpc, chainInfo.commitmentLevel || "confirmed");
45+
const tokenRouter = getTokenRouterProgram(connection);
46+
47+
return toUniversal(chain, tokenRouter.custodianAddress().toBytes()).toString();
48+
}

deployment/scripts/evm/TokenRouter/deploy-token-router.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
11
import { ethers } from "ethers";
2-
import { ecosystemChains, evm, LoggerFn, solana, writeDeployedContract } from "../../../helpers";
2+
import { evm, getChainInfo, LoggerFn, writeDeployedContract } from "../../../helpers";
33
import { TokenRouterConfiguration } from "../../../config/config-types";
44
import { deployImplementation, getMatchingEngineMintRecipientAddress, getTokenRouterConfiguration } from "./utils";
55
import { ERC1967Proxy__factory } from "../../../contract-bindings";
66
import { toUniversal } from "@wormhole-foundation/sdk-definitions";
77
import { Connection } from "@solana/web3.js";
8+
import { toChainId } from "@wormhole-foundation/sdk-base";
89

910
evm.runOnEvms("deploy-token-router", async (chain, signer, log) => {
1011
const config = await getTokenRouterConfiguration(chain);
12+
const solanaChainInfo = getChainInfo(toChainId("Solana"));
13+
const solanaConnection = new Connection(solanaChainInfo.rpc, solanaChainInfo.commitmentLevel || "confirmed");
1114

12-
// TODO: write a `getChain(chainId: ChainId): ChainInfo` function to replace these lines
13-
if (ecosystemChains.solana.networks.length !== 1) {
14-
throw Error("Unexpected number of Solana networks.");
15-
}
16-
const solanaRpc = ecosystemChains.solana.networks[0].rpc;
17-
18-
const solanaConnection = new Connection(solanaRpc, solana.connectionCommitmentLevel);
1915
const matchingEngineMintRecipient = toUniversal("Solana", getMatchingEngineMintRecipientAddress(solanaConnection));
2016
const implementation = await deployImplementation(signer, config, matchingEngineMintRecipient, log);
2117
await deployProxy(signer, config, implementation, log);

deployment/scripts/evm/TokenRouter/upgrade-token-router.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,18 @@
1-
import { evm, ChainInfo, getContractInstance, getContractAddress, getDependencyAddress, ecosystemChains, solana } from "../../../helpers";
1+
import { evm, ChainInfo, getContractInstance, getContractAddress, getDependencyAddress, getChainInfo } from "../../../helpers";
22
import { deployImplementation, getMatchingEngineMintRecipientAddress, getTokenRouterConfiguration, matchingEngineChain, matchingEngineDomain } from "./utils";
33
import { TokenRouter } from "../../../contract-bindings";
44
import { UniversalAddress, toUniversal } from "@wormhole-foundation/sdk-definitions";
55
import { Connection } from "@solana/web3.js";
6+
import { toChainId } from "@wormhole-foundation/sdk-base";
67

78
evm.runOnEvms("upgrade-token-router", async (chain, signer, log) => {
89
const currentImplementationAddress = getContractAddress("TokenRouterImplementation", chain.chainId);
910
const proxyAddress = getContractAddress("TokenRouterProxy", chain.chainId);
1011
const proxy = (await getContractInstance("TokenRouter", proxyAddress, chain)) as TokenRouter;
1112
const config = await getTokenRouterConfiguration(chain);
12-
13-
// TODO: write a `getChain(chainId: ChainId): ChainInfo` function to replace these lines
14-
if (ecosystemChains.solana.networks.length !== 1) {
15-
throw Error("Unexpected number of Solana networks.");
16-
}
17-
const solanaRpc = ecosystemChains.solana.networks[0].rpc;
18-
19-
const solanaConnection = new Connection(solanaRpc, solana.connectionCommitmentLevel);
13+
14+
const solanaChainInfo = getChainInfo(toChainId("Solana"));
15+
const solanaConnection = new Connection(solanaChainInfo.rpc, solanaChainInfo.commitmentLevel || "confirmed");
2016
const matchingEngineMintRecipient = toUniversal("Solana", getMatchingEngineMintRecipientAddress(solanaConnection));
2117

2218
log(`Checking immutables for TokenRouter`);

deployment/scripts/evm/TokenRouter/utils.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ import { TokenRouter, TokenRouter__factory } from "../../../contract-bindings";
44
import { ChainInfo, getChainConfig, LoggerFn, getDependencyAddress, writeDeployedContract, getContractAddress, getContractInstance, logComparison, someoneIsDifferent } from "../../../helpers";
55
import { IERC20 } from "../../../contract-bindings";
66
import { UniversalAddress, toUniversal } from "@wormhole-foundation/sdk-definitions";
7-
import { circle, toChain, toChainId } from "@wormhole-foundation/sdk-base";
8-
import { MatchingEngineProgram, ProgramId } from "@wormhole-foundation/example-liquidity-layer-solana/matchingEngine";
9-
import { Connection, PublicKey } from "@solana/web3.js";
7+
import { Connection } from "@solana/web3.js";
8+
import { getMatchingEngineProgram } from "../../../helpers/solana";
109

1110
/**
1211
* Chain ID for the Solana wormhole chain
@@ -19,11 +18,7 @@ export const matchingEngineChain = 1;
1918
export const matchingEngineDomain = 5;
2019

2120
export function getMatchingEngineMintRecipientAddress(connection: Connection) {
22-
const matchingEngineId = getContractAddress("MatchingEngine", toChainId("Solana")) as ProgramId;
23-
24-
const env = "Mainnet";
25-
const usdcMint = new PublicKey(circle.usdcContract(env, "Solana"));
26-
const matchingEngine = new MatchingEngineProgram(connection, matchingEngineId, usdcMint);
21+
const matchingEngine = getMatchingEngineProgram(connection);
2722
return matchingEngine.cctpMintRecipientAddress().toBytes();
2823
};
2924

0 commit comments

Comments
 (0)