From ff328b313c59589172bcca390820bb8f60c7aafb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Mart=C3=ADnez?= Date: Fri, 10 Jan 2025 18:00:03 +0100 Subject: [PATCH 1/5] Add onchain tracking page --- pages/sdk/_meta.json | 1 + pages/sdk/onchain-tracking.mdx | 182 +++++++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 pages/sdk/onchain-tracking.mdx diff --git a/pages/sdk/_meta.json b/pages/sdk/_meta.json index 982acac7..3d9dbec9 100644 --- a/pages/sdk/_meta.json +++ b/pages/sdk/_meta.json @@ -22,5 +22,6 @@ "title": "Integrations" }, "signers": "Signers", + "onchain-tracking": "On-chain Tracking", "onramp": "Onramp" } diff --git a/pages/sdk/onchain-tracking.mdx b/pages/sdk/onchain-tracking.mdx new file mode 100644 index 00000000..c57e8723 --- /dev/null +++ b/pages/sdk/onchain-tracking.mdx @@ -0,0 +1,182 @@ +import { Tabs, Steps } from 'nextra/components' + +# On-chain Tracking + +We aim to understand better and recognise our key contributors who are driving the adoption of smart accounts within our ecosystem. + +Implementing a Safe on-chain identifier enables tracking of complex data, such as whether a Safe transaction is executed via our SDK or another, whether it originates from a platform like a Safe App or widget (e.g., the CoW Swap widget in our Safe interface), the tool version, the project, and more. + +By submitting your on-chain identifier through the form provided at the end of this page, you will help us accurately attribute activity and allow us to return value to our Ecosystem Partners in the future. + +## On-chain identifier format + +The identifiers used to track Safe deployments and transactions are 50 bytes in length and follow the format below: + +`5afe` `00` `6363643438383836663461336661366162653539` `646561` `393238` `653366` + +Check the last 50 bytes of the `data` field in this [example transaction](https://sepolia.etherscan.io/tx/0xe0192eedd1fc2d06be0561d57380d610dd6d162af0f3cfbd6c08f9062d738761) to see how the identifier appears after the transaction is executed. + +### Prefix hash + +- **Type:** `2 bytes` +- **Example:** `5afe` + +Static prefix to identify the Safe on-chain identifier. + +### Version hash + +- **Type:** `1 byte` +- **Example:** `00` + +Version number of the Safe on-chain identifier format. + +### Project hash + +- **Type:** `20 bytes` +- **Example:** `6363643438383836663461336661366162653539` + +Truncated hash of the project's name (e.g., "Gnosis", "CoW Swap"). + +### Platform hash + +- **Type:** `3 bytes` +- **Example:** `646561` + +Truncated hash of the platform's name (e.g., "Web", "Mobile", "Safe App", "Widget"). + +### Tool hash + +- **Type:** `3 bytes` +- **Example:** `393238` + +Truncated hash of the tool's name (e.g., "protocol-kit", "relay-kit", or any custom tool built by projects). + +### Tool version hash + +- **Type:** `3 bytes` +- **Example:** `653366` + +Truncated hash of the tool's version (e.g., "1.0.0", "1.0.1"). + +## Steps + +The on-chain identifier allows tracking the deployment of Safe accounts, the execution of Safe transactions, and the execution of Safe user operations: + + + + ### Track Safe deployments + + Safe deployments can be tracked by assigning an on-chain identifier to the [`paymentReceiver`](../reference-smart-account/setup/setup.mdx#paymentreceiver) or [`saltNonce`](https://github.com/safe-global/safe-smart-account/blob/main/contracts/proxies/SafeProxyFactory.sol#L55) properties during the Safe configuration and deployment. + + If you use the [Protocol Kit](../sdk/protocol-kit.mdx) or the [Relay Kit](../sdk/relay-kit.mdx) to deploy a Safe, adding the `onchainAnalytics` property to the initialization method will automatically handle this. The deployment transaction will include the identifier. + + {/* */} + + + + ```typescript + import Safe, { OnchainAnalyticsProps } from '@safe-global/protocol-kit' + + const onchainAnalytics: OnchainAnalyticsProps = { + project: 'YOUR_PROJECT_NAME' + platform: 'CURRENT_PLATFORM' // Optional + } + + const protocolKit = await Safe.init({ + // ... + onchainAnalytics + }) + + // Execute the deployment + ``` + + + ```typescript + import { Safe4337Pack } from '@safe-global/relay-kit' + import { OnchainAnalyticsProps } from '@safe-global/protocol-kit' + + const onchainAnalytics: OnchainAnalyticsProps = { + project: 'YOUR_PROJECT_NAME' + platform: 'CURRENT_PLATFORM' // Optional + } + + const safe4337Pack = await Safe4337Pack.init({ + // ... + onchainAnalytics + }) + + // Execute the deployment + ``` + + + + {/* */} + + ### Track Safe transactions + + Safe transactions can be tracked by concatenating the on-chain identifier at the end of the transaction `data` or user operation `callData` properties. + + If you use the [Protocol Kit](../sdk/protocol-kit.mdx) or the [Relay Kit](../sdk/relay-kit.mdx) to execute the Safe transactions, adding the `onchainAnalytics` property to the initialization method will automatically handle this. The Safe transactions will include the identifier. + + + + ```typescript + import Safe, { OnchainAnalyticsProps } from '@safe-global/protocol-kit' + + const onchainAnalytics: OnchainAnalyticsProps = { + project: 'YOUR_PROJECT_NAME' + platform: 'CURRENT_PLATFORM' // Optional + } + + const protocolKit = await Safe.init({ + // ... + onchainAnalytics + }) + + // Execute the transaction + ``` + + + ```typescript + import { Safe4337Pack } from '@safe-global/relay-kit' + import { OnchainAnalyticsProps } from '@safe-global/protocol-kit' + + const onchainAnalytics: OnchainAnalyticsProps = { + project: 'YOUR_PROJECT_NAME' + platform: 'CURRENT_PLATFORM' // Optional + } + + const safe4337Pack = await Safe4337Pack.init({ + // ... + onchainAnalytics + }) + + // Execute the transaction + ``` + + + + ### Get the on-chain identifier + + To get the current safe on-chain identifier, you can use the `getOnchainIdentifier` method from an initialized instance of the Protocol Kit. + + {/* */} + + ```typescript + const onchainIdentifier = protocolKit.getOnchainIdentifier() + ``` + + {/* */} + + + +## Submission Form + +
+ + From 330c672bced559e8f7ecf83284fda2e5624d8449 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Mart=C3=ADnez?= Date: Fri, 10 Jan 2025 18:02:07 +0100 Subject: [PATCH 2/5] Update Protocol Kit guides with onchain tracking --- .../guides/execute-transactions.mdx | 35 +++---------------- .../guides/multichain-safe-deployment.mdx | 10 ++++-- .../protocol-kit/guides/safe-deployment.mdx | 5 ++- 3 files changed, 16 insertions(+), 34 deletions(-) diff --git a/pages/sdk/protocol-kit/guides/execute-transactions.mdx b/pages/sdk/protocol-kit/guides/execute-transactions.mdx index 4c2e9fac..b5e34c50 100644 --- a/pages/sdk/protocol-kit/guides/execute-transactions.mdx +++ b/pages/sdk/protocol-kit/guides/execute-transactions.mdx @@ -73,13 +73,16 @@ pnpm add @safe-global/api-kit \ To handle transactions and signatures, you need to create an instance of the Protocol Kit with the `provider`, `signer` and `safeAddress`. + Optionally, you can [track your Safe transactions on-chain](../../onchain-tracking.mdx) by using the `onchainAnalytics` property. + {/* */} ```typescript const protocolKitOwner1 = await Safe.init({ provider: RPC_URL, signer: OWNER_1_PRIVATE_KEY, - safeAddress: SAFE_ADDRESS + safeAddress: SAFE_ADDRESS, + onchainAnalytics // Optional }) ``` @@ -108,36 +111,6 @@ pnpm add @safe-global/api-kit \ For more details on what to include in a transaction, see the [`createTransaction`](../reference/safe.mdx#createtransaction) method in the reference. - ### Track the Safe transaction - - Optionally, you can track all your Safe transactions on-chain by attaching an on-chain identifier to the `data` property. - - This identifier must be unique for every project and has a length of 16 bytes. You can create a random one or derive it from a text string, maybe from your project name: - - {/* */} - - ```typescript - const onchainIdentifier = toHex( - 'TEXT_TO_DERIVE_THE_IDENTIFIER', // It could be your project name - { size: 16 } - ) - ``` - - {/* */} - - Once generated, fill out the [Ecosystem On-chain Tracking Form](https://docs.google.com/forms/d/e/1FAIpQLSfHWSPbSQwmo0mbtuFFewfLvDEOvTxfuvEl7AHOyrFE_dqpwQ/viewform) and provide the value of your `onchainIdentifier`. - - Add the `onchainIdentifier` at the end of the Safe transaction `data`. - - {/* */} - - ```typescript - safeTransaction.data.data = concat([ - safeOperation.data.data as `0x{string}`, - onchainIdentifier - ]).toString() - ``` - {/* */} ### Propose the transaction diff --git a/pages/sdk/protocol-kit/guides/multichain-safe-deployment.mdx b/pages/sdk/protocol-kit/guides/multichain-safe-deployment.mdx index 364fbba2..2c65b292 100644 --- a/pages/sdk/protocol-kit/guides/multichain-safe-deployment.mdx +++ b/pages/sdk/protocol-kit/guides/multichain-safe-deployment.mdx @@ -87,16 +87,22 @@ pnpm add @safe-global/protocol-kit viem const protocolKitSepolia = await Safe.init({ provider: sepolia.rpcUrls.default.http[0], signer: SIGNER_PRIVATE_KEY, - predictedSafe + predictedSafe, + onchainAnalytics // Optional + // ... }) const protocolKitChiado = await Safe.init({ provider: gnosisChiado.rpcUrls.default.http[0], signer: PRIVATE_KEY, - predictedSafe + predictedSafe, + onchainAnalytics // Optional + // ... }) ``` + Optionally, you can [track your Safe deployments and transactions on-chain](../../onchain-tracking.mdx) by using the `onchainAnalytics` property. + {/* */} ### Predict the Safe addresses diff --git a/pages/sdk/protocol-kit/guides/safe-deployment.mdx b/pages/sdk/protocol-kit/guides/safe-deployment.mdx index a771dc51..83c4bb95 100644 --- a/pages/sdk/protocol-kit/guides/safe-deployment.mdx +++ b/pages/sdk/protocol-kit/guides/safe-deployment.mdx @@ -59,6 +59,8 @@ pnpm add @safe-global/protocol-kit viem Initialize an instance of the Protocol Kit for each network where you want to deploy a new Safe smart account by calling the [`init`](../../../reference-sdk-protocol-kit/initialization/init.mdx) method. Pass the `provider` with its corresponding value depending on the network, the `signer` executing the deployment, and the [`predictedSafe`](../../../reference-sdk-protocol-kit/initialization/init.mdx#predictedsafe-optional) with the Safe account configuration. + Optionally, you can [track your Safe deployments and transactions on-chain](../../onchain-tracking.mdx) by using the `onchainAnalytics` property. + {/* */} ```typescript @@ -76,7 +78,8 @@ pnpm add @safe-global/protocol-kit viem const protocolKit = await Safe.init({ provider: sepolia.rpcUrls.default.http[0], signer: SIGNER_PRIVATE_KEY, - predictedSafe + predictedSafe, + onchainAnalytics // Optional }) ``` From c98a5c907143f73c7b05a881730d5575afd54560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Mart=C3=ADnez?= Date: Fri, 10 Jan 2025 18:02:15 +0100 Subject: [PATCH 3/5] Update Relay Kit guides with onchain tracking --- pages/sdk/relay-kit/guides/4337-safe-sdk.mdx | 44 +++----------------- 1 file changed, 6 insertions(+), 38 deletions(-) diff --git a/pages/sdk/relay-kit/guides/4337-safe-sdk.mdx b/pages/sdk/relay-kit/guides/4337-safe-sdk.mdx index a8776902..c9c6b98d 100644 --- a/pages/sdk/relay-kit/guides/4337-safe-sdk.mdx +++ b/pages/sdk/relay-kit/guides/4337-safe-sdk.mdx @@ -67,6 +67,8 @@ yarn add @safe-global/relay-kit When deploying a new Safe account, we need to pass the configuration of the Safe in the `options` property. In this case, we are configuring a Safe account that will have our signer as the only owner. + Optionally, you can [track your ERC-4337 Safe transactions on-chain](../../onchain-tracking.mdx) by using the `onchainAnalytics` property. + ```typescript const safe4337Pack = await Safe4337Pack.init({ provider: RPC_URL, @@ -76,12 +78,15 @@ yarn add @safe-global/relay-kit owners: [SIGNER_ADDRESS], threshold: 1 }, + onchainAnalytics // Optional // ... }) ``` When connecting an existing Safe account, we need to pass the `safeAddress` in the `options` property. + + Optionally, you can [track your ERC-4337 Safe transactions on-chain](../../onchain-tracking.mdx) by using the `onchainAnalytics` property. ```typescript const safe4337Pack = await Safe4337Pack.init({ @@ -91,6 +96,7 @@ yarn add @safe-global/relay-kit options: { safeAddress: '0x...' }, + onchainAnalytics // Optional // ... }) ``` @@ -166,44 +172,6 @@ yarn add @safe-global/relay-kit The `safeOperation` object has the `data` and `signatures` properties, which contain all the information about the transaction batch and the signatures of the Safe owners, respectively. - ### Track the user operation - - Optionally, you can track all your ERC-4337 Safe transactions on-chain by attaching an on-chain identifier to the user operation `callData`. - - This identifier must be unique for every project and has a length of 16 bytes. You can create a random one or derive it from a text string, maybe from your project name: - - {/* */} - - ```typescript - const onchainIdentifier = toHex( - 'TEXT_TO_DERIVE_THE_IDENTIFIER', // It could be your project name - { size: 16 } - ) - ``` - - {/* */} - - Once generated, fill the [Ecosystem On-chain Tracking Form](https://docs.google.com/forms/d/e/1FAIpQLSfHWSPbSQwmo0mbtuFFewfLvDEOvTxfuvEl7AHOyrFE_dqpwQ/viewform) and provide the value of your `onchainIdentifier`. - - Add the `onchainIdentifier` at the end of the ERC-4337 user operation `callData`. - - {/* */} - - ```typescript - safeOperation.data.callData = concat([ - safeOperation.data.callData as `0x{string}`, - onchainIdentifier - ]).toString() - - const identifiedSafeOperation = await safe4337Pack.getEstimateFee({ - safeOperation - }) - ``` - - {/* */} - - Once added, the Safe owners can sign the `identifiedSafeOperation`. - ### Sign the user operation Before sending the user operation to the bundler, it's required to sign the `safeOperation` object with the connected signer. The `signSafeOperation()` method, which receives a `SafeOperation` object, generates a signature that will be checked when the `Safe4337Module` validates the user operation. From 6ab7fcf613c2a8b8398c2da9e2d9333bb319bfec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Mart=C3=ADnez?= Date: Fri, 10 Jan 2025 18:05:10 +0100 Subject: [PATCH 4/5] Fix language --- pages/sdk/onchain-tracking.mdx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pages/sdk/onchain-tracking.mdx b/pages/sdk/onchain-tracking.mdx index c57e8723..53073523 100644 --- a/pages/sdk/onchain-tracking.mdx +++ b/pages/sdk/onchain-tracking.mdx @@ -4,7 +4,7 @@ import { Tabs, Steps } from 'nextra/components' We aim to understand better and recognise our key contributors who are driving the adoption of smart accounts within our ecosystem. -Implementing a Safe on-chain identifier enables tracking of complex data, such as whether a Safe transaction is executed via our SDK or another, whether it originates from a platform like a Safe App or widget (e.g., the CoW Swap widget in our Safe interface), the tool version, the project, and more. +Implementing a Safe on-chain identifier enables tracking of complex data, such as whether a Safe transaction is executed via our SDK or another, whether it originates from a platform like a Safe App or widget (for example, the CoW Swap widget in our Safe interface), the tool version, the project, and more. By submitting your on-chain identifier through the form provided at the end of this page, you will help us accurately attribute activity and allow us to return value to our Ecosystem Partners in the future. @@ -35,28 +35,28 @@ Version number of the Safe on-chain identifier format. - **Type:** `20 bytes` - **Example:** `6363643438383836663461336661366162653539` -Truncated hash of the project's name (e.g., "Gnosis", "CoW Swap"). +Truncated hash of the project's name (for example, "Gnosis", "CoW Swap"). ### Platform hash - **Type:** `3 bytes` - **Example:** `646561` -Truncated hash of the platform's name (e.g., "Web", "Mobile", "Safe App", "Widget"). +Truncated hash of the platform's name (for example, "Web", "Mobile", "Safe App", "Widget"). ### Tool hash - **Type:** `3 bytes` - **Example:** `393238` -Truncated hash of the tool's name (e.g., "protocol-kit", "relay-kit", or any custom tool built by projects). +Truncated hash of the tool's name (for example, "protocol-kit", "relay-kit", or any custom tool built by projects). ### Tool version hash - **Type:** `3 bytes` - **Example:** `653366` -Truncated hash of the tool's version (e.g., "1.0.0", "1.0.1"). +Truncated hash of the tool's version (for example, "1.0.0", "1.0.1"). ## Steps From c711a0ca0cc47707c3ac7ecbe81ff5b56083c745 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Mart=C3=ADnez?= Date: Fri, 10 Jan 2025 18:09:02 +0100 Subject: [PATCH 5/5] Update Vale checks --- pages/sdk/onchain-tracking.mdx | 4 ++++ pages/sdk/protocol-kit/guides/execute-transactions.mdx | 6 ++---- .../protocol-kit/guides/multichain-safe-deployment.mdx | 8 ++++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/pages/sdk/onchain-tracking.mdx b/pages/sdk/onchain-tracking.mdx index 53073523..7ae2217d 100644 --- a/pages/sdk/onchain-tracking.mdx +++ b/pages/sdk/onchain-tracking.mdx @@ -118,6 +118,8 @@ The on-chain identifier allows tracking the deployment of Safe accounts, the exe If you use the [Protocol Kit](../sdk/protocol-kit.mdx) or the [Relay Kit](../sdk/relay-kit.mdx) to execute the Safe transactions, adding the `onchainAnalytics` property to the initialization method will automatically handle this. The Safe transactions will include the identifier. + {/* */} + ```typescript @@ -156,6 +158,8 @@ The on-chain identifier allows tracking the deployment of Safe accounts, the exe + {/* */} + ### Get the on-chain identifier To get the current safe on-chain identifier, you can use the `getOnchainIdentifier` method from an initialized instance of the Protocol Kit. diff --git a/pages/sdk/protocol-kit/guides/execute-transactions.mdx b/pages/sdk/protocol-kit/guides/execute-transactions.mdx index b5e34c50..5d3a9842 100644 --- a/pages/sdk/protocol-kit/guides/execute-transactions.mdx +++ b/pages/sdk/protocol-kit/guides/execute-transactions.mdx @@ -90,10 +90,10 @@ pnpm add @safe-global/api-kit \ ### Create a transaction - {/* */} - Create a `safeTransactionData` object with the properties of the transaction, add it to an array of transactions you want to execute, and pass it to the `createTransaction` method. + {/* */} + ```typescript const safeTransactionData: MetaTransactionData = { to: '0x', @@ -111,8 +111,6 @@ pnpm add @safe-global/api-kit \ For more details on what to include in a transaction, see the [`createTransaction`](../reference/safe.mdx#createtransaction) method in the reference. - {/* */} - ### Propose the transaction Before a transaction can be executed, the signer who creates it needs to send it to the Safe Transaction Service so that it is accessible by the other owners, who can then give their approval and sign the transaction. diff --git a/pages/sdk/protocol-kit/guides/multichain-safe-deployment.mdx b/pages/sdk/protocol-kit/guides/multichain-safe-deployment.mdx index 2c65b292..af488de4 100644 --- a/pages/sdk/protocol-kit/guides/multichain-safe-deployment.mdx +++ b/pages/sdk/protocol-kit/guides/multichain-safe-deployment.mdx @@ -66,12 +66,12 @@ pnpm add @safe-global/protocol-kit viem const safeAccountConfig: SafeAccountConfig = { owners: ['0x...', '0x...', '0x...'], threshold: 2 - // More optional properties + // ... } const predictedSafe: PredictedSafeProps = { safeAccountConfig - // More optional properties + // ... } ``` @@ -101,10 +101,10 @@ pnpm add @safe-global/protocol-kit viem }) ``` - Optionally, you can [track your Safe deployments and transactions on-chain](../../onchain-tracking.mdx) by using the `onchainAnalytics` property. - {/* */} + Optionally, you can [track your Safe deployments and transactions on-chain](../../onchain-tracking.mdx) by using the `onchainAnalytics` property. + ### Predict the Safe addresses You can predict the Safe addresses by calling the [`getAddress`](../../../reference-sdk-protocol-kit/safe-info/getaddress.mdx) method from each Protocol Kit instance and ensure that the result addresses are the same.