From 518bf52de6d8351d845d23f89f5dc4e7bdec3a90 Mon Sep 17 00:00:00 2001 From: Pablo Maldonado Date: Thu, 19 Dec 2024 10:53:21 +0000 Subject: [PATCH] feat: read program id from deployed addresses or pass it as arg Signed-off-by: Pablo Maldonado --- deployments/deployments.json | 5 ++++ src/DeploymentUtils.ts | 6 +++- src/svm/programConnectors.ts | 58 +++++++++++++++++++++++++++--------- src/types/svm.ts | 5 ++++ 4 files changed, 59 insertions(+), 15 deletions(-) diff --git a/deployments/deployments.json b/deployments/deployments.json index cb2162d3d..d3cd44afe 100644 --- a/deployments/deployments.json +++ b/deployments/deployments.json @@ -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 } } } diff --git a/src/DeploymentUtils.ts b/src/DeploymentUtils.ts index 58844ac45..b822aa933 100644 --- a/src/DeploymentUtils.ts +++ b/src/DeploymentUtils.ts @@ -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`); diff --git a/src/svm/programConnectors.ts b/src/svm/programConnectors.ts index 6564ccd92..629722e63 100644 --- a/src/svm/programConnectors.ts +++ b/src/svm/programConnectors.ts @@ -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

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

(idl: P, provider: AnchorProvider, programId: string) { + idl.address = programId; return new Program

(idl, provider); } -export function getSpokePoolProgram(provider: Provider) { - return getConnectedProgram(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(SvmSpokeIdl, provider, id); } -export function getMessageTransmitterProgram(provider: Provider) { - return getConnectedProgram(MessageTransmitterIdl, provider); +export function getMessageTransmitterProgram(provider: AnchorProvider, options?: ProgramOptions) { + const id = resolveProgramId("MessageTransmitter", provider, options); + return getConnectedProgram(MessageTransmitterIdl, provider, id); } -export function getTokenMessengerMinterProgram(provider: Provider) { - return getConnectedProgram(TokenMessengerMinterIdl, provider); +export function getTokenMessengerMinterProgram(provider: AnchorProvider, options?: ProgramOptions) { + const id = resolveProgramId("TokenMessengerMinter", provider, options); + return getConnectedProgram(TokenMessengerMinterIdl, provider, id); } -export function getMulticallHandlerProgram(provider: Provider) { - return getConnectedProgram(MulticallHandlerIdl, provider); +export function getMulticallHandlerProgram(provider: AnchorProvider, options?: ProgramOptions) { + const id = resolveProgramId("MulticallHandler", provider, options); + return getConnectedProgram(MulticallHandlerIdl, provider, id); } diff --git a/src/types/svm.ts b/src/types/svm.ts index 63b26d27a..e181eec29 100644 --- a/src/types/svm.ts +++ b/src/types/svm.ts @@ -131,3 +131,8 @@ export interface EventType { blockTime: number; signature: string; } + +/** + * Supported Networks + */ +export type SupportedNetworks = "mainnet" | "devnet";