Skip to content

Conversation

@samgermain
Copy link
Contributor

@samgermain samgermain commented May 2, 2025

builds on #497

Relates to

#301

What does this PR do?

Hyperlane methods use walletClient for signing, sendingTransactions, etc instead of using ethers.Signer, ethers.Contract ...

  • properties added to EVMTransaction
  • new types TransactionLog, EVMTransactionResult
  • ViemEVMWalletClient waitForReceipt returns the whole transaction receipt
  • LitEVMWalletClient waitForReceipt returns the whole transaction receipt
  • created custom EVMWalletClientSigner to use instead of ethers signer
  • hyperlane methods now use the walletClient to signTransactions
  • hyperlane bug fixes
  • updated hyperlane node_modules
  • updated error handling in hyperlane

Testing

import { http, createWalletClient } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { sepolia } from "viem/chains";
import { viem } from "../../../packages/wallets/viem/dist/ViemEVMWalletClient.js";

import dotenv from "dotenv";
import { HyperlaneService } from "../../../packages/plugins/hyperlane/dist/hyperlane.service.js";
dotenv.config();
const account = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY as `0x${string}`);

const walletClient = createWalletClient({
    account: account,
    transport: http(process.env.RPC_PROVIDER_URL),
    chain: sepolia,
});

const hyperlane = new HyperlaneService();
const address = "0x0Ef3456E616552238B0c562d409507Ed6051A7b3";
const originChain = "sepolia";
const destinationChain = "linea";
const contractType = "mailbox";
const sepoliaMailbox = "0xfFAEF09B3cd11D9b20d1a19bECca54EEC2884766";
const sepoliaTestnetValidator = "0x28b91d3dc0d0e138adf914105d88c8830cc66f4e";

const wallet = viem(walletClient);

async function main() {
    const sendMessageResponse = JSON.parse(
        await hyperlane.sendMessage(wallet, {
            originChain: originChain,
            destinationChain: destinationChain,
            destinationAddress: address,
            message: "hello",
        }),
    );
    console.log(`sendMessage response: ${JSON.stringify(sendMessageResponse)} \n`);

    const messageId = sendMessageResponse.messageId;

    const readMessageResponseOrig = JSON.parse (await hyperlane.readMessage({
      chain: originChain,
      messageId,
    }));
    console.log(`readMessage origin response: ${JSON.stringify(readMessageResponseOrig)} \n`);

    const getMailboxResponse = JSON.parse (await hyperlane.getMailbox({
      chain: originChain,
    }));
    console.log(`getMailbox response: ${JSON.stringify(getMailboxResponse)} \n`);

    const getDeployedContractsResponse = JSON.parse (await hyperlane.getDeployedContracts({
      chain: originChain,
      contractType,
    }));
    console.log(`getDeployedContracts response: ${JSON.stringify(getDeployedContractsResponse)} \n`);

    const configureIsmResponse = JSON.parse(
        await hyperlane.configureIsm(wallet, {
            chain: originChain,
            type: "trustedRelayerIsm",
            mailbox: sepoliaMailbox,
            config: {
                relayer: address,
            },
        }),
    );
    console.log(`configureIsm response: ${JSON.stringify(configureIsmResponse)} \n`);

    const manageValidatorsResponse = JSON.parse(
        await hyperlane.manageValidators(wallet, {
            chain: originChain,
            action: "ADD",
            validator: sepoliaTestnetValidator,
            weight: 1,
        })
    );
    console.log(`manageValidators response: ${JSON.stringify(manageValidatorsResponse)} \n`);
}

main();

// RESPONSE
//
// % tsx src/index.ts
// Fetching from github: https://raw.githubusercontent.com/hyperlane-xyz/hyperlane-registry/main/chains/metadata.yaml
// Fetching from github: https://raw.githubusercontent.com/hyperlane-xyz/hyperlane-registry/main/chains/addresses.yaml
// {"level":30,"time":1746227894431,"pid":68360,"module":"MultiProvider","msg":"Pending https://sepolia.etherscan.io/tx/0xb750fcc38bb61212e9e0bc28fc45f457ed9ccf0f813fa9da7304691e3b385ebc (waiting 1 blocks for confirmation)"}
// sendMessage response: {"message":"Message sent successfully","messageId":"0x4f96c0d94ffb83abccda43c86f4570e6354cccac4dc12b50d327f75668b4291b","transactionHash":"0xb750fcc38bb61212e9e0bc28fc45f457ed9ccf0f813fa9da7304691e3b385ebc","dispatchedMessage":{"parsed":{"version":3,"nonce":858529,"origin":11155111,"sender":"0x0000000000000000000000000ef3456e616552238b0c562d409507ed6051a7b3","destination":59144,"recipient":"0x0000000000000000000000000ef3456e616552238b0c562d409507ed6051a7b3","body":"0x68656c6c6f","originChain":"sepolia","destinationChain":"linea"},"id":"0x4f96c0d94ffb83abccda43c86f4570e6354cccac4dc12b50d327f75668b4291b","message":"0x03000d19a100aa36a70000000000000000000000000ef3456e616552238b0c562d409507ed6051a7b30000e7080000000000000000000000000ef3456e616552238b0c562d409507ed6051a7b368656c6c6f"},"isDelivered":false,"originDomain":11155111,"destinationDomain":59144} 
// 
// readMessage origin response: {"message":"Message is pending delivery","details":{"id":"0x4f96c0d94ffb83abccda43c86f4570e6354cccac4dc12b50d327f75668b4291b","status":"PENDING","chain":{"name":"sepolia","domainId":11155111},"content":{"raw":"0x03000d19a100aa36a70000000000000000000000000ef3456e616552238b0c562d409507ed6051a7b30000e7080000000000000000000000000ef3456e616552238b0c562d409507ed6051a7b368656c6c6f","decoded":"0x68656c6c6f"},"metadata":{"sender":"0x0000000000000000000000000ef3456e616552238b0c562d409507ed6051a7b3","recipient":"0x0000000000000000000000000ef3456e616552238b0c562d409507ed6051a7b3","nonce":858529,"originChain":"sepolia","destinationChain":"linea"}}} 
// 
// getMailbox response: {"message":"Mailbox address retrieved successfully","details":{"chain":"sepolia","mailboxAddress":"0xfFAEF09B3cd11D9b20d1a19bECca54EEC2884766","chainInfo":{"name":"sepolia","chainId":11155111,"domainId":11155111,"protocol":"ethereum","rpcUrls":[{"http":"https://ethereum-sepolia.publicnode.com"},{"http":"https://gateway.tenderly.co/public/sepolia"},{"http":"https://sepolia.drpc.org"},{"http":"https://1rpc.io/sepolia"}]}}} 
// 
// getDeployedContracts response: {"message":"Deployed contracts retrieved successfully","details":{"chain":"sepolia","chainInfo":{"name":"sepolia","chainId":11155111,"domainId":11155111},"contracts":{"mailbox":"0xfFAEF09B3cd11D9b20d1a19bECca54EEC2884766"}}} 
// 
// {"level":30,"time":1746227901494,"pid":68360,"module":"deployer","msg":"Deploying trustedRelayerIsm on sepolia with constructor args (0xfFAEF09B3cd11D9b20d1a19bECca54EEC2884766, 0x0Ef3456E616552238B0c562d409507Ed6051A7b3)..."}
// {"level":30,"time":1746227912918,"pid":68360,"module":"MultiProvider","msg":"Pending https://sepolia.etherscan.io/tx/0x76d7fd2d875d5c8b4a8754d3a83b15463ee43df9dcaecdfeab3eea9f37e59d7b (waiting 1 blocks for confirmation)"}
// configureIsm response: {"message":"ISM configured successfully","details":{"chain":"sepolia","type":"trustedRelayerIsm","config":{"type":"trustedRelayerIsm","relayer":"0x0Ef3456E616552238B0c562d409507Ed6051A7b3"}}} 
// 
// manageValidators response: {"message":"Validator added successfully","details":{"chain":"sepolia","action":"ADD","validator":"0x28b91d3dc0d0e138adf914105d88c8830cc66f4e","weight":1,"transactionHash":"0x8813a16fd3b2e004dc32b62325360da3738bda52a01df0ef48b909e96e5a1ebe"}} 

Detailed testing results

Can test using this model-context-protocol server: https://github.com/samgermain/hyperlane-claude (set path to typescript/examples/by-use-case/hyperlane-claude)

Method Prompt Screenshot Transaction Link
sendMessage send message https://sepolia.etherscan.io/tx/0xd39f75ef3899a7540519c62b490d5002d63ceecb641cde14bed0753b43394673
readMessage read message
getMailbox get mailbox
getDeployedContracts get deployed contracts
deployIsm configure Ism
manageValidators manage Validators https://sepolia.etherscan.io/tx/0x9c8172718dc46d84b9059cfd1b63131104036158d82011e3b779b62910df580e
getTokens get all tokens for chain sepolia
inspectWarpRoute inspect a warpRoute on sepolia with address 0xeDF994D49F865D3a4bd6F74AeFbe1DcCAE7204F2
sendAssets can you send assets from lineasepolia to basesepolia warpRouteAddress: "0x1c3784590F1ccA6ae346953061684c4A18079f5b", tokenAddress: "0xF64E6E064a71B45514691D397ad4204972cD6508", recipientAddress: "0x0Ef3456E616552238B0c562d409507Ed6051A7b3", amount: "0.0001" https://sepolia.lineascan.build/tx/0xda6aea4ce794879278607d5932d2057b21d28ec741cff82d359ad1a2cd5d4ac6

Checklist

  • I have tested this change and added the relevant screenshots to the PR description
  • I updated the README if necessary to include the new plugin, wallet, chain, etc.

If you require releasing a new version of the package:

  • I have added a changset for the specific package by running pnpm change:add from the typescript directory

@changeset-bot
Copy link

changeset-bot bot commented May 2, 2025

⚠️ No Changeset found

Latest commit: e332184

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

created custom EVMWalletClientSigner to use instead of ethers signer, hyperlane methods now use the walletClient to signTransactions, hyperlane bug fixes, updated hyperlane dependencies, updated error handling in hyperlane
samgermain added 5 commits May 2, 2025 23:12
more clear variable names, more enum options for standard, case insensitive filters
removed monitorSecurity, announceValidator, configureRelayer, manageGasPayment, monitorRelayer, deployChain
@samgermain samgermain marked this pull request as ready for review May 7, 2025 21:22
samgermain added 27 commits May 26, 2025 20:51
Use per chain wallet clients plugin-wide, so the chain of the wallet client no longer needs to match the chain a transaction is being performed on
@samgermain samgermain changed the title Hyperlane walletClient integration Hyperlane May 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant