Skip to content

Commit

Permalink
feat: read program id from deployed addresses or pass it as arg
Browse files Browse the repository at this point in the history
Signed-off-by: Pablo Maldonado <[email protected]>
  • Loading branch information
md0x committed Dec 19, 2024
1 parent 97973eb commit 518bf52
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 15 deletions.
5 changes: 5 additions & 0 deletions deployments/deployments.json
Original file line number Diff line number Diff line change
Expand Up @@ -157,5 +157,10 @@
"41455": {
"SpokePool": { "address": "0x13fDac9F9b4777705db45291bbFF3c972c6d1d97", "blockNumber": 4240318 },
"MulticallHandler": { "address": "0x924a9f036260DdD5808007E1AA95f08eD08aA569", "blockNumber": 4112529 }
},
"1810017368444177321": {
"SvmSpoke": { "address": "YVMQN27RnCNt23NRxzJPumXRd8iovEfKtzkqyMc5vDt", "blockNumber": 0 },
"MessageTransmitter": { "address": "CCTPmbSD7gX1bxKPAmg77w8oFzNFpaQiQUWD43TKaecd", "blockNumber": 0 },
"TokenMessengerMinter": { "address": "CCTPiPYPc6AsJuwueEnWgSgucamXDZwBd53dQ11YiKX3", "blockNumber": 0 }
}
}
6 changes: 5 additions & 1 deletion src/DeploymentUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ interface DeploymentExport {
const deployments: DeploymentExport = deployments_ as any;

// Returns the deployed address of any contract on any network.
export function getDeployedAddress(contractName: string, networkId: number, throwOnError = true): string | undefined {
export function getDeployedAddress(
contractName: string,
networkId: number | string,
throwOnError = true
): string | undefined {
const address = deployments[networkId.toString()]?.[contractName]?.address;
if (!address && throwOnError) {
throw new Error(`Contract ${contractName} not found on ${networkId} in deployments.json`);
Expand Down
58 changes: 44 additions & 14 deletions src/svm/programConnectors.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,61 @@
import { Idl, Program, Provider } from "@coral-xyz/anchor";
import { Idl, Program, AnchorProvider } from "@coral-xyz/anchor";
import { getSolanaChainId, isSolanaDevnet } from "../../scripts/svm/utils/helpers";
import { getDeployedAddress } from "../DeploymentUtils";
import { SupportedNetworks } from "../types/svm";
import {
SvmSpokeIdl,
SvmSpokeAnchor,
MessageTransmitterAnchor,
MessageTransmitterIdl,
TokenMessengerMinterAnchor,
TokenMessengerMinterIdl,
MulticallHandlerAnchor,
MulticallHandlerIdl,
SvmSpokeAnchor,
SvmSpokeIdl,
TokenMessengerMinterAnchor,
TokenMessengerMinterIdl,
} from "./assets";

export function getConnectedProgram<P extends Idl>(idl: P, provider: Provider) {
type ProgramOptions = { network?: SupportedNetworks; programId?: string };

export function getConnectedProgram<P extends Idl>(idl: P, provider: AnchorProvider, programId: string) {
idl.address = programId;
return new Program<P>(idl, provider);
}

export function getSpokePoolProgram(provider: Provider) {
return getConnectedProgram<SvmSpokeAnchor>(SvmSpokeIdl, provider);
// Resolves the program ID from options or defaults to the deployed address. Prioritizes programId, falls back to
// network, and if network is not defined, determines the network from the provider's RPC URL. Throws an error if
// the program ID cannot be resolved.
function resolveProgramId(programName: string, provider: AnchorProvider, options?: ProgramOptions): string {
const { network, programId } = options ?? {};

if (programId) {
return programId; // Prioritize explicitly provided programId
}

const resolvedNetwork = network ?? (isSolanaDevnet(provider) ? "devnet" : "mainnet");
const deployedAddress = getDeployedAddress(programName, getSolanaChainId(resolvedNetwork).toString());

if (!deployedAddress) {
throw new Error(`${programName} Program ID not found for ${resolvedNetwork}`);
}

return deployedAddress;
}

export function getSpokePoolProgram(provider: AnchorProvider, options?: ProgramOptions) {
const id = resolveProgramId("SvmSpoke", provider, options);
return getConnectedProgram<SvmSpokeAnchor>(SvmSpokeIdl, provider, id);
}

export function getMessageTransmitterProgram(provider: Provider) {
return getConnectedProgram<MessageTransmitterAnchor>(MessageTransmitterIdl, provider);
export function getMessageTransmitterProgram(provider: AnchorProvider, options?: ProgramOptions) {
const id = resolveProgramId("MessageTransmitter", provider, options);
return getConnectedProgram<MessageTransmitterAnchor>(MessageTransmitterIdl, provider, id);
}

export function getTokenMessengerMinterProgram(provider: Provider) {
return getConnectedProgram<TokenMessengerMinterAnchor>(TokenMessengerMinterIdl, provider);
export function getTokenMessengerMinterProgram(provider: AnchorProvider, options?: ProgramOptions) {
const id = resolveProgramId("TokenMessengerMinter", provider, options);
return getConnectedProgram<TokenMessengerMinterAnchor>(TokenMessengerMinterIdl, provider, id);
}

export function getMulticallHandlerProgram(provider: Provider) {
return getConnectedProgram<MulticallHandlerAnchor>(MulticallHandlerIdl, provider);
export function getMulticallHandlerProgram(provider: AnchorProvider, options?: ProgramOptions) {
const id = resolveProgramId("MulticallHandler", provider, options);
return getConnectedProgram<MulticallHandlerAnchor>(MulticallHandlerIdl, provider, id);
}
5 changes: 5 additions & 0 deletions src/types/svm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,8 @@ export interface EventType {
blockTime: number;
signature: string;
}

/**
* Supported Networks
*/
export type SupportedNetworks = "mainnet" | "devnet";

0 comments on commit 518bf52

Please sign in to comment.