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

Safe module tutorial #670

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open

Safe module tutorial #670

wants to merge 14 commits into from

Conversation

akshay-ap
Copy link
Member

@akshay-ap akshay-ap commented Jan 8, 2025

Fixes: https://github.com/orgs/safe-global/projects/29/views/1?pane=issue&itemId=92625006&issue=safe-global%7Cdeveloper-experience%7C328

Changes in PR:

  • Add step by step tutorial to create a Safe Module
  • Add step by step tutorial to create UI for the module

@akshay-ap akshay-ap self-assigned this Jan 8, 2025
@akshay-ap akshay-ap marked this pull request as draft January 8, 2025 12:50
Copy link

github-actions bot commented Jan 8, 2025

Branch preview

✅ Deployed successfully in branch deployment:

https://feature_safe_module_tutorial--docs.review.5afe.dev

Copy link

github-actions bot commented Jan 8, 2025

Overall readability score: 31.4 (🟢 +0.08)

File Readability
smart-account-modules-tutorial.mdx 58.29 (-)
View detailed metrics

🟢 - Shows an increase in readability
🔴 - Shows a decrease in readability

File Readability FRE GF ARI CLI DCRS
smart-account-modules-tutorial.mdx 58.29 42.98 8.75 11.4 13.9 7.57
  - - - - - -

Averages:

  Readability FRE GF ARI CLI DCRS
Average 31.4 27.33 13.69 17.42 15.73 8.97
  🟢 +0.08 🟢 +0.05 🟢 +0.02 🟢 +0.02 🟢 +0.01 🟢 +0
View metric targets
Metric Range Ideal score
Flesch Reading Ease 100 (very easy read) to 0 (extremely difficult read) 60
Gunning Fog 6 (very easy read) to 17 (extremely difficult read) 8 or less
Auto. Read. Index 6 (very easy read) to 14 (extremely difficult read) 8 or less
Coleman Liau Index 6 (very easy read) to 17 (extremely difficult read) 8 or less
Dale-Chall Readability 4.9 (very easy read) to 9.9 (extremely difficult read) 6.9 or less

@akshay-ap akshay-ap marked this pull request as ready for review January 9, 2025 15:05

Before progressing with the tutorial, please make sure you have the following:

- Downloaded and installed [Node.js](https://nodejs.org/en/download/package-manager) and [pnpm](https://pnpm.io/installation).
Copy link
Member

Choose a reason for hiding this comment

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

here it mentions pnpm but then throughout the tutorial npm is used


```json
...
"overrides": {
Copy link
Member

Choose a reason for hiding this comment

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

I think you can include a more specific overide:

  "overrides": {
    "@safe-global/safe-contracts": {
      "ethers": "^6.13.5"
    }
  }


### Initialize hardhat project

Select create TypeScript project.
Copy link
Member

Choose a reason for hiding this comment

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

should be after calling the init command right?

Copy link
Collaborator

Choose a reason for hiding this comment

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

yes.

Copy link
Collaborator

Choose a reason for hiding this comment

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

The other options to choose should be namen, too.

(If it is possible to start with an empty hardhat.config, because it gets overwritten in the next step, this option should be chosen because it is easiest.


### Update hardhat.config.ts

When compiling Safe contracts with solidity 0.8.x the bytecode size exceeds the limit of 24KB. To overcome this, set `allowUnlimitedContractSize` to `true` in the hardhat config.
Copy link
Member

Choose a reason for hiding this comment

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

this means after the tutorial the contract will not be deployable to public networks, not sure if this is a good experience

Copy link
Member Author

Choose a reason for hiding this comment

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

In practice, users will only deploy module code and not the Safe contracts.

);

bytes32 hash = keccak256(
abi.encodePacked("\x19\x01", getDomainSeparator(), signatureData)
Copy link
Member

Choose a reason for hiding this comment

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

getDomainSeparator is used here but only added in the next step. I'd define everything that's needed for signing first


```solidity
function getDomainSeparator() private view returns (bytes32) {
uint256 chainId;
Copy link
Member

Choose a reason for hiding this comment

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

in 0.8.x block.chainid can be used

Copy link
Collaborator

@valle-xyz valle-xyz left a comment

Choose a reason for hiding this comment

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

Overall a great tutorial. I especially like the gradual process, as it focusses the learner's attention on the individual added code blocks.

There seems to be an issue with TestToken which is not part of the tutorial code, which needs to be resolved.

  TokenTransferModule Tests
    1) "before all" hook for "Should successfully transfer tokens to bob"


  0 passing (594ms)
  1 failing

  1) TokenTransferModule Tests
       "before all" hook for "Should successfully transfer tokens to bob":
     HardhatError: HH700: Artifact for contract "TestToken" not found. 


This tutorial will guide creating a Safe Module that allows users to withdraw ERC20 tokens from a Safe account, provided that the Safe owners have given their approval in the form of off-chain signatures. The primary use case is to enable beneficiaries to withdraw tokens themselves without requiring the Safe owners to execute transactions directly.

### Use cases
Copy link
Collaborator

Choose a reason for hiding this comment

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

This list is a duplication of the text above. Choose either one (I would go with the text).

### Limitations
- Beneficiaries must be externally owned accounts (EOAs) and cannot be smart contracts.
- The nonce is sequential for simplicity
- The contract will work only for specific token and Safe address provided during deployment.
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is gramatically incorrect or hard to understand. (I recommend running all of the text through ChatGPT).

```

```bash
npm init
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you add a line like "you can choose all default values".

Also, it would be nice to have a line that says, "add npm-modules to .gitignore." Or you leave out the git init command.


### Initialize hardhat project

Select create TypeScript project.
Copy link
Collaborator

Choose a reason for hiding this comment

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

yes.


### Initialize hardhat project

Select create TypeScript project.
Copy link
Collaborator

Choose a reason for hiding this comment

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

The other options to choose should be namen, too.

(If it is possible to start with an empty hardhat.config, because it gets overwritten in the next step, this option should be chosen because it is easiest.


Create a new file named `utils.ts` in the `test/utils` directory and include the code below. This file contains utility functions to generate the EIP-712 digest and execute transaction through the Safe account.

```typescript
Copy link
Collaborator

Choose a reason for hiding this comment

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

This file is wordy :D Does it have to be so wordy? Do the digest and the other hashes need to be generated on the spot, or are they constant? Is there any way to shorten the code and make it more easy to understand?

};
```

#### Step 3: Setup contracts and variables
Copy link
Collaborator

Choose a reason for hiding this comment

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

Change the order, so that it is code first, and then explanation to be consistent.
Also, only include the before section, because the import scripts are added in the skeleton file.


```

#### Step 4: Add test case
Copy link
Collaborator

Choose a reason for hiding this comment

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

As above, change the order, so it is code first, and then the explanation.

import { expect } from "chai";
import { Signer, ZeroAddress } from "ethers";
import { Safe__factory, TestToken, TokenWithdrawModule } from "../typechain-types";
import { SafeTransaction } from "@safe-global/safe-contracts";
Copy link
Collaborator

Choose a reason for hiding this comment

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

Remove this line. This import is not used and the line is removed from the complete file.

import { ethers } from "hardhat";
import { expect } from "chai";
import { Signer, ZeroAddress } from "ethers";
import { Safe__factory, TestToken, TokenWithdrawModule } from "../typechain-types";
Copy link
Collaborator

Choose a reason for hiding this comment

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

I get an error here. Module '"../typechain-types"' has no exported member 'TestToken'.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants