Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor interface #57

Merged
merged 62 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
0441549
evm: splits up governance into subcategories at the root level
scnale Sep 25, 2024
aa3591e
evm: further adjustments to sdk layouts
scnale Sep 25, 2024
fe47b47
sdk: removes obsolete comment
scnale Sep 25, 2024
2fcda1e
evm: makes space for acquire ownership method
scnale Sep 25, 2024
196e777
evm: add shared components
AgusVelez5 Sep 26, 2024
fc29f17
evm: fix acquire ownership
AgusVelez5 Sep 26, 2024
1b5a48f
evm: fix access control commands
AgusVelez5 Sep 26, 2024
e215ca9
fix comment
AgusVelez5 Sep 26, 2024
6872eb5
evm: add components integration
AgusVelez5 Sep 27, 2024
c84dd2a
evm: fix tests
AgusVelez5 Sep 27, 2024
b8fd168
evm: add ADMINS_ID command
AgusVelez5 Sep 27, 2024
e2fe4aa
evm: split update admin command
AgusVelez5 Sep 28, 2024
6b0698d
evm: shrink admins length
AgusVelez5 Sep 28, 2024
9135002
evm: check consistency between chainIds
AgusVelez5 Sep 29, 2024
3fac29c
evm: adds layout for approve token instruction
scnale Sep 25, 2024
2e9402b
evm: implements approve token instruction
scnale Sep 25, 2024
c256623
evm: fixes tests and adds some more
scnale Sep 25, 2024
c05a419
evm: adds token bridge allowance query
scnale Sep 25, 2024
68cf55e
sdk-evm: updates transfer and relaying fee logic
scnale Sep 25, 2024
bc2d93b
sdk: partially fixes tests for EVM
scnale Sep 26, 2024
21f0597
deployment: partial fix for EVM deployment scripts
scnale Sep 27, 2024
c6b64e2
sdk: adds clean script for EVM sdk
scnale Sep 28, 2024
c13c453
evm: eliminates the quoting logic specific to L2 chains
scnale Sep 30, 2024
febb609
evm: fixes rounding error in `relayFee`
scnale Sep 30, 2024
33340d3
sdk: WIP EVM ids update
scnale Oct 1, 2024
0b4cf99
evm: several fixes to contract and sdk
scnale Oct 1, 2024
502c0c6
evm: fixes token acquisition so that it only receives the normalized …
scnale Oct 1, 2024
cd1bfab
evm: fixes build and tests
scnale Oct 1, 2024
4577ffd
evm: add external functions
AgusVelez5 Oct 1, 2024
d5088fd
evm: extracts layouts meant to go to the wormhole solidity sdk
scnale Oct 1, 2024
7bf8ea4
sdk: fix comment
AgusVelez5 Oct 1, 2024
46fdfc5
evm: remove constructor chainId validation
AgusVelez5 Oct 1, 2024
ec3031b
sdk: adds a few methods in EVM sdk
scnale Oct 1, 2024
27ef9f8
evm: retrieves default gas token from the sdk
scnale Oct 1, 2024
c778a14
evm: add senderAuthorization function to access control
AgusVelez5 Oct 1, 2024
343382e
evm: role enum to access control component
AgusVelez5 Oct 2, 2024
645a085
evm: refactor access control role checking
AgusVelez5 Oct 2, 2024
e37d23d
evm: add vaa parse test
AgusVelez5 Oct 2, 2024
e8d5822
evm: adds dispatcher functions to shared components
scnale Oct 2, 2024
34338dd
evm: improve craft vaa function
AgusVelez5 Oct 2, 2024
2e83370
evm-sdk: fixes integration tests
scnale Oct 3, 2024
7b2bc58
evm: fixes solidity sdk import
scnale Oct 3, 2024
121c7c5
evm: updates submodule and fixes tests
scnale Oct 3, 2024
3af0c5a
deployment: fixes addresses passed in as strings instead of EvmAddress
scnale Oct 3, 2024
7b9dd92
refactor TBRv3 EVM SDK without breaking transfer/complete/relayfee in…
nonergodic Oct 3, 2024
902dc12
evm: updates price oracle submodule
scnale Oct 3, 2024
967a5b2
fix invalid type generation in case of nested query arrays
nonergodic Oct 4, 2024
e77e428
evm: fixes sdk typo
scnale Oct 4, 2024
71dd589
evm-sdk: fixes tests
scnale Oct 4, 2024
565efdf
deployment: updates EVM scripts
scnale Oct 4, 2024
f690b92
evm: updates price oracle submodule
scnale Oct 4, 2024
1f816df
evm: reorders config query ids for future size optimization
scnale Oct 4, 2024
6425f8a
evm: updates price oracle submodule and solidity sdk contracts
scnale Oct 4, 2024
b6d1ce5
sdk: fixes evm sdk gas token retrieval
scnale Oct 4, 2024
4d0c166
deployment: fixes gas token retrieval in test transfer
scnale Oct 4, 2024
e4ccdd4
misc: updates sdk packages and fixes build scripts
scnale Oct 4, 2024
24e81e2
evm: fixes canonical chain token redeem
scnale Oct 5, 2024
fc73f85
evm: add complete function tests
AgusVelez5 Oct 5, 2024
d849987
evm: update IWETH interface
AgusVelez5 Oct 7, 2024
b2b93be
evm: updates price oracle submodule to point to latest `main` commit
scnale Oct 8, 2024
695658d
solana: fixes sdk IDL import
scnale Oct 8, 2024
3b12a66
solana: fixes path of price oracle contract ELF
scnale Oct 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
389 changes: 119 additions & 270 deletions .pnp.cjs

Large diffs are not rendered by default.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion Anchor.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ upgradeable = true

[[test.genesis]]
address = "ATqjh2vkjogyVUUNmXQssQZNSFGgSA7Tm6P1UzEUg85s"
program = "lib/relayer-infra-contracts/src/solana/target/sbf-solana-solana/release/solana_price_oracle.so"
program = "target/sbf-solana-solana/release/solana_price_oracle.so"

# [[test.genesis]]
# address = "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth" # Mainnet in lib.rs
Expand Down
1 change: 0 additions & 1 deletion deployment/config/config.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export type BaseTbrV3Config = ChainConfig & {
// TODO: in reality this should limit ChainConfig to only containing evm chain ids..
export type EvmTbrV3Config = BaseTbrV3Config & {
initGasErc20TokenizationIsExplicit: boolean;
txSizeSensitive: boolean;
};

// TODO: in reality this should limit ChainConfig to only containing solana chain ids..
Expand Down
3 changes: 1 addition & 2 deletions deployment/config/localnet/tbr-v3.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"feeRecipient": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
"initGasErc20TokenizationIsExplicit": false,
"relayFee": 1,
"maxGasDropoff": 1,
"txSizeSensitive": false
"maxGasDropoff": 1
}
]
12 changes: 4 additions & 8 deletions deployment/config/testnet/tbr-v3.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,24 @@
"chainId": 10002,
"initGasErc20TokenizationIsExplicit": true,
"relayFee": 1,
"maxGasDropoff": 0.1,
"txSizeSensitive": false
"maxGasDropoff": 0.1
},
{
"chainId": 10003,
"initGasErc20TokenizationIsExplicit": true,
"relayFee": 1000,
"maxGasDropoff": 0.1,
"txSizeSensitive": false
"maxGasDropoff": 0.1
},
{
"chainId": 10004,
"initGasErc20TokenizationIsExplicit": true,
"relayFee": 1000,
"maxGasDropoff": 0.1,
"txSizeSensitive": false
"maxGasDropoff": 0.1
},
{
"chainId": 10005,
"initGasErc20TokenizationIsExplicit": true,
"relayFee": 1000,
"maxGasDropoff": 0.1,
"txSizeSensitive": false
"maxGasDropoff": 0.1
}
]
87 changes: 41 additions & 46 deletions deployment/evm/configure-fee-and-dropoff.ts
Original file line number Diff line number Diff line change
@@ -1,75 +1,70 @@
import {
contracts,
evm,
getChainConfig,
getContractAddress,
loadTbrPeers,
} from "../helpers/index.js";
import { chainIdToChain } from "@wormhole-foundation/sdk-base";
import { SupportedChains, Tbrv3 } from "@xlabs-xyz/evm-arbitrary-token-transfers";
import { ethers } from "ethers";
import { chainIdToChain, encoding } from "@wormhole-foundation/sdk-base";
import { SupportedChain, Tbrv3 } from "@xlabs-xyz/evm-arbitrary-token-transfers";
import { EvmTbrV3Config } from "../config/config.types.js";
import { EvmAddress } from "@wormhole-foundation/sdk-evm/dist/cjs";
import { wrapEthersProvider } from "../helpers/evm.js";

/**
* Configures relay fee and max gas dropoff for Tbrv3 contracts
*/
evm.runOnEvms("configure-fee-and-dropoff", async (chain, signer, log) => {
const tbrv3ProxyAddress = getContractAddress("TbrV3Proxies", chain.chainId);
const tbrv3 = new Tbrv3(signer.provider!, chain.network, tbrv3ProxyAddress);
const tbrv3ProxyAddress = new EvmAddress(getContractAddress("TbrV3Proxies", chain.chainId));
const tbrv3 = Tbrv3.connect(wrapEthersProvider(signer.provider!), chain.network, "Sepolia", tbrv3ProxyAddress);
const peers = loadTbrPeers(chain);

const relayFeeUpdates: Map<SupportedChains, number> = new Map();
const queries = [];
for (const otherTbrv3 of peers) {
const otherTbrv3Chain = chainIdToChain(otherTbrv3.chainId) as SupportedChains;
const peerChainCfg = await getChainConfig<EvmTbrV3Config>("tbr-v3", otherTbrv3.chainId);
const desiredRelayFee = Number(peerChainCfg.relayFee);
const otherTbrv3Chain = chainIdToChain(otherTbrv3.chainId) as SupportedChain;

const currentRelayFee = await tbrv3.relayFee(otherTbrv3Chain as SupportedChains);
if (currentRelayFee.fee !== desiredRelayFee) {
log(`Will updaterelay fee for ${otherTbrv3Chain}: ${peerChainCfg.maxGasDropoff}`);
relayFeeUpdates.set(otherTbrv3Chain, desiredRelayFee);
}
}
queries.push({query: "BaseFee", chain: otherTbrv3Chain} as const);
queries.push({query: "MaxGasDropoff", chain: otherTbrv3Chain} as const);
}

if (relayFeeUpdates.size !== 0) {
log("Updating relay fee");
const partialTx = tbrv3.updateRelayFees(relayFeeUpdates);
const { error, receipt } = await evm.sendTx(signer, { ...partialTx, data: ethers.hexlify(partialTx.data) });
if (error) {
log("Error updating relay fee: ", error);
throw error;
}
if (receipt) {
log("Updated relay fee");
const configValues = await tbrv3.query([{query: "ConfigQueries", queries}]);

const currentState: Map<SupportedChain, {baseFee: number; maxGasDropoff: number}> = new Map(peers.map(({chainId}) => [
chainIdToChain(chainId) as SupportedChain,
{} as any
]));
for (const config of configValues) {
const chainState = currentState.get(config.chain)!;
if (config.query === "BaseFee") {
chainState.baseFee = config.result;
} else {
chainState.maxGasDropoff = config.result;
}
}

const updateMaxGasDropoff: Map<SupportedChains, number> = new Map();
const commands = [];
for (const otherTbrv3 of peers) {
const otherTbrv3Chain = chainIdToChain(otherTbrv3.chainId) as SupportedChains;
const peerChainCfg = await getChainConfig<EvmTbrV3Config>("tbr-v3", otherTbrv3.chainId);
const desiredBaseFee = Number(peerChainCfg.relayFee);
const desiredMaxGasDropoff = Number(peerChainCfg.maxGasDropoff);

const currentMaxGasDropoff = await tbrv3.maxGasDropoff(otherTbrv3Chain);
if (currentMaxGasDropoff !== desiredMaxGasDropoff) {
const otherTbrv3Chain = chainIdToChain(otherTbrv3.chainId) as SupportedChain;
const chainState = currentState.get(otherTbrv3Chain)!;
// schedule update
if (chainState.baseFee !== desiredBaseFee) {
log(`Will update base fee for ${otherTbrv3Chain}: ${peerChainCfg.maxGasDropoff}`);
commands.push({command: "UpdateBaseFee", chain: otherTbrv3Chain, value: desiredBaseFee} as const);
}
if (chainState.maxGasDropoff !== desiredMaxGasDropoff) {
log(`Will update max gas dropoff for ${otherTbrv3Chain}: ${peerChainCfg.maxGasDropoff}`);
updateMaxGasDropoff.set(otherTbrv3Chain, desiredMaxGasDropoff);
commands.push({command: "UpdateMaxGasDropoff", chain: otherTbrv3Chain, value: desiredMaxGasDropoff} as const);
}
}

if (updateMaxGasDropoff.size !== 0) {
log("Updating max gas dropoff");
const partialTx = tbrv3.updateMaxGasDroppoffs(updateMaxGasDropoff);
const { error, receipt } = await evm.sendTx(signer, { ...partialTx, data: ethers.hexlify(partialTx.data) });
if (error) {
log("Error updating max gas dropoff: ", error);
throw error;
}
if (receipt) {
log("Updated max gas dropoff");
}
} else {
log("No max gas dropoff to update");
if (commands.length === 0) {
log("No updates to base fee or max gas dropoff are needed.");
return;
}


const partialTx = tbrv3.execTx(0n, [{ command: "ConfigCommands", commands}]);
const { txid } = await evm.sendTx(signer, { ...partialTx, data: encoding.hex.encode(partialTx.data) });
log(`Update tx successful in ${txid}`);
});
13 changes: 9 additions & 4 deletions deployment/evm/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { ethers } from "ethers";
import { encoding } from "@wormhole-foundation/sdk-base";
import { Tbr__factory, Proxy__factory } from "../ethers-contracts/index.js";
import { getSigner } from "../helpers/evm";
import { EvmAddress } from "@wormhole-foundation/sdk-evm/dist/cjs";


const processName = "tbr-v3";
Expand Down Expand Up @@ -107,13 +108,17 @@ async function deployProxy(
) {
console.log("deployRelayerProxy " + chain.chainId);
const signer = await getSigner(chain);
const signerAddress = await signer.getAddress();
const signerAddress = new EvmAddress(await signer.getAddress());
const { Tbrv3 } = await import("@xlabs-xyz/evm-arbitrary-token-transfers");
const owner = config.owner !== undefined ? new EvmAddress(config.owner) : signerAddress;
const admin = config.admin !== undefined ? new EvmAddress(config.admin) : signerAddress;
const feeRecipient = config.feeRecipient !== undefined ? new EvmAddress(config.feeRecipient) : signerAddress;

const proxyConstructorArgs = Tbrv3.proxyConstructor(
config.owner || signerAddress,
config.admin || signerAddress,
config.feeRecipient || signerAddress,
owner,
// TODO: accept more admins in config
[admin],
feeRecipient,
);

const contractInterface = Proxy__factory.createInterface();
Expand Down
64 changes: 35 additions & 29 deletions deployment/evm/read-configured-fee-and-dropoff.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,41 @@
import {
contracts,
evm,
getContractAddress,
} from "../helpers/index.js";
import { chainIdToChain } from "@wormhole-foundation/sdk-base";
import { SupportedChains, Tbrv3 } from "@xlabs-xyz/evm-arbitrary-token-transfers";
evm,
getContractAddress,
loadTbrPeers,
} from "../helpers/index.js";
import { chainIdToChain } from "@wormhole-foundation/sdk-base";
import { EvmAddress } from "@wormhole-foundation/sdk-evm/dist/cjs";
import { SupportedChain, Tbrv3 } from "@xlabs-xyz/evm-arbitrary-token-transfers";
import { wrapEthersProvider } from "../helpers/evm.js";

/**
* Reads the configured relay fee and max gas dropoff for Tbrv3 contracts
*/
evm.runOnEvmsSequentially("read-configured-fee-and-dropoff", async (chain, signer, log) => {
console.log(`Operating chain: ${chain.name}`);
/**
* Reads the configured relay fee and max gas dropoff for Tbrv3 contracts
*/
evm.runOnEvmsSequentially("read-configured-fee-and-dropoff", async (chain, signer, log) => {
console.log(`Operating chain: ${chain.name}`);

const tbrv3ProxyAddress = getContractAddress("TbrV3Proxies", chain.chainId);
const tbrv3 = new Tbrv3(signer.provider!, chain.network, tbrv3ProxyAddress);
const deployedTbrv3s = contracts["TbrV3Proxies"];

for (const otherTbrv3 of deployedTbrv3s){
const otherTbrv3Chain = chainIdToChain(otherTbrv3.chainId) as SupportedChains;
const currentRelayFee = await tbrv3.relayFee(otherTbrv3Chain);
const tbrv3ProxyAddress = new EvmAddress(getContractAddress("TbrV3Proxies", chain.chainId));
const tbrv3 = Tbrv3.connect(
wrapEthersProvider(signer.provider!),
chain.network,
chainIdToChain(chain.chainId),
tbrv3ProxyAddress
);
const peers = loadTbrPeers(chain);

log(`Current relay fee for ${otherTbrv3Chain}: ${currentRelayFee.fee}`);
}

for (const otherTbrv3 of deployedTbrv3s) {
const otherTbrv3Chain = chainIdToChain(otherTbrv3.chainId) as SupportedChains;

const currentMaxGasDropoff = await tbrv3.maxGasDropoff(otherTbrv3Chain);

log(`Current max gas dropoff for ${otherTbrv3Chain}: ${currentMaxGasDropoff}`);
}
});
let queries = [];
for (const otherTbrv3 of peers) {
const otherTbrv3Chain = chainIdToChain(otherTbrv3.chainId) as SupportedChain;

queries.push({query: "BaseFee", chain: otherTbrv3Chain} as const);
queries.push({query: "MaxGasDropoff", chain: otherTbrv3Chain} as const);
}
const configValues = await tbrv3.query([{query: "ConfigQueries", queries}]);

for (const config of configValues) {
log(`Current ${config.query} for ${config.chain}: ${config.result}`);
}

});

89 changes: 32 additions & 57 deletions deployment/evm/register-peers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,72 +3,47 @@ import {
getContractAddress,
loadTbrPeers,
} from "../helpers/index.js";
import { UniversalAddress } from "@wormhole-foundation/sdk-definitions";
import { SolanaAddress } from "@wormhole-foundation/sdk-solana";
import { chainIdToChain } from "@wormhole-foundation/sdk-base";
import { SupportedChains, Tbrv3 } from "@xlabs-xyz/evm-arbitrary-token-transfers";
import { ethers } from "ethers";
import { toUniversal } from "@wormhole-foundation/sdk-definitions";
import { chainIdToChain, encoding } from "@wormhole-foundation/sdk-base";
import { SupportedChain, Tbrv3 } from "@xlabs-xyz/evm-arbitrary-token-transfers";
import { EvmAddress } from "@wormhole-foundation/sdk-evm";
import { wrapEthersProvider } from "../helpers/evm.js";

/**
* Configure peers for Tbrv3 contracts:
* - Add all other Tbrv3 contracts as canonical peers
* - Add all other Tbrv3 contracts as peers
*
* If no peer is registered for a chain, it will be set as the canonical peer.
*/
evm.runOnEvms("register-peers", async (chain, signer, log) => {
const tbrv3ProxyAddress = getContractAddress("TbrV3Proxies", chain.chainId);
const tbrv3 = new Tbrv3(signer.provider!, chain.network, tbrv3ProxyAddress);
const deployedTbrv3s = loadTbrPeers(chain)

const addPeersCmd: { chain: SupportedChains, peer: UniversalAddress }[] = [];
const updateCanonicalPeersCmd: Map<SupportedChains, UniversalAddress> = new Map();
for (const otherTbrv3 of deployedTbrv3s) {
const otherTbrv3Chain = chainIdToChain(otherTbrv3.chainId) as SupportedChains;
const peerAddress = (otherTbrv3Chain === "Solana" ?
new SolanaAddress(otherTbrv3.address).toUniversalAddress() :
new UniversalAddress(otherTbrv3.address)) as UniversalAddress;

const currentCanonicalPeer = await tbrv3.canonicalPeer(otherTbrv3Chain);
if (!currentCanonicalPeer.equals(peerAddress)) {
log(`Will update canonical peer: ${peerAddress} (${otherTbrv3.chainId})`);
updateCanonicalPeersCmd.set(otherTbrv3Chain, peerAddress);
}

const isPeer = updateCanonicalPeersCmd.get(otherTbrv3Chain)?.equals(peerAddress) || await tbrv3.isPeer(otherTbrv3Chain, peerAddress);
if (!isPeer) {
log(`Will add peer: ${peerAddress}(${otherTbrv3.chainId})`);
addPeersCmd.push({ chain: otherTbrv3Chain, peer: peerAddress });
}

const tbrv3ProxyAddress = new EvmAddress(getContractAddress("TbrV3Proxies", chain.chainId));
const tbrv3 = Tbrv3.connect(
wrapEthersProvider(signer.provider!),
chain.network,
chainIdToChain(chain.chainId),
tbrv3ProxyAddress
);
const peers = loadTbrPeers(chain);

const queries = [];
for (const otherTbrv3 of peers) {
const otherTbrv3Chain = chainIdToChain(otherTbrv3.chainId) as SupportedChain;
const peerAddress = toUniversal(otherTbrv3Chain, otherTbrv3.address);
queries.push({query: "IsPeer", chain: otherTbrv3Chain, address: peerAddress} as const);
}
const isPeerResults = await tbrv3.query([{query: "ConfigQueries", queries}]);

if (updateCanonicalPeersCmd.size !== 0) {
log("updating canonical peers");
const partialTx = await tbrv3.updateCanonicalPeers(updateCanonicalPeersCmd);
const { error, receipt } = await evm.sendTx(signer, { ...partialTx, data: ethers.hexlify(partialTx.data) });
if (error) {
log("Error updating canonical peers: ", error);
}
if (receipt) {
log(`Updated canonical peers: ${updateCanonicalPeersCmd.size}`);
}
} else {
log("No canonical peers to update");
}
const commands = isPeerResults.filter(({result}) => !result)
.map(({result, query, ...rest}) => ({command: "AddPeer", ...rest} as const));

if (addPeersCmd.length !== 0) {
log("adding peers");
const partialTx = await tbrv3.addPeers(addPeersCmd);
const { error, receipt } = await evm.sendTx(signer, { ...partialTx, data: ethers.hexlify(partialTx.data) });
if (error) {
log("Error adding peers: ", error);
}
if (receipt) {
log(`Added peers: ${addPeersCmd.length}`);
}
} else {
log("No peers to add");
if (commands.length === 0) {
log("No new peers to add.");
return;
}


for (const command of commands) {
log(`Will add peer: ${command.address} (${command.chain})`);
}
const partialTx = tbrv3.execTx(0n, [{ command: "ConfigCommands", commands}]);
const { txid } = await evm.sendTx(signer, { ...partialTx, data: encoding.hex.encode(partialTx.data) });
log(`Update tx successful in ${txid}`);
});
Loading
Loading