Skip to content

Commit

Permalink
Merge 6b390de into b369f75
Browse files Browse the repository at this point in the history
  • Loading branch information
DaniSomoza committed Dec 13, 2023
2 parents b369f75 + 6b390de commit 3c95fdb
Show file tree
Hide file tree
Showing 30 changed files with 4,314 additions and 459 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"tsc-alias": "^1.8.8",
"typescript": "^4.9.5"
"typescript": "^5.3.2"
},
"lint-staged": {
"./packages/**/*.{js,jsx,ts,tsx}": [
Expand Down
2 changes: 1 addition & 1 deletion packages/onramp-kit/example/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"@types/react-dom": "^18.2.14",
"@vitejs/plugin-react": "^3.1.0",
"rollup-plugin-polyfill-node": "^0.12.0",
"typescript": "^4.9.5",
"typescript": "^5.3.2",
"vite": "^4.5.0",
"vite-plugin-node-polyfills": "^0.16.0"
}
Expand Down
2 changes: 1 addition & 1 deletion packages/onramp-kit/example/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@
"@types/node": "^18.18.8",
"nodemon": "^2.0.22",
"ts-node": "^10.9.1",
"typescript": "^4.9.5"
"typescript": "^5.3.2"
}
}
1 change: 1 addition & 0 deletions packages/protocol-kit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"@types/semver": "^7.5.4",
"@types/web3": "1.0.20",
"@types/yargs": "^16.0.7",
"abitype": "^0.10.2",
"chai": "^4.3.10",
"chai-as-promised": "^7.1.1",
"coveralls": "^3.1.1",
Expand Down
7 changes: 5 additions & 2 deletions packages/protocol-kit/scripts/generateTypechainFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const safeContracts_V1_4_1 = [
`${safeContractsPath}/v1.4.1/simulate_tx_accessor.json`
].join(' ')
const safeContracts_V1_3_0 = [
`${safeContractsPath}/v1.3.0/gnosis_safe.json`,
// `${safeContractsPath}/v1.3.0/gnosis_safe.json`, // Remove contract 1.3.0 from typechain as it's migrated to Abitype
`${safeContractsPath}/v1.3.0/proxy_factory.json`,
`${safeContractsPath}/v1.3.0/multi_send.json`,
`${safeContractsPath}/v1.3.0/multi_send_call_only.json`,
Expand Down Expand Up @@ -103,7 +103,10 @@ function generateTypes(typechainTarget: string) {
generateTypechainFiles(
typechainTarget,
`${outDirSrc}${typechainTarget}/v1.4.1`,
safeContracts_V1_4_1
// Remove Safe Contract v1.4.1 for web3-v1
typechainTarget === 'web3-v1'
? safeContracts_V1_4_1.replace(`${safeContractsPath}/v1.4.1/safe.json `, '')
: safeContracts_V1_4_1
)
generateTypechainFiles(
typechainTarget,
Expand Down
69 changes: 69 additions & 0 deletions packages/protocol-kit/src/adapters/SafeBaseContract.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import {
contractName,
safeDeploymentsL1ChainIds,
getContractDeployment
} from '@safe-global/protocol-kit/contracts/config'
import { SafeVersion } from 'packages/safe-core-sdk-types'

/**
* Abstract class SafeBaseContract serves as a base for creating a Safe contract for a specific adapter (Ethers.js, Web3.js, or viem.js)
* This class is designed to be extended by adapter-specific abstract classes, such as SafeBaseContractEthers, SafeBaseContractWeb3, and SafeBaseContractViem.
* It includes the core logic for selecting the appropriate ABI and the address from Safe deployments and determining the correct L1 or L2 contract version of the Safe.
*
* @template SafeContractAbiType - The ABI associated with the Safe contract.
*
* Example subclasses extending this base class:
* - SafeBaseContractEthers<SafeContract_v1_3_0_Abi> extends SafeBaseContract<SafeContract_v1_3_0_Abi>
* - SafeBaseContractWeb3<SafeContract_v1_3_0_Abi> extends SafeBaseContract<SafeContract_v1_3_0_Abi>
* - SafeBaseContractViem<SafeContract_v1_3_0_Abi> extends SafeBaseContract<SafeContract_v1_3_0_Abi>
*/
abstract class SafeBaseContract<SafeContractAbiType> {
contractAbi: SafeContractAbiType
contractAddress: string

contractName: contractName
abstract safeVersion: SafeVersion

abstract contract: unknown // This needs to be implemented for each adapter.
abstract adapter: unknown // This needs to be implemented for each adapter.

/**
* Constructs a new SafeBaseContract instance.
*
* @param chainId - The chain ID of the contract.
* @param defaultAbi - The hardcoded ABI of the Safe contract.
* @param safeVersion - The version of the Safe contract.
* @param isL1SafeSingleton - Flag to indicate if it's an L1 Safe Singleton.
* @param customContractAddress - Optional custom address for the contract.
* @param customContractAbi - Optional custom ABI for the contract.
* @throws Will throw an error if the contract address is invalid.
*/
constructor(
chainId: bigint,
defaultAbi: SafeContractAbiType,
safeVersion: SafeVersion,
isL1SafeSingleton = false,
customContractAddress?: string,
customContractAbi?: SafeContractAbiType
) {
const isL1Contract = safeDeploymentsL1ChainIds.includes(chainId) || isL1SafeSingleton

this.contractName = isL1Contract ? 'safeSingletonVersion' : 'safeSingletonL2Version'

const singletonDeployment = getContractDeployment(safeVersion, chainId, this.contractName)

const contractAddress = customContractAddress || singletonDeployment?.defaultAddress

if (!contractAddress) {
throw new Error('Invalid SafeProxy contract address')
}

this.contractAddress = contractAddress
this.contractAbi =
customContractAbi ||
(singletonDeployment?.abi as SafeContractAbiType) || // this cast is required because abi is set as any[] in safe-deployments
defaultAbi // if no customAbi and no abi is present in the safe-deployments we use our hardcoded abi
}
}

export default SafeBaseContract
13 changes: 11 additions & 2 deletions packages/protocol-kit/src/adapters/ethers/EthersAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ class EthersAdapter implements EthAdapter {
async getSafeContract({
safeVersion,
singletonDeployment,
customContractAddress
customContractAddress,
customContractAbi,
isL1SafeSingleton
}: GetContractProps): Promise<SafeContractEthers> {
const chainId = await this.getChainId()
const contractAddress =
Expand All @@ -104,7 +106,14 @@ class EthersAdapter implements EthAdapter {
throw new Error('Invalid SafeProxy contract address')
}
const signerOrProvider = this.#signer || this.#provider
return getSafeContractInstance(safeVersion, contractAddress, signerOrProvider)
return getSafeContractInstance(
safeVersion,
contractAddress,
signerOrProvider,
this,
customContractAbi,
isL1SafeSingleton
)
}

async getSafeProxyFactoryContract({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { Contract, InterfaceAbi } from 'ethers'

import EthersAdapter from '@safe-global/protocol-kit/adapters/ethers/EthersAdapter'
import { SafeVersion } from 'packages/safe-core-sdk-types'
import SafeBaseContract from '@safe-global/protocol-kit/adapters/SafeBaseContract'

/**
* Abstract class SafeBaseContractEthers extends SafeBaseContract to specifically integrate with the Ethers.js v6 library.
* It is designed to be instantiated for different versions of the Safe contract.
*
* This abstract class sets up the Ethers v6 Contract object that interacts with a Safe contract version.
*
* Subclasses of SafeBaseContractEthers are expected to represent specific versions of the Safe contract.
*
* @template SafeContractAbiType - The ABI type specific to the version of the Safe contract, extending InterfaceAbi from Ethers.
* @extends SafeBaseContract<SafeContractAbiType> - Extends the generic SafeBaseContract with Ethers-specific implementation.
*
* Example subclasses:
* - SafeContract_v1_4_1_Ethers extends SafeBaseContractEthers<SafeContract_v1_4_1_Abi>
* - SafeContract_v1_3_0_Ethers extends SafeBaseContractEthers<SafeContract_v1_3_0_Abi>
* - SafeContract_v1_2_0_Ethers extends SafeBaseContractEthers<SafeContract_v1_2_0_Abi>
* - SafeContract_v1_1_1_Ethers extends SafeBaseContractEthers<SafeContract_v1_1_1_Abi>
* - SafeContract_v1_0_0_Ethers extends SafeBaseContractEthers<SafeContract_v1_0_0_Abi>
*/
abstract class SafeBaseContractEthers<
SafeContractAbiType extends InterfaceAbi
> extends SafeBaseContract<SafeContractAbiType> {
contract: Contract
adapter: EthersAdapter

/**
* @constructor
* Constructs an instance of SafeBaseContractEthers.
*
* @param chainId - The chain ID of the contract.
* @param ethersAdapter - An instance of EthersAdapter.
* @param defaultAbi - The default ABI for the Safe contract. It should be compatible with the specific version of the Safe contract.
* @param safeVersion - The version of the Safe contract.
* @param isL1SafeSingleton - A flag indicating if the contract is a L1 Safe Singleton.
* @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the Safe deployments based on the chainId and safeVersion.
* @param customContractAbi - Optional custom ABI for the contract. If not provided, the ABI is derived from the Safe deployments or the defaultAbi is used.
*/
constructor(
chainId: bigint,
ethersAdapter: EthersAdapter,
defaultAbi: SafeContractAbiType,
safeVersion: SafeVersion,
isL1SafeSingleton = false,
customContractAddress?: string,
customContractAbi?: SafeContractAbiType
) {
super(
chainId,
defaultAbi,
safeVersion,
isL1SafeSingleton,
customContractAddress,
customContractAbi
)

this.adapter = ethersAdapter
this.contract = new Contract(this.contractAddress, this.contractAbi, this.adapter.getSigner())
}
}

export default SafeBaseContractEthers
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ import { toTxResult } from '@safe-global/protocol-kit/adapters/ethers/utils'
import { Gnosis_safe as Safe_V1_0_0 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.0.0/Gnosis_safe'
import { Gnosis_safe as Safe_V1_1_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.1.1/Gnosis_safe'
import { Gnosis_safe as Safe_V1_2_0 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.2.0/Gnosis_safe'
import {
Gnosis_safeInterface as SafeInterface,
Gnosis_safe as Safe_V1_3_0
} from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.3.0/Gnosis_safe'
import { Safe as Safe_V1_4_1 } from '@safe-global/protocol-kit/typechain/src/ethers-v6/v1.4.1/Safe'
import {
SafeContract,
Expand All @@ -20,9 +16,7 @@ import {
} from '@safe-global/safe-core-sdk-types'

abstract class SafeContractEthers implements SafeContract {
constructor(
public contract: Safe_V1_4_1 | Safe_V1_3_0 | Safe_V1_2_0 | Safe_V1_1_1 | Safe_V1_0_0
) {}
constructor(public contract: Safe_V1_4_1 | Safe_V1_2_0 | Safe_V1_1_1 | Safe_V1_0_0) {}

abstract setup(
setupConfig: SafeSetupConfig,
Expand Down Expand Up @@ -170,7 +164,7 @@ abstract class SafeContractEthers implements SafeContract {
return toTxResult(txResponse, options)
}

encode: SafeInterface['encodeFunctionData'] = (methodName: any, params: any): string => {
encode = (methodName: any, params: any): string => {
return this.contract.interface.encodeFunctionData(methodName, params)
}

Expand Down

This file was deleted.

Loading

0 comments on commit 3c95fdb

Please sign in to comment.