Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: Add On-chain tracking page #671

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pages/sdk/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@
"title": "Integrations"
},
"signers": "Signers",
"onchain-tracking": "On-chain Tracking",
"onramp": "Onramp"
}
186 changes: 186 additions & 0 deletions pages/sdk/onchain-tracking.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
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 (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.

## 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 (for example, "Gnosis", "CoW Swap").

### Platform hash

- **Type:** `3 bytes`
- **Example:** `646561`

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 (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 (for example, "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:

<Steps>

### 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.

{/* <!-- vale off --> */}

<Tabs items={['Protocol Kit', 'Relay Kit']}>
<Tabs.Tab>
```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
```
</Tabs.Tab>
<Tabs.Tab>
```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
```
</Tabs.Tab>
</Tabs>

{/* <!-- vale on --> */}

### 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.

{/* <!-- vale off --> */}

<Tabs items={['Protocol Kit', 'Relay Kit']}>
<Tabs.Tab>
```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
```
</Tabs.Tab>
<Tabs.Tab>
```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
```
</Tabs.Tab>
</Tabs>

{/* <!-- vale on --> */}

### 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.

{/* <!-- vale off --> */}

```typescript
const onchainIdentifier = protocolKit.getOnchainIdentifier()
```

{/* <!-- vale on --> */}

</Steps>

## Submission Form

<br/>

<iframe
src="https://docs.google.com/forms/d/e/1FAIpQLSfHWSPbSQwmo0mbtuFFewfLvDEOvTxfuvEl7AHOyrFE_dqpwQ/viewform?embedded=true"
width="100%"
height="1750"
frameborder="0"
>Loading…</iframe>
41 changes: 6 additions & 35 deletions pages/sdk/protocol-kit/guides/execute-transactions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -73,24 +73,27 @@ 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.

{/* <!-- vale off --> */}

```typescript
const protocolKitOwner1 = await Safe.init({
provider: RPC_URL,
signer: OWNER_1_PRIVATE_KEY,
safeAddress: SAFE_ADDRESS
safeAddress: SAFE_ADDRESS,
onchainAnalytics // Optional
})
```

{/* <!-- vale on --> */}

### Create a transaction

{/* <!-- vale off --> */}

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.

{/* <!-- vale off --> */}

```typescript
const safeTransactionData: MetaTransactionData = {
to: '0x',
Expand All @@ -108,38 +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:

{/* <!-- vale off --> */}

```typescript
const onchainIdentifier = toHex(
'TEXT_TO_DERIVE_THE_IDENTIFIER', // It could be your project name
{ size: 16 }
)
```

{/* <!-- vale on --> */}

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`.

{/* <!-- vale off --> */}

```typescript
safeTransaction.data.data = concat([
safeOperation.data.data as `0x{string}`,
onchainIdentifier
]).toString()
```

{/* <!-- vale on --> */}

### 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.
Expand Down
14 changes: 10 additions & 4 deletions pages/sdk/protocol-kit/guides/multichain-safe-deployment.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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
// ...
}
```

Expand All @@ -87,18 +87,24 @@ 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
// ...
})
```

{/* <!-- vale on --> */}

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.
Expand Down
5 changes: 4 additions & 1 deletion pages/sdk/protocol-kit/guides/safe-deployment.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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.

{/* <!-- vale off --> */}

```typescript
Expand All @@ -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
})
```

Expand Down
Loading
Loading