@skalenetwork/upgrade-tools 2.0.0-refactor.8 → 3.0.0-skale-contracts.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +66 -11
  2. package/dist/hardhat.config.js +1 -0
  3. package/dist/src/deploy.js +44 -63
  4. package/dist/src/gnosis-safe.d.ts +2 -2
  5. package/dist/src/gnosis-safe.js +129 -103
  6. package/dist/src/index.d.ts +1 -1
  7. package/dist/src/index.js +1 -1
  8. package/dist/src/submitters/auto-submitter.d.ts +7 -2
  9. package/dist/src/submitters/auto-submitter.js +145 -21
  10. package/dist/src/submitters/eoa-submitter.js +14 -25
  11. package/dist/src/submitters/index.d.ts +6 -0
  12. package/dist/src/submitters/index.js +22 -0
  13. package/dist/src/submitters/safe-ima-legacy-marionette-submitter.js +16 -28
  14. package/dist/src/submitters/safe-ima-marionette-submitter.d.ts +7 -0
  15. package/dist/src/submitters/safe-ima-marionette-submitter.js +66 -0
  16. package/dist/src/submitters/safe-submitter.js +16 -27
  17. package/dist/src/submitters/safe-to-ima-submitter.d.ts +6 -4
  18. package/dist/src/submitters/safe-to-ima-submitter.js +19 -27
  19. package/dist/src/submitters/types/marionette.d.ts +13 -0
  20. package/dist/src/submitters/types/marionette.js +4 -0
  21. package/dist/src/upgrader.d.ts +3 -4
  22. package/dist/src/upgrader.js +81 -101
  23. package/dist/src/verification.js +23 -36
  24. package/dist/src/version.js +11 -22
  25. package/dist/typechain-types/AccessControlEnumerableUpgradeable.d.ts +9 -9
  26. package/dist/typechain-types/AccessControlUpgradeable.d.ts +9 -9
  27. package/dist/typechain-types/AdminUpgradeabilityProxy.d.ts +14 -99
  28. package/dist/typechain-types/ContextUpgradeable.d.ts +3 -3
  29. package/dist/typechain-types/ERC165Upgradeable.d.ts +3 -3
  30. package/dist/typechain-types/IAccessControlEnumerableUpgradeable.d.ts +7 -7
  31. package/dist/typechain-types/IAccessControlUpgradeable.d.ts +7 -7
  32. package/dist/typechain-types/IERC165Upgradeable.d.ts +1 -1
  33. package/dist/typechain-types/ISafeMock.d.ts +1 -1
  34. package/dist/typechain-types/Initializable.d.ts +3 -3
  35. package/dist/typechain-types/OwnableUpgradeable.d.ts +5 -5
  36. package/dist/typechain-types/ProxyAdmin.d.ts +3 -3
  37. package/dist/typechain-types/SafeMock.d.ts +5 -5
  38. package/dist/typechain-types/common.d.ts +4 -4
  39. package/dist/typechain-types/factories/AdminUpgradeabilityProxy__factory.d.ts +2 -27
  40. package/dist/typechain-types/factories/AdminUpgradeabilityProxy__factory.js +1 -71
  41. package/dist/typechain-types/factories/ProxyAdmin__factory.d.ts +2 -2
  42. package/dist/typechain-types/factories/ProxyAdmin__factory.js +6 -6
  43. package/dist/typechain-types/factories/SafeMock__factory.d.ts +1 -1
  44. package/package.json +8 -7
  45. package/dist/src/types/SkaleABIFile.d.ts +0 -3
  46. package/dist/src/types/SkaleABIFile.js +0 -2
  47. package/dist/src/upgrade.d.ts +0 -8
  48. package/dist/src/upgrade.js +0 -234
package/README.md CHANGED
@@ -4,19 +4,74 @@ Scripts to support upgrades of smart contracts. The package contains common used
4
4
 
5
5
  ## Upgrade scripts
6
6
 
7
- To write upgrade script import `upgrade` function.
7
+ To write an upgrade script extend `Upgrader` class.
8
8
 
9
9
  ```typescript
10
- import { upgrade } from "@skalenetwork/upgrade-tools"
10
+ import { Upgrader } from "@skalenetwork/upgrade-tools";
11
+
12
+ class ExampleContractUpgrader extends Upgrader {
13
+
14
+ getDeployedVersion = async () => {
15
+ return await (await this.getExampleContract()).version();
16
+ };
17
+
18
+ setVersion = async (newVersion: string) => {
19
+ const exampleContract = await this.getExampleContract();
20
+ const setVersionTransaction = {
21
+ to: exampleContract.address,
22
+ data: exampleContract.interface.encodeFunctionData("setVersion", [newVersion])
23
+ };
24
+ this.transactions.push(setVersionTransaction);
25
+ }
26
+
27
+ async getExampleContract() {
28
+ return await ethers.getContractAt("ExampleContract", this.abi["example_contract_address"] as string);
29
+ }
30
+ }
31
+
32
+ async function main() {
33
+ const abi = JSON.parse(await fs.readFile(process.env.ABI, "utf-8")) as SkaleABIFile;
34
+
35
+ const upgrader = new ExampleContractUpgrader(
36
+ "ExampleContract",
37
+ "1.0.0",
38
+ abi,
39
+ ["ExampleContract"]
40
+ );
41
+
42
+ await upgrader.upgrade();
43
+ }
44
+
45
+ if (require.main === module) {
46
+ main()
47
+ .then(() => process.exit(0))
48
+ .catch(error => {
49
+ console.error(error);
50
+ process.exit(1);
51
+ });
52
+ }
53
+ ```
54
+
55
+ ### Abstract functions
56
+
57
+ The `Upgrader` has 2 abstract functions. It's mandatory to override them:
58
+
59
+ ```typescript
60
+ abstract getDeployedVersion: () => Promise<string | undefined>
61
+ abstract setVersion: (newVersion: string) => Promise<void>
11
62
  ```
12
63
 
13
- Then call it with parameters below:
64
+ - `getDeployedVersion` returns string representing a deployed version of the contract
65
+ - `setVersion` creates a transaction to set a new version of the contract
66
+
67
+ ### Protected functions
68
+
69
+ There are functions that may be overridden to customize an upgrade process
70
+
71
+ ```typescript
72
+ deployNewContracts = () => { return Promise.resolve() };
73
+ initialize = () => { return Promise.resolve() };
74
+ ```
14
75
 
15
- - `projectName` - project name
16
- - `targetVersion` - version of smart contracts that can be upgraded by the script
17
- - `getDeployedVersion` - a function to request current version from smart contracts
18
- - `setVersion` - function that sets version to smart contracts
19
- - `safeMockAccessRequirements` - list of smart contracts that requires ownership changing for successful upgrade (when EOA + SafeMock are used during upgrade)
20
- - `contractNamesToUpgrade` - list of smart contracts to upgrade
21
- - `deployNewContracts` - optional - a function that deploys new smart contracts
22
- - `initialize` - optional - a function that setup smart contracts after upgrade
76
+ - `deployNewContracts` is called before proxies upgrade and is used to deploy new instances
77
+ - `initialize` is called after proxies upgrade and is used to send initializing transactions
@@ -18,6 +18,7 @@ const config = {
18
18
  ]
19
19
  },
20
20
  typechain: {
21
+ target: "ethers-v5",
21
22
  externalArtifacts: ['node_modules/@openzeppelin/upgrades-core/artifacts/[!b]*.json']
22
23
  }
23
24
  };
@@ -1,34 +1,21 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  exports.getContractFactory = exports.getManifestFile = exports.getLinkedContractFactory = exports.deployLibraries = void 0;
13
4
  const upgrades_core_1 = require("@openzeppelin/upgrades-core");
14
5
  const hardhat_1 = require("hardhat");
15
6
  const fs_1 = require("fs");
16
- function _deployLibrary(libraryName) {
17
- return __awaiter(this, void 0, void 0, function* () {
18
- const Library = yield hardhat_1.ethers.getContractFactory(libraryName);
19
- const library = yield Library.deploy();
20
- yield library.deployed();
21
- return library.address;
22
- });
7
+ async function _deployLibrary(libraryName) {
8
+ const Library = await hardhat_1.ethers.getContractFactory(libraryName);
9
+ const library = await Library.deploy();
10
+ await library.deployed();
11
+ return library.address;
23
12
  }
24
- function deployLibraries(libraryNames) {
25
- return __awaiter(this, void 0, void 0, function* () {
26
- const libraries = new Map();
27
- for (const libraryName of libraryNames) {
28
- libraries.set(libraryName, yield _deployLibrary(libraryName));
29
- }
30
- return libraries;
31
- });
13
+ async function deployLibraries(libraryNames) {
14
+ const libraries = new Map();
15
+ for (const libraryName of libraryNames) {
16
+ libraries.set(libraryName, await _deployLibrary(libraryName));
17
+ }
18
+ return libraries;
32
19
  }
33
20
  exports.deployLibraries = deployLibraries;
34
21
  function _linkBytecode(artifact, libraries) {
@@ -49,49 +36,43 @@ function _linkBytecode(artifact, libraries) {
49
36
  }
50
37
  return bytecode;
51
38
  }
52
- function getLinkedContractFactory(contractName, libraries) {
53
- return __awaiter(this, void 0, void 0, function* () {
54
- const cArtifact = yield hardhat_1.artifacts.readArtifact(contractName);
55
- const linkedBytecode = _linkBytecode(cArtifact, libraries);
56
- const ContractFactory = yield hardhat_1.ethers.getContractFactory(cArtifact.abi, linkedBytecode);
57
- return ContractFactory;
58
- });
39
+ async function getLinkedContractFactory(contractName, libraries) {
40
+ const cArtifact = await hardhat_1.artifacts.readArtifact(contractName);
41
+ const linkedBytecode = _linkBytecode(cArtifact, libraries);
42
+ const ContractFactory = await hardhat_1.ethers.getContractFactory(cArtifact.abi, linkedBytecode);
43
+ return ContractFactory;
59
44
  }
60
45
  exports.getLinkedContractFactory = getLinkedContractFactory;
61
- function getManifestFile() {
62
- return __awaiter(this, void 0, void 0, function* () {
63
- return (yield upgrades_core_1.Manifest.forNetwork(hardhat_1.ethers.provider)).file;
64
- });
46
+ async function getManifestFile() {
47
+ return (await upgrades_core_1.Manifest.forNetwork(hardhat_1.ethers.provider)).file;
65
48
  }
66
49
  exports.getManifestFile = getManifestFile;
67
- function getContractFactory(contract) {
68
- return __awaiter(this, void 0, void 0, function* () {
69
- const { linkReferences } = yield hardhat_1.artifacts.readArtifact(contract);
70
- if (!Object.keys(linkReferences).length)
71
- return yield hardhat_1.ethers.getContractFactory(contract);
72
- const libraryNames = [];
73
- for (const key of Object.keys(linkReferences)) {
74
- const libraryName = Object.keys(linkReferences[key])[0];
75
- libraryNames.push(libraryName);
76
- }
77
- const libraries = yield deployLibraries(libraryNames);
78
- const libraryArtifacts = {};
79
- for (const [libraryName, libraryAddress] of libraries.entries()) {
80
- const { bytecode } = yield hardhat_1.artifacts.readArtifact(libraryName);
81
- libraryArtifacts[libraryName] = { "address": libraryAddress, "bytecodeHash": (0, upgrades_core_1.hashBytecode)(bytecode) };
82
- }
83
- let manifest;
84
- try {
85
- manifest = JSON.parse(yield fs_1.promises.readFile(yield getManifestFile(), "utf-8"));
86
- Object.assign(libraryArtifacts, manifest.libraries);
87
- }
88
- finally {
89
- if (manifest !== undefined) {
90
- Object.assign(manifest, { libraries: libraryArtifacts });
91
- }
92
- yield fs_1.promises.writeFile(yield getManifestFile(), JSON.stringify(manifest, null, 4));
50
+ async function getContractFactory(contract) {
51
+ const { linkReferences } = await hardhat_1.artifacts.readArtifact(contract);
52
+ if (!Object.keys(linkReferences).length)
53
+ return await hardhat_1.ethers.getContractFactory(contract);
54
+ const libraryNames = [];
55
+ for (const key of Object.keys(linkReferences)) {
56
+ const libraryName = Object.keys(linkReferences[key])[0];
57
+ libraryNames.push(libraryName);
58
+ }
59
+ const libraries = await deployLibraries(libraryNames);
60
+ const libraryArtifacts = {};
61
+ for (const [libraryName, libraryAddress] of libraries.entries()) {
62
+ const { bytecode } = await hardhat_1.artifacts.readArtifact(libraryName);
63
+ libraryArtifacts[libraryName] = { "address": libraryAddress, "bytecodeHash": (0, upgrades_core_1.hashBytecode)(bytecode) };
64
+ }
65
+ let manifest;
66
+ try {
67
+ manifest = JSON.parse(await fs_1.promises.readFile(await getManifestFile(), "utf-8"));
68
+ Object.assign(libraryArtifacts, manifest.libraries);
69
+ }
70
+ finally {
71
+ if (manifest !== undefined) {
72
+ Object.assign(manifest, { libraries: libraryArtifacts });
93
73
  }
94
- return yield getLinkedContractFactory(contract, libraries);
95
- });
74
+ await fs_1.promises.writeFile(await getManifestFile(), JSON.stringify(manifest, null, 4));
75
+ }
76
+ return await getLinkedContractFactory(contract, libraries);
96
77
  }
97
78
  exports.getContractFactory = getContractFactory;
@@ -1,6 +1,6 @@
1
1
  import { ethers } from "ethers";
2
2
  import { HardhatEthersHelpers } from "@nomiclabs/hardhat-ethers/types";
3
- declare type Ethers = typeof ethers & HardhatEthersHelpers;
3
+ type Ethers = typeof ethers & HardhatEthersHelpers;
4
4
  interface SafeMultisigTransaction {
5
5
  safe: string;
6
6
  to: string;
@@ -20,6 +20,6 @@ interface SafeMultisigTransaction {
20
20
  }
21
21
  export declare function getSafeTransactionUrl(chainId: number): string;
22
22
  export declare function getSafeRelayUrl(chainId: number): string;
23
- export declare function createMultiSendTransaction(ethers: Ethers, safeAddress: string, privateKey: string, transactions: string[], nonce?: number): Promise<SafeMultisigTransaction>;
23
+ export declare function createMultiSendTransaction(ethers: Ethers, safeAddress: string, privateKey: string, transactions: string[], chainId: number, nonce?: number): Promise<SafeMultisigTransaction>;
24
24
  export declare function sendSafeTransaction(safe: string, chainId: number, safeTx: SafeMultisigTransaction): Promise<void>;
25
25
  export {};
@@ -22,15 +22,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
- return new (P || (P = Promise))(function (resolve, reject) {
28
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
- step((generator = generator.apply(thisArg, _arguments || [])).next());
32
- });
33
- };
34
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
35
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
36
27
  };
@@ -87,102 +78,99 @@ function getSafeRelayUrl(chainId) {
87
78
  }
88
79
  }
89
80
  exports.getSafeRelayUrl = getSafeRelayUrl;
90
- function createMultiSendTransaction(ethers, safeAddress, privateKey, transactions, nonce) {
91
- return __awaiter(this, void 0, void 0, function* () {
92
- const chainId = (yield ethers.provider.getNetwork()).chainId;
93
- const multiSendAddress = getMultiSendAddress(chainId);
94
- const multiSendAbi = [{ "constant": false, "inputs": [{ "internalType": "bytes", "name": "transactions", "type": "bytes" }], "name": "multiSend", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }];
95
- const multiSend = new ethers.Contract(multiSendAddress, new ethers.utils.Interface(multiSendAbi), ethers.provider);
96
- const safeAbi = [{ "constant": true, "inputs": [{ "internalType": "address", "name": "to", "type": "address" }, { "internalType": "uint256", "name": "value", "type": "uint256" }, { "internalType": "bytes", "name": "data", "type": "bytes" }, { "internalType": "enum Enum.Operation", "name": "operation", "type": "uint8" }, { "internalType": "uint256", "name": "safeTxGas", "type": "uint256" }, { "internalType": "uint256", "name": "baseGas", "type": "uint256" }, { "internalType": "uint256", "name": "gasPrice", "type": "uint256" }, { "internalType": "address", "name": "gasToken", "type": "address" }, { "internalType": "address", "name": "refundReceiver", "type": "address" }, { "internalType": "uint256", "name": "_nonce", "type": "uint256" }], "name": "getTransactionHash", "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], "payable": false, "stateMutability": "view", "type": "function" }];
97
- const safe = new ethers.Contract(safeAddress, new ethers.utils.Interface(safeAbi), ethers.provider);
98
- let nonceValue = 0;
99
- if (nonce === undefined) {
100
- try {
101
- if (process.env.NONCE) {
102
- // NONCE variable is set
103
- if (isNaN(Number.parseInt(process.env.NONCE))) {
104
- // NONCE variable is not a number
105
- if (process.env.NONCE.toLowerCase() === "pending") {
106
- nonceValue = yield getSafeNonceWithPending(chainId, safeAddress);
107
- }
108
- else {
109
- nonceValue = yield getSafeNonce(chainId, safeAddress);
110
- }
81
+ async function createMultiSendTransaction(ethers, safeAddress, privateKey, transactions, chainId, nonce) {
82
+ const multiSendAddress = getMultiSendAddress(chainId);
83
+ const multiSendAbi = [{ "constant": false, "inputs": [{ "internalType": "bytes", "name": "transactions", "type": "bytes" }], "name": "multiSend", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }];
84
+ const multiSend = new ethers.Contract(multiSendAddress, new ethers.utils.Interface(multiSendAbi), ethers.provider);
85
+ let nonceValue = 0;
86
+ if (nonce === undefined) {
87
+ try {
88
+ if (process.env.NONCE) {
89
+ // NONCE variable is set
90
+ if (isNaN(Number.parseInt(process.env.NONCE))) {
91
+ // NONCE variable is not a number
92
+ if (process.env.NONCE.toLowerCase() === "pending") {
93
+ nonceValue = await getSafeNonceWithPending(chainId, safeAddress);
111
94
  }
112
95
  else {
113
- // NONCE variable is a number
114
- nonceValue = Number.parseInt(process.env.NONCE);
96
+ nonceValue = await getSafeNonce(chainId, safeAddress);
115
97
  }
116
98
  }
117
99
  else {
118
- // NONCE variable is not set
119
- nonceValue = yield getSafeNonce(chainId, safeAddress);
100
+ // NONCE variable is a number
101
+ nonceValue = Number.parseInt(process.env.NONCE);
120
102
  }
121
103
  }
122
- catch (e) {
123
- if (!(e instanceof Error) || !e.toString().startsWith("Error: Can't get safe-transaction url")) {
124
- throw e;
125
- }
104
+ else {
105
+ // NONCE variable is not set
106
+ nonceValue = await getSafeNonce(chainId, safeAddress);
126
107
  }
127
108
  }
128
- else {
129
- nonceValue = nonce;
109
+ catch (e) {
110
+ if (!(e instanceof Error) || !e.toString().startsWith("Error: Can't get safe-transaction url")) {
111
+ throw e;
112
+ }
130
113
  }
131
- console.log("Will send tx to Gnosis with nonce", nonceValue);
132
- const tx = {
133
- "safe": safeAddress,
134
- "to": multiSend.address,
135
- "value": 0,
136
- "data": multiSend.interface.encodeFunctionData("multiSend", [concatTransactions(transactions)]),
137
- "operation": 1,
138
- "gasToken": ethers.constants.AddressZero,
139
- "safeTxGas": 0,
140
- "baseGas": 0,
141
- "gasPrice": 0,
142
- "refundReceiver": ethers.constants.AddressZero,
143
- "nonce": nonceValue, // Nonce of the Safe, transaction cannot be executed until Safe's nonce is not equal to this nonce
144
- };
145
- const digestHex = yield safe.getTransactionHash(tx.to, tx.value, tx.data, tx.operation, tx.safeTxGas, tx.baseGas, tx.gasPrice, tx.gasToken, tx.refundReceiver, tx.nonce);
146
- const privateKeyBuffer = ethUtil.toBuffer(privateKey);
147
- const { r, s, v } = ethUtil.ecsign(ethUtil.toBuffer(digestHex), privateKeyBuffer);
148
- const signature = ethUtil.toRpcSig(v, r, s).toString();
149
- const txToSend = Object.assign(Object.assign({}, tx), { "contractTransactionHash": digestHex,
150
- // Owner of the Safe proposing the transaction. Must match one of the signatures
151
- "sender": ethers.utils.getAddress(ethUtil.bufferToHex(ethUtil.privateToAddress(privateKeyBuffer))), "signature": signature, "origin": "Upgrade skale-manager" // Give more information about the transaction, e.g. "My Custom Safe app"
152
- });
153
- return txToSend;
154
- });
114
+ }
115
+ else {
116
+ nonceValue = nonce;
117
+ }
118
+ console.log("Will send tx to Gnosis with nonce", nonceValue);
119
+ const tx = {
120
+ "safe": safeAddress,
121
+ "to": multiSend.address,
122
+ "value": 0,
123
+ "data": multiSend.interface.encodeFunctionData("multiSend", [concatTransactions(transactions)]),
124
+ "operation": 1,
125
+ "gasToken": ethers.constants.AddressZero,
126
+ "safeTxGas": 0,
127
+ "baseGas": 0,
128
+ "gasPrice": 0,
129
+ "refundReceiver": ethers.constants.AddressZero,
130
+ "nonce": nonceValue, // Nonce of the Safe, transaction cannot be executed until Safe's nonce is not equal to this nonce
131
+ };
132
+ const digestHex = getTransactionHash(tx.to, tx.value, tx.data, tx.operation, tx.safeTxGas, tx.baseGas, tx.gasPrice, tx.gasToken, tx.refundReceiver, tx.nonce, safeAddress, chainId);
133
+ const privateKeyBuffer = ethUtil.toBuffer(privateKey);
134
+ const { r, s, v } = ethUtil.ecsign(ethUtil.toBuffer(digestHex), privateKeyBuffer);
135
+ const signature = ethUtil.toRpcSig(v, r, s).toString();
136
+ const txToSend = {
137
+ ...tx,
138
+ "contractTransactionHash": digestHex,
139
+ // Owner of the Safe proposing the transaction. Must match one of the signatures
140
+ "sender": ethers.utils.getAddress(ethUtil.bufferToHex(ethUtil.privateToAddress(privateKeyBuffer))),
141
+ "signature": signature,
142
+ "origin": "Upgrade skale-manager" // Give more information about the transaction, e.g. "My Custom Safe app"
143
+ };
144
+ return txToSend;
155
145
  }
156
146
  exports.createMultiSendTransaction = createMultiSendTransaction;
157
- function sendSafeTransaction(safe, chainId, safeTx) {
158
- return __awaiter(this, void 0, void 0, function* () {
147
+ async function sendSafeTransaction(safe, chainId, safeTx) {
148
+ try {
149
+ console.log("Estimate gas");
150
+ const estimateRequest = safeTx;
159
151
  try {
160
- console.log("Estimate gas");
161
- const estimateRequest = safeTx;
162
- try {
163
- const estimateResponse = yield axios_1.default.post(`${getSafeRelayUrl(chainId)}/api/v2/safes/${safe}/transactions/estimate/`, estimateRequest);
164
- console.log(chalk_1.default.cyan(`Recommend to set gas limit to ${parseInt(estimateResponse.data.safeTxGas, 10) + parseInt(estimateResponse.data.baseGas, 10)}`));
165
- }
166
- catch (e) {
167
- console.log(chalk_1.default.red("Failed to estimate gas"));
168
- console.log(e);
169
- }
170
- console.log(chalk_1.default.green("Send transaction to gnosis safe"));
171
- yield axios_1.default.post(`${getSafeTransactionUrl(chainId)}/api/v1/safes/${safe}/multisig-transactions/`, safeTx);
152
+ const estimateResponse = await axios_1.default.post(`${getSafeRelayUrl(chainId)}/api/v2/safes/${safe}/transactions/estimate/`, estimateRequest);
153
+ console.log(chalk_1.default.cyan(`Recommend to set gas limit to ${parseInt(estimateResponse.data.safeTxGas, 10) + parseInt(estimateResponse.data.baseGas, 10)}`));
172
154
  }
173
155
  catch (e) {
174
- if (axios_1.default.isAxiosError(e)) {
175
- if (e.response) {
176
- console.log(JSON.stringify(e.response.data, null, 4));
177
- console.log(chalk_1.default.red(`Request failed with ${e.response.status} code`));
178
- }
179
- else {
180
- console.log(chalk_1.default.red("Request failed with unknown reason"));
181
- }
156
+ console.log(chalk_1.default.red("Failed to estimate gas"));
157
+ console.log(e);
158
+ }
159
+ console.log(chalk_1.default.green("Send transaction to gnosis safe"));
160
+ await axios_1.default.post(`${getSafeTransactionUrl(chainId)}/api/v1/safes/${safe}/multisig-transactions/`, safeTx);
161
+ }
162
+ catch (e) {
163
+ if (axios_1.default.isAxiosError(e)) {
164
+ if (e.response) {
165
+ console.log(JSON.stringify(e.response.data, null, 4));
166
+ console.log(chalk_1.default.red(`Request failed with ${e.response.status} code`));
167
+ }
168
+ else {
169
+ console.log(chalk_1.default.red("Request failed with unknown reason"));
182
170
  }
183
- throw e;
184
171
  }
185
- });
172
+ throw e;
173
+ }
186
174
  }
187
175
  exports.sendSafeTransaction = sendSafeTransaction;
188
176
  // private functions
@@ -207,20 +195,58 @@ function concatTransactions(transactions) {
207
195
  }
208
196
  }).join("");
209
197
  }
210
- function getSafeNonce(chainId, safeAddress) {
211
- return __awaiter(this, void 0, void 0, function* () {
212
- const safeInfo = yield axios_1.default.get(`${getSafeTransactionUrl(chainId)}/api/v1/safes/${safeAddress}/`);
213
- return safeInfo.data.nonce;
214
- });
198
+ async function getSafeNonce(chainId, safeAddress) {
199
+ const safeInfo = await axios_1.default.get(`${getSafeTransactionUrl(chainId)}/api/v1/safes/${safeAddress}/`);
200
+ return safeInfo.data.nonce;
215
201
  }
216
- function getSafeNonceWithPending(chainId, safeAddress) {
217
- return __awaiter(this, void 0, void 0, function* () {
218
- const allTransactions = yield axios_1.default.get(`${getSafeTransactionUrl(chainId)}/api/v1/safes/${safeAddress}/all-transactions/?executed=false&queued=true&trusted=true`);
219
- if (allTransactions.data.results.length > 0) {
220
- return allTransactions.data.results[0].nonce + 1;
221
- }
222
- else {
223
- return 0;
224
- }
225
- });
202
+ async function getSafeNonceWithPending(chainId, safeAddress) {
203
+ const allTransactions = await axios_1.default.get(`${getSafeTransactionUrl(chainId)}/api/v1/safes/${safeAddress}/all-transactions/?executed=false&queued=true&trusted=true`);
204
+ if (allTransactions.data.results.length > 0) {
205
+ return allTransactions.data.results[0].nonce + 1;
206
+ }
207
+ else {
208
+ return 0;
209
+ }
210
+ }
211
+ function getDomainSeparator(safeAddress, chainId) {
212
+ const DOMAIN_SEPARATOR_TYPEHASH = "0x47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a79469218";
213
+ return ethers_1.ethers.utils.solidityKeccak256(["bytes"], [
214
+ ethers_1.ethers.utils.defaultAbiCoder.encode(["bytes32", "uint256", "address"], [DOMAIN_SEPARATOR_TYPEHASH, chainId, safeAddress])
215
+ ]);
216
+ }
217
+ function encodeTransactionData(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce, safeAddress, chainId) {
218
+ const dataHash = ethers_1.ethers.utils.solidityKeccak256(["bytes"], [data]);
219
+ const SAFE_TX_TYPEHASH = "0xbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d8";
220
+ const encoded = ethers_1.ethers.utils.defaultAbiCoder.encode([
221
+ "bytes32",
222
+ "address",
223
+ "uint256",
224
+ "bytes32",
225
+ "uint256",
226
+ "uint256",
227
+ "uint256",
228
+ "uint256",
229
+ "address",
230
+ "address",
231
+ "uint256"
232
+ ], [
233
+ SAFE_TX_TYPEHASH,
234
+ to,
235
+ value,
236
+ dataHash,
237
+ operation,
238
+ safeTxGas,
239
+ baseGas,
240
+ gasPrice,
241
+ gasToken,
242
+ refundReceiver,
243
+ _nonce
244
+ ]);
245
+ const encodedHash = ethers_1.ethers.utils.solidityKeccak256(["bytes"], [encoded]);
246
+ return ethers_1.ethers.utils.solidityPack(["bytes1", "bytes1", "bytes32", "bytes32"], ["0x19", "0x01", getDomainSeparator(safeAddress, chainId), encodedHash]);
247
+ }
248
+ function getTransactionHash(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce, safeAddress, chainId) {
249
+ return ethers_1.ethers.utils.solidityKeccak256(["bytes"], [
250
+ encodeTransactionData(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce, safeAddress, chainId)
251
+ ]);
226
252
  }
@@ -2,7 +2,7 @@ export * from "./abi";
2
2
  export * from "./deploy";
3
3
  export * from "./gnosis-safe";
4
4
  export * from "./multiSend";
5
- export * from "./upgrade";
5
+ export * from "./submitters";
6
6
  export * from "./verification";
7
7
  export * from "./version";
8
8
  export * from "./upgrader";
package/dist/src/index.js CHANGED
@@ -18,7 +18,7 @@ __exportStar(require("./abi"), exports);
18
18
  __exportStar(require("./deploy"), exports);
19
19
  __exportStar(require("./gnosis-safe"), exports);
20
20
  __exportStar(require("./multiSend"), exports);
21
- __exportStar(require("./upgrade"), exports);
21
+ __exportStar(require("./submitters"), exports);
22
22
  __exportStar(require("./verification"), exports);
23
23
  __exportStar(require("./version"), exports);
24
24
  __exportStar(require("./upgrader"), exports);
@@ -1,5 +1,10 @@
1
- import { UnsignedTransaction } from "ethers";
1
+ import { Transaction } from "ethers";
2
2
  import { Submitter } from "./submitter";
3
3
  export declare class AutoSubmitter extends Submitter {
4
- submit(transactions: UnsignedTransaction[]): Promise<void>;
4
+ submit(transactions: Transaction[]): Promise<void>;
5
+ _getImaInstance(): Promise<import("@skalenetwork/skale-contracts").Instance>;
6
+ _getSafeAddress(): string;
7
+ _getSchainHash(): string;
8
+ _getMainnetChainId(): number;
9
+ _versionFunctionExists(): Promise<boolean>;
5
10
  }