From 9c77c3055739681bd49d5ecf082184a6a9fa6100 Mon Sep 17 00:00:00 2001
From: Ino Murko <2582555+InoMurko@users.noreply.github.com>
Date: Tue, 3 Sep 2024 12:58:28 +0200
Subject: [PATCH 1/6] tidy things
---
.../1-create_multisig.ts | 79 ++++++++++
.../setup-fast-withdrawal/2-add_validators.ts | 117 ++++++++++++++
.../3-set-any-trust-fast-confirmer.ts | 90 +++++++++++
.../4-configure-minimum-assertion-period.ts | 149 ++++++++++++++++++
examples/setup-fast-withdrawal/README.md | 19 +++
examples/setup-fast-withdrawal/common.ts | 53 +++++++
examples/setup-fast-withdrawal/tsconfig.json | 6 +-
package.json | 5 +
src/createSafePrepareTransactionRequest.ts | 4 +-
...tFastConfirmerPrepareTransactionRequest.ts | 4 +-
yarn.lock | 70 +++++++-
11 files changed, 590 insertions(+), 6 deletions(-)
create mode 100644 examples/setup-fast-withdrawal/1-create_multisig.ts
create mode 100644 examples/setup-fast-withdrawal/2-add_validators.ts
create mode 100644 examples/setup-fast-withdrawal/3-set-any-trust-fast-confirmer.ts
create mode 100644 examples/setup-fast-withdrawal/4-configure-minimum-assertion-period.ts
create mode 100644 examples/setup-fast-withdrawal/common.ts
diff --git a/examples/setup-fast-withdrawal/1-create_multisig.ts b/examples/setup-fast-withdrawal/1-create_multisig.ts
new file mode 100644
index 00000000..fbcc6ed4
--- /dev/null
+++ b/examples/setup-fast-withdrawal/1-create_multisig.ts
@@ -0,0 +1,79 @@
+import { createPublicClient, http, isAddress } from 'viem';
+import {
+ createSafePrepareTransactionRequest,
+} from '@arbitrum/orbit-sdk';
+import { getParentChainFromId } from '@arbitrum/orbit-sdk/utils';
+import { config } from 'dotenv';
+import { propose } from './common.js';
+
+config();
+
+//check environment variables
+if (typeof process.env.OWNER_1_ADDRESS_PRIVATE_KEY === 'undefined') {
+ throw new Error(`Please provide the "OWNER_1_ADDRESS_PRIVATE_KEY" environment variable`);
+}
+
+if (typeof process.env.PARENT_CHAIN_ID === 'undefined') {
+ throw new Error(`Please provide the "PARENT_CHAIN_ID" environment variable`);
+}
+
+if (typeof process.env.SAFE_ADDRESS === 'undefined') {
+ throw new Error(`Please provide the "SAFE_ADDRESS" environment variable`);
+}
+
+if (typeof process.env.FC_VALIDATORS === 'undefined') {
+ throw new Error(`Please provide the "FC_VALIDATORS" environment variable`);
+}
+
+const rollupOwnerSafeAddress = process.env.SAFE_ADDRESS as `0x${string}`;
+// // set the parent chain and create a public client for it
+const parentChainId = Number(process.env.PARENT_CHAIN_ID);
+const parentChain = getParentChainFromId(parentChainId);
+const parentChainPublicClient = createPublicClient({
+ chain: parentChain,
+ transport: http(process.env.RPC),
+});
+// sanitize validator addresses
+const fcValidators = JSON.parse(process.env.FC_VALIDATORS);
+const safeWalletThreshold = fcValidators.length;
+if (!fcValidators) {
+ throw new Error(`The "FC_VALIDATORS" environment variable must be a valid array`);
+}
+
+const sanitizedFcValidators = [
+ ...new Set(
+ fcValidators.filter((validator: `0x${string}`) =>
+ isAddress(validator) ? validator : undefined,
+ ),
+ ),
+];
+if (sanitizedFcValidators.length !== safeWalletThreshold) {
+ throw new Error(
+ `Some of the addresses in the "FC_VALIDATORS" environment variable appear to not be valid or duplicated.`,
+ );
+}
+
+async function main() {
+ //
+ // Step 1. Create Safe multisig
+ //
+ console.log(
+ `Step 1: Create a new ${safeWalletThreshold}/${safeWalletThreshold} Safe wallet with the following addresses as signers:`,
+ fcValidators,
+ );
+ console.log('---');
+ const txRequest = await createSafePrepareTransactionRequest({
+ publicClient: parentChainPublicClient,
+ account: rollupOwnerSafeAddress,
+ owners: fcValidators,
+ threshold: safeWalletThreshold,
+ saltNonce: BigInt(Date.now())
+ });
+ propose(txRequest.to as string, txRequest.data as string, rollupOwnerSafeAddress);
+ //execute the transaction
+ //https://help.safe.global/en/articles/40834-verify-safe-creation
+ //in the executed transaction find `ProxyCreation` event
+ //Data singleton :
is what you're looing for
+}
+
+main();
diff --git a/examples/setup-fast-withdrawal/2-add_validators.ts b/examples/setup-fast-withdrawal/2-add_validators.ts
new file mode 100644
index 00000000..30af8b25
--- /dev/null
+++ b/examples/setup-fast-withdrawal/2-add_validators.ts
@@ -0,0 +1,117 @@
+import { createPublicClient, http, isAddress, Address } from 'viem';
+import {
+ createRollupFetchTransactionHash,
+ createRollupPrepareTransactionReceipt,
+ rollupAdminLogicPublicActions,
+} from '@arbitrum/orbit-sdk';
+import { getParentChainFromId } from '@arbitrum/orbit-sdk/utils';
+import { config } from 'dotenv';
+import { propose } from './common.js';
+
+
+config();
+
+//check environment variables
+if (typeof process.env.OWNER_1_ADDRESS_PRIVATE_KEY === 'undefined') {
+ throw new Error(`Please provide the "OWNER_1_ADDRESS_PRIVATE_KEY" environment variable`);
+}
+
+if (typeof process.env.PARENT_CHAIN_ID === 'undefined') {
+ throw new Error(`Please provide the "PARENT_CHAIN_ID" environment variable`);
+}
+
+if (typeof process.env.SAFE_ADDRESS === 'undefined') {
+ throw new Error(`Please provide the "SAFE_ADDRESS" environment variable`);
+}
+
+if (typeof process.env.FC_VALIDATORS_SAFE_ADDRESS === 'undefined') {
+ throw new Error(`Please provide the "FC_VALIDATORS_SAFE_ADDRESS" environment variable (run step 1)`);
+}
+
+if (typeof process.env.FC_VALIDATORS === 'undefined') {
+ throw new Error(`Please provide the "FC_VALIDATORS" environment variable`);
+}
+
+if (typeof process.env.ROLLUP_ADDRESS === 'undefined') {
+ throw new Error(`Please provide the "ROLLUP_ADDRESS" environment variable`);
+}
+
+if (typeof process.env.RPC === 'undefined') {
+ throw new Error(`Please provide an "RPC" endpoint with unlimited eth_getLogs range`);
+}
+
+const rollupOwnerSafeAddress = process.env.SAFE_ADDRESS as `0x${string}`;
+const safeAddress = process.env.FC_VALIDATORS_SAFE_ADDRESS as `0x${string}`;
+const rollupAddress = process.env.ROLLUP_ADDRESS as Address;
+// // set the parent chain and create a public client for it
+const parentChainId = Number(process.env.PARENT_CHAIN_ID);
+const parentChain = getParentChainFromId(parentChainId);
+const parentChainPublicClient = createPublicClient({
+ chain: parentChain,
+ transport: http(process.env.RPC),
+}).extend(
+ rollupAdminLogicPublicActions({
+ rollup: rollupAddress,
+ }),
+);
+
+// sanitize validator addresses
+const fcValidators = JSON.parse(process.env.FC_VALIDATORS);
+const safeWalletThreshold = fcValidators.length;
+if (!fcValidators) {
+ throw new Error(`The "FC_VALIDATORS" environment variable must be a valid array`);
+}
+
+const sanitizedFcValidators = [
+ ...new Set(
+ fcValidators.filter((validator: `0x${string}`) =>
+ isAddress(validator) ? validator : undefined,
+ ),
+ ),
+];
+if (sanitizedFcValidators.length !== safeWalletThreshold) {
+ throw new Error(
+ `Some of the addresses in the "FC_VALIDATORS" environment variable appear to not be valid or duplicated.`,
+ );
+}
+
+async function main() {
+ console.log('Add the new Safe address (created in step 1) as a validator');
+ fcValidators.push(safeAddress);
+
+ console.log('Gather necessary data (UpgradeExecutor address)');
+ const transactionHash = await createRollupFetchTransactionHash({
+ rollup: rollupAddress,
+ publicClient: parentChainPublicClient,
+ });
+ const transactionReceipt = createRollupPrepareTransactionReceipt(
+ await parentChainPublicClient.getTransactionReceipt({ hash: transactionHash }),
+ );
+ const coreContracts = transactionReceipt.getCoreContracts();
+ const upgradeExecutorAddress = coreContracts.upgradeExecutor;
+
+ //
+ // Step 2. Add validators to the Orbit chain rollup validator whitelist
+ //
+ console.log(
+ `Step 2: Adding the following validators to the Rollup validator whitelist:`,
+ fcValidators,
+ );
+ console.log('---');
+
+ // prepare set validator transaction request
+ const fcValidatorsStatus = Array(fcValidators.length).fill(true);
+ const setValidatorTransactionRequest =
+ await parentChainPublicClient.rollupAdminLogicPrepareTransactionRequest({
+ functionName: 'setValidator',
+ args: [
+ fcValidators, // validator address list
+ fcValidatorsStatus, // validator status list
+ ],
+ upgradeExecutor: upgradeExecutorAddress,
+ account: rollupOwnerSafeAddress,
+ });
+ propose(setValidatorTransactionRequest.to as string, setValidatorTransactionRequest.data as string, rollupOwnerSafeAddress);
+}
+
+main();
diff --git a/examples/setup-fast-withdrawal/3-set-any-trust-fast-confirmer.ts b/examples/setup-fast-withdrawal/3-set-any-trust-fast-confirmer.ts
new file mode 100644
index 00000000..63ebb297
--- /dev/null
+++ b/examples/setup-fast-withdrawal/3-set-any-trust-fast-confirmer.ts
@@ -0,0 +1,90 @@
+import { createPublicClient, http, Address, parseAbi } from 'viem';
+import {
+ createRollupFetchTransactionHash,
+ createRollupPrepareTransactionReceipt,
+ rollupAdminLogicPublicActions,
+ setAnyTrustFastConfirmerPrepareTransactionRequest,
+} from '@arbitrum/orbit-sdk';
+import { getParentChainFromId } from '@arbitrum/orbit-sdk/utils';
+import { config } from 'dotenv';
+import { propose } from './common.js';
+
+
+config();
+
+//check environment variables
+if (typeof process.env.OWNER_1_ADDRESS_PRIVATE_KEY === 'undefined') {
+ throw new Error(`Please provide the "OWNER_1_ADDRESS_PRIVATE_KEY" environment variable`);
+}
+
+if (typeof process.env.PARENT_CHAIN_ID === 'undefined') {
+ throw new Error(`Please provide the "PARENT_CHAIN_ID" environment variable`);
+}
+
+if (typeof process.env.SAFE_ADDRESS === 'undefined') {
+ throw new Error(`Please provide the "SAFE_ADDRESS" environment variable`);
+}
+
+if (typeof process.env.FC_VALIDATORS_SAFE_ADDRESS === 'undefined') {
+ throw new Error(`Please provide the "FC_VALIDATORS_SAFE_ADDRESS" environment variable (run step 1)`);
+}
+
+if (typeof process.env.ROLLUP_ADDRESS === 'undefined') {
+ throw new Error(`Please provide the "ROLLUP_ADDRESS" environment variable`);
+}
+
+if (typeof process.env.RPC === 'undefined') {
+ throw new Error(`Please provide an "RPC" endpoint with unlimited eth_getLogs range`);
+}
+
+const rollupOwnerSafeAddress = process.env.SAFE_ADDRESS as `0x${string}`;
+const safeAddress = process.env.FC_VALIDATORS_SAFE_ADDRESS as `0x${string}`;
+const rollupAddress = process.env.ROLLUP_ADDRESS as Address;
+// // set the parent chain and create a public client for it
+const parentChainId = Number(process.env.PARENT_CHAIN_ID);
+const parentChain = getParentChainFromId(parentChainId);
+const parentChainPublicClient = createPublicClient({
+ chain: parentChain,
+ transport: http(process.env.RPC),
+}).extend(
+ rollupAdminLogicPublicActions({
+ rollup: rollupAddress,
+ }),
+);
+
+async function main() {
+ const currentAnyTrustFastConfirmer = await parentChainPublicClient.readContract({
+ address: rollupAddress,
+ abi: parseAbi(['function anyTrustFastConfirmer() view returns (address)']),
+ functionName: 'anyTrustFastConfirmer',
+ });
+
+ if (currentAnyTrustFastConfirmer.toLowerCase() !== safeAddress.toLowerCase()) {
+ console.log('Gather necessary data (UpgradeExecutor address)');
+ const transactionHash = await createRollupFetchTransactionHash({
+ rollup: rollupAddress,
+ publicClient: parentChainPublicClient,
+ });
+ const transactionReceipt = createRollupPrepareTransactionReceipt(
+ await parentChainPublicClient.getTransactionReceipt({ hash: transactionHash }),
+ );
+ const coreContracts = transactionReceipt.getCoreContracts();
+ const upgradeExecutorAddress = coreContracts.upgradeExecutor;
+ const setAnyTrustFastConfirmerTransactionRequest =
+ await setAnyTrustFastConfirmerPrepareTransactionRequest({
+ publicClient: parentChainPublicClient,
+ account: rollupOwnerSafeAddress,
+ rollup: rollupAddress,
+ upgradeExecutor: upgradeExecutorAddress,
+ fastConfirmer: safeAddress,
+ });
+ propose(setAnyTrustFastConfirmerTransactionRequest.to as string, setAnyTrustFastConfirmerTransactionRequest.data as string, rollupOwnerSafeAddress);
+
+ } else {
+ console.log(
+ `AnyTrust fast confirmer is already configured to ${currentAnyTrustFastConfirmer}. Skipping.`,
+ );
+ }
+}
+
+main();
diff --git a/examples/setup-fast-withdrawal/4-configure-minimum-assertion-period.ts b/examples/setup-fast-withdrawal/4-configure-minimum-assertion-period.ts
new file mode 100644
index 00000000..61b496c7
--- /dev/null
+++ b/examples/setup-fast-withdrawal/4-configure-minimum-assertion-period.ts
@@ -0,0 +1,149 @@
+import { createPublicClient, http, Address } from 'viem';
+import {
+ createRollupFetchTransactionHash,
+ createRollupPrepareTransactionReceipt,
+ rollupAdminLogicPublicActions,
+} from '@arbitrum/orbit-sdk';
+import { base, baseSepolia } from '@arbitrum/orbit-sdk/chains';
+import { getParentChainFromId } from '@arbitrum/orbit-sdk/utils';
+import { config } from 'dotenv';
+import { propose } from './common.js';
+
+
+config();
+
+function getTimeDelayFromNumberOfBlocks(chainId: number, blocks: bigint): string {
+ // For Arbitrum L2s built on top of Ethereum, or Arbitrum L3s built on top of an Arbitrum L2, `block.number` always returns the L1 block number.
+ // L1 blocks are produced every 12 seconds.
+ //
+ // For Arbitrum L3s built on top of an OP Stack L2, `block.number` will return the L2 block number.
+ // L2 blocks in OP Stack chains are produced every 2 seconds.
+ const seconds = Number(
+ chainId === base.id || chainId === baseSepolia.id ? blocks * 2n : blocks * 12n,
+ );
+
+ const h = Math.floor(seconds / 3600);
+ const m = Math.floor((seconds % 3600) / 60);
+ const s = seconds % 60;
+ return `${h}h${m}m${s}s`;
+}
+
+
+//check environment variables
+if (typeof process.env.OWNER_1_ADDRESS_PRIVATE_KEY === 'undefined') {
+ throw new Error(`Please provide the "OWNER_1_ADDRESS_PRIVATE_KEY" environment variable`);
+}
+
+if (typeof process.env.PARENT_CHAIN_ID === 'undefined') {
+ throw new Error(`Please provide the "PARENT_CHAIN_ID" environment variable`);
+}
+
+if (typeof process.env.SAFE_ADDRESS === 'undefined') {
+ throw new Error(`Please provide the "SAFE_ADDRESS" environment variable`);
+}
+
+if (typeof process.env.ROLLUP_ADDRESS === 'undefined') {
+ throw new Error(`Please provide the "ROLLUP_ADDRESS" environment variable`);
+}
+
+if (typeof process.env.RPC === 'undefined') {
+ throw new Error(`Please provide an "RPC" endpoint with unlimited eth_getLogs range`);
+}
+
+if (typeof process.env.MINIMUM_ASSERTION_PERIOD === 'undefined') {
+ console.log('MinimumAssertionPeriod set to 75')
+}
+
+if (typeof process.env.FC_VALIDATORS_SAFE_ADDRESS === 'undefined') {
+ throw new Error(`Please provide the "FC_VALIDATORS_SAFE_ADDRESS" environment variable (run step 1)`);
+}
+
+const minimumAssertionPeriod = BigInt(process.env.MINIMUM_ASSERTION_PERIOD || 75);
+const rollupOwnerSafeAddress = process.env.SAFE_ADDRESS as `0x${string}`;
+const rollupAddress = process.env.ROLLUP_ADDRESS as Address;
+// // set the parent chain and create a public client for it
+const parentChainId = Number(process.env.PARENT_CHAIN_ID);
+const parentChain = getParentChainFromId(parentChainId);
+const parentChainPublicClient = createPublicClient({
+ chain: parentChain,
+ transport: http(process.env.RPC),
+}).extend(
+ rollupAdminLogicPublicActions({
+ rollup: rollupAddress,
+ }),
+);
+
+async function main() {
+ //
+ // Step 0. Gather necessary data (UpgradeExecutor address)
+ //
+ const transactionHash = await createRollupFetchTransactionHash({
+ rollup: rollupAddress,
+ publicClient: parentChainPublicClient,
+ });
+ const transactionReceipt = createRollupPrepareTransactionReceipt(
+ await parentChainPublicClient.getTransactionReceipt({ hash: transactionHash }),
+ );
+ const coreContracts = transactionReceipt.getCoreContracts();
+ const upgradeExecutorAddress = coreContracts.upgradeExecutor;
+
+ console.log(
+ `Step 4: Configure the minimumAssertionPeriod in the Rollup contract to: ${Number(
+ minimumAssertionPeriod,
+ )}`,
+ );
+ console.log('---');
+
+ // get current minimumAssertionPeriod
+ const currentMinimumAssertionPeriod = await parentChainPublicClient.rollupAdminLogicReadContract({
+ functionName: 'minimumAssertionPeriod',
+ });
+
+ if (currentMinimumAssertionPeriod !== minimumAssertionPeriod) {
+ // prepare setMinimumAssertionPeriod transaction request
+ const setMinimumAssertionPeriodTransactionRequest =
+ await parentChainPublicClient.rollupAdminLogicPrepareTransactionRequest({
+ functionName: 'setMinimumAssertionPeriod',
+ args: [minimumAssertionPeriod],
+ upgradeExecutor: upgradeExecutorAddress,
+ account: rollupOwnerSafeAddress,
+ });
+ propose(setMinimumAssertionPeriodTransactionRequest.to as string, setMinimumAssertionPeriodTransactionRequest.data as string, rollupOwnerSafeAddress);
+ console.log('Transaction proposed');
+ } else {
+ console.log(
+ `Minimum assertion period is already configured to ${currentMinimumAssertionPeriod}. Skipping.`,
+ );
+ }
+ console.log('');
+
+ //
+ // Step 5. Show a confirmation message with the next steps
+ //
+ console.log(`Step 5: Configure your batch poster and your validator nodes`);
+ console.log(`---`);
+ console.log(
+ 'Your chain is now configured with a fast-withdrawal committee. The following instructions show how to configure your batch poster and your validators to start using this feature.',
+ );
+ console.log('');
+
+ // Batch poster configuration
+ const timeDelay = getTimeDelayFromNumberOfBlocks(parentChain.id, minimumAssertionPeriod);
+ console.log('Your batch poster has to run at least nitro v3.1.1');
+ console.log('Add the following parameter:');
+ console.log(`--node.batch-poster.max-delay=${timeDelay}`);
+ console.log('');
+
+ // Validator configuration
+ console.log('Your validators have to run at least nitro v3.1.1');
+ console.log('Add the following parameters:');
+ console.log(`--node.staker.enable-fast-confirmation=true`);
+ console.log(`--node.staker.fast-confirm-safe-address=${process.env.FC_VALIDATORS_SAFE_ADDRESS}`);
+ console.log(`--node.staker.make-assertion-interval=${timeDelay}`);
+ console.log('');
+
+ // Final recommendation
+ console.log('Finally, restart your batch poster and validator nodes.');
+}
+
+main();
diff --git a/examples/setup-fast-withdrawal/README.md b/examples/setup-fast-withdrawal/README.md
index d7e8663c..f3672c58 100644
--- a/examples/setup-fast-withdrawal/README.md
+++ b/examples/setup-fast-withdrawal/README.md
@@ -52,3 +52,22 @@ You need to set the following environment variables in an .env file:
```bash
yarn dev
```
+
+
+
+## Multisig ownership
+Beware: At least one of the signers needs to be an EOA account so that it can propose transactions through this script.
+
+1. Build this example: rm -rf dist/ && tsc --outDir dist && ls dist
+2. OWNER_1_ADDRESS_PRIVATE_KEY= PARENT_CHAIN_ID= SAFE_ADDRESS= FC_VALIDATORS='["0x1234567890123456789012345678901234567890"]' node ./dist/1-create_multisig.js
+This step will create a new Safe on the parent chain and add fast confirmation validators as owners.
+
+If you want to use this script then you need to make sure the owner of the Rollup has been transfered to a Multisig.
+
+3. OWNER_1_ADDRESS_PRIVATE_KEY= PARENT_CHAIN_ID= SAFE_ADDRESS= FC_VALIDATORS_SAFE_ADDRESS= FC_VALIDATORS='["0x1234567890123456789012345678901234567890"]' ROLLUP_ADDRESS= RPC= node ./dist/2-add_validators.js
+the validators list is expanded with the Safe created with step 1 (1-create_multisig). That's why you need to provide FC_VALIDATORS_SAFE_ADDRESS.
+
+4. OWNER_1_ADDRESS_PRIVATE_KEY= PARENT_CHAIN_ID= SAFE_ADDRESS= FC_VALIDATORS_SAFE_ADDRESS= ROLLUP_ADDRESS= RPC= node ./dist/3-set-any-trust-fast-confirmer.js
+We also add this Safe as `fast confirmer`.
+
+5. OWNER_1_ADDRESS_PRIVATE_KEY= PARENT_CHAIN_ID= SAFE_ADDRESS= MINIMUM_ASSERTION_PERIOD=1 ROLLUP_ADDRESS= RPC= node ./dist/4-configure-minimum-assertion-period.js
diff --git a/examples/setup-fast-withdrawal/common.ts b/examples/setup-fast-withdrawal/common.ts
new file mode 100644
index 00000000..d5ee67a7
--- /dev/null
+++ b/examples/setup-fast-withdrawal/common.ts
@@ -0,0 +1,53 @@
+import { createPublicClient, http } from 'viem';
+import { getParentChainFromId, sanitizePrivateKey } from '@arbitrum/orbit-sdk/utils';
+import SafeApiKit from '@safe-global/api-kit'
+import Safe from '@safe-global/protocol-kit'
+import { privateKeyToAccount } from 'viem/accounts';
+import {
+ MetaTransactionData,
+ OperationType
+} from '@safe-global/safe-core-sdk-types'
+
+export async function propose(to: string, data: string, rollupOwnerSafeAddress: string): Promise {
+ const parentChainId = Number(process.env.PARENT_CHAIN_ID);
+ const parentChain = getParentChainFromId(parentChainId);
+ let h = http()
+ if (typeof process.env.RPC !== 'undefined') {
+ h = http(process.env.RPC)
+ }
+ const parentChainPublicClient = createPublicClient({
+ chain: parentChain,
+ transport: h,
+ });
+
+ const safeTransactionData: MetaTransactionData = {
+ to: to as `0x${string}`,
+ value: '0',
+ data: data as `0x${string}`,
+ operation: OperationType.Call
+ }
+ const protocolKitOwner1 = await Safe.default.init({
+ provider: parentChainPublicClient.transport,
+ signer: process.env.OWNER_1_ADDRESS_PRIVATE_KEY as `${string}`,
+ safeAddress: process.env.SAFE_ADDRESS as `0x${string}`,
+ })
+ const safeTransaction = await protocolKitOwner1.createTransaction({
+ transactions: [safeTransactionData]
+ })
+ // Propose transaction to the service
+ const chainId = BigInt(String(process.env.PARENT_CHAIN_ID));
+ const apiKit = new SafeApiKit.default({
+ chainId: chainId, // set the correct chainId
+ })
+ const safeTxHash = await protocolKitOwner1.getTransactionHash(safeTransaction)
+ const signature = await protocolKitOwner1.signHash(safeTxHash)
+ const senderAddress = privateKeyToAccount(sanitizePrivateKey(process.env.OWNER_1_ADDRESS_PRIVATE_KEY as `${string}`));
+ await apiKit.proposeTransaction({
+ safeAddress: rollupOwnerSafeAddress,
+ safeTransactionData: safeTransaction.data,
+ safeTxHash,
+ senderAddress: senderAddress.address,
+ senderSignature: signature.data
+ })
+ console.log('Transaction proposed.')
+}
diff --git a/examples/setup-fast-withdrawal/tsconfig.json b/examples/setup-fast-withdrawal/tsconfig.json
index abf0a90d..7101af0f 100644
--- a/examples/setup-fast-withdrawal/tsconfig.json
+++ b/examples/setup-fast-withdrawal/tsconfig.json
@@ -1,4 +1,8 @@
{
"extends": "../tsconfig.base.json",
- "include": ["./**/*"]
+ "include": ["./**/*"],
+ "compilerOptions": {
+ "moduleResolution": "NodeNext",
+ "module": "NodeNext",
+ }
}
diff --git a/package.json b/package.json
index c93d3b55..439de957 100644
--- a/package.json
+++ b/package.json
@@ -35,5 +35,10 @@
"**/@wagmi/cli/viem/ws": "8.17.1",
"**/@ethersproject/providers/ws": "7.5.10",
"**/elliptic": "6.5.7"
+ },
+ "dependencies": {
+ "@safe-global/api-kit": "^2.4.5",
+ "@safe-global/protocol-kit": "4.0.2",
+ "@safe-global/safe-core-sdk-types": "^5.1.0"
}
}
diff --git a/src/createSafePrepareTransactionRequest.ts b/src/createSafePrepareTransactionRequest.ts
index f8b3d406..2a3c6c5a 100644
--- a/src/createSafePrepareTransactionRequest.ts
+++ b/src/createSafePrepareTransactionRequest.ts
@@ -77,7 +77,7 @@ export const SafeProxyFactoryAbi = [
*/
export type CreateSafePrepareTransactionRequestParams = {
publicClient: PublicClient;
- account: PrivateKeyAccount;
+ account: PrivateKeyAccount | `0x${string}`;
owners: Address[];
threshold: number;
saltNonce?: bigint;
@@ -92,7 +92,7 @@ export type CreateSafePrepareTransactionRequestParams = {
publicClient: PublicClient;
- account: PrivateKeyAccount;
+ account: PrivateKeyAccount | `0x${string}`;
rollup: Address;
upgradeExecutor: Address;
fastConfirmer: Address;
@@ -30,7 +30,7 @@ export type SetAnyTrustFastConfirmerPrepareTransactionRequestParams<
*
* @param {SetAnyTrustFastConfirmerPrepareTransactionRequestParams} setAnyTrustFastConfirmerPrepareTransactionRequestParams {@link SetAnyTrustFastConfirmerPrepareTransactionRequestParams}
* @param {PublicClient} setAnyTrustFastConfirmerPrepareTransactionRequestParams.publicClient - A Viem Public Client
- * @param {PrivateKeyAccount} setAnyTrustFastConfirmerPrepareTransactionRequestParams.account - The private key of the chain owner or an account with the executor role in the UpgradeExecutor
+ * @param {PrivateKeyAccount | `0x${string}`} setAnyTrustFastConfirmerPrepareTransactionRequestParams.account - The private key of the deployer of the new Safe or the address of the Safe
* @param {Address} setAnyTrustFastConfirmerPrepareTransactionRequestParams.rollup - Address of the Rollup contract
* @param {Address} setAnyTrustFastConfirmerPrepareTransactionRequestParams.upgradeExecutor - Address of the UpgradeExecutor contract
* @param {Address} setAnyTrustFastConfirmerPrepareTransactionRequestParams.fastConfirmer - Address of the fast confirmer validator (usually a Safe multisig)
diff --git a/yarn.lock b/yarn.lock
index d5c76a35..819d6c3e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -808,7 +808,17 @@
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz#5d694d345ce36b6ecf657349e03eb87297e68da4"
integrity sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==
-"@safe-global/protocol-kit@^4.0.2":
+"@safe-global/api-kit@^2.4.5":
+ version "2.4.5"
+ resolved "https://registry.yarnpkg.com/@safe-global/api-kit/-/api-kit-2.4.5.tgz#e2fb5d9b0949c8f8726e4e9f3343031ff38802b5"
+ integrity sha512-kMV6snDLSuoXLpEHKDbbURBda8iaMMDZp19uDj4d34smIUIPLE6XHpjXR+1S6i+GkaJH/kdIrCe6v4/ip/BjpQ==
+ dependencies:
+ "@safe-global/protocol-kit" "^4.1.0"
+ "@safe-global/safe-core-sdk-types" "^5.1.0"
+ ethers "^6.13.1"
+ node-fetch "^2.7.0"
+
+"@safe-global/protocol-kit@4.0.2", "@safe-global/protocol-kit@^4.0.2":
version "4.0.2"
resolved "https://registry.yarnpkg.com/@safe-global/protocol-kit/-/protocol-kit-4.0.2.tgz#5555e65359eeb5d210608aaa1ab889df15c14150"
integrity sha512-csmBR22XY0Sgx2Q6WSdRiAPj5UlR3FxrMeoAqUbV7kCzT7SVXBwrsRqLjiW2+B59Dgcxs6fR8aLjl7maweBPXw==
@@ -821,6 +831,20 @@
ethers "^6.13.1"
semver "^7.6.2"
+"@safe-global/protocol-kit@^4.1.0":
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/@safe-global/protocol-kit/-/protocol-kit-4.1.0.tgz#8ab41e179c559840f0cd6b6ae296438dabe1793f"
+ integrity sha512-WAGXEn6UvKGlEYNqcWUasLZ4240sVWBg8T2SsfHoTs8Im0x2i48CNNZ5Mw9x+oKqhWs/Q9frNG6JcycN19LDRw==
+ dependencies:
+ "@noble/hashes" "^1.3.3"
+ "@safe-global/safe-core-sdk-types" "^5.1.0"
+ "@safe-global/safe-deployments" "^1.37.3"
+ "@safe-global/safe-modules-deployments" "^2.2.1"
+ abitype "^1.0.2"
+ ethereumjs-util "^7.1.5"
+ ethers "^6.13.1"
+ semver "^7.6.2"
+
"@safe-global/safe-core-sdk-types@^5.0.2":
version "5.0.2"
resolved "https://registry.yarnpkg.com/@safe-global/safe-core-sdk-types/-/safe-core-sdk-types-5.0.2.tgz#9552f5793581333c81676986b3eb19697e1c6627"
@@ -828,6 +852,13 @@
dependencies:
abitype "^1.0.2"
+"@safe-global/safe-core-sdk-types@^5.1.0":
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/@safe-global/safe-core-sdk-types/-/safe-core-sdk-types-5.1.0.tgz#af8d877b9af231242d023c7182f78ff4223bc3f4"
+ integrity sha512-UzXR4zWmVzux25FcIm4H049QhZZpVpIBL5HE+V0p5gHpArZROL+t24fZmsKUf403CtBxIJM5zZSVQL0nFJi+IQ==
+ dependencies:
+ abitype "^1.0.2"
+
"@safe-global/safe-deployments@^1.37.0":
version "1.37.1"
resolved "https://registry.yarnpkg.com/@safe-global/safe-deployments/-/safe-deployments-1.37.1.tgz#d8293c421b1b7445899aec720061be26bb3c4976"
@@ -835,6 +866,18 @@
dependencies:
semver "^7.6.2"
+"@safe-global/safe-deployments@^1.37.3":
+ version "1.37.3"
+ resolved "https://registry.yarnpkg.com/@safe-global/safe-deployments/-/safe-deployments-1.37.3.tgz#ded9fa6bb04f0e8972c00c481badcf513d590b0b"
+ integrity sha512-EtbiOJVGe697+GcbHtfo75NYpp+hTlIIBqL2ETPLGoQBHoxo9HWbGX/6ZkVxsZv/NN4nKawyMi+MvpUkH9VXGg==
+ dependencies:
+ semver "^7.6.2"
+
+"@safe-global/safe-modules-deployments@^2.2.1":
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/@safe-global/safe-modules-deployments/-/safe-modules-deployments-2.2.1.tgz#a8b88f2afc6ec04fed09968fe1e4990ed975c86e"
+ integrity sha512-H0XpusyXVcsTuRsQSq0FoBKqRfhZH87/1DrFEmXXPXmI3fJkvxq3KpTaTTqzcqoIe/J+erwVZQUYNfL68EcvAQ==
+
"@scure/base@~1.1.0", "@scure/base@~1.1.2":
version "1.1.3"
resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.3.tgz#8584115565228290a6c6c4961973e0903bb3df2f"
@@ -2667,6 +2710,13 @@ node-domexception@^1.0.0:
resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5"
integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==
+node-fetch@^2.7.0:
+ version "2.7.0"
+ resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d"
+ integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==
+ dependencies:
+ whatwg-url "^5.0.0"
+
node-fetch@^3.3.0:
version "3.3.2"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.2.tgz#d1e889bacdf733b4ff3b2b243eb7a12866a0b78b"
@@ -3450,6 +3500,11 @@ to-regex-range@^5.0.1:
dependencies:
is-number "^7.0.0"
+tr46@~0.0.3:
+ version "0.0.3"
+ resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
+ integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
+
ts-morph@^21.0.1:
version "21.0.1"
resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-21.0.1.tgz#712302a0f6e9dbf1aa8d9cf33a4386c4b18c2006"
@@ -3645,6 +3700,19 @@ web-streams-polyfill@^3.0.3:
resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6"
integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==
+webidl-conversions@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
+ integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
+
+whatwg-url@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
+ integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==
+ dependencies:
+ tr46 "~0.0.3"
+ webidl-conversions "^3.0.0"
+
which-boxed-primitive@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6"
From 1e365f148082e9481f528a4b8c0c53cfb13fa195 Mon Sep 17 00:00:00 2001
From: Ino Murko <2582555+InoMurko@users.noreply.github.com>
Date: Mon, 28 Oct 2024 22:02:26 +0100
Subject: [PATCH 2/6] updates from upstream
---
examples/setup-fast-withdrawal/1-create_multisig.ts | 2 +-
.../4-configure-minimum-assertion-period.ts | 5 ++---
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/examples/setup-fast-withdrawal/1-create_multisig.ts b/examples/setup-fast-withdrawal/1-create_multisig.ts
index fbcc6ed4..a30d7334 100644
--- a/examples/setup-fast-withdrawal/1-create_multisig.ts
+++ b/examples/setup-fast-withdrawal/1-create_multisig.ts
@@ -73,7 +73,7 @@ async function main() {
//execute the transaction
//https://help.safe.global/en/articles/40834-verify-safe-creation
//in the executed transaction find `ProxyCreation` event
- //Data singleton : is what you're looing for
+ //Data proxy : is what you're looing for
}
main();
diff --git a/examples/setup-fast-withdrawal/4-configure-minimum-assertion-period.ts b/examples/setup-fast-withdrawal/4-configure-minimum-assertion-period.ts
index 61b496c7..1514e17c 100644
--- a/examples/setup-fast-withdrawal/4-configure-minimum-assertion-period.ts
+++ b/examples/setup-fast-withdrawal/4-configure-minimum-assertion-period.ts
@@ -129,16 +129,15 @@ async function main() {
// Batch poster configuration
const timeDelay = getTimeDelayFromNumberOfBlocks(parentChain.id, minimumAssertionPeriod);
- console.log('Your batch poster has to run at least nitro v3.1.1');
+ console.log('Your batch poster has to run at least nitro v3.1.2');
console.log('Add the following parameter:');
console.log(`--node.batch-poster.max-delay=${timeDelay}`);
console.log('');
// Validator configuration
- console.log('Your validators have to run at least nitro v3.1.1');
+ console.log('Your validators have to run at least nitro v3.1.2');
console.log('Add the following parameters:');
console.log(`--node.staker.enable-fast-confirmation=true`);
- console.log(`--node.staker.fast-confirm-safe-address=${process.env.FC_VALIDATORS_SAFE_ADDRESS}`);
console.log(`--node.staker.make-assertion-interval=${timeDelay}`);
console.log('');
From 2118ad79dabda01922bc73cab47c6e4443567301 Mon Sep 17 00:00:00 2001
From: Ino Murko <2582555+InoMurko@users.noreply.github.com>
Date: Tue, 29 Oct 2024 21:48:59 +0100
Subject: [PATCH 3/6] refactor
---
.../.env.example | 0
.../README.md | 18 ------
.../index.ts | 0
.../package.json | 0
.../tsconfig.json | 0
.../.env.example | 57 +++++++++++++++++++
.../1-create_multisig.ts | 0
.../2-add_validators.ts | 0
.../3-set-any-trust-fast-confirmer.ts | 0
.../4-configure-minimum-assertion-period.ts | 0
.../setup-fast-withdrawal-multisig/README.md | 26 +++++++++
.../common.ts | 0
.../package.json | 15 +++++
.../tsconfig.json | 8 +++
package.json | 5 --
15 files changed, 106 insertions(+), 23 deletions(-)
rename examples/{setup-fast-withdrawal => setup-fast-withdrawal-eoa}/.env.example (100%)
rename examples/{setup-fast-withdrawal => setup-fast-withdrawal-eoa}/README.md (63%)
rename examples/{setup-fast-withdrawal => setup-fast-withdrawal-eoa}/index.ts (100%)
rename examples/{setup-fast-withdrawal => setup-fast-withdrawal-eoa}/package.json (100%)
rename examples/{setup-fast-withdrawal => setup-fast-withdrawal-eoa}/tsconfig.json (100%)
create mode 100644 examples/setup-fast-withdrawal-multisig/.env.example
rename examples/{setup-fast-withdrawal => setup-fast-withdrawal-multisig}/1-create_multisig.ts (100%)
rename examples/{setup-fast-withdrawal => setup-fast-withdrawal-multisig}/2-add_validators.ts (100%)
rename examples/{setup-fast-withdrawal => setup-fast-withdrawal-multisig}/3-set-any-trust-fast-confirmer.ts (100%)
rename examples/{setup-fast-withdrawal => setup-fast-withdrawal-multisig}/4-configure-minimum-assertion-period.ts (100%)
create mode 100644 examples/setup-fast-withdrawal-multisig/README.md
rename examples/{setup-fast-withdrawal => setup-fast-withdrawal-multisig}/common.ts (100%)
create mode 100644 examples/setup-fast-withdrawal-multisig/package.json
create mode 100644 examples/setup-fast-withdrawal-multisig/tsconfig.json
diff --git a/examples/setup-fast-withdrawal/.env.example b/examples/setup-fast-withdrawal-eoa/.env.example
similarity index 100%
rename from examples/setup-fast-withdrawal/.env.example
rename to examples/setup-fast-withdrawal-eoa/.env.example
diff --git a/examples/setup-fast-withdrawal/README.md b/examples/setup-fast-withdrawal-eoa/README.md
similarity index 63%
rename from examples/setup-fast-withdrawal/README.md
rename to examples/setup-fast-withdrawal-eoa/README.md
index f3672c58..baba9ad5 100644
--- a/examples/setup-fast-withdrawal/README.md
+++ b/examples/setup-fast-withdrawal-eoa/README.md
@@ -53,21 +53,3 @@ You need to set the following environment variables in an .env file:
yarn dev
```
-
-
-## Multisig ownership
-Beware: At least one of the signers needs to be an EOA account so that it can propose transactions through this script.
-
-1. Build this example: rm -rf dist/ && tsc --outDir dist && ls dist
-2. OWNER_1_ADDRESS_PRIVATE_KEY= PARENT_CHAIN_ID= SAFE_ADDRESS= FC_VALIDATORS='["0x1234567890123456789012345678901234567890"]' node ./dist/1-create_multisig.js
-This step will create a new Safe on the parent chain and add fast confirmation validators as owners.
-
-If you want to use this script then you need to make sure the owner of the Rollup has been transfered to a Multisig.
-
-3. OWNER_1_ADDRESS_PRIVATE_KEY= PARENT_CHAIN_ID= SAFE_ADDRESS= FC_VALIDATORS_SAFE_ADDRESS= FC_VALIDATORS='["0x1234567890123456789012345678901234567890"]' ROLLUP_ADDRESS= RPC= node ./dist/2-add_validators.js
-the validators list is expanded with the Safe created with step 1 (1-create_multisig). That's why you need to provide FC_VALIDATORS_SAFE_ADDRESS.
-
-4. OWNER_1_ADDRESS_PRIVATE_KEY= PARENT_CHAIN_ID= SAFE_ADDRESS= FC_VALIDATORS_SAFE_ADDRESS= ROLLUP_ADDRESS= RPC= node ./dist/3-set-any-trust-fast-confirmer.js
-We also add this Safe as `fast confirmer`.
-
-5. OWNER_1_ADDRESS_PRIVATE_KEY= PARENT_CHAIN_ID= SAFE_ADDRESS= MINIMUM_ASSERTION_PERIOD=1 ROLLUP_ADDRESS= RPC= node ./dist/4-configure-minimum-assertion-period.js
diff --git a/examples/setup-fast-withdrawal/index.ts b/examples/setup-fast-withdrawal-eoa/index.ts
similarity index 100%
rename from examples/setup-fast-withdrawal/index.ts
rename to examples/setup-fast-withdrawal-eoa/index.ts
diff --git a/examples/setup-fast-withdrawal/package.json b/examples/setup-fast-withdrawal-eoa/package.json
similarity index 100%
rename from examples/setup-fast-withdrawal/package.json
rename to examples/setup-fast-withdrawal-eoa/package.json
diff --git a/examples/setup-fast-withdrawal/tsconfig.json b/examples/setup-fast-withdrawal-eoa/tsconfig.json
similarity index 100%
rename from examples/setup-fast-withdrawal/tsconfig.json
rename to examples/setup-fast-withdrawal-eoa/tsconfig.json
diff --git a/examples/setup-fast-withdrawal-multisig/.env.example b/examples/setup-fast-withdrawal-multisig/.env.example
new file mode 100644
index 00000000..aea0e8b2
--- /dev/null
+++ b/examples/setup-fast-withdrawal-multisig/.env.example
@@ -0,0 +1,57 @@
+#step 1
+#signer of the Safe multisignature contract that can propose a transaction
+OWNER_1_ADDRESS_PRIVATE_KEY=
+#parent chain id - 1 etheruem, 42161 arbitrum one
+PARENT_CHAIN_ID=
+#Safe multisignature contract address
+SAFE_ADDRESS=
+#stakers and validators that are whitelisted on the Rollup contract
+FC_VALIDATORS='["0x1234567890123456789012345678901234567890"]'
+
+#step 2
+#Rollup contract address
+ROLLUP_ADDRESS=
+#Safe address that was created on step 1
+FC_VALIDATORS_SAFE_ADDRESS=
+#RPC url
+RPC=
+#signer of the Safe multisignature contract that can propose a transaction
+OWNER_1_ADDRESS_PRIVATE_KEY=
+#parent chain id - 1 etheruem, 42161 arbitrum one
+PARENT_CHAIN_ID=
+#Safe multisignature contract address
+SAFE_ADDRESS=
+#stakers and validators that are whitelisted on the Rollup contract
+FC_VALIDATORS='["0x1234567890123456789012345678901234567890"]'
+
+#step 3
+#Rollup contract address
+ROLLUP_ADDRESS=
+#add Safe address that was created on step 1 as fast-confirmer (setAnyTrustFastConfirmerPrepareTransactionRequest - fastConfirmer: safeAddress)
+FC_VALIDATORS_SAFE_ADDRESS=
+#RPC url
+RPC=
+#signer of the Safe multisignature contract that can propose a transaction
+OWNER_1_ADDRESS_PRIVATE_KEY=
+#parent chain id - 1 etheruem, 42161 arbitrum one
+PARENT_CHAIN_ID=
+#Safe multisignature contract address
+SAFE_ADDRESS=
+#stakers and validators that are whitelisted on the Rollup contract
+FC_VALIDATORS='["0x1234567890123456789012345678901234567890"]'
+
+#step 4
+#Rollup contract address
+ROLLUP_ADDRESS=
+#Safe address that was created on step 1
+FC_VALIDATORS_SAFE_ADDRESS=
+#RPC url
+RPC=
+#signer of the Safe multisignature contract that can propose a transaction
+OWNER_1_ADDRESS_PRIVATE_KEY=
+#parent chain id - 1 etheruem, 42161 arbitrum one
+PARENT_CHAIN_ID=
+#Safe multisignature contract address
+SAFE_ADDRESS=
+#default is 75 (15minutes)
+MINIMUM_ASSERTION_PERIOD=1
diff --git a/examples/setup-fast-withdrawal/1-create_multisig.ts b/examples/setup-fast-withdrawal-multisig/1-create_multisig.ts
similarity index 100%
rename from examples/setup-fast-withdrawal/1-create_multisig.ts
rename to examples/setup-fast-withdrawal-multisig/1-create_multisig.ts
diff --git a/examples/setup-fast-withdrawal/2-add_validators.ts b/examples/setup-fast-withdrawal-multisig/2-add_validators.ts
similarity index 100%
rename from examples/setup-fast-withdrawal/2-add_validators.ts
rename to examples/setup-fast-withdrawal-multisig/2-add_validators.ts
diff --git a/examples/setup-fast-withdrawal/3-set-any-trust-fast-confirmer.ts b/examples/setup-fast-withdrawal-multisig/3-set-any-trust-fast-confirmer.ts
similarity index 100%
rename from examples/setup-fast-withdrawal/3-set-any-trust-fast-confirmer.ts
rename to examples/setup-fast-withdrawal-multisig/3-set-any-trust-fast-confirmer.ts
diff --git a/examples/setup-fast-withdrawal/4-configure-minimum-assertion-period.ts b/examples/setup-fast-withdrawal-multisig/4-configure-minimum-assertion-period.ts
similarity index 100%
rename from examples/setup-fast-withdrawal/4-configure-minimum-assertion-period.ts
rename to examples/setup-fast-withdrawal-multisig/4-configure-minimum-assertion-period.ts
diff --git a/examples/setup-fast-withdrawal-multisig/README.md b/examples/setup-fast-withdrawal-multisig/README.md
new file mode 100644
index 00000000..87a001f7
--- /dev/null
+++ b/examples/setup-fast-withdrawal-multisig/README.md
@@ -0,0 +1,26 @@
+
+
+## Multisig ownership
+Beware: At least one of the signers needs to be an EOA account so that it can propose transactions through this script.
+If you want to use this script then you need to make sure the owner of the Rollup has been transfered to a Multisig contract and it has execution rights on L1 Executor Contract.
+
+1. Build this example: yarn dev
+2. This step will create a new Safe on the parent chain and add fast confirmation validators as owners.
+```
+node ./dist/1-create_multisig.js
+```
+3. The validators list is expanded with the Safe created with step 1 (1-create_multisig). That's why you need to provide FC_VALIDATORS_SAFE_ADDRESS.
+```
+node ./dist/2-add_validators.js
+```
+
+4. We also add Safe as `fast confirmer`.
+```
+node ./dist/3-set-any-trust-fast-confirmer.js
+```
+
+
+5. Configure minimum assertion period. The default is 75 (~15 minutes)
+```
+node ./dist/4-configure-minimum-assertion-period.js
+```
diff --git a/examples/setup-fast-withdrawal/common.ts b/examples/setup-fast-withdrawal-multisig/common.ts
similarity index 100%
rename from examples/setup-fast-withdrawal/common.ts
rename to examples/setup-fast-withdrawal-multisig/common.ts
diff --git a/examples/setup-fast-withdrawal-multisig/package.json b/examples/setup-fast-withdrawal-multisig/package.json
new file mode 100644
index 00000000..1377971b
--- /dev/null
+++ b/examples/setup-fast-withdrawal-multisig/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "setup-fast-withdrawal",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "tsc --outDir dist"
+ },
+ "devDependencies": {
+ "@types/node": "^20.9.0",
+ "typescript": "^5.2.2",
+ "@safe-global/api-kit": "^2.4.5",
+ "@safe-global/safe-core-sdk-types": "^5.1.0"
+ }
+}
diff --git a/examples/setup-fast-withdrawal-multisig/tsconfig.json b/examples/setup-fast-withdrawal-multisig/tsconfig.json
new file mode 100644
index 00000000..7101af0f
--- /dev/null
+++ b/examples/setup-fast-withdrawal-multisig/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "extends": "../tsconfig.base.json",
+ "include": ["./**/*"],
+ "compilerOptions": {
+ "moduleResolution": "NodeNext",
+ "module": "NodeNext",
+ }
+}
diff --git a/package.json b/package.json
index 439de957..c93d3b55 100644
--- a/package.json
+++ b/package.json
@@ -35,10 +35,5 @@
"**/@wagmi/cli/viem/ws": "8.17.1",
"**/@ethersproject/providers/ws": "7.5.10",
"**/elliptic": "6.5.7"
- },
- "dependencies": {
- "@safe-global/api-kit": "^2.4.5",
- "@safe-global/protocol-kit": "4.0.2",
- "@safe-global/safe-core-sdk-types": "^5.1.0"
}
}
From dcd18247d08283e324ef512f059dee070206ed0d Mon Sep 17 00:00:00 2001
From: Ino Murko
Date: Wed, 30 Oct 2024 12:35:35 +0100
Subject: [PATCH 4/6] Update tsconfig.json
---
examples/setup-fast-withdrawal-eoa/tsconfig.json | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/examples/setup-fast-withdrawal-eoa/tsconfig.json b/examples/setup-fast-withdrawal-eoa/tsconfig.json
index 7101af0f..abf0a90d 100644
--- a/examples/setup-fast-withdrawal-eoa/tsconfig.json
+++ b/examples/setup-fast-withdrawal-eoa/tsconfig.json
@@ -1,8 +1,4 @@
{
"extends": "../tsconfig.base.json",
- "include": ["./**/*"],
- "compilerOptions": {
- "moduleResolution": "NodeNext",
- "module": "NodeNext",
- }
+ "include": ["./**/*"]
}
From 0791a795f84605b27813edb2c4d2d257632e5006 Mon Sep 17 00:00:00 2001
From: Ino Murko
Date: Thu, 31 Oct 2024 12:28:07 +0100
Subject: [PATCH 5/6] Update src/createSafePrepareTransactionRequest.ts
Co-authored-by: spsjvc
---
src/createSafePrepareTransactionRequest.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/createSafePrepareTransactionRequest.ts b/src/createSafePrepareTransactionRequest.ts
index 2a3c6c5a..0684ec46 100644
--- a/src/createSafePrepareTransactionRequest.ts
+++ b/src/createSafePrepareTransactionRequest.ts
@@ -77,7 +77,7 @@ export const SafeProxyFactoryAbi = [
*/
export type CreateSafePrepareTransactionRequestParams = {
publicClient: PublicClient;
- account: PrivateKeyAccount | `0x${string}`;
+ account: Address;
owners: Address[];
threshold: number;
saltNonce?: bigint;
From ebbf155381dc066e1e438a088c8442fb4a189482 Mon Sep 17 00:00:00 2001
From: Ino Murko
Date: Thu, 31 Oct 2024 12:28:21 +0100
Subject: [PATCH 6/6] Update
src/setAnyTrustFastConfirmerPrepareTransactionRequest.ts
Co-authored-by: spsjvc
---
src/setAnyTrustFastConfirmerPrepareTransactionRequest.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/setAnyTrustFastConfirmerPrepareTransactionRequest.ts b/src/setAnyTrustFastConfirmerPrepareTransactionRequest.ts
index 1bf2c7cc..b6beeb89 100644
--- a/src/setAnyTrustFastConfirmerPrepareTransactionRequest.ts
+++ b/src/setAnyTrustFastConfirmerPrepareTransactionRequest.ts
@@ -17,7 +17,7 @@ export type SetAnyTrustFastConfirmerPrepareTransactionRequestParams<
TChain extends Chain | undefined,
> = {
publicClient: PublicClient;
- account: PrivateKeyAccount | `0x${string}`;
+ account: Address;
rollup: Address;
upgradeExecutor: Address;
fastConfirmer: Address;