Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add Delegation Signing Script #28

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 32 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,13 +1,42 @@

# Required for scripts
# Key used for signing transactions
PRIVATE_KEY=
# Salt used for CREATE2 contract deployments
SALT=
# The entrypoint in use for hte Delegation Framework
ENTRYPOINT_ADDRESS=0x0000000071727De22E5E9d8BAf0edAc6f37da032


# Required for deploying Caveat Enforcer contracts
DELEGATION_MANAGER_ADDRESS=

# Required for deploying instances of MultiSigDeleGators
MULTISIG_DELEGATOR_IMPLEMENTATION_ADDRESS=

# Required if broadcasting to Mainnet RPC URLs
MAINNET_RPC_URL=
LINEA_RPC_URL=
ARBITRUM_RPC_URL=
AVALANCHE_RPC_URL=
BASE_RPC_URL=
OPTIMISM_RPC_URL=
POLYGON_RPC_URL=

# Required if broadcasting to Testnet RPC URLs
ANVIL_RPC_URL=
SEPOLIA_RPC_URL=
LINEA_GOERLI_RPC_URL=
LINEA_SEPOLIA_RPC_URL=
BASE_SEPOLIA_RPC_URL=

# Required for verifying contracts
ETHERSCAN_API_KEY=
OPTIMISTIC_ETHERSCAN_API_KEY=
POLYGONSCAN_API_KEY=
ARBISCAN_API_KEY=
LINEASCAN_API_KEY=
BASESCAN_API_KEY=

# RPC URLs
MAINNET_RPC_URL=https://mainnet.infura.io/v3/
LINEA_RPC_URL=https://linea-mainnet.infura.io/v3/
# Required for signing delegation script (uint256)
SIGNER_PRIVATE_KEY=
117 changes: 117 additions & 0 deletions script/SignDelegation.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// SPDX-License-Identifier: MIT AND Apache-2.0
pragma solidity 0.8.23;

import "forge-std/Script.sol";
import { console2 } from "forge-std/console2.sol";
import { IEntryPoint } from "@account-abstraction/interfaces/IEntryPoint.sol";
import { MessageHashUtils } from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";

import { Delegation, Caveat } from "../src/utils/Types.sol";
import { DelegationManager } from "../src/DelegationManager.sol";
import { SigningUtilsLib } from "../test/utils/SigningUtilsLib.t.sol";
import { EncoderLib } from "../src/libraries/EncoderLib.sol";
import { MultiSigDeleGator } from "../src/MultiSigDeleGator.sol";
import { HybridDeleGator } from "../src/HybridDeleGator.sol";
import { IDelegationManager } from "../src/interfaces/IDelegationManager.sol";
Comment on lines +4 to +15
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some unused imports

Suggested change
import "forge-std/Script.sol";
import { console2 } from "forge-std/console2.sol";
import { IEntryPoint } from "@account-abstraction/interfaces/IEntryPoint.sol";
import { MessageHashUtils } from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
import { Delegation, Caveat } from "../src/utils/Types.sol";
import { DelegationManager } from "../src/DelegationManager.sol";
import { SigningUtilsLib } from "../test/utils/SigningUtilsLib.t.sol";
import { EncoderLib } from "../src/libraries/EncoderLib.sol";
import { MultiSigDeleGator } from "../src/MultiSigDeleGator.sol";
import { HybridDeleGator } from "../src/HybridDeleGator.sol";
import { IDelegationManager } from "../src/interfaces/IDelegationManager.sol";
import "forge-std/Script.sol";
import { console2 } from "forge-std/console2.sol";
import { MessageHashUtils } from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
import { Delegation, Caveat } from "../src/utils/Types.sol";
import { DelegationManager } from "../src/DelegationManager.sol";
import { SigningUtilsLib } from "../test/utils/SigningUtilsLib.t.sol";
import { EncoderLib } from "../src/libraries/EncoderLib.sol";


// This is the domain struct used for EIP712 signing.
struct Domain {
string name;
string version;
uint256 chainId;
address verifyingContract;
}

/**
* @title SignDelegation
* @notice Produces a signature for a given delegation and private key.
* @dev Fill in necessary config in the run function and inside the .env file.
* @dev forge script script/SignDelegation.s.sol
*/
contract SignDelegation is Script {
using MessageHashUtils for bytes32;

// Constant value dependent on the DelegationManager implementation
bytes32 ROOT_AUTHORITY = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
bytes32 salt;
address signer;
uint256 privateKey;

function setUp() public {
privateKey = vm.envUint("SIGNER_PRIVATE_KEY");
console2.log("~~~");
console2.log("Signer:");
console2.log(vm.addr(privateKey));
}

function run() public view {
console2.log("~~~");

///////////////////////////////////////////// Config /////////////////////////////////////////////

// The domain of the DelegationManager that this delegation is tied to
Domain memory domain = Domain({
name: "DelegationManager",
version: "1",
chainId: 31337,
Copy link
Contributor

@hanzel98 hanzel98 Oct 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be better to use block.chainid or pass the chainId as part of .env, or some initial configuration section in this file

verifyingContract: address(0x687137B4C3C05F90c2e372DCd7700f088d1De708)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be better to pass it as part of .env or some initial configuration section in this file

});

// The delegation to sign
Caveat[] memory caveats = new Caveat[](0);
Delegation memory delegation = Delegation({
delegate: address(0x6c722F91Fd91219a4939e4f5176a119388Cc556b),
delegator: address(0x8741DD57847F94E519820cD54D5F90eC2FB7F6b9),
authority: ROOT_AUTHORITY,
caveats: caveats,
salt: 0,
signature: hex""
});

/////////////////////////////////////////////////////////////////////////////////////////////////

// Compute the hash of the delegation to sign
bytes32 domainSeparator_ = computeDomainSeparator(domain);

// For testing purposes to validate alignment with external SDKs.
// bytes32 delegationHash_ = EncoderLib._getDelegationHash(delegation_);
// bytes32 typedDataHash_ = MessageHashUtils.toTypedDataHash(domainSeparator_, delegationHash_);
// console2.log("domainSeparator_:");
// console2.logBytes32(domainSeparator_);
// console2.log("delegationHash_:");
// console2.logBytes32(delegationHash_);
// console2.log("typedDataHash_:");
// console2.logBytes32(typedDataHash_);

bytes memory signature_ = signDelegation(delegation, domainSeparator_, privateKey);

console2.log("Signature:");
console2.logBytes(signature_);
}

function signDelegation(
Delegation memory delegation_,
bytes32 domainSeparator_,
uint256 privateKey_
)
public
pure
returns (bytes memory signature_)
{
bytes32 delegationHash_ = EncoderLib._getDelegationHash(delegation_);
bytes32 typedDataHash_ = MessageHashUtils.toTypedDataHash(domainSeparator_, delegationHash_);
signature_ = SigningUtilsLib.signHash_EOA(privateKey_, typedDataHash_);
}

function computeDomainSeparator(Domain memory domain_) public pure returns (bytes32) {
return keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(domain_.name)),
keccak256(bytes(domain_.version)),
domain_.chainId,
domain_.verifyingContract
)
);
}
}
Loading