diff --git a/packages/api-kit/package.json b/packages/api-kit/package.json index dfb7f8ff6..8ec5b808b 100644 --- a/packages/api-kit/package.json +++ b/packages/api-kit/package.json @@ -1,6 +1,6 @@ { "name": "@safe-global/api-kit", - "version": "2.5.1", + "version": "2.5.4", "description": "SDK that facilitates the interaction with the Safe Transaction Service API", "main": "dist/src/index.js", "typings": "dist/src/index.d.ts", @@ -39,8 +39,8 @@ ], "homepage": "https://github.com/safe-global/safe-core-sdk#readme", "devDependencies": { - "@safe-global/relay-kit": "^3.2.1", - "@safe-global/testing-kit": "^0.1.0", + "@safe-global/relay-kit": "^3.2.4", + "@safe-global/testing-kit": "^0.1.1", "@types/chai": "^4.3.19", "@types/chai-as-promised": "^7.1.8", "@types/mocha": "^10.0.8", @@ -58,7 +58,7 @@ "web3": "^4.12.1" }, "dependencies": { - "@safe-global/protocol-kit": "^5.0.1", + "@safe-global/protocol-kit": "^5.0.4", "@safe-global/types-kit": "^1.0.0", "node-fetch": "^2.7.0", "viem": "^2.21.8" diff --git a/packages/api-kit/src/SafeApiKit.ts b/packages/api-kit/src/SafeApiKit.ts index e7bd087ac..be9089339 100644 --- a/packages/api-kit/src/SafeApiKit.ts +++ b/packages/api-kit/src/SafeApiKit.ts @@ -12,6 +12,7 @@ import { ListOptions, ModulesResponse, OwnerResponse, + PendingTransactionsOptions, ProposeTransactionProps, SafeCreationInfoResponse, SafeDelegateListResponse, @@ -528,7 +529,7 @@ class SafeApiKit { * Returns the list of multi-signature transactions that are waiting for the confirmation of the Safe owners. * * @param safeAddress - The Safe address - * @param currentNonce - Current nonce of the Safe + * @param currentNonce - Deprecated, use inside object property: Current nonce of the Safe. * @returns The list of transactions waiting for the confirmation of the Safe owners * @throws "Invalid Safe address" * @throws "Invalid data" @@ -537,15 +538,70 @@ class SafeApiKit { async getPendingTransactions( safeAddress: string, currentNonce?: number + ): Promise + /** + * Returns the list of multi-signature transactions that are waiting for the confirmation of the Safe owners. + * + * @param safeAddress - The Safe address + * @param {PendingTransactionsOptions} options The options to filter the list of transactions + * @returns The list of transactions waiting for the confirmation of the Safe owners + * @throws "Invalid Safe address" + * @throws "Invalid data" + * @throws "Invalid ethereum address" + */ + async getPendingTransactions( + safeAddress: string, + { currentNonce, hasConfirmations, ordering, limit, offset }: PendingTransactionsOptions + ): Promise + async getPendingTransactions( + safeAddress: string, + propsOrCurrentNonce: PendingTransactionsOptions | number = {} ): Promise { if (safeAddress === '') { throw new Error('Invalid Safe address') } + + // TODO: Remove @deprecated migration code + let currentNonce: number | undefined + let hasConfirmations: boolean | undefined + let ordering: string | undefined + let limit: number | undefined + let offset: number | undefined + if (typeof propsOrCurrentNonce === 'object') { + ;({ currentNonce, hasConfirmations, ordering, limit, offset } = propsOrCurrentNonce) + } else { + console.warn( + 'Deprecated: Use `currentNonce` inside an object instead. See `PendingTransactionsOptions`.' + ) + currentNonce = propsOrCurrentNonce + } + // END of @deprecated migration code + const { address } = this.#getEip3770Address(safeAddress) const nonce = currentNonce ? currentNonce : (await this.getSafeInfo(address)).nonce + const url = new URL( + `${this.#txServiceBaseUrl}/v1/safes/${address}/multisig-transactions/?executed=false&nonce__gte=${nonce}` + ) + + if (hasConfirmations) { + url.searchParams.set('has_confirmations', hasConfirmations.toString()) + } + + if (ordering) { + url.searchParams.set('ordering', ordering) + } + + if (limit != null) { + url.searchParams.set('limit', limit.toString()) + } + + if (offset != null) { + url.searchParams.set('offset', offset.toString()) + } + return sendRequest({ - url: `${this.#txServiceBaseUrl}/v1/safes/${address}/multisig-transactions/?executed=false&nonce__gte=${nonce}`, + url: url.toString(), method: HttpMethod.Get }) } diff --git a/packages/api-kit/src/types/safeTransactionServiceTypes.ts b/packages/api-kit/src/types/safeTransactionServiceTypes.ts index a09256697..5b75d0147 100644 --- a/packages/api-kit/src/types/safeTransactionServiceTypes.ts +++ b/packages/api-kit/src/types/safeTransactionServiceTypes.ts @@ -124,6 +124,13 @@ export type ProposeTransactionProps = { origin?: string } +export type PendingTransactionsOptions = { + currentNonce?: number + hasConfirmations?: boolean + /** Which field to use when ordering the results. It can be: `nonce`, `created`, `modified` (default: `-created`) */ + ordering?: string +} & ListOptions + export type SafeMultisigTransactionListResponse = ListResponse export type TransferResponse = { diff --git a/packages/api-kit/tests/e2e/getPendingTransactions.test.ts b/packages/api-kit/tests/e2e/getPendingTransactions.test.ts index e136ae8b4..2808f553c 100644 --- a/packages/api-kit/tests/e2e/getPendingTransactions.test.ts +++ b/packages/api-kit/tests/e2e/getPendingTransactions.test.ts @@ -48,4 +48,26 @@ describe('getPendingTransactions', () => { chai.expect(transactionList.count).to.be.equal(10) chai.expect(transactionList.results.length).to.be.equal(10) }) + + it('should return a maximum of 2 transactions with limit = 2', async () => { + const safeAddress = '0xCa2f5A815b642c79FC530B60BC15Aee4eF6252b3' // Safe with pending transaction + const transactionList = await safeApiKit.getPendingTransactions(safeAddress, { + limit: 2 + }) + + chai.expect(transactionList).to.have.property('count').greaterThan(1) + chai.expect(transactionList).to.have.property('results').to.be.an('array') + chai.expect(transactionList.results.length).to.be.equal(2) + }) + + it('should return all pending transactions excluding the first one with offset = 1', async () => { + const safeAddress = '0xCa2f5A815b642c79FC530B60BC15Aee4eF6252b3' // Safe with pending transaction + const transactionList = await safeApiKit.getPendingTransactions(safeAddress, { + offset: 1 + }) + + chai.expect(transactionList).to.have.property('count').greaterThan(1) + chai.expect(transactionList).to.have.property('results').to.be.an('array') + chai.expect(transactionList.results.length).to.be.lessThanOrEqual(transactionList.count - 1) + }) }) diff --git a/packages/api-kit/tests/endpoint/index.test.ts b/packages/api-kit/tests/endpoint/index.test.ts index d0d59d0b8..229324ccd 100644 --- a/packages/api-kit/tests/endpoint/index.test.ts +++ b/packages/api-kit/tests/endpoint/index.test.ts @@ -512,7 +512,7 @@ describe('Endpoint tests', () => { it('getPendingTransactions', async () => { const currentNonce = 1 await chai - .expect(safeApiKit.getPendingTransactions(safeAddress, currentNonce)) + .expect(safeApiKit.getPendingTransactions(safeAddress, { currentNonce })) .to.be.eventually.deep.equals({ data: { success: true } }) chai.expect(fetchData).to.have.been.calledWith({ url: `${txServiceBaseUrl}/v1/safes/${safeAddress}/multisig-transactions/?executed=false&nonce__gte=${currentNonce}`, @@ -523,7 +523,7 @@ describe('Endpoint tests', () => { it('getPendingTransactions EIP-3770', async () => { const currentNonce = 1 await chai - .expect(safeApiKit.getPendingTransactions(eip3770SafeAddress, currentNonce)) + .expect(safeApiKit.getPendingTransactions(eip3770SafeAddress, { currentNonce })) .to.be.eventually.deep.equals({ data: { success: true } }) chai.expect(fetchData).to.have.been.calledWith({ url: `${txServiceBaseUrl}/v1/safes/${safeAddress}/multisig-transactions/?executed=false&nonce__gte=${currentNonce}`, diff --git a/packages/protocol-kit/package.json b/packages/protocol-kit/package.json index 18b3322af..7c26a1ea3 100644 --- a/packages/protocol-kit/package.json +++ b/packages/protocol-kit/package.json @@ -1,6 +1,6 @@ { "name": "@safe-global/protocol-kit", - "version": "5.0.1", + "version": "5.0.4", "description": "SDK that facilitates the interaction with Safe Smart Accounts", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", @@ -51,8 +51,7 @@ ], "homepage": "https://github.com/safe-global/safe-core-sdk#readme", "devDependencies": { - "@safe-global/safe-passkey": "0.2.0-alpha.1", - "@safe-global/testing-kit": "^0.1.0", + "@safe-global/testing-kit": "^0.1.1", "@types/chai": "^4.3.19", "@types/chai-as-promised": "^7.1.8", "@types/mocha": "^10.0.8", @@ -68,7 +67,7 @@ }, "dependencies": { "@noble/hashes": "^1.3.3", - "@safe-global/safe-deployments": "^1.37.9", + "@safe-global/safe-deployments": "^1.37.14", "@safe-global/safe-modules-deployments": "^2.2.4", "@safe-global/types-kit": "^1.0.0", "abitype": "^1.0.2", diff --git a/packages/protocol-kit/src/Safe.ts b/packages/protocol-kit/src/Safe.ts index 26517716b..3b9dd9859 100644 --- a/packages/protocol-kit/src/Safe.ts +++ b/packages/protocol-kit/src/Safe.ts @@ -282,6 +282,7 @@ class Safe { return predictSafeAddress({ safeProvider: this.#safeProvider, chainId, + isL1SafeSingleton: this.#contractManager.isL1SafeSingleton, customContracts: this.#contractManager.contractNetworks?.[chainId.toString()], ...this.#predictedSafe }) @@ -1520,19 +1521,22 @@ class Safe { const isL1SafeSingleton = this.#contractManager.isL1SafeSingleton const customContracts = this.#contractManager.contractNetworks?.[chainId.toString()] + const deploymentType = this.#predictedSafe.safeDeploymentConfig?.deploymentType const safeSingletonContract = await getSafeContract({ safeProvider, safeVersion, isL1SafeSingleton, - customContracts + customContracts, + deploymentType }) // we use the SafeProxyFactory.sol contract, see: https://github.com/safe-global/safe-contracts/blob/main/contracts/proxies/SafeProxyFactory.sol const safeProxyFactoryContract = await getSafeProxyFactoryContract({ safeProvider, safeVersion, - customContracts + customContracts, + deploymentType }) // this is the call to the setup method that sets the threshold & owners of the new Safe, see: https://github.com/safe-global/safe-contracts/blob/main/contracts/Safe.sol#L95 @@ -1540,7 +1544,8 @@ class Safe { safeProvider, safeContract: safeSingletonContract, safeAccountConfig: safeAccountConfig, - customContracts + customContracts, + deploymentType }) const safeDeployTransactionData = { diff --git a/packages/protocol-kit/src/contracts/BaseContract.ts b/packages/protocol-kit/src/contracts/BaseContract.ts index 82f42cc72..f19aec1f4 100644 --- a/packages/protocol-kit/src/contracts/BaseContract.ts +++ b/packages/protocol-kit/src/contracts/BaseContract.ts @@ -9,7 +9,8 @@ import { Chain } from 'viem' import { estimateContractGas, getTransactionReceipt } from 'viem/actions' -import { SingletonDeployment } from '@safe-global/safe-deployments' +import { SingletonDeploymentV2 } from '@safe-global/safe-deployments' +import { Deployment } from '@safe-global/safe-modules-deployments' import { contractName, getContractDeployment } from '@safe-global/protocol-kit/contracts/config' import { DeploymentType } from '@safe-global/protocol-kit/types' import SafeProvider from '@safe-global/protocol-kit/SafeProvider' @@ -105,26 +106,35 @@ class BaseContract { #resolveAddress( networkAddresses: string | string[] | undefined, - deployment: SingletonDeployment, + deployment: SingletonDeploymentV2 | Deployment | undefined, deploymentType?: DeploymentType ): string | undefined { + // If there are no addresses for the given chainId we return undefined if (!networkAddresses) { return undefined } - if (typeof networkAddresses === 'string') { - return networkAddresses - } - - if (deploymentType) { + // If a custom deployment type is selected, we check that type is available in the given chain + // We ensure that we receive a SingletonDeploymentV2 object for this check, + // otherwise we continue with the next logic (`@safe-global/safe-module-deployments` is not having this property.) + if (deploymentType && deployment && 'deployments' in deployment) { const customDeploymentTypeAddress = deployment.deployments[deploymentType]?.address - return ( - networkAddresses.find((address) => address === customDeploymentTypeAddress) ?? - networkAddresses[0] - ) + if (typeof networkAddresses === 'string') { + return networkAddresses === customDeploymentTypeAddress + ? customDeploymentTypeAddress + : undefined + } + + return networkAddresses.find((address) => address === customDeploymentTypeAddress) + } + + // Deployment type is not selected and there is only one address for this contract in the given chain, we return it + if (typeof networkAddresses === 'string') { + return networkAddresses } + // If there are multiple addresses available for this contract, we return the first one. return networkAddresses[0] } diff --git a/packages/protocol-kit/src/contracts/Safe/SafeBaseContract.ts b/packages/protocol-kit/src/contracts/Safe/SafeBaseContract.ts index 7634d5f0f..39ce34ce5 100644 --- a/packages/protocol-kit/src/contracts/Safe/SafeBaseContract.ts +++ b/packages/protocol-kit/src/contracts/Safe/SafeBaseContract.ts @@ -46,15 +46,13 @@ abstract class SafeBaseContract< safeProvider: SafeProvider, defaultAbi: SafeContractAbiType, safeVersion: SafeVersion, - isL1SafeSingleton = false, + isL1SafeSingleton = safeDeploymentsL1ChainIds.includes(chainId), customContractAddress?: string, customContractAbi?: SafeContractAbiType, deploymentType?: DeploymentType ) { const isL1Contract = - safeDeploymentsL1ChainIds.includes(chainId) || - isL1SafeSingleton || - !hasSafeFeature(SAFE_FEATURES.SAFE_L2_CONTRACTS, safeVersion) + isL1SafeSingleton || !hasSafeFeature(SAFE_FEATURES.SAFE_L2_CONTRACTS, safeVersion) const contractName = isL1Contract ? 'safeSingletonVersion' : 'safeSingletonL2Version' diff --git a/packages/protocol-kit/src/contracts/Safe/v1.0.0/SafeContract_v1_0_0.ts b/packages/protocol-kit/src/contracts/Safe/v1.0.0/SafeContract_v1_0_0.ts index b3ee89a94..8e4837c7e 100644 --- a/packages/protocol-kit/src/contracts/Safe/v1.0.0/SafeContract_v1_0_0.ts +++ b/packages/protocol-kit/src/contracts/Safe/v1.0.0/SafeContract_v1_0_0.ts @@ -42,7 +42,7 @@ class SafeContract_v1_0_0 constructor( chainId: bigint, safeProvider: SafeProvider, - isL1SafeSingleton = false, + isL1SafeSingleton?: boolean, customContractAddress?: string, customContractAbi?: SafeContract_v1_0_0_Abi, deploymentType?: DeploymentType diff --git a/packages/protocol-kit/src/contracts/Safe/v1.1.1/SafeContract_v1_1_1.ts b/packages/protocol-kit/src/contracts/Safe/v1.1.1/SafeContract_v1_1_1.ts index 7b59e5b50..d01040f38 100644 --- a/packages/protocol-kit/src/contracts/Safe/v1.1.1/SafeContract_v1_1_1.ts +++ b/packages/protocol-kit/src/contracts/Safe/v1.1.1/SafeContract_v1_1_1.ts @@ -41,7 +41,7 @@ class SafeContract_v1_1_1 constructor( chainId: bigint, safeProvider: SafeProvider, - isL1SafeSingleton = false, + isL1SafeSingleton?: boolean, customContractAddress?: string, customContractAbi?: SafeContract_v1_1_1_Abi, deploymentType?: DeploymentType diff --git a/packages/protocol-kit/src/contracts/Safe/v1.2.0/SafeContract_v1_2_0.ts b/packages/protocol-kit/src/contracts/Safe/v1.2.0/SafeContract_v1_2_0.ts index 82f96a5e5..523025fcc 100644 --- a/packages/protocol-kit/src/contracts/Safe/v1.2.0/SafeContract_v1_2_0.ts +++ b/packages/protocol-kit/src/contracts/Safe/v1.2.0/SafeContract_v1_2_0.ts @@ -40,7 +40,7 @@ class SafeContract_v1_2_0 constructor( chainId: bigint, safeProvider: SafeProvider, - isL1SafeSingleton = false, + isL1SafeSingleton?: boolean, customContractAddress?: string, customContractAbi?: SafeContract_v1_2_0_Abi, deploymentType?: DeploymentType diff --git a/packages/protocol-kit/src/contracts/Safe/v1.3.0/SafeContract_v1_3_0.ts b/packages/protocol-kit/src/contracts/Safe/v1.3.0/SafeContract_v1_3_0.ts index f6976edee..db3ed4ad3 100644 --- a/packages/protocol-kit/src/contracts/Safe/v1.3.0/SafeContract_v1_3_0.ts +++ b/packages/protocol-kit/src/contracts/Safe/v1.3.0/SafeContract_v1_3_0.ts @@ -41,7 +41,7 @@ class SafeContract_v1_3_0 constructor( chainId: bigint, safeProvider: SafeProvider, - isL1SafeSingleton = false, + isL1SafeSingleton?: boolean, customContractAddress?: string, customContractAbi?: SafeContract_v1_3_0_Abi, deploymentType?: DeploymentType diff --git a/packages/protocol-kit/src/contracts/Safe/v1.4.1/SafeContract_v1_4_1.ts b/packages/protocol-kit/src/contracts/Safe/v1.4.1/SafeContract_v1_4_1.ts index 279786f05..71f445a4c 100644 --- a/packages/protocol-kit/src/contracts/Safe/v1.4.1/SafeContract_v1_4_1.ts +++ b/packages/protocol-kit/src/contracts/Safe/v1.4.1/SafeContract_v1_4_1.ts @@ -41,7 +41,7 @@ class SafeContract_v1_4_1 constructor( chainId: bigint, safeProvider: SafeProvider, - isL1SafeSingleton = false, + isL1SafeSingleton?: boolean, customContractAddress?: string, customContractAbi?: SafeContract_v1_4_1_Abi, deploymentType?: DeploymentType diff --git a/packages/protocol-kit/src/contracts/config.ts b/packages/protocol-kit/src/contracts/config.ts index 115dfe7be..79e77ac11 100644 --- a/packages/protocol-kit/src/contracts/config.ts +++ b/packages/protocol-kit/src/contracts/config.ts @@ -118,9 +118,7 @@ export const safeDeploymentsL1ChainIds = [ const contractFunctions: Record< contractName, - ( - filter?: DeploymentFilter - ) => SingletonDeployment | SingletonDeploymentV2 | undefined | Deployment + (filter?: DeploymentFilter) => SingletonDeploymentV2 | undefined | Deployment > = { safeSingletonVersion: getSafeSingletonDeployments, safeSingletonL2Version: getSafeL2SingletonDeployments, @@ -148,7 +146,7 @@ export function getContractDeployment( released: true } - const deployment = contractFunctions[contractName](filters) as SingletonDeployment + const deployment = contractFunctions[contractName](filters) return deployment } diff --git a/packages/protocol-kit/src/contracts/utils.ts b/packages/protocol-kit/src/contracts/utils.ts index 6250eebda..a8f0f268a 100644 --- a/packages/protocol-kit/src/contracts/utils.ts +++ b/packages/protocol-kit/src/contracts/utils.ts @@ -254,7 +254,7 @@ export async function getPredictedSafeAddressInitCode({ chainId, safeAccountConfig, safeDeploymentConfig = {}, - isL1SafeSingleton = false, + isL1SafeSingleton, customContracts }: PredictSafeAddressProps): Promise { validateSafeAccountConfig(safeAccountConfig) @@ -314,7 +314,7 @@ export async function predictSafeAddress({ chainId, safeAccountConfig, safeDeploymentConfig = {}, - isL1SafeSingleton = false, + isL1SafeSingleton, customContracts }: PredictSafeAddressProps): Promise { validateSafeAccountConfig(safeAccountConfig) diff --git a/packages/protocol-kit/src/utils/eip-3770/config.ts b/packages/protocol-kit/src/utils/eip-3770/config.ts index df9542ad4..e9f943c3d 100644 --- a/packages/protocol-kit/src/utils/eip-3770/config.ts +++ b/packages/protocol-kit/src/utils/eip-3770/config.ts @@ -38,7 +38,7 @@ export const networks: NetworkShortName[] = [ { chainId: 81n, shortName: 'joc' }, { chainId: 82n, shortName: 'meter' }, { chainId: 83n, shortName: 'meter-test' }, - { chainId: 88n, shortName: 'tomo' }, + { chainId: 88n, shortName: 'vic' }, { chainId: 97n, shortName: 'bnbt' }, { chainId: 100n, shortName: 'gno' }, { chainId: 106n, shortName: 'vlx' }, @@ -56,6 +56,7 @@ export const networks: NetworkShortName[] = [ { chainId: 195n, shortName: 'tokb' }, { chainId: 196n, shortName: 'okb' }, { chainId: 204n, shortName: 'opbnb' }, + { chainId: 240n, shortName: 'zkTCRO' }, { chainId: 246n, shortName: 'ewt' }, { chainId: 250n, shortName: 'ftm' }, { chainId: 252n, shortName: 'fraxtal' }, @@ -71,6 +72,7 @@ export const networks: NetworkShortName[] = [ { chainId: 324n, shortName: 'zksync' }, { chainId: 336n, shortName: 'sdn' }, { chainId: 338n, shortName: 'tcro' }, + { chainId: 360n, shortName: 'shape' }, { chainId: 369n, shortName: 'pls' }, { chainId: 388n, shortName: 'zkCRO' }, { chainId: 420n, shortName: 'ogor' }, @@ -88,6 +90,8 @@ export const networks: NetworkShortName[] = [ { chainId: 787n, shortName: 'aca' }, { chainId: 919n, shortName: 'modesep' }, { chainId: 943n, shortName: 't4pls' }, + { chainId: 970n, shortName: 'ccn' }, + { chainId: 995n, shortName: '5ire' }, { chainId: 1001n, shortName: 'baobab' }, { chainId: 1008n, shortName: 'eun' }, { chainId: 1030n, shortName: 'cfx' }, @@ -107,6 +111,7 @@ export const networks: NetworkShortName[] = [ { chainId: 1329n, shortName: 'sei' }, { chainId: 1337n, shortName: 'geth' }, { chainId: 1442n, shortName: 'testnet-zkEVM-mango' }, + { chainId: 1513n, shortName: 'Story' }, { chainId: 1516n, shortName: 'story-odyssey' }, { chainId: 1559n, shortName: 'tenet' }, { chainId: 1625n, shortName: 'gravity' }, @@ -126,12 +131,15 @@ export const networks: NetworkShortName[] = [ { chainId: 2020n, shortName: 'pmint' }, { chainId: 2021n, shortName: 'edg' }, { chainId: 2039n, shortName: 'aleph' }, + { chainId: 2187n, shortName: 'g7' }, { chainId: 2192n, shortName: 'snax' }, { chainId: 2221n, shortName: 'tkava' }, { chainId: 2222n, shortName: 'kava' }, { chainId: 2331n, shortName: 'rss3-testnet' }, { chainId: 2358n, shortName: 'kroma-sepolia' }, + { chainId: 2442n, shortName: 'zkevm-testnet-cardona' }, { chainId: 2810n, shortName: 'hmorph' }, + { chainId: 2818n, shortName: 'morph' }, { chainId: 3338n, shortName: 'PEAQ' }, { chainId: 3636n, shortName: 'BTNX' }, { chainId: 3737n, shortName: 'csb' }, @@ -151,11 +159,14 @@ export const networks: NetworkShortName[] = [ { chainId: 5000n, shortName: 'mantle' }, { chainId: 5001n, shortName: 'mantle-testnet' }, { chainId: 5003n, shortName: 'mnt-sep' }, + { chainId: 5115n, shortName: 'citrea-testnet' }, + { chainId: 5165n, shortName: 'ftn' }, { chainId: 5700n, shortName: 'tsys' }, { chainId: 6001n, shortName: 'bouncebit-mainnet' }, { chainId: 6102n, shortName: 'cascadia' }, { chainId: 6321n, shortName: 'eaura' }, { chainId: 6322n, shortName: 'aura' }, + { chainId: 6398n, shortName: 'connext-sepolia' }, { chainId: 6688n, shortName: 'iris' }, { chainId: 7000n, shortName: 'zetachain-mainnet' }, { chainId: 7001n, shortName: 'zetachain-testnet' }, @@ -181,6 +192,7 @@ export const networks: NetworkShortName[] = [ { chainId: 10242n, shortName: 'aa' }, { chainId: 10243n, shortName: 'aat' }, { chainId: 10849n, shortName: 'lamina1' }, + { chainId: 11011n, shortName: 'shapesep' }, { chainId: 11111n, shortName: 'WAGMI' }, { chainId: 11235n, shortName: 'islm' }, { chainId: 11437n, shortName: 'shyftt' }, @@ -194,6 +206,8 @@ export const networks: NetworkShortName[] = [ { chainId: 13337n, shortName: 'beam-testnet' }, { chainId: 13371n, shortName: 'imx' }, { chainId: 13473n, shortName: 'imx-testnet' }, + { chainId: 13746n, shortName: 'g7t' }, + { chainId: 14800n, shortName: 'vana-moksha' }, { chainId: 17000n, shortName: 'holesky' }, { chainId: 17069n, shortName: 'garnet' }, { chainId: 17172n, shortName: 'eclipse' }, @@ -202,9 +216,11 @@ export const networks: NetworkShortName[] = [ { chainId: 22776n, shortName: 'mapo' }, { chainId: 23294n, shortName: 'sapphire' }, { chainId: 23295n, shortName: 'sapphire-testnet' }, + { chainId: 25327n, shortName: 'Everclear' }, { chainId: 28979n, shortName: 'kimbonet-testnet' }, { chainId: 32769n, shortName: 'zil' }, { chainId: 33101n, shortName: 'zil-testnet' }, + { chainId: 33139n, shortName: 'apechain' }, { chainId: 33401n, shortName: 'slingshot' }, { chainId: 34443n, shortName: 'mode' }, { chainId: 35441n, shortName: 'q' }, @@ -276,6 +292,8 @@ export const networks: NetworkShortName[] = [ { chainId: 808813n, shortName: 'bob-sepolia' }, { chainId: 810180n, shortName: 'zklink-nova' }, { chainId: 978657n, shortName: 'treasure-ruby' }, + { chainId: 3441006n, shortName: 'mantaSepoliaTestnet' }, + { chainId: 4457845n, shortName: 'zero-sepolia' }, { chainId: 6038361n, shortName: 'azkyt' }, { chainId: 7225878n, shortName: 'saakuru' }, { chainId: 7777777n, shortName: 'zora' }, diff --git a/packages/relay-kit/package.json b/packages/relay-kit/package.json index bd89b07b5..5e5be690d 100644 --- a/packages/relay-kit/package.json +++ b/packages/relay-kit/package.json @@ -1,6 +1,6 @@ { "name": "@safe-global/relay-kit", - "version": "3.2.1", + "version": "3.2.4", "description": "SDK for Safe Smart Accounts with support for ERC-4337 and Relay", "main": "dist/src/index.js", "typings": "dist/src/index.d.ts", @@ -39,7 +39,7 @@ }, "dependencies": { "@gelatonetwork/relay-sdk": "^5.5.0", - "@safe-global/protocol-kit": "^5.0.1", + "@safe-global/protocol-kit": "^5.0.4", "@safe-global/safe-modules-deployments": "^2.2.4", "@safe-global/types-kit": "^1.0.0", "viem": "^2.21.8" diff --git a/packages/sdk-starter-kit/package.json b/packages/sdk-starter-kit/package.json index 3a3f70f9a..e9443b1b5 100644 --- a/packages/sdk-starter-kit/package.json +++ b/packages/sdk-starter-kit/package.json @@ -1,6 +1,6 @@ { "name": "@safe-global/sdk-starter-kit", - "version": "1.0.1", + "version": "1.0.4", "description": "SDK that provides the basic tools to interact with the Safe Smart Account.", "main": "dist/src/index.js", "typings": "dist/src/index.d.ts", @@ -36,9 +36,9 @@ "access": "public" }, "dependencies": { - "@safe-global/api-kit": "^2.5.1", - "@safe-global/protocol-kit": "^5.0.1", - "@safe-global/relay-kit": "^3.2.1", + "@safe-global/api-kit": "^2.5.4", + "@safe-global/protocol-kit": "^5.0.4", + "@safe-global/relay-kit": "^3.2.4", "@safe-global/types-kit": "^1.0.0", "viem": "^2.21.8" } diff --git a/packages/testing-kit/package.json b/packages/testing-kit/package.json index 6027d2f41..0541fb4c8 100644 --- a/packages/testing-kit/package.json +++ b/packages/testing-kit/package.json @@ -1,6 +1,6 @@ { "name": "@safe-global/testing-kit", - "version": "0.1.0", + "version": "0.1.1", "description": "Helper package providing testing utilities", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", @@ -39,6 +39,7 @@ "@nomicfoundation/hardhat-viem": "^2.0.4", "@openzeppelin/contracts": "^2.5.1", "@safe-global/safe-contracts-v1.4.1": "npm:@safe-global/safe-contracts@1.4.1", + "@safe-global/safe-passkey": "0.2.0-alpha.1", "@safe-global/types-kit": "^1.0.0", "@types/semver": "^7.5.8", "hardhat": "^2.19.3", diff --git a/playground/config/run.ts b/playground/config/run.ts index 749a724b1..6f7e6148a 100644 --- a/playground/config/run.ts +++ b/playground/config/run.ts @@ -7,6 +7,7 @@ const playInput = process.argv[2] const playgroundProtocolKitPaths = { 'create-execute-transaction': 'protocol-kit/create-execute-transaction', 'deploy-safe': 'protocol-kit/deploy-safe', + 'replicate-address': 'protocol-kit/replicate-address', 'generate-safe-address': 'protocol-kit/generate-safe-address', 'validate-signatures': 'protocol-kit/validate-signatures' } diff --git a/playground/protocol-kit/replicate-address.ts b/playground/protocol-kit/replicate-address.ts new file mode 100644 index 000000000..800217ef8 --- /dev/null +++ b/playground/protocol-kit/replicate-address.ts @@ -0,0 +1,101 @@ +import Safe, { DeploymentType, SafeAccountConfig } from '@safe-global/protocol-kit' +import { SafeVersion } from '@safe-global/types-kit' +import { + gnosis, + mainnet, + base, + optimism, + arbitrum, + bsc, + polygon, + linea, + scroll, + xLayer, + celo, + avalanche, + blast, + mantle, + aurora, + sepolia +} from 'viem/chains' + +// This file can be used to play around with the Safe Core SDK + +// Safe config to be replicated in different chains +const safeAccountConfig: SafeAccountConfig = { + owners: ['0x0Ee26C4481485AC64BfFf2bdCaA21EdAeCEcdCa9'], + threshold: 1 +} + +// saltNonce used +const saltNonce = '1234567890987654321' + +async function main() { + console.log('Safe Account config: ', safeAccountConfig) + console.log('saltNonce: ', saltNonce) + + const deploymentTypes: DeploymentType[] = ['canonical'] // 'canonical' or 'eip155' + const isL1SafeSingletons = [true, false] + const safeVersions: SafeVersion[] = ['1.3.0', '1.4.1'] + + const chains = [ + mainnet, + gnosis, + polygon, + bsc, + arbitrum, + optimism, + base, + linea, + scroll, + xLayer, + celo, + avalanche, + blast, + mantle, + aurora, + + // tesnets + sepolia + ] + + for (let i = 0; i < safeVersions.length; i++) { + for (let j = 0; j < deploymentTypes.length; j++) { + for (let k = 0; k < isL1SafeSingletons.length; k++) { + const safeVersion = safeVersions[i] + const deploymentType = deploymentTypes[j] + const isL1SafeSingleton = isL1SafeSingletons[k] + + console.log(' ') + console.log( + ` ---------- [Safe v${safeVersion}; ${deploymentType} deployment; ${isL1SafeSingleton ? 'L1' : 'L2'} contract ] ---------- ` + ) + console.log(' ') + + for (let l = 0; l < chains.length; l++) { + const chain = chains[l] + const provider = chain.rpcUrls.default.http[0] + + const protocolKit = await Safe.init({ + provider, + isL1SafeSingleton, + predictedSafe: { + safeAccountConfig, + safeDeploymentConfig: { + deploymentType, + saltNonce, + safeVersion + } + } + }) + + const safeAddress = await protocolKit.getAddress() + + console.log(`${safeAddress} --> Safe address in ${chain.name} chain`) + } + } + } + } +} + +main() diff --git a/yarn.lock b/yarn.lock index f32ab1524..904bf6e2a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1735,10 +1735,10 @@ resolved "https://registry.yarnpkg.com/@safe-global/safe-contracts/-/safe-contracts-1.4.1-build.0.tgz#5d82e2f3fd8430b4589df992b9ee2c71386082fe" integrity sha512-TIpoKJtMqLcLFoid0cvpxo8YTcnRUj95MHvxzwgPbJPRONOckNS6ebgGyBBRDmnpxFh34IBpPUZ7JD+z2Cfbbg== -"@safe-global/safe-deployments@^1.37.9": - version "1.37.9" - resolved "https://registry.yarnpkg.com/@safe-global/safe-deployments/-/safe-deployments-1.37.9.tgz#efcc3633cab725c91a1961d09e6a6b70c4006b1f" - integrity sha512-j/4V5fJNddi4/oBhuDWSx2ocfXMkNGBpke2B3nPTIrzgXQam0wObkBQOe85tqjte9KEuDPW1D3bvvVCdz0WrRQ== +"@safe-global/safe-deployments@^1.37.14": + version "1.37.14" + resolved "https://registry.yarnpkg.com/@safe-global/safe-deployments/-/safe-deployments-1.37.14.tgz#31c1d1ff924d94ce639c136bef154de3adf5f75e" + integrity sha512-uHpYizq52j1arwWRxHbEbrZsECD5tG87NwLo/xDViRVw/GIrkRC6HerkzfZwiHVjVrC8gN8o3ApLsknYbxrF4w== dependencies: semver "^7.6.2" @@ -3603,7 +3603,7 @@ electron-to-chromium@^1.4.535: resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.589.tgz" integrity sha512-zF6y5v/YfoFIgwf2dDfAqVlPPsyQeWNpEWXbAlDUS8Ax4Z2VoiiZpAPC0Jm9hXEkJm2vIZpwB6rc4KnLTQffbQ== -elliptic@6.5.4, elliptic@^6.5.2, elliptic@^6.5.4: +elliptic@6.5.4: version "6.5.4" resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz" integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== @@ -3616,6 +3616,19 @@ elliptic@6.5.4, elliptic@^6.5.2, elliptic@^6.5.4: minimalistic-assert "^1.0.1" minimalistic-crypto-utils "^1.0.1" +elliptic@^6.5.2, elliptic@^6.5.7: + version "6.5.7" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.7.tgz#8ec4da2cb2939926a1b9a73619d768207e647c8b" + integrity sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + emittery@^0.13.1: version "0.13.1" resolved "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz" @@ -6441,6 +6454,11 @@ node-addon-api@^2.0.0: resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz" integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== +node-addon-api@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-5.1.0.tgz#49da1ca055e109a23d537e9de43c09cca21eb762" + integrity sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA== + node-fetch@2.6.7: version "2.6.7" resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz" @@ -7544,12 +7562,12 @@ scrypt-js@3.0.1, scrypt-js@^3.0.0: integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== secp256k1@^4.0.1: - version "4.0.3" - resolved "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz" - integrity sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA== + version "4.0.4" + resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.4.tgz#58f0bfe1830fe777d9ca1ffc7574962a8189f8ab" + integrity sha512-6JfvwvjUOn8F/jUoBY2Q1v5WY5XS+rj8qSe0v8Y4ezH4InLgTEeOOPQsRll9OV429Pvo6BCHGavIyJfr3TAhsw== dependencies: - elliptic "^6.5.4" - node-addon-api "^2.0.0" + elliptic "^6.5.7" + node-addon-api "^5.0.0" node-gyp-build "^4.2.0" "semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0: