From 4dbe1af51d17a236b5d3f5313f0787742258a59b Mon Sep 17 00:00:00 2001 From: Agusx1211 Date: Wed, 10 Apr 2024 20:17:14 +0200 Subject: [PATCH] Contract Internals section (#28) * Internals section * Add v2 wallet configuration * Spell fixes --- .../internals/01-deployment.mdx | 47 ++++++ .../v1/01-deploy.mdx} | 77 +--------- .../v1}/03-wallet-factory.mdx | 0 .../v1}/04-wallet-configuration.mdx | 2 +- .../v1}/05-modules-and-updates.mdx | 0 .../v1}/06-main-module-upgradeable.mdx | 0 .../v1}/08-signature-encoding.mdx | 0 .../v1}/09-nested-transaction-batching.mdx | 0 .../v1}/10-guest-module.mdx | 0 .../v1}/11-wallet-context.mdx | 0 .../v1}/12-contract-audits.mdx | 0 .../internals/v2/01-deploy.mdx | 52 +++++++ .../internals/v2/04-configuration.mdx | 143 ++++++++++++++++++ .../07-transaction-encoding.mdx | 2 - nav.ts | 29 ++-- 15 files changed, 263 insertions(+), 89 deletions(-) create mode 100644 docs/pages/solutions/technical-references/internals/01-deployment.mdx rename docs/pages/solutions/technical-references/{wallet-contracts/02-universal-deployer.mdx => internals/v1/01-deploy.mdx} (50%) rename docs/pages/solutions/technical-references/{wallet-contracts => internals/v1}/03-wallet-factory.mdx (100%) rename docs/pages/solutions/technical-references/{wallet-contracts => internals/v1}/04-wallet-configuration.mdx (98%) rename docs/pages/solutions/technical-references/{wallet-contracts => internals/v1}/05-modules-and-updates.mdx (100%) rename docs/pages/solutions/technical-references/{wallet-contracts => internals/v1}/06-main-module-upgradeable.mdx (100%) rename docs/pages/solutions/technical-references/{wallet-contracts => internals/v1}/08-signature-encoding.mdx (100%) rename docs/pages/solutions/technical-references/{wallet-contracts => internals/v1}/09-nested-transaction-batching.mdx (100%) rename docs/pages/solutions/technical-references/{wallet-contracts => internals/v1}/10-guest-module.mdx (100%) rename docs/pages/solutions/technical-references/{wallet-contracts => internals/v1}/11-wallet-context.mdx (100%) rename docs/pages/solutions/technical-references/{wallet-contracts => internals/v1}/12-contract-audits.mdx (100%) create mode 100644 docs/pages/solutions/technical-references/internals/v2/01-deploy.mdx create mode 100644 docs/pages/solutions/technical-references/internals/v2/04-configuration.mdx delete mode 100644 docs/pages/solutions/technical-references/wallet-contracts/07-transaction-encoding.mdx diff --git a/docs/pages/solutions/technical-references/internals/01-deployment.mdx b/docs/pages/solutions/technical-references/internals/01-deployment.mdx new file mode 100644 index 0000000000..ef88a22097 --- /dev/null +++ b/docs/pages/solutions/technical-references/internals/01-deployment.mdx @@ -0,0 +1,47 @@ +import { Callout } from "vocs/components"; + +# Contract Deployment + +Sequence contract wallets are fully deterministic; a wallet will map to the same address on any network that is EVM compatible. + +This means that when a wallet is created, its address can be derived in advance, and it will be the same on networks like Ethereum, Arbitrum, Polygon, and others. + + + **Limitations**
+ Sequence wallets **may not** receive the same address on chains that aren't 100% EVM compatible. + + **Double-check your addresses** before sending any assets to them. +
+ +To achieve this, Sequence uses variations of [Nick's method](https://weka.medium.com/how-to-send-ether-to-11-440-people-187e332566b7), which allows for the deployment of the same contract on multiple chains in a fully trustless way. + +Nick's method is used to deploy a "deployer" contract, which is then used to deploy the core Sequence contracts. + +These contracts are: + +#### Factory Contract + +Creates new Sequence wallets, with an initial configuration. + +#### MainModule (v1 and v2) + +The main module implements the core logic of the wallet, with a fixed configuration. + +#### MainModuleUpgradable (v1 and v2) + +Similar to the MainModule, but with the ability to upgrade the configuration of the wallet. + +#### Auxiliary Contracts + +Both v1 and v2 have auxiliary contracts that are used by the SDK to interact with the wallet; these contracts are not critical for the wallet to function, but they are required for the SDK to work. + +See the v1 and v2 documentation for more information on the contracts. + + + Notice
A complete script for deployment can be found in the [Sequence Live Contracts repository](https://github.com/0xsequence/live-contracts). +
+ +## Detailed Deployment Steps + +- v1: [Deploy v1 Contracts](/solutions/technical-references/internals/v1/01-deploy) +- v2: [Deploy v2 Contracts](/solutions/technical-references/internals/v2/01-deploy) \ No newline at end of file diff --git a/docs/pages/solutions/technical-references/wallet-contracts/02-universal-deployer.mdx b/docs/pages/solutions/technical-references/internals/v1/01-deploy.mdx similarity index 50% rename from docs/pages/solutions/technical-references/wallet-contracts/02-universal-deployer.mdx rename to docs/pages/solutions/technical-references/internals/v1/01-deploy.mdx index adb1c64411..fe69d61421 100644 --- a/docs/pages/solutions/technical-references/wallet-contracts/02-universal-deployer.mdx +++ b/docs/pages/solutions/technical-references/internals/v1/01-deploy.mdx @@ -1,85 +1,14 @@ import { Callout } from "vocs/components"; -# Universal Deployer +# Deploy Process V1 -The Sequence contract wallets use [Nick's method](https://weka.medium.com/how-to-send-ether-to-11-440-people-187e332566b7) to deploy the contracts that compose the smart contract wallet. -This method has been chosen because it allows each wallet to take the same address on multiple chains, making it easier to use and less prone to mistakes. - - - Limitations
- Sequence wallets **may not** receive the same address on all EVM compatible chains. -
- -Networks that implement only a subset of the EVM opcodes, or alternative virtual -machines, will result in a different address for each chain. - -**Double-check your addresses** before sending any assets to them. - - - Notice
A complete script for deployment can be found in the [Sequence - Live Contracts repository](https://github.com/0xsequence/live-contracts). -
- -## Deploy Process V2 - -The following steps are required to deploy the [Sequence Wallet Context](/solutions/technical-references/wallet-contracts/02-universal-deployer#3---deploy-wallet-context) on a new network. - - - Notice
- For most popular networks this process **is not** required; due to the wallet contracts - being already deployed. - To see if a configuration already exists for a given chain go to [Networks](/solutions/technical-references/chain-support). - -
- -### 1 - Deploy Singleton Factory - -The Singleton Factory is a contract that allows the deployment of a single contract instance per address. Unlike the -[Universal Deployer](#universal-deployer), the Singleton Factory requires a salt to manage deployment instances. More information about the -Singleton Factory can be found in the [EIP-2470 specification](https://eips.ethereum.org/EIPS/eip-2470). - -The Pre-fund the Singleton Factory's deployer with the required funds to deploy the contract. - -``` -Address: 0xBb6e024b9cFFACB947A71991E386681B1Cd1477D -Funds: 0.0247 -``` - -**Do not send additional funds to the address, as funds can't be refunded.** - -Once the address is funded, you can deploy the Singleton Factory by executing the following pre-signed transaction: - -``` -0xf9016c8085174876e8008303c4d88080b90154608060405234801561001057600080fd5b50610134806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c80634af63f0214602d575b600080fd5b60cf60048036036040811015604157600080fd5b810190602081018135640100000000811115605b57600080fd5b820183602082011115606c57600080fd5b80359060200191846001830284011164010000000083111715608d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550509135925060eb915050565b604080516001600160a01b039092168252519081900360200190f35b6000818351602085016000f5939250505056fea26469706673582212206b44f8a82cb6b156bfcc3dc6aadd6df4eefd204bc928a4397fd15dacf6d5320564736f6c634300060200331b83247000822470 -``` - -After the transaction is confirmed, you should see the address of the Singleton Factory: - -``` -Singleton Deployer: 0xce0042B868300000d44A59004Da54A005ffdcf9f -``` - -### 2 - Deploy Wallet Context - -Deploy each of the contracts in the [Sequence Wallet Context](/solutions/technical-references/wallet-contracts/02-universal-deployer/#) using the Singleton Factory. - -A script can be found in the [Sequence Wallet Contracts repository](https://github.com/0xsequence/wallet-contracts/). - -Clone the repository, configure the environment variables and run the script with: - -``` -yarn deploy -``` - -## Deploy Process V1 - -The following steps are required to deploy the [Sequence Wallet V1 Context](/solutions/technical-references/wallet-contracts/02-universal-deployer#3---deploy-wallet-context) on a new network. +The following steps are required to deploy the [Sequence Wallet V1 Context](#3---deploy-wallet-context) on a new network. Notice
For most popular networks this process **is not** required; due to the wallet contracts being already deployed. To see if a configuration already exists for a given chain - go to [Networks](solutions/technical-references/chain-support). + go to [Networks](../../solutions/technical-references/chain-support).
A complete code example of this deployment flow can be found in the [0xSequence.js test suite](https://github.com/0xsequence/sequence.js/blob/91ed0df67fc5ddc47abf727ae8b94a8ca4f66912/packages/0xsequence/tests/browser/testutils/deploy-wallet-context.ts) diff --git a/docs/pages/solutions/technical-references/wallet-contracts/03-wallet-factory.mdx b/docs/pages/solutions/technical-references/internals/v1/03-wallet-factory.mdx similarity index 100% rename from docs/pages/solutions/technical-references/wallet-contracts/03-wallet-factory.mdx rename to docs/pages/solutions/technical-references/internals/v1/03-wallet-factory.mdx diff --git a/docs/pages/solutions/technical-references/wallet-contracts/04-wallet-configuration.mdx b/docs/pages/solutions/technical-references/internals/v1/04-wallet-configuration.mdx similarity index 98% rename from docs/pages/solutions/technical-references/wallet-contracts/04-wallet-configuration.mdx rename to docs/pages/solutions/technical-references/internals/v1/04-wallet-configuration.mdx index 5800d752ea..07807f16d6 100644 --- a/docs/pages/solutions/technical-references/wallet-contracts/04-wallet-configuration.mdx +++ b/docs/pages/solutions/technical-references/internals/v1/04-wallet-configuration.mdx @@ -1,4 +1,4 @@ -import { TabGroup, Tab, TabPanel } from "../../../../components/TabGroup.tsx"; +import { TabGroup, Tab, TabPanel } from "../../../../../components/TabGroup.tsx"; # Wallet Configuration diff --git a/docs/pages/solutions/technical-references/wallet-contracts/05-modules-and-updates.mdx b/docs/pages/solutions/technical-references/internals/v1/05-modules-and-updates.mdx similarity index 100% rename from docs/pages/solutions/technical-references/wallet-contracts/05-modules-and-updates.mdx rename to docs/pages/solutions/technical-references/internals/v1/05-modules-and-updates.mdx diff --git a/docs/pages/solutions/technical-references/wallet-contracts/06-main-module-upgradeable.mdx b/docs/pages/solutions/technical-references/internals/v1/06-main-module-upgradeable.mdx similarity index 100% rename from docs/pages/solutions/technical-references/wallet-contracts/06-main-module-upgradeable.mdx rename to docs/pages/solutions/technical-references/internals/v1/06-main-module-upgradeable.mdx diff --git a/docs/pages/solutions/technical-references/wallet-contracts/08-signature-encoding.mdx b/docs/pages/solutions/technical-references/internals/v1/08-signature-encoding.mdx similarity index 100% rename from docs/pages/solutions/technical-references/wallet-contracts/08-signature-encoding.mdx rename to docs/pages/solutions/technical-references/internals/v1/08-signature-encoding.mdx diff --git a/docs/pages/solutions/technical-references/wallet-contracts/09-nested-transaction-batching.mdx b/docs/pages/solutions/technical-references/internals/v1/09-nested-transaction-batching.mdx similarity index 100% rename from docs/pages/solutions/technical-references/wallet-contracts/09-nested-transaction-batching.mdx rename to docs/pages/solutions/technical-references/internals/v1/09-nested-transaction-batching.mdx diff --git a/docs/pages/solutions/technical-references/wallet-contracts/10-guest-module.mdx b/docs/pages/solutions/technical-references/internals/v1/10-guest-module.mdx similarity index 100% rename from docs/pages/solutions/technical-references/wallet-contracts/10-guest-module.mdx rename to docs/pages/solutions/technical-references/internals/v1/10-guest-module.mdx diff --git a/docs/pages/solutions/technical-references/wallet-contracts/11-wallet-context.mdx b/docs/pages/solutions/technical-references/internals/v1/11-wallet-context.mdx similarity index 100% rename from docs/pages/solutions/technical-references/wallet-contracts/11-wallet-context.mdx rename to docs/pages/solutions/technical-references/internals/v1/11-wallet-context.mdx diff --git a/docs/pages/solutions/technical-references/wallet-contracts/12-contract-audits.mdx b/docs/pages/solutions/technical-references/internals/v1/12-contract-audits.mdx similarity index 100% rename from docs/pages/solutions/technical-references/wallet-contracts/12-contract-audits.mdx rename to docs/pages/solutions/technical-references/internals/v1/12-contract-audits.mdx diff --git a/docs/pages/solutions/technical-references/internals/v2/01-deploy.mdx b/docs/pages/solutions/technical-references/internals/v2/01-deploy.mdx new file mode 100644 index 0000000000..1510c859c0 --- /dev/null +++ b/docs/pages/solutions/technical-references/internals/v2/01-deploy.mdx @@ -0,0 +1,52 @@ +import { Callout } from "vocs/components"; + +# Deploy Process V2 + +The following steps are required to deploy the [Sequence Wallet Context](/solutions/technical-references/wallet-contracts/02-universal-deployer#3---deploy-wallet-context) on a new network. + + + Notice
+ For most popular networks this process **is not** required; due to the wallet contracts + being already deployed. + To see if a configuration already exists for a given chain go to [Networks](/solutions/technical-references/chain-support). + +
+ +### 1 - Deploy Singleton Factory + +The Singleton Factory is a contract that allows the deployment of a single contract instance per address. Unlike the +[Universal Deployer](#universal-deployer), the Singleton Factory requires a salt to manage deployment instances. More information about the +Singleton Factory can be found in the [EIP-2470 specification](https://eips.ethereum.org/EIPS/eip-2470). + +The Pre-fund the Singleton Factory's deployer with the required funds to deploy the contract. + +``` +Address: 0xBb6e024b9cFFACB947A71991E386681B1Cd1477D +Funds: 0.0247 +``` + +**Do not send additional funds to the address, as funds can't be refunded.** + +Once the address is funded, you can deploy the Singleton Factory by executing the following pre-signed transaction: + +``` +0xf9016c8085174876e8008303c4d88080b90154608060405234801561001057600080fd5b50610134806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c80634af63f0214602d575b600080fd5b60cf60048036036040811015604157600080fd5b810190602081018135640100000000811115605b57600080fd5b820183602082011115606c57600080fd5b80359060200191846001830284011164010000000083111715608d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550509135925060eb915050565b604080516001600160a01b039092168252519081900360200190f35b6000818351602085016000f5939250505056fea26469706673582212206b44f8a82cb6b156bfcc3dc6aadd6df4eefd204bc928a4397fd15dacf6d5320564736f6c634300060200331b83247000822470 +``` + +After the transaction is confirmed, you should see the address of the Singleton Factory: + +``` +Singleton Deployer: 0xce0042B868300000d44A59004Da54A005ffdcf9f +``` + +### 2 - Deploy Wallet Context + +Deploy each of the contracts in the [Sequence Wallet Context](/solutions/technical-references/wallet-contracts/02-universal-deployer/#) using the Singleton Factory. + +A script can be found in the [Sequence Wallet Contracts repository](https://github.com/0xsequence/wallet-contracts/). + +Clone the repository, configure the environment variables and run the script with: + +``` +yarn deploy +``` diff --git a/docs/pages/solutions/technical-references/internals/v2/04-configuration.mdx b/docs/pages/solutions/technical-references/internals/v2/04-configuration.mdx new file mode 100644 index 0000000000..88e9104cf4 --- /dev/null +++ b/docs/pages/solutions/technical-references/internals/v2/04-configuration.mdx @@ -0,0 +1,143 @@ +# Wallet Configuration + +In the context of Sequence Wallets, the "Wallet Configuration" is a set of parameters that defines the behavior of the wallet, primarily used to define the access control of the wallet, meaning who can sign transactions and how many signatures are needed. + +## Top level properties + +Sequence v2 configurations contain the following 3 properties: + +- `threshold` - The required "weight sum" needed for a signature to be considered valid. +- `checkpoint` - Used as a salt and ordering mechanism for wallet updates. +- `tree` - Determines the signers and their weights for the wallet. + +### Threshold + +The `threshold` is a `uint16`; it can have any value between 0 and 65535. Signatures are only considered valid or invalid if the sum of the weights of the signers that signed the transaction is greater or equal to the threshold. + +### Checkpoint + +The `checkpoint` is a `uint32`. During wallet creation, a semi-random value can be provided to generate independent wallets with the same initial configuration. Then, during normal operation, the `checkpoint` is used by Light State Sync to ensure that wallet updates are applied in the correct order. + +### Tree + +The `tree` is an unbalanced binary Merkle tree, where each leaf may contain a signer, a static signature, or a subtree. The tree can represent any combination of signers and weights and can be used to create complex multi-signature wallets. + +The possible leaf types are: + +#### Signer + +Signers are represented by a signer `address` and a `uint8` weight. The weight is how much the signer contributes to the threshold. +The address can belong to either an `ERC1271` compliant contract or an `EOA` wallet. + +The leaf hash is calculated as follows: + +```solidity +bytes32(uint256(weight) << 160 | uint256(uint160(addr))) +``` + +#### Subdigest + +This represents a static subdigest for which any signature is valid. If a signature for this subdigest is provided, the total weight of the signature is automatically set to `Infinity`. + +Notice static subdigests that exist within nested trees will have their "Infinity" weight reduced to the weight of the nested tree. + +The leaf hash is calculated as follows: + +```solidity +keccak256(abi.encodePacked('Sequence static digest:\n', subdigest)); +``` + +#### Subtree (nested configuration) + +This represents a whole new wallet configuration, this "nested configuration" has its own: + +- External `weight` (`uint8`) +- Internal `threshold` (`uint16`) +- Internal `tree` + +The way it works is that if a signature reaches the `internal threshold` within the subtree it is considered valid, and the `external weight` is added to the parent tree. Any number of nested configurations can be created, and it is possible to create multiple nesting levels. + +This pattern can be used, among other things, to express the following scenarios: +- Non-linear weight distribution, A and B signers can provide 1 weight each, but together they can provide 3 weight. +- Limited total weight contribution, A, B, and C signers can provide 1 weight each, but together they can only provide 2 weight. +- "Department configurations", N departments are required to sign, and each department has its own inner configuration. + +The leaf hash is calculated as follows: + +```solidity +keccak256(abi.encodePacked( + 'Sequence nested config:\n', + imageHash(tree), + threshold, + weight +)) +``` + +:::warning +The wallet contracts have no way of validating the correctness of the configuration, the responsibility of ensuring the configuration is correct is on the SDKs interacting with the contracts. + +Things like `threshold == 0` or `threshold > total weight` will result in fully unauthenticated wallets or inaccessible wallets respectively. +::: + +## ImageHash + +The `configuration` is never stored as a whole; instead, the Merkle tree is hashed into a single `bytes32` value, this is internally called the `imageHash` of the configuration. + +The `imageHash` is calculated as follows: + +```solidity +imageHash := keccak256(abi.encode( + keccak256(abi.encode( + hashTree(tree), + threshold + )), + checkpoint +)) +``` + +The `hashTree` function is a recursive function that hashes the tree into a single `bytes32` value, pseudo code for the `hashTree` function is as follows: + +```typescript +export function hashTree(node: Node | Leaf): string { + if (isSignerLeaf(node)) { + return ethers.utils.solidityPack( + ['uint96', 'address'], + [node.weight, node.address] + ) + } + + if (isSubdigestLeaf(node)) { + return ethers.utils.solidityKeccak256( + ['string', 'bytes32'], + ['Sequence static digest:\n', node.subdigest] + ) + } + + if (isNestedLeaf(node)) { + const nested = hashTree(node.tree) + return ethers.utils.solidityKeccak256( + ['string', 'bytes32', 'uint256', 'uint256'], + ['Sequence nested config:\n', nested, node.threshold, node.weight] + ) + } + + return ethers.utils.solidityKeccak256( + ['bytes32', 'bytes32'], + [hashTree(node.left), hashTree(node.right)] + ) +} +``` + +## Initial Configuration + +All Sequence Wallets have an "initial configuration", implemented by using the `imageHash` of the initial configuration as the SALT during the `CREATE2` deployment of the wallet. + +Wallets are deployed by calling the `deploy` function of the `Factory` contract, which takes the following parameters: +- `mainModule`: The address of the initial code implementation of the wallet. +- `salt`: The `imageHash` of the initial configuration. + +:::info +The `MainModule` should always be used as the initial code implementation of the wallet. The `MainModule` validates the `imageHash` (during signature validation) by re-computing the counterfactual address of the wallet, hence it does not require any storage initialization. + +If the `imageHash` is ever changed, `MainModule` will automatically replace the wallet code implementation with `MainModuleUpgradeable`, while handling the storage initialization. +::: diff --git a/docs/pages/solutions/technical-references/wallet-contracts/07-transaction-encoding.mdx b/docs/pages/solutions/technical-references/wallet-contracts/07-transaction-encoding.mdx deleted file mode 100644 index c73f0de3d7..0000000000 --- a/docs/pages/solutions/technical-references/wallet-contracts/07-transaction-encoding.mdx +++ /dev/null @@ -1,2 +0,0 @@ -# Transaction encoding - diff --git a/nav.ts b/nav.ts index 691f1bc7b4..f4a506bc5d 100644 --- a/nav.ts +++ b/nav.ts @@ -174,18 +174,23 @@ export const sidebar = { // { text: 'EIP5189 vs. 4337', link: '/solutions/technical-references/5189-4337' }, { text: 'Smart Contract Wallets', collapsed: true, items: [ { text: 'Why smart contract wallets?', link: '/solutions/technical-references/wallet-contracts/01-why' }, - { text: 'Universal Deployer', link: '/solutions/technical-references/wallet-contracts/02-universal-deployer' }, - {text: 'Wallet Factory', link: '/solutions/technical-references/wallet-contracts/03-wallet-factory'}, - {text: 'Wallet Configuration', link: '/solutions/technical-references/wallet-contracts/04-wallet-configuration'}, - // {text: 'Modules & Wallet update', link: 'solutions/technical-references/wallet-contracts/05-modules-and-updates'}, - // {text: 'MainModuleUpgradeable & configuration migration', link: 'solutions/technical-references/wallet-contracts/06-main-module-upgradeable'}, - {text: 'Transaction Encoding', link: '/solutions/technical-references/wallet-contracts/07-transaction-encoding'}, - {text: 'Signature Encoding', link: '/solutions/technical-references/wallet-contracts/08-signature-encoding'}, - // {text: 'Nested Transaction Batching', link: 'solutions/technical-references/wallet-contracts/09-nested-transaction-batching'}, - // {text: 'GuestModule and on-demand deployment', link: 'solutions/technical-references/wallet-contracts/10-guest-module'}, - {text: 'Wallet Context', link: '/solutions/technical-references/wallet-contracts/11-wallet-context'}, - {text: 'Contract Audits', link: '/solutions/technical-references/wallet-contracts/12-contract-audits'}, - ] } + ] }, + { text: 'Contract Internals', collapsed: true, items: [ + {text: 'Deployment', link: '/solutions/technical-references/internals/01-deployment'}, + { text: 'Sequence v1', collapsed: true, items: [ + {text: 'Deploy', link: '/solutions/technical-references/internals/v1/01-deploy'}, + {text: 'Wallet Factory', link: '/solutions/technical-references/internals/v1/03-wallet-factory'}, + {text: 'Wallet Configuration', link: '/solutions/technical-references/internals/v1/04-wallet-configuration'}, + // {text: 'Transaction Encoding', link: '/solutions/technical-references/internals/v1/07-transaction-encoding'}, + {text: 'Signature Encoding', link: '/solutions/technical-references/internals/v1/08-signature-encoding'}, + {text: 'Wallet Context', link: '/solutions/technical-references/internals/v1/11-wallet-context'}, + {text: 'Contract Audits', link: '/solutions/technical-references/internals/v1/12-contract-audits'}, + ]}, + { text: 'Sequence v2', collapsed: true, items: [ + {text: 'Deploy', link: '/solutions/technical-references/internals/v2/01-deploy'}, + {text: 'Wallet Configuration', link: "/solutions/technical-references/internals/v2/04-configuration"}, + ]} + ]} ] },