Merge branch 'main' into usx/tnl/ENG-4668-naive-callback
This commit is contained in:
12
CHANGELOG.md
12
CHANGELOG.md
@@ -1,3 +1,15 @@
|
|||||||
|
## [0.105.0](https://github.com/propeller-heads/tycho-execution/compare/0.104.0...0.105.0) (2025-07-09)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Upgrade scripts to submit to Safe wallet ([2733bb0](https://github.com/propeller-heads/tycho-execution/commit/2733bb00724fb2df8d6f8151df02826807289c9a))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Simplify nonceOffset logic ([ba60e4b](https://github.com/propeller-heads/tycho-execution/commit/ba60e4bb73741c17c44e1cfcdea3fd599ae027eb))
|
||||||
|
|
||||||
## [0.104.0](https://github.com/propeller-heads/tycho-execution/compare/0.103.0...0.104.0) (2025-07-08)
|
## [0.104.0](https://github.com/propeller-heads/tycho-execution/compare/0.103.0...0.104.0) (2025-07-08)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -4658,7 +4658,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tycho-execution"
|
name = "tycho-execution"
|
||||||
version = "0.104.0"
|
version = "0.105.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"alloy",
|
"alloy",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "tycho-execution"
|
name = "tycho-execution"
|
||||||
version = "0.104.0"
|
version = "0.105.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "Provides tools for encoding and executing swaps against Tycho router and protocol executors."
|
description = "Provides tools for encoding and executing swaps against Tycho router and protocol executors."
|
||||||
repository = "https://github.com/propeller-heads/tycho-execution"
|
repository = "https://github.com/propeller-heads/tycho-execution"
|
||||||
|
|||||||
3793
foundry/package-lock.json
generated
3793
foundry/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nomicfoundation/hardhat-foundry": "^1.1.3",
|
"@nomicfoundation/hardhat-foundry": "^1.1.3",
|
||||||
"ethers": "^5.0.0",
|
"@safe-global/api-kit": "^1.1.0",
|
||||||
|
"@safe-global/protocol-kit": "^1.0.1",
|
||||||
|
"ethers": "^5.8.0",
|
||||||
"prompt-sync": "^4.2.0"
|
"prompt-sync": "^4.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,3 +54,16 @@ For each of the following, you must select one of `tenderly_ethereum`, `tenderly
|
|||||||
1. If you set a new executor for the same protocol, you need to remove the old one.
|
1. If you set a new executor for the same protocol, you need to remove the old one.
|
||||||
2. Run: `npx hardhat run scripts/remove-executor.js --network NETWORK`
|
2. Run: `npx hardhat run scripts/remove-executor.js --network NETWORK`
|
||||||
3. There will be a prompt for you to insert the executor address you want to remove.
|
3. There will be a prompt for you to insert the executor address you want to remove.
|
||||||
|
|
||||||
|
### Revoke roles
|
||||||
|
|
||||||
|
1. If you wish to revoke a role for a certain address, run: `npx hardhat run scripts/revoke-role.js --network NETWORK`
|
||||||
|
2. There will be a prompt for you to insert the role hash and the address you want to revoke it for.
|
||||||
|
|
||||||
|
### Safe wallet
|
||||||
|
|
||||||
|
1. If the wallet that has the role, is a Gnosis Safe, you need to set the `SAFE_ADDRESS` env var.
|
||||||
|
2. The scripts deploy-executors, remove-executor, set-roles and revoke-role all support this.
|
||||||
|
1. If `SAFE_ADDRESS` is set, then it will propose a transaction to the safe wallet and later on it needs to be
|
||||||
|
approved in their UI to execute on chain.
|
||||||
|
2. If it's not set, it will submit the transaction directly to the chain.
|
||||||
@@ -1,16 +1,22 @@
|
|||||||
require('dotenv').config();
|
require('dotenv').config();
|
||||||
const {ethers} = require("hardhat");
|
const {ethers} = require("hardhat");
|
||||||
const hre = require("hardhat");
|
const hre = require("hardhat");
|
||||||
|
const {proposeOrSendTransaction} = require("./utils");
|
||||||
const prompt = require('prompt-sync')();
|
const prompt = require('prompt-sync')();
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const network = hre.network.name;
|
const network = hre.network.name;
|
||||||
const routerAddress = process.env.ROUTER_ADDRESS;
|
const routerAddress = process.env.ROUTER_ADDRESS;
|
||||||
console.log(`Removing executors on TychoRouter at ${routerAddress} on ${network}`);
|
const safeAddress = process.env.SAFE_ADDRESS;
|
||||||
|
if (!routerAddress) {
|
||||||
|
throw new Error("Missing ROUTER_ADDRESS");
|
||||||
|
}
|
||||||
|
|
||||||
const [deployer] = await ethers.getSigners();
|
console.log(`Removing executor on TychoRouter at ${routerAddress} on ${network}`);
|
||||||
console.log(`Removing executors with account: ${deployer.address}`);
|
|
||||||
console.log(`Account balance: ${ethers.utils.formatEther(await deployer.getBalance())} ETH`);
|
const [signer] = await ethers.getSigners();
|
||||||
|
console.log(`Removing executors with account: ${signer.address}`);
|
||||||
|
console.log(`Account balance: ${ethers.utils.formatEther(await signer.getBalance())} ETH`);
|
||||||
|
|
||||||
const TychoRouter = await ethers.getContractFactory("TychoRouter");
|
const TychoRouter = await ethers.getContractFactory("TychoRouter");
|
||||||
const router = TychoRouter.attach(routerAddress);
|
const router = TychoRouter.attach(routerAddress);
|
||||||
@@ -22,12 +28,15 @@ async function main() {
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove executor
|
const txData = {
|
||||||
const tx = await router.removeExecutor(executorAddress, {
|
to: router.address,
|
||||||
|
data: router.interface.encodeFunctionData("removeExecutor", [executorAddress]),
|
||||||
|
value: "0",
|
||||||
gasLimit: 50000
|
gasLimit: 50000
|
||||||
});
|
};
|
||||||
await tx.wait(); // Wait for the transaction to be mined
|
|
||||||
console.log(`Executor removed at transaction: ${tx.hash}`);
|
const txHash = await proposeOrSendTransaction(safeAddress, txData, signer, "removeExecutor");
|
||||||
|
console.log(`TX hash: ${txHash}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|||||||
51
foundry/scripts/revoke-role.js
Normal file
51
foundry/scripts/revoke-role.js
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
require('dotenv').config();
|
||||||
|
const {ethers} = require("hardhat");
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
const hre = require("hardhat");
|
||||||
|
const {proposeOrSendTransaction} = require("./utils");
|
||||||
|
const prompt = require('prompt-sync')();
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const network = hre.network.name;
|
||||||
|
const routerAddress = process.env.ROUTER_ADDRESS;
|
||||||
|
const safeAddress = process.env.SAFE_ADDRESS;
|
||||||
|
if (!routerAddress) {
|
||||||
|
throw new Error("Missing ROUTER_ADDRESS");
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Revoking role on TychoRouter at ${routerAddress} on ${network}`);
|
||||||
|
|
||||||
|
const [signer] = await ethers.getSigners();
|
||||||
|
console.log(`Setting roles with account: ${signer.address}`);
|
||||||
|
console.log(`Account balance: ${ethers.utils.formatEther(await signer.getBalance())} ETH`);
|
||||||
|
const TychoRouter = await ethers.getContractFactory("TychoRouter");
|
||||||
|
const router = TychoRouter.attach(routerAddress);
|
||||||
|
|
||||||
|
const roleHash = prompt("Enter role hash to be removed: ");
|
||||||
|
const address = prompt("Enter the address to remove: ");
|
||||||
|
|
||||||
|
|
||||||
|
if (!roleHash || !address) {
|
||||||
|
console.error("Please provide the executorAddress as an argument.");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Revoking ${roleHash} to the following address:`, address);
|
||||||
|
|
||||||
|
const txData = {
|
||||||
|
to: router.address,
|
||||||
|
data: router.interface.encodeFunctionData("revokeRole", [roleHash, address]),
|
||||||
|
value: "0",
|
||||||
|
};
|
||||||
|
|
||||||
|
const txHash = await proposeOrSendTransaction(safeAddress, txData, signer, "revokeRole");
|
||||||
|
console.log(`TX hash: ${txHash}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
|
.then(() => process.exit(0))
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Error setting roles:", error);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
@@ -1,44 +1,50 @@
|
|||||||
{
|
{
|
||||||
"ethereum": {
|
"ethereum": {
|
||||||
"EXECUTOR_SETTER_ROLE": [
|
"EXECUTOR_SETTER_ROLE": [
|
||||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
"0x06e580B872a37402764f909FCcAb0Eb5bb38fe23"
|
||||||
],
|
],
|
||||||
"PAUSER_ROLE": [
|
"PAUSER_ROLE": [
|
||||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
"0xB279A562C726F9F3011c1945c9c23Fe1FB631B59",
|
||||||
|
"0xAC3649A6DFBBB230632604f2fc43773977ec6E67"
|
||||||
],
|
],
|
||||||
"UNPAUSER_ROLE": [
|
"UNPAUSER_ROLE": [
|
||||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
"0xB279A562C726F9F3011c1945c9c23Fe1FB631B59",
|
||||||
|
"0xAC3649A6DFBBB230632604f2fc43773977ec6E67"
|
||||||
],
|
],
|
||||||
"FUND_RESCUER_ROLE": [
|
"FUND_RESCUER_ROLE": [
|
||||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
"0xF621770E96bcf1335150faecf77D757faf7ca4A9"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"base": {
|
"base": {
|
||||||
"EXECUTOR_SETTER_ROLE": [
|
"EXECUTOR_SETTER_ROLE": [
|
||||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
"0x06e580B872a37402764f909FCcAb0Eb5bb38fe23"
|
||||||
],
|
],
|
||||||
"PAUSER_ROLE": [
|
"PAUSER_ROLE": [
|
||||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
"0xB279A562C726F9F3011c1945c9c23Fe1FB631B59",
|
||||||
|
"0xAC3649A6DFBBB230632604f2fc43773977ec6E67"
|
||||||
],
|
],
|
||||||
"UNPAUSER_ROLE": [
|
"UNPAUSER_ROLE": [
|
||||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
"0xB279A562C726F9F3011c1945c9c23Fe1FB631B59",
|
||||||
|
"0xAC3649A6DFBBB230632604f2fc43773977ec6E67"
|
||||||
],
|
],
|
||||||
"FUND_RESCUER_ROLE": [
|
"FUND_RESCUER_ROLE": [
|
||||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
"0xF621770E96bcf1335150faecf77D757faf7ca4A9"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"unichain": {
|
"unichain": {
|
||||||
"EXECUTOR_SETTER_ROLE": [
|
"EXECUTOR_SETTER_ROLE": [
|
||||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
"0x06e580B872a37402764f909FCcAb0Eb5bb38fe23"
|
||||||
],
|
],
|
||||||
"PAUSER_ROLE": [
|
"PAUSER_ROLE": [
|
||||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
"0xB279A562C726F9F3011c1945c9c23Fe1FB631B59",
|
||||||
|
"0xAC3649A6DFBBB230632604f2fc43773977ec6E67"
|
||||||
],
|
],
|
||||||
"UNPAUSER_ROLE": [
|
"UNPAUSER_ROLE": [
|
||||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
"0xB279A562C726F9F3011c1945c9c23Fe1FB631B59",
|
||||||
|
"0xAC3649A6DFBBB230632604f2fc43773977ec6E67"
|
||||||
],
|
],
|
||||||
"FUND_RESCUER_ROLE": [
|
"FUND_RESCUER_ROLE": [
|
||||||
"0x58Dc7Bf9eD1f4890A7505D5bE4E4252978eAF655"
|
"0xF621770E96bcf1335150faecf77D757faf7ca4A9"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,18 +1,25 @@
|
|||||||
require('dotenv').config();
|
require('dotenv').config();
|
||||||
const {ethers} = require("hardhat");
|
const {ethers} = require("hardhat");
|
||||||
const path = require('path');
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const hre = require("hardhat");
|
const path = require('path');
|
||||||
|
const {proposeOrSendTransaction} = require("./utils");
|
||||||
const prompt = require('prompt-sync')();
|
const prompt = require('prompt-sync')();
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const network = hre.network.name;
|
const network = hre.network.name;
|
||||||
const routerAddress = process.env.ROUTER_ADDRESS;
|
const routerAddress = process.env.ROUTER_ADDRESS;
|
||||||
|
const safeAddress = process.env.SAFE_ADDRESS;
|
||||||
|
if (!routerAddress) {
|
||||||
|
throw new Error("Missing ROUTER_ADDRESS");
|
||||||
|
}
|
||||||
|
|
||||||
console.log(`Setting executors on TychoRouter at ${routerAddress} on ${network}`);
|
console.log(`Setting executors on TychoRouter at ${routerAddress} on ${network}`);
|
||||||
|
|
||||||
const [deployer] = await ethers.getSigners();
|
const [signer] = await ethers.getSigners();
|
||||||
console.log(`Setting executors with account: ${deployer.address}`);
|
const balance = await signer.getBalance();
|
||||||
console.log(`Account balance: ${ethers.utils.formatEther(await deployer.getBalance())} ETH`);
|
|
||||||
|
console.log(`Using signer: ${signer.address}`);
|
||||||
|
console.log(`Account balance: ${ethers.utils.formatEther(balance)} ETH`);
|
||||||
|
|
||||||
const TychoRouter = await ethers.getContractFactory("TychoRouter");
|
const TychoRouter = await ethers.getContractFactory("TychoRouter");
|
||||||
const router = TychoRouter.attach(routerAddress);
|
const router = TychoRouter.attach(routerAddress);
|
||||||
@@ -48,13 +55,16 @@ async function main() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set executors
|
const executorAddresses = executorsToSet.map(({executor}) => executor);
|
||||||
const executorAddresses = executorsToSet.map(executor => executor.executor);
|
const txData = {
|
||||||
const tx = await router.setExecutors(executorAddresses, {
|
to: router.address,
|
||||||
gasLimit: 300000 // should be around 50k per executor
|
data: router.interface.encodeFunctionData("setExecutors", [executorAddresses]),
|
||||||
});
|
value: "0",
|
||||||
await tx.wait(); // Wait for the transaction to be mined
|
gasLimit: 300000
|
||||||
console.log(`Executors set at transaction: ${tx.hash}`);
|
};
|
||||||
|
|
||||||
|
const txHash = await proposeOrSendTransaction(safeAddress, txData, signer, "setExecutors");
|
||||||
|
console.log(`TX hash: ${txHash}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|||||||
@@ -3,15 +3,21 @@ const {ethers} = require("hardhat");
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const hre = require("hardhat");
|
const hre = require("hardhat");
|
||||||
|
const {proposeOrSendTransaction} = require("./utils");
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const network = hre.network.name;
|
const network = hre.network.name;
|
||||||
const routerAddress = process.env.ROUTER_ADDRESS;
|
const routerAddress = process.env.ROUTER_ADDRESS;
|
||||||
|
const safeAddress = process.env.SAFE_ADDRESS;
|
||||||
|
if (!routerAddress) {
|
||||||
|
throw new Error("Missing ROUTER_ADDRESS");
|
||||||
|
}
|
||||||
|
|
||||||
console.log(`Setting roles on TychoRouter at ${routerAddress} on ${network}`);
|
console.log(`Setting roles on TychoRouter at ${routerAddress} on ${network}`);
|
||||||
|
|
||||||
const [deployer] = await ethers.getSigners();
|
const [signer] = await ethers.getSigners();
|
||||||
console.log(`Setting roles with account: ${deployer.address}`);
|
console.log(`Setting roles with account: ${signer.address}`);
|
||||||
console.log(`Account balance: ${ethers.utils.formatEther(await deployer.getBalance())} ETH`);
|
console.log(`Account balance: ${ethers.utils.formatEther(await signer.getBalance())} ETH`);
|
||||||
const TychoRouter = await ethers.getContractFactory("TychoRouter");
|
const TychoRouter = await ethers.getContractFactory("TychoRouter");
|
||||||
const router = TychoRouter.attach(routerAddress);
|
const router = TychoRouter.attach(routerAddress);
|
||||||
|
|
||||||
@@ -20,7 +26,6 @@ async function main() {
|
|||||||
|
|
||||||
const roles = {
|
const roles = {
|
||||||
EXECUTOR_SETTER_ROLE: "0x6a1dd52dcad5bd732e45b6af4e7344fa284e2d7d4b23b5b09cb55d36b0685c87",
|
EXECUTOR_SETTER_ROLE: "0x6a1dd52dcad5bd732e45b6af4e7344fa284e2d7d4b23b5b09cb55d36b0685c87",
|
||||||
FEE_SETTER_ROLE: "0xe6ad9a47fbda1dc18de1eb5eeb7d935e5e81b4748f3cfc61e233e64f88182060",
|
|
||||||
PAUSER_ROLE: "0x65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a",
|
PAUSER_ROLE: "0x65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a",
|
||||||
UNPAUSER_ROLE: "0x427da25fe773164f88948d3e215c94b6554e2ed5e5f203a821c9f2f6131cf75a",
|
UNPAUSER_ROLE: "0x427da25fe773164f88948d3e215c94b6554e2ed5e5f203a821c9f2f6131cf75a",
|
||||||
FUND_RESCUER_ROLE: "0x912e45d663a6f4cc1d0491d8f046e06c616f40352565ea1cdb86a0e1aaefa41b"
|
FUND_RESCUER_ROLE: "0x912e45d663a6f4cc1d0491d8f046e06c616f40352565ea1cdb86a0e1aaefa41b"
|
||||||
@@ -31,9 +36,15 @@ async function main() {
|
|||||||
const addresses = rolesDict[network][roleName];
|
const addresses = rolesDict[network][roleName];
|
||||||
if (addresses && addresses.length > 0) {
|
if (addresses && addresses.length > 0) {
|
||||||
console.log(`Granting ${roleName} to the following addresses:`, addresses);
|
console.log(`Granting ${roleName} to the following addresses:`, addresses);
|
||||||
const tx = await router.batchGrantRole(roleHash, addresses);
|
|
||||||
await tx.wait(); // Wait for the transaction to be mined
|
const txData = {
|
||||||
console.log(`Role ${roleName} granted at transaction: ${tx.hash}`);
|
to: router.address,
|
||||||
|
data: router.interface.encodeFunctionData("batchGrantRole", [roleHash, addresses]),
|
||||||
|
value: "0",
|
||||||
|
};
|
||||||
|
|
||||||
|
const txHash = await proposeOrSendTransaction(safeAddress, txData, signer, "batchGrantRole");
|
||||||
|
console.log(`Role ${roleName} granted at TX hash: ${txHash}`);
|
||||||
} else {
|
} else {
|
||||||
console.log(`No addresses found for role ${roleName}`);
|
console.log(`No addresses found for role ${roleName}`);
|
||||||
}
|
}
|
||||||
|
|||||||
66
foundry/scripts/utils.js
Normal file
66
foundry/scripts/utils.js
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
const {ethers} = require("hardhat");
|
||||||
|
const Safe = require('@safe-global/protocol-kit').default;
|
||||||
|
const {EthersAdapter} = require('@safe-global/protocol-kit');
|
||||||
|
const {default: SafeApiKit} = require("@safe-global/api-kit");
|
||||||
|
|
||||||
|
const txServiceUrls = {
|
||||||
|
mainnet: "https://safe-transaction-mainnet.safe.global",
|
||||||
|
base: "https://safe-transaction-base.safe.global",
|
||||||
|
unichain: "https://safe-transaction-unichain.safe.global",
|
||||||
|
};
|
||||||
|
|
||||||
|
const txServiceUrl = txServiceUrls[hre.network.name];
|
||||||
|
|
||||||
|
async function proposeOrSendTransaction(safeAddress, txData, signer, methodName) {
|
||||||
|
if (safeAddress) {
|
||||||
|
return proposeTransaction(safeAddress, txData, signer, methodName);
|
||||||
|
} else {
|
||||||
|
console.log(`Executing the transaction directly`);
|
||||||
|
const tx = await signer.sendTransaction(txData);
|
||||||
|
await tx.wait();
|
||||||
|
return tx.hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function proposeTransaction(safeAddress, txData, signer, methodName) {
|
||||||
|
const signerAddress = await signer.getAddress();
|
||||||
|
console.log(`Proposing transaction to Safe: ${safeAddress} with account: ${signerAddress}`);
|
||||||
|
|
||||||
|
const ethAdapter = new EthersAdapter({
|
||||||
|
ethers,
|
||||||
|
signerOrProvider: signer,
|
||||||
|
});
|
||||||
|
|
||||||
|
const safeService = new SafeApiKit({txServiceUrl, ethAdapter});
|
||||||
|
|
||||||
|
const safeSdk = await Safe.create({
|
||||||
|
ethAdapter,
|
||||||
|
safeAddress,
|
||||||
|
});
|
||||||
|
let next_nonce = await safeService.getNextNonce(safeAddress);
|
||||||
|
const safeTransaction = await safeSdk.createTransaction({
|
||||||
|
safeTransactionData: {
|
||||||
|
...txData,
|
||||||
|
nonce: next_nonce
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const safeTxHash = await safeSdk.getTransactionHash(safeTransaction);
|
||||||
|
const senderSignature = await safeSdk.signTransactionHash(safeTxHash);
|
||||||
|
|
||||||
|
const proposeArgs = {
|
||||||
|
safeAddress,
|
||||||
|
safeTransactionData: safeTransaction.data,
|
||||||
|
safeTxHash,
|
||||||
|
senderAddress: signerAddress,
|
||||||
|
senderSignature: senderSignature.data,
|
||||||
|
origin: `Proposed from hardhat: ${methodName}`,
|
||||||
|
nonce: next_nonce,
|
||||||
|
};
|
||||||
|
|
||||||
|
await safeService.proposeTransaction(proposeArgs);
|
||||||
|
return safeTxHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
proposeOrSendTransaction
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user