From de4f1de028e13663dd34a927c4baf8f18ecf192d Mon Sep 17 00:00:00 2001 From: Dani Somoza Date: Mon, 16 Dec 2024 13:56:42 +0100 Subject: [PATCH 1/8] feat: Onchain Identifier via transaction `data` and `calldata` fields (#1059) --- packages/protocol-kit/src/Safe.ts | 76 +++++++- packages/protocol-kit/src/index.ts | 2 + packages/protocol-kit/src/types/safeConfig.ts | 11 ++ .../src/utils/getProtocolKitVersion.ts | 7 + .../generateOnChainIdentifier.ts | 57 ++++++ .../tests/e2e/onChainIdentifier.test.ts | 171 ++++++++++++++++++ packages/protocol-kit/tsconfig.build.json | 3 +- packages/protocol-kit/tsconfig.json | 3 +- .../src/packs/safe-4337/Safe4337Pack.ts | 44 ++++- .../relay-kit/src/packs/safe-4337/types.ts | 8 +- .../safe-4337/utils/getRelayKitVersion.ts | 7 + packages/relay-kit/tsconfig.build.json | 3 +- packages/relay-kit/tsconfig.json | 3 +- .../create-execute-transaction.ts | 2 +- 14 files changed, 382 insertions(+), 15 deletions(-) create mode 100644 packages/protocol-kit/src/utils/getProtocolKitVersion.ts create mode 100644 packages/protocol-kit/src/utils/on-chain-tracking/generateOnChainIdentifier.ts create mode 100644 packages/protocol-kit/tests/e2e/onChainIdentifier.test.ts create mode 100644 packages/relay-kit/src/packs/safe-4337/utils/getRelayKitVersion.ts diff --git a/packages/protocol-kit/src/Safe.ts b/packages/protocol-kit/src/Safe.ts index 6b39deeb8..c578ac8af 100644 --- a/packages/protocol-kit/src/Safe.ts +++ b/packages/protocol-kit/src/Safe.ts @@ -20,6 +20,7 @@ import { getChainSpecificDefaultSaltNonce, getPredictedSafeAddressInitCode, predictSafeAddress, + toTxResult, validateSafeAccountConfig, validateSafeDeploymentConfig } from './contracts/utils' @@ -83,9 +84,11 @@ import SafeMessage from './utils/messages/SafeMessage' import semverSatisfies from 'semver/functions/satisfies' import SafeProvider from './SafeProvider' import { asHash, asHex } from './utils/types' -import { Hash, Hex } from 'viem' +import { Hash, Hex, SendTransactionParameters } from 'viem' import getPasskeyOwnerAddress from './utils/passkeys/getPasskeyOwnerAddress' import createPasskeyDeploymentTransaction from './utils/passkeys/createPasskeyDeploymentTransaction' +import generateOnChainIdentifier from './utils/on-chain-tracking/generateOnChainIdentifier' +import getProtocolKitVersion from './utils/getProtocolKitVersion' const EQ_OR_GT_1_4_1 = '>=1.4.1' const EQ_OR_GT_1_3_0 = '>=1.3.0' @@ -102,6 +105,9 @@ class Safe { #MAGIC_VALUE = '0x1626ba7e' #MAGIC_VALUE_BYTES = '0x20c13b0b' + // on-chain Analytics + #onchainIdentifier: string = '' + /** * Creates an instance of the Safe Core SDK. * @param config - Ethers Safe configuration @@ -126,7 +132,17 @@ class Safe { * @throws "MultiSendCallOnly contract is not deployed on the current network" */ async #initializeProtocolKit(config: SafeConfig) { - const { provider, signer, isL1SafeSingleton, contractNetworks } = config + const { provider, signer, isL1SafeSingleton, contractNetworks, onchainAnalytics } = config + + if (onchainAnalytics?.project) { + const { project, platform } = onchainAnalytics + this.#onchainIdentifier = generateOnChainIdentifier({ + project, + platform, + tool: 'protocol-kit', + toolVersion: getProtocolKitVersion() + }) + } this.#safeProvider = await SafeProvider.init({ provider, @@ -1340,6 +1356,32 @@ class Safe { const signerAddress = await this.#safeProvider.getSignerAddress() + if (this.#onchainIdentifier) { + const encodedTransaction = await this.getEncodedTransaction(signedSafeTransaction) + + const transaction = { + to: await this.getAddress(), + value: 0n, + data: encodedTransaction + this.#onchainIdentifier + } + + const signer = await this.#safeProvider.getExternalSigner() + + if (!signer) { + throw new Error('A signer must be set') + } + + const hash = await signer.sendTransaction({ + ...transaction, + account: signer.account, + ...options + } as SendTransactionParameters) + + const provider = this.#safeProvider.getExternalProvider() + + return toTxResult(provider, hash, options) + } + const txResponse = await this.#contractManager.safeContract.execTransaction( signedSafeTransaction, { @@ -1466,6 +1508,14 @@ class Safe { // we create the deployment transaction const safeDeploymentTransaction = await this.createSafeDeploymentTransaction() + // remove the onchain idendifier if it is included + if (safeDeploymentTransaction.data.endsWith(this.#onchainIdentifier)) { + safeDeploymentTransaction.data = safeDeploymentTransaction.data.replace( + this.#onchainIdentifier, + '' + ) + } + // First transaction of the batch: The Safe deployment Transaction const safeDeploymentBatchTransaction = { to: safeDeploymentTransaction.to, @@ -1486,7 +1536,11 @@ class Safe { const transactions = [safeDeploymentBatchTransaction, safeBatchTransaction] // this is the transaction with the batch - const safeDeploymentBatch = await this.createTransactionBatch(transactions, transactionOptions) + const safeDeploymentBatch = await this.createTransactionBatch( + transactions, + transactionOptions, + !!this.#onchainIdentifier // include the on chain identifier + ) return safeDeploymentBatch } @@ -1561,6 +1615,10 @@ class Safe { ]) } + if (this.#onchainIdentifier) { + safeDeployTransactionData.data += this.#onchainIdentifier + } + return safeDeployTransactionData } @@ -1572,12 +1630,14 @@ class Safe { * @function createTransactionBatch * @param {MetaTransactionData[]} transactions - An array of MetaTransactionData objects to be batched together. * @param {TransactionOption} [transactionOptions] - Optional TransactionOption object to specify additional options for the transaction batch. + * @param {boolean} [includeOnchainIdentifier=false] - A flag indicating whether to append the onchain identifier to the data field of the resulting transaction. * @returns {Promise} A Promise that resolves with the created transaction batch. * */ async createTransactionBatch( transactions: MetaTransactionData[], - transactionOptions?: TransactionOptions + transactionOptions?: TransactionOptions, + includeOnchainIdentifier: boolean = false ): Promise { // we use the MultiSend contract to create the batch, see: https://github.com/safe-global/safe-contracts/blob/main/contracts/libraries/MultiSendCallOnly.sol const multiSendCallOnlyContract = this.#contractManager.multiSendCallOnlyContract @@ -1594,6 +1654,10 @@ class Safe { data: batchData } + if (includeOnchainIdentifier) { + transactionBatch.data += this.#onchainIdentifier + } + return transactionBatch } @@ -1701,6 +1765,10 @@ class Safe { return getContractInfo(contractAddress) } + getOnchainIdentifier(): string { + return this.#onchainIdentifier + } + /** * This method creates a signer to be used with the init method * @param {Credential} credential - The credential to be used to create the signer. Can be generated in the web with navigator.credentials.create diff --git a/packages/protocol-kit/src/index.ts b/packages/protocol-kit/src/index.ts index 9c502e2e0..9e895e60f 100644 --- a/packages/protocol-kit/src/index.ts +++ b/packages/protocol-kit/src/index.ts @@ -66,6 +66,7 @@ import { } from './utils/eip-712' import { createPasskeyClient } from './utils/passkeys/PasskeyClient' import getPasskeyOwnerAddress from './utils/passkeys/getPasskeyOwnerAddress' +import generateOnChainIdentifier from './utils/on-chain-tracking/generateOnChainIdentifier' export { estimateTxBaseGas, @@ -80,6 +81,7 @@ export { EthSafeSignature, MultiSendCallOnlyBaseContract, MultiSendBaseContract, + generateOnChainIdentifier, PREDETERMINED_SALT_NONCE, SafeBaseContract, SafeProxyFactoryBaseContract, diff --git a/packages/protocol-kit/src/types/safeConfig.ts b/packages/protocol-kit/src/types/safeConfig.ts index 11d606ab9..7c330ceaf 100644 --- a/packages/protocol-kit/src/types/safeConfig.ts +++ b/packages/protocol-kit/src/types/safeConfig.ts @@ -41,6 +41,13 @@ type SafeConfigWithPredictedSafeProps = { predictedSafe: PredictedSafeProps } +export type OnchainAnalyticsProps = { + /** project - The project that is using the SDK */ + project?: string + /** platform - The platform that is using the SDK */ + platform?: string +} + export type SafeConfigProps = { provider: SafeProviderConfig['provider'] signer?: SafeProviderConfig['signer'] @@ -48,6 +55,8 @@ export type SafeConfigProps = { isL1SafeSingleton?: boolean /** contractNetworks - Contract network configuration */ contractNetworks?: ContractNetworksConfig + // on-chain analytics + onchainAnalytics?: OnchainAnalyticsProps } export type SafeConfigWithSafeAddress = SafeConfigProps & SafeConfigWithSafeAddressProps @@ -75,6 +84,8 @@ type ConnectSafeConfigProps = { isL1SafeSingleton?: boolean /** contractNetworks - Contract network configuration */ contractNetworks?: ContractNetworksConfig + // on-chain analytics + onchainAnalytics?: OnchainAnalyticsProps } export type ConnectSafeConfigWithSafeAddress = ConnectSafeConfigProps & diff --git a/packages/protocol-kit/src/utils/getProtocolKitVersion.ts b/packages/protocol-kit/src/utils/getProtocolKitVersion.ts new file mode 100644 index 000000000..3abd3bdb4 --- /dev/null +++ b/packages/protocol-kit/src/utils/getProtocolKitVersion.ts @@ -0,0 +1,7 @@ +import packageJson from '../../package.json' + +function getProtocolKitVersion(): string { + return packageJson.version +} + +export default getProtocolKitVersion diff --git a/packages/protocol-kit/src/utils/on-chain-tracking/generateOnChainIdentifier.ts b/packages/protocol-kit/src/utils/on-chain-tracking/generateOnChainIdentifier.ts new file mode 100644 index 000000000..aee82d29f --- /dev/null +++ b/packages/protocol-kit/src/utils/on-chain-tracking/generateOnChainIdentifier.ts @@ -0,0 +1,57 @@ +import { keccak256, toHex } from 'viem' + +/** + * Generates a hash from the given input string and truncates it to the specified size. + * + * @param {string} input - The input string to be hashed. + * @param {number} size - The number of bytes to take from the end of the hash. + * @returns {string} A hexadecimal string representation of the truncated hash, without the `0x` prefix. + */ +export function generateHash(input: string, size: number): string { + const fullHash = keccak256(toHex(input)) + return toHex(fullHash.slice(-size)).replace('0x', '') // Take the last X bytes +} + +export type OnChainIdentifierParamsType = { + project: string + platform?: string + tool: string + toolVersion: string +} + +/** + * Generates an on-chain identifier for tracking transactions on the blockchain. + * This identifier includes hashed metadata such as the project name, platform, tool, and tool version. + * + * @param {Object} params - An object containing the metadata for generating the on-chain identifier. + * @param {string} params.project - The name of the project initiating the transaction. + * @param {string} [params.platform='Web'] - The platform from which the transaction originates (e.g., "Web", "Mobile", "Safe App", "Widget"...). + * @param {string} params.tool - The tool used to generate the transaction (e.g., "protocol-kit"). + * @param {string} params.toolVersion - The version of the tool used to generate the transaction. + * @returns {string} A string representing the on-chain identifier, composed of multiple hashed segments. + * + * @example + * const identifier = generateOnChainIdentifier({ + * project: 'MyProject', + * platform: 'Mobile', + * tool: 'protocol-kit', + * toolVersion: '4.0.0' + * }) + */ +function generateOnChainIdentifier({ + project, + platform = 'Web', + tool, + toolVersion +}: OnChainIdentifierParamsType): string { + const identifierPrefix = '5afe' + const identifierVersion = '00' // first version + const projectHash = generateHash(project, 20) // Take the last 20 bytes + const platformHash = generateHash(platform, 3) // Take the last 3 bytes + const toolHash = generateHash(tool, 3) // Take the last 3 bytes + const toolVersionHash = generateHash(toolVersion, 3) // Take the last 3 bytes + + return `${identifierPrefix}${identifierVersion}${projectHash}${platformHash}${toolHash}${toolVersionHash}` +} + +export default generateOnChainIdentifier diff --git a/packages/protocol-kit/tests/e2e/onChainIdentifier.test.ts b/packages/protocol-kit/tests/e2e/onChainIdentifier.test.ts new file mode 100644 index 000000000..b45f47769 --- /dev/null +++ b/packages/protocol-kit/tests/e2e/onChainIdentifier.test.ts @@ -0,0 +1,171 @@ +import { setupTests, safeVersionDeployed } from '@safe-global/testing-kit' +import Safe, { + generateOnChainIdentifier, + OnchainAnalyticsProps, + PredictedSafeProps, + SafeAccountConfig +} from '@safe-global/protocol-kit/index' +import chai from 'chai' +import Sinon from 'sinon' +import chaiAsPromised from 'chai-as-promised' + +import { generateHash } from '@safe-global/protocol-kit/utils/on-chain-tracking/generateOnChainIdentifier' +import getProtocolKitVersion, * as getProtocolKitVersionModule from '@safe-global/protocol-kit/utils/getProtocolKitVersion' +import { getEip1193Provider } from './utils/setupProvider' +import { waitSafeTxReceipt } from './utils/transactions' + +chai.use(chaiAsPromised) + +describe('On-chain analytics', () => { + const provider = getEip1193Provider() + + describe('generateOnChainIdentifier fn', () => { + it('should return the correct on-chain identifier format', async () => { + const project = 'Test e2e Project' + const platform = 'Web' + const tool = 'protocol-kit' + const toolVersion = '1.0.0' + + const onChainIdentifier = generateOnChainIdentifier({ project, platform, tool, toolVersion }) + + const identifierPrefix = '5afe' + const identifierVersion = '00' + + chai.expect(onChainIdentifier.startsWith(identifierPrefix)).to.be.true + chai.expect(onChainIdentifier.substring(4, 6)).to.equals(identifierVersion) + chai.expect(onChainIdentifier.substring(6, 46)).to.equals(generateHash(project, 20)) + chai.expect(onChainIdentifier.substring(46, 52)).to.equals(generateHash(platform, 3)) + chai.expect(onChainIdentifier.substring(52, 58)).to.equals(generateHash(tool, 3)) + chai.expect(onChainIdentifier.substring(58, 64)).to.equals(generateHash(toolVersion, 3)) + }) + }) + + describe('getOnchainIdentifier method', () => { + it('should return the on-chain identifier when provided', async () => { + const onchainAnalytics: OnchainAnalyticsProps = { + project: 'Test e2e Project', + platform: 'Web' + } + + const stub = Sinon.stub(getProtocolKitVersionModule, 'default').returns('5.0.4') + + const { safe, contractNetworks } = await setupTests() + const safeAddress = safe.address + + const protocolKit = await Safe.init({ + provider, + safeAddress, + contractNetworks, + onchainAnalytics + }) + + const onChainIdentifier = '5afe003861653435366632366138366164643038373864646561393238653366' + + chai.expect(onChainIdentifier).to.equals(protocolKit.getOnchainIdentifier()) + stub.restore() + }) + + it('should return an empty string when no onchain Analiticts is provided', async () => { + const { safe, contractNetworks } = await setupTests() + const safeAddress = safe.address + + const protocolKit = await Safe.init({ + provider, + safeAddress, + contractNetworks + }) + + chai.expect(protocolKit.getOnchainIdentifier()).to.empty + }) + }) + + describe('Tracking Safe Deployment on-chain via the transaction data field', () => { + it('should append the on-chain identifier to the deployment transaction data field', async () => { + const onchainAnalytics: OnchainAnalyticsProps = { + project: 'Test e2e Project', + platform: 'Web' + } + + const { accounts, contractNetworks } = await setupTests() + const [account1, account2] = accounts + const owners = [account1.address, account2.address] + const threshold = 1 + const safeAccountConfig: SafeAccountConfig = { owners, threshold } + const predictedSafe: PredictedSafeProps = { + safeAccountConfig, + safeDeploymentConfig: { + safeVersion: safeVersionDeployed + } + } + + const protocolKit = await Safe.init({ + provider, + predictedSafe, + contractNetworks, + onchainAnalytics + }) + + const deploymentTransaction = await protocolKit.createSafeDeploymentTransaction() + + // toolVersion is dynamic (currrent protocol-kit version) + const toolVersion = getProtocolKitVersion() + const toolHash = generateHash(toolVersion, 3) + + const onChainIdentifier = + '5afe003861653435366632366138366164643038373864646561393238' + toolHash + + chai.expect(onChainIdentifier).to.equals(protocolKit.getOnchainIdentifier()) + chai.expect(deploymentTransaction.data.endsWith(onChainIdentifier)).to.be.true + }) + }) + + describe('Tracking Safe transactions on-chain via the transaction data field', () => { + it('should append the on-chain identifier to the execTransaction data field', async () => { + const onchainAnalytics: OnchainAnalyticsProps = { + project: 'Test e2e Project', + platform: 'Web' + } + + const { safe, contractNetworks } = await setupTests() + const safeAddress = safe.address + + const protocolKit = await Safe.init({ + provider, + safeAddress, + contractNetworks, + onchainAnalytics + }) + + const testTransaction = { + to: safeAddress, + value: '0', + data: '0x' + } + + const safeTransaction = await protocolKit.createTransaction({ + transactions: [testTransaction] + }) + + const isValidTransaction = await protocolKit.isValidTransaction(safeTransaction) + chai.expect(isValidTransaction).to.be.eq(true) + + const transactionResponse = await protocolKit.executeTransaction(safeTransaction) + + await waitSafeTxReceipt(transactionResponse) + + const transaction = await protocolKit + .getSafeProvider() + .getTransaction(transactionResponse.hash) + + // toolVersion is dynamic (currrent protocol-kit version) + const toolVersion = getProtocolKitVersion() + const toolHash = generateHash(toolVersion, 3) + + const onChainIdentifier = + '5afe003861653435366632366138366164643038373864646561393238' + toolHash + + chai.expect(onChainIdentifier).to.equals(protocolKit.getOnchainIdentifier()) + chai.expect(transaction.input.endsWith(onChainIdentifier)).to.be.true + }) + }) +}) diff --git a/packages/protocol-kit/tsconfig.build.json b/packages/protocol-kit/tsconfig.build.json index c05e497c4..416bcce06 100644 --- a/packages/protocol-kit/tsconfig.build.json +++ b/packages/protocol-kit/tsconfig.build.json @@ -1,8 +1,9 @@ { "extends": "../../tsconfig.settings.json", "compilerOptions": { + "resolveJsonModule": true, "composite": true, "outDir": "dist" }, - "include": ["src/**/*"] + "include": ["src/**/*", "package.json"] } diff --git a/packages/protocol-kit/tsconfig.json b/packages/protocol-kit/tsconfig.json index 5f6bc90a7..77c78ede6 100644 --- a/packages/protocol-kit/tsconfig.json +++ b/packages/protocol-kit/tsconfig.json @@ -1,8 +1,9 @@ { "extends": "../../tsconfig.settings.json", "compilerOptions": { + "resolveJsonModule": true, "composite": true, "outDir": "dist" }, - "include": ["src/**/*", "tests/**/*", "hardhat/**/*", "hardhat.config.ts"] + "include": ["package.json", "src/**/*", "tests/**/*", "hardhat/**/*", "hardhat.config.ts"] } diff --git a/packages/relay-kit/src/packs/safe-4337/Safe4337Pack.ts b/packages/relay-kit/src/packs/safe-4337/Safe4337Pack.ts index aa045d232..e45507f4a 100644 --- a/packages/relay-kit/src/packs/safe-4337/Safe4337Pack.ts +++ b/packages/relay-kit/src/packs/safe-4337/Safe4337Pack.ts @@ -5,7 +5,8 @@ import Safe, { encodeMultiSendData, getMultiSendContract, PasskeyClient, - SafeProvider + SafeProvider, + generateOnChainIdentifier } from '@safe-global/protocol-kit' import { RelayKitBasePack } from '@safe-global/relay-kit/RelayKitBasePack' import { @@ -52,6 +53,7 @@ import { } from './utils' import { entryPointToSafeModules, EQ_OR_GT_0_3_0 } from './utils/entrypoint' import { PimlicoFeeEstimator } from './estimators/PimlicoFeeEstimator' +import getRelayKitVersion from './utils/getRelayKitVersion' const MAX_ERC20_AMOUNT_TO_APPROVE = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn @@ -87,6 +89,8 @@ export class Safe4337Pack extends RelayKitBasePack<{ #paymasterOptions?: PaymasterOptions + #onchainIdentifier: string = '' + /** * Creates an instance of the Safe4337Pack. * @@ -100,7 +104,8 @@ export class Safe4337Pack extends RelayKitBasePack<{ paymasterOptions, entryPointAddress, safe4337ModuleAddress, - safeWebAuthnSharedSignerAddress + safeWebAuthnSharedSignerAddress, + onchainAnalytics }: Safe4337Options) { super(protocolKit) @@ -111,6 +116,16 @@ export class Safe4337Pack extends RelayKitBasePack<{ this.#ENTRYPOINT_ADDRESS = entryPointAddress this.#SAFE_4337_MODULE_ADDRESS = safe4337ModuleAddress this.#SAFE_WEBAUTHN_SHARED_SIGNER_ADDRESS = safeWebAuthnSharedSignerAddress || '0x' + + if (onchainAnalytics?.project) { + const { project, platform } = onchainAnalytics + this.#onchainIdentifier = generateOnChainIdentifier({ + project, + platform, + tool: 'relay-kit', + toolVersion: getRelayKitVersion() + }) + } } /** @@ -124,7 +139,16 @@ export class Safe4337Pack extends RelayKitBasePack<{ * @return {Promise} The Promise object that will be resolved into an instance of Safe4337Pack. */ static async init(initOptions: Safe4337InitOptions): Promise { - const { provider, signer, options, bundlerUrl, customContracts, paymasterOptions } = initOptions + const { + provider, + signer, + options, + bundlerUrl, + customContracts, + paymasterOptions, + onchainAnalytics + } = initOptions + let protocolKit: Safe const bundlerClient = getEip4337BundlerProvider(bundlerUrl) const chainId = await bundlerClient.request({ method: RPC_4337_CALLS.CHAIN_ID }) @@ -329,7 +353,8 @@ export class Safe4337Pack extends RelayKitBasePack<{ payment: 0, paymentReceiver: zeroAddress } - } + }, + onchainAnalytics }) } @@ -372,7 +397,8 @@ export class Safe4337Pack extends RelayKitBasePack<{ bundlerUrl, entryPointAddress: selectedEntryPoint!, safe4337ModuleAddress, - safeWebAuthnSharedSignerAddress + safeWebAuthnSharedSignerAddress, + onchainAnalytics }) } @@ -526,6 +552,10 @@ export class Safe4337Pack extends RelayKitBasePack<{ signature: '0x' } + if (this.#onchainIdentifier) { + userOperation.callData += this.#onchainIdentifier + } + const isSafeDeployed = await this.protocolKit.isSafeDeployed() if (!isSafeDeployed) { @@ -799,4 +829,8 @@ export class Safe4337Pack extends RelayKitBasePack<{ ] }) } + + getOnchainIdentifier(): string { + return this.#onchainIdentifier + } } diff --git a/packages/relay-kit/src/packs/safe-4337/types.ts b/packages/relay-kit/src/packs/safe-4337/types.ts index a64bda523..77ba49ae0 100644 --- a/packages/relay-kit/src/packs/safe-4337/types.ts +++ b/packages/relay-kit/src/packs/safe-4337/types.ts @@ -1,5 +1,9 @@ import { Account, Address, Chain, Hash, Hex, PublicClient, PublicRpcSchema, Transport } from 'viem' -import Safe, { DeploymentType, SafeProviderConfig } from '@safe-global/protocol-kit' +import Safe, { + DeploymentType, + SafeProviderConfig, + OnchainAnalyticsProps +} from '@safe-global/protocol-kit' import { EstimateGasData, MetaTransactionData, @@ -50,6 +54,7 @@ export type Safe4337InitOptions = { } options: ExistingSafeOptions | PredictedSafeOptions paymasterOptions?: PaymasterOptions + onchainAnalytics?: OnchainAnalyticsProps } export type Safe4337Options = { @@ -61,6 +66,7 @@ export type Safe4337Options = { entryPointAddress: string safe4337ModuleAddress: string safeWebAuthnSharedSignerAddress?: string + onchainAnalytics?: OnchainAnalyticsProps } export type Safe4337CreateTransactionProps = { diff --git a/packages/relay-kit/src/packs/safe-4337/utils/getRelayKitVersion.ts b/packages/relay-kit/src/packs/safe-4337/utils/getRelayKitVersion.ts new file mode 100644 index 000000000..8f90e8f67 --- /dev/null +++ b/packages/relay-kit/src/packs/safe-4337/utils/getRelayKitVersion.ts @@ -0,0 +1,7 @@ +import packageJson from '../../../../package.json' + +function getRelayKitVersion(): string { + return packageJson.version +} + +export default getRelayKitVersion diff --git a/packages/relay-kit/tsconfig.build.json b/packages/relay-kit/tsconfig.build.json index cc22498f1..9c287382b 100644 --- a/packages/relay-kit/tsconfig.build.json +++ b/packages/relay-kit/tsconfig.build.json @@ -1,9 +1,10 @@ { "extends": "../../tsconfig.settings.json", "compilerOptions": { + "resolveJsonModule": true, "composite": true, "outDir": "dist" }, - "include": ["src/**/*"], + "include": ["src/**/*", "package.json"], "exclude": ["src/**/*.test.ts", "src/**/*.test-d.ts"] } diff --git a/packages/relay-kit/tsconfig.json b/packages/relay-kit/tsconfig.json index c05e497c4..416bcce06 100644 --- a/packages/relay-kit/tsconfig.json +++ b/packages/relay-kit/tsconfig.json @@ -1,8 +1,9 @@ { "extends": "../../tsconfig.settings.json", "compilerOptions": { + "resolveJsonModule": true, "composite": true, "outDir": "dist" }, - "include": ["src/**/*"] + "include": ["src/**/*", "package.json"] } diff --git a/playground/protocol-kit/create-execute-transaction.ts b/playground/protocol-kit/create-execute-transaction.ts index 52e00230b..e4a9a3b9a 100644 --- a/playground/protocol-kit/create-execute-transaction.ts +++ b/playground/protocol-kit/create-execute-transaction.ts @@ -37,7 +37,7 @@ async function main() { console.log(' - Version: ', await safe.getContractVersion()) console.log(' - Threshold: ', await safe.getThreshold(), '\n') - // Create transaction + // Create rejection transaction const safeTransactionData: SafeTransactionDataPartial = { to: config.SAFE_ADDRESS, value: '1000000000000000', // 0.001 ether From 2b81d18e9834fa7cbca488c883122bd92fe23abd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Mart=C3=ADnez?= <6764315+germartinez@users.noreply.github.com> Date: Mon, 13 Jan 2025 17:15:17 +0100 Subject: [PATCH 2/8] Update license year (#1093) --- LICENSE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE.md b/LICENSE.md index 0e923d187..2b02a9d0b 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021-2024 Safe Ecosystem Foundation +Copyright (c) 2021-2025 Safe Ecosystem Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: From fe00fb165061e500b71ba6c8ae75de1cd864e748 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 17:55:38 +0100 Subject: [PATCH 3/8] chore(deps): bump cross-spawn from 7.0.3 to 7.0.6 (#1053) Bumps [cross-spawn](https://github.com/moxystudio/node-cross-spawn) from 7.0.3 to 7.0.6. - [Changelog](https://github.com/moxystudio/node-cross-spawn/blob/master/CHANGELOG.md) - [Commits](https://github.com/moxystudio/node-cross-spawn/compare/v7.0.3...v7.0.6) --- updated-dependencies: - dependency-name: cross-spawn dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index fd534b609..2db415d2c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3420,9 +3420,9 @@ cross-fetch@^4.0.0: node-fetch "^2.6.12" cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== dependencies: path-key "^3.1.0" shebang-command "^2.0.0" From ade2a9b60836faea749965caf0a0bf80b844888f Mon Sep 17 00:00:00 2001 From: Richard Henry Date: Wed, 15 Jan 2025 07:53:23 -0800 Subject: [PATCH 4/8] fix(protocol-kit): Fix non-ArrayBuffer passkey signature error (#1054) (#1094) --- .../protocol-kit/src/utils/passkeys/PasskeyClient.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/protocol-kit/src/utils/passkeys/PasskeyClient.ts b/packages/protocol-kit/src/utils/passkeys/PasskeyClient.ts index 40bec29dd..10eb5290a 100644 --- a/packages/protocol-kit/src/utils/passkeys/PasskeyClient.ts +++ b/packages/protocol-kit/src/utils/passkeys/PasskeyClient.ts @@ -200,11 +200,11 @@ function extractClientDataFields(clientDataJSON: ArrayBuffer): Hex { * Extracts the numeric values r and s from a DER-encoded ECDSA signature. * This function decodes the signature based on a specific format and validates the encoding at each step. * - * @param {ArrayBuffer} signature - The DER-encoded signature to be decoded. + * @param {ArrayBuffer | Uint8Array | Array} signature - The DER-encoded signature to be decoded. The WebAuthn standard expects the signature to be an ArrayBuffer, but some password managers (including Bitwarden) provide a Uint8Array or an array of numbers instead. * @returns {[bigint, bigint]} A tuple containing two BigInt values, r and s, which are the numeric values extracted from the signature. * @throws {Error} Throws an error if the signature encoding is invalid or does not meet expected conditions. */ -function extractSignature(signature: ArrayBuffer): [bigint, bigint] { +function extractSignature(signature: ArrayBuffer | Uint8Array | Array): [bigint, bigint] { const check = (x: boolean) => { if (!x) { throw new Error('invalid signature encoding') @@ -214,7 +214,13 @@ function extractSignature(signature: ArrayBuffer): [bigint, bigint] { // Decode the DER signature. Note that we assume that all lengths fit into 8-bit integers, // which is true for the kinds of signatures we are decoding but generally false. I.e. this // code should not be used in any serious application. - const view = new DataView(signature) + const view = new DataView( + signature instanceof ArrayBuffer + ? signature + : signature instanceof Uint8Array + ? signature.buffer + : new Uint8Array(signature).buffer + ) // check that the sequence header is valid check(view.getUint8(0) === 0x30) From 6d75e96289b48d126a1dca236c6825d2f10778ab Mon Sep 17 00:00:00 2001 From: Daniel <25051234+dasanra@users.noreply.github.com> Date: Wed, 15 Jan 2025 17:57:03 +0100 Subject: [PATCH 5/8] chore: fix typos (#1096) --- CONTRIBUTING.md | 4 ++-- playground/README.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3af627092..62fb3dcb6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,7 +17,7 @@ You will need to agree to [our CLA](https://safe.global/cla) in order to be poss ### Starting Guide -By following the steps bellow you will understand the development process and worflow. +By following the steps below you will understand the development process and workflow. 1. [Forking the repository](#forking-the-repository) 2. [Installing Node and Yarn](#installing-node-and-yarn) 3. [Installing dependencies](#installing-dependencies) @@ -44,7 +44,7 @@ yarn -v #### Installing dependencies -The Safe{Core} SDK uses a mono-repository structure managed by [Yarn Workspaces](https://classic.yarnpkg.com/lang/en/docs/workspaces/) and [Lerna](https://lerna.js.org). From the root of the repository you will need to install the whole dependency stack and do the project build. Some packages depend on each other, so even when modifiying only one package it's better to run the full build. +The Safe{Core} SDK uses a mono-repository structure managed by [Yarn Workspaces](https://classic.yarnpkg.com/lang/en/docs/workspaces/) and [Lerna](https://lerna.js.org). From the root of the repository you will need to install the whole dependency stack and do the project build. Some packages depend on each other, so even when modifying only one package it's better to run the full build. Install all dependencies and build the whole project by using the following commands at the project root. diff --git a/playground/README.md b/playground/README.md index 8558750a2..fa08b7625 100644 --- a/playground/README.md +++ b/playground/README.md @@ -55,7 +55,7 @@ In case you want to execute the transaction via a transaction relay, this script yarn play relay-sponsored-transaction ``` -#### Generate a custon Safe address +#### Generate a custom Safe address This script allows to find the right `saltNonce` to generate a vanity Safe address with any given configuration: From fdfb6c7e28b0b52f31f9885fdc43fdcb33670b68 Mon Sep 17 00:00:00 2001 From: Dani Somoza Date: Thu, 16 Jan 2025 15:48:19 +0100 Subject: [PATCH 6/8] fix Generate getProtocolKitVersion dynamically via prebuild script (#1098) --- packages/protocol-kit/package.json | 1 + packages/protocol-kit/src/Safe.ts | 2 +- packages/protocol-kit/src/utils/getProtocolKitVersion.ts | 8 +------- packages/protocol-kit/tests/e2e/onChainIdentifier.test.ts | 5 +++-- packages/protocol-kit/tsconfig.build.json | 3 +-- packages/protocol-kit/tsconfig.json | 3 +-- packages/relay-kit/package.json | 1 + packages/relay-kit/src/packs/safe-4337/Safe4337Pack.ts | 2 +- .../src/packs/safe-4337/utils/getRelayKitVersion.ts | 8 +------- packages/relay-kit/tsconfig.build.json | 3 +-- packages/relay-kit/tsconfig.json | 3 +-- 11 files changed, 13 insertions(+), 26 deletions(-) diff --git a/packages/protocol-kit/package.json b/packages/protocol-kit/package.json index 865e511d9..445205ae7 100644 --- a/packages/protocol-kit/package.json +++ b/packages/protocol-kit/package.json @@ -35,6 +35,7 @@ "format:check": "prettier --check \"*/**/*.{js,json,md,ts}\"", "format": "prettier --write \"*/**/*.{js,json,md,ts}\"", "unbuild": "rimraf dist artifacts deployments cache .nyc_output *.tsbuildinfo", + "prebuild": "node -p \"'export const getProtocolKitVersion = () => \\'' + require('./package.json').version.split('-')[0] + '\\''\" > src/utils/getProtocolKitVersion.ts", "build": "yarn unbuild && yarn check-safe-deployments && NODE_OPTIONS=--max-old-space-size=8192 tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json" }, "repository": { diff --git a/packages/protocol-kit/src/Safe.ts b/packages/protocol-kit/src/Safe.ts index c578ac8af..b9482711f 100644 --- a/packages/protocol-kit/src/Safe.ts +++ b/packages/protocol-kit/src/Safe.ts @@ -88,7 +88,7 @@ import { Hash, Hex, SendTransactionParameters } from 'viem' import getPasskeyOwnerAddress from './utils/passkeys/getPasskeyOwnerAddress' import createPasskeyDeploymentTransaction from './utils/passkeys/createPasskeyDeploymentTransaction' import generateOnChainIdentifier from './utils/on-chain-tracking/generateOnChainIdentifier' -import getProtocolKitVersion from './utils/getProtocolKitVersion' +import { getProtocolKitVersion } from './utils/getProtocolKitVersion' const EQ_OR_GT_1_4_1 = '>=1.4.1' const EQ_OR_GT_1_3_0 = '>=1.3.0' diff --git a/packages/protocol-kit/src/utils/getProtocolKitVersion.ts b/packages/protocol-kit/src/utils/getProtocolKitVersion.ts index 3abd3bdb4..1b0fb92fd 100644 --- a/packages/protocol-kit/src/utils/getProtocolKitVersion.ts +++ b/packages/protocol-kit/src/utils/getProtocolKitVersion.ts @@ -1,7 +1 @@ -import packageJson from '../../package.json' - -function getProtocolKitVersion(): string { - return packageJson.version -} - -export default getProtocolKitVersion +export const getProtocolKitVersion = () => '5.1.1' diff --git a/packages/protocol-kit/tests/e2e/onChainIdentifier.test.ts b/packages/protocol-kit/tests/e2e/onChainIdentifier.test.ts index b45f47769..c18f6050c 100644 --- a/packages/protocol-kit/tests/e2e/onChainIdentifier.test.ts +++ b/packages/protocol-kit/tests/e2e/onChainIdentifier.test.ts @@ -10,7 +10,8 @@ import Sinon from 'sinon' import chaiAsPromised from 'chai-as-promised' import { generateHash } from '@safe-global/protocol-kit/utils/on-chain-tracking/generateOnChainIdentifier' -import getProtocolKitVersion, * as getProtocolKitVersionModule from '@safe-global/protocol-kit/utils/getProtocolKitVersion' +import * as getProtocolKitVersionModule from '@safe-global/protocol-kit/utils/getProtocolKitVersion' +import { getProtocolKitVersion } from '@safe-global/protocol-kit/utils/getProtocolKitVersion' import { getEip1193Provider } from './utils/setupProvider' import { waitSafeTxReceipt } from './utils/transactions' @@ -47,7 +48,7 @@ describe('On-chain analytics', () => { platform: 'Web' } - const stub = Sinon.stub(getProtocolKitVersionModule, 'default').returns('5.0.4') + const stub = Sinon.stub(getProtocolKitVersionModule, 'getProtocolKitVersion').returns('5.0.4') const { safe, contractNetworks } = await setupTests() const safeAddress = safe.address diff --git a/packages/protocol-kit/tsconfig.build.json b/packages/protocol-kit/tsconfig.build.json index 416bcce06..c05e497c4 100644 --- a/packages/protocol-kit/tsconfig.build.json +++ b/packages/protocol-kit/tsconfig.build.json @@ -1,9 +1,8 @@ { "extends": "../../tsconfig.settings.json", "compilerOptions": { - "resolveJsonModule": true, "composite": true, "outDir": "dist" }, - "include": ["src/**/*", "package.json"] + "include": ["src/**/*"] } diff --git a/packages/protocol-kit/tsconfig.json b/packages/protocol-kit/tsconfig.json index 77c78ede6..5f6bc90a7 100644 --- a/packages/protocol-kit/tsconfig.json +++ b/packages/protocol-kit/tsconfig.json @@ -1,9 +1,8 @@ { "extends": "../../tsconfig.settings.json", "compilerOptions": { - "resolveJsonModule": true, "composite": true, "outDir": "dist" }, - "include": ["package.json", "src/**/*", "tests/**/*", "hardhat/**/*", "hardhat.config.ts"] + "include": ["src/**/*", "tests/**/*", "hardhat/**/*", "hardhat.config.ts"] } diff --git a/packages/relay-kit/package.json b/packages/relay-kit/package.json index 51313a3e6..4522c6033 100644 --- a/packages/relay-kit/package.json +++ b/packages/relay-kit/package.json @@ -19,6 +19,7 @@ "format:check": "prettier --check \"*/**/*.{js,json,md,ts}\"", "format": "prettier --write \"*/**/*.{js,json,md,ts}\"", "unbuild": "rimraf dist .nyc_output cache", + "prebuild": "node -p \"'export const getRelayKitVersion = () => \\'' + require('./package.json').version.split('-')[0] + '\\''\" > src/packs/safe-4337/utils/getRelayKitVersion.ts", "build": "yarn unbuild && tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json" }, "repository": { diff --git a/packages/relay-kit/src/packs/safe-4337/Safe4337Pack.ts b/packages/relay-kit/src/packs/safe-4337/Safe4337Pack.ts index e45507f4a..5162c88f2 100644 --- a/packages/relay-kit/src/packs/safe-4337/Safe4337Pack.ts +++ b/packages/relay-kit/src/packs/safe-4337/Safe4337Pack.ts @@ -53,7 +53,7 @@ import { } from './utils' import { entryPointToSafeModules, EQ_OR_GT_0_3_0 } from './utils/entrypoint' import { PimlicoFeeEstimator } from './estimators/PimlicoFeeEstimator' -import getRelayKitVersion from './utils/getRelayKitVersion' +import { getRelayKitVersion } from './utils/getRelayKitVersion' const MAX_ERC20_AMOUNT_TO_APPROVE = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn diff --git a/packages/relay-kit/src/packs/safe-4337/utils/getRelayKitVersion.ts b/packages/relay-kit/src/packs/safe-4337/utils/getRelayKitVersion.ts index 8f90e8f67..33ed10cdc 100644 --- a/packages/relay-kit/src/packs/safe-4337/utils/getRelayKitVersion.ts +++ b/packages/relay-kit/src/packs/safe-4337/utils/getRelayKitVersion.ts @@ -1,7 +1 @@ -import packageJson from '../../../../package.json' - -function getRelayKitVersion(): string { - return packageJson.version -} - -export default getRelayKitVersion +export const getRelayKitVersion = () => '3.3.1' diff --git a/packages/relay-kit/tsconfig.build.json b/packages/relay-kit/tsconfig.build.json index 9c287382b..cc22498f1 100644 --- a/packages/relay-kit/tsconfig.build.json +++ b/packages/relay-kit/tsconfig.build.json @@ -1,10 +1,9 @@ { "extends": "../../tsconfig.settings.json", "compilerOptions": { - "resolveJsonModule": true, "composite": true, "outDir": "dist" }, - "include": ["src/**/*", "package.json"], + "include": ["src/**/*"], "exclude": ["src/**/*.test.ts", "src/**/*.test-d.ts"] } diff --git a/packages/relay-kit/tsconfig.json b/packages/relay-kit/tsconfig.json index 416bcce06..c05e497c4 100644 --- a/packages/relay-kit/tsconfig.json +++ b/packages/relay-kit/tsconfig.json @@ -1,9 +1,8 @@ { "extends": "../../tsconfig.settings.json", "compilerOptions": { - "resolveJsonModule": true, "composite": true, "outDir": "dist" }, - "include": ["src/**/*", "package.json"] + "include": ["src/**/*"] } From d71adfb1f18133ba575c51da9fbf4b6c5f30f455 Mon Sep 17 00:00:00 2001 From: Daniel <25051234+dasanra@users.noreply.github.com> Date: Mon, 20 Jan 2025 14:17:48 +0100 Subject: [PATCH 7/8] chore: set release versions --- packages/api-kit/package.json | 6 +++--- packages/protocol-kit/package.json | 2 +- packages/relay-kit/package.json | 4 ++-- packages/sdk-starter-kit/package.json | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/api-kit/package.json b/packages/api-kit/package.json index 71389b68f..f0af74cd8 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.6", + "version": "2.5.7", "description": "SDK that facilitates the interaction with the Safe Transaction Service API", "main": "dist/src/index.js", "typings": "dist/src/index.d.ts", @@ -39,7 +39,7 @@ ], "homepage": "https://github.com/safe-global/safe-core-sdk#readme", "devDependencies": { - "@safe-global/relay-kit": "^3.3.1", + "@safe-global/relay-kit": "^3.4.0", "@safe-global/testing-kit": "^0.1.1", "@types/chai": "^4.3.19", "@types/chai-as-promised": "^7.1.8", @@ -58,7 +58,7 @@ "web3": "^4.12.1" }, "dependencies": { - "@safe-global/protocol-kit": "^5.1.1", + "@safe-global/protocol-kit": "^5.2.0", "@safe-global/types-kit": "^1.0.1", "node-fetch": "^2.7.0", "viem": "^2.21.8" diff --git a/packages/protocol-kit/package.json b/packages/protocol-kit/package.json index 445205ae7..4f3c30e55 100644 --- a/packages/protocol-kit/package.json +++ b/packages/protocol-kit/package.json @@ -1,6 +1,6 @@ { "name": "@safe-global/protocol-kit", - "version": "5.1.1", + "version": "5.2.0", "description": "SDK that facilitates the interaction with Safe Smart Accounts", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", diff --git a/packages/relay-kit/package.json b/packages/relay-kit/package.json index 4522c6033..8edc57761 100644 --- a/packages/relay-kit/package.json +++ b/packages/relay-kit/package.json @@ -1,6 +1,6 @@ { "name": "@safe-global/relay-kit", - "version": "3.3.1", + "version": "3.4.0", "description": "SDK for Safe Smart Accounts with support for ERC-4337 and Relay", "main": "dist/src/index.js", "typings": "dist/src/index.d.ts", @@ -40,7 +40,7 @@ }, "dependencies": { "@gelatonetwork/relay-sdk": "^5.5.0", - "@safe-global/protocol-kit": "^5.1.1", + "@safe-global/protocol-kit": "^5.2.0", "@safe-global/safe-modules-deployments": "^2.2.4", "@safe-global/types-kit": "^1.0.1", "viem": "^2.21.8" diff --git a/packages/sdk-starter-kit/package.json b/packages/sdk-starter-kit/package.json index 67dc95cdd..f13623588 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.1.1", + "version": "1.1.2", "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.6", - "@safe-global/protocol-kit": "^5.1.1", - "@safe-global/relay-kit": "^3.3.1", + "@safe-global/api-kit": "^2.5.7", + "@safe-global/protocol-kit": "^5.2.0", + "@safe-global/relay-kit": "^3.4.0", "@safe-global/types-kit": "^1.0.1", "viem": "^2.21.8" } From 35a2e197b9ff76892bc370ce91845ee71819e407 Mon Sep 17 00:00:00 2001 From: Daniel <25051234+dasanra@users.noreply.github.com> Date: Mon, 20 Jan 2025 14:32:01 +0100 Subject: [PATCH 8/8] chore: update versioning function from packages --- packages/protocol-kit/src/utils/getProtocolKitVersion.ts | 2 +- .../relay-kit/src/packs/safe-4337/utils/getRelayKitVersion.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/protocol-kit/src/utils/getProtocolKitVersion.ts b/packages/protocol-kit/src/utils/getProtocolKitVersion.ts index 1b0fb92fd..5d86d0cc2 100644 --- a/packages/protocol-kit/src/utils/getProtocolKitVersion.ts +++ b/packages/protocol-kit/src/utils/getProtocolKitVersion.ts @@ -1 +1 @@ -export const getProtocolKitVersion = () => '5.1.1' +export const getProtocolKitVersion = () => '5.2.0' diff --git a/packages/relay-kit/src/packs/safe-4337/utils/getRelayKitVersion.ts b/packages/relay-kit/src/packs/safe-4337/utils/getRelayKitVersion.ts index 33ed10cdc..ff61d506d 100644 --- a/packages/relay-kit/src/packs/safe-4337/utils/getRelayKitVersion.ts +++ b/packages/relay-kit/src/packs/safe-4337/utils/getRelayKitVersion.ts @@ -1 +1 @@ -export const getRelayKitVersion = () => '3.3.1' +export const getRelayKitVersion = () => '3.4.0'