From 3a94adc98f852d100a54d44b85b2d8efa4c3546a Mon Sep 17 00:00:00 2001 From: James Lawton Date: Thu, 7 Mar 2024 18:57:11 +0000 Subject: [PATCH] initial content migration for solutions --- .DS_Store | Bin 6148 -> 8196 bytes docs/.DS_Store | Bin 6148 -> 6148 bytes docs/pages/.DS_Store | Bin 0 -> 8196 bytes docs/pages/index.mdx | 8 +- docs/pages/intro/auth.mdx | 4 - docs/pages/intro/chains.mdx | 3 - docs/pages/intro/eth-compat.mdx | 4 - docs/pages/intro/getting-started.mdx | 3 - docs/pages/intro/lets-build.mdx | 4 - docs/pages/intro/marketplaces.mdx | 4 - docs/pages/intro/multi-chain.mdx | 4 - docs/pages/intro/open-source.mdx | 3 - docs/pages/intro/payments.mdx | 3 - docs/pages/intro/sequence-stack.mdx | 3 - docs/pages/intro/tokens-nfts-contracts.mdx | 3 - docs/pages/intro/tools.mdx | 4 - docs/pages/intro/vision.mdx | 4 - docs/pages/intro/wallets.mdx | 9 - docs/pages/intro/welcome-to-web3.mdx | 3 - .../sdk/sequence-kit/02-getting-started.mdx | 211 +++++++++ .../sdk/sequence-kit/03-configuration.mdx | 130 ++++++ docs/pages/sdk/sequence-kit/04-checkout.mdx | 110 +++++ .../sdk/sequence-kit/05-custom-connectors.mdx | 84 ++++ docs/pages/sdk/sequence-kit/_category_.json | 7 + docs/pages/solutions/.DS_Store | Bin 0 -> 6148 bytes docs/pages/solutions/builder.mdx | 1 - docs/pages/solutions/builder/contracts.mdx | 45 ++ docs/pages/solutions/builder/gas-tank.mdx | 26 ++ docs/pages/solutions/builder/indexer.mdx | 29 ++ docs/pages/solutions/builder/marketplaces.mdx | 20 + docs/pages/solutions/builder/node-gateway.mdx | 23 + docs/pages/solutions/builder/overview.mdx | 11 + .../solutions/builder/project-management.mdx | 25 ++ .../solutions/builder/project-settings.mdx | 399 ++++++++++++++++++ docs/pages/{ => solutions}/builder/stub.mdx | 0 docs/pages/solutions/builder/wallet-sdks.mdx | 32 ++ docs/pages/solutions/chain-support.mdx | 11 +- .../contracts/900-mint-items-from-ERC1155.mdx | 93 ++++ .../902-mint-collectibles-from-ERC721.mdx | 98 +++++ .../903-mint-currency-from-ERC20.mdx | 94 +++++ .../800-manage-contract-metadata-builder.mdx | 101 +++++ docs/pages/solutions/contracts.mdx | 3 - docs/pages/solutions/embedded-wallet.mdx | 3 - .../solutions/ethereum-compatibility.mdx | 1 - docs/pages/solutions/marketplaces/.DS_Store | Bin 0 -> 6148 bytes .../marketplaces/orderbook/01-overview.mdx | 3 + .../marketplaces/orderbook/02-quickstart.mdx | 19 + .../marketplaces/white-label-marketplace.mdx | 22 + docs/pages/solutions/metadata-manager.mdx | 3 - docs/pages/solutions/orderbook.mdx | 1 - .../payments/onramps/01-fiat-on-ramps.mdx | 20 + .../10-wallet-contracts/01-why.mdx | 43 ++ .../02-universal-deployer.mdx | 128 ++++++ .../10-wallet-contracts/03-wallet-factory.mdx | 48 +++ .../04-wallet-configuration.mdx | 160 +++++++ .../05-modules-and-updates.mdx | 218 ++++++++++ .../06-main-module-upgradeable.mdx | 2 + .../07-transaction-encoding.mdx | 2 + .../08-signature-encoding.mdx | 96 +++++ .../09-nested-transaction-batching.mdx | 2 + .../10-wallet-contracts/10-guest-module.mdx | 2 + .../10-wallet-contracts/11-wallet-context.mdx | 14 + .../12-contract-audits.mdx | 14 + docs/pages/solutions/universal-wallet.mdx | 3 - .../wallets/embedded-wallet/01-overview.mdx | 40 ++ .../wallets/embedded-wallet/02-quickstart.mdx | 50 +++ .../embedded-wallet/03-manage-sessions.mdx | 256 +++++++++++ .../embedded-wallet/04-use-wallets.mdx | 287 +++++++++++++ .../wallets/embedded-wallet/05-validation.mdx | 96 +++++ .../06-transaction-receipts.mdx | 143 +++++++ docs/pages/solutions/wallets/overview.mdx | 1 + .../wallets/universal-wallet/01-overview.mdx | 18 + .../universal-wallet/02-quickstart.mdx | 65 +++ .../03-guides/01-connect-wallet.mdx | 303 +++++++++++++ .../03-guides/02-auth-address.mdx | 84 ++++ .../03-guides/03-sign-message.mdx | 1 + .../03-guides/04-session-keys.mdx | 85 ++++ .../03-guides/05-send-transaction.mdx | 16 + .../03-guides/06-send-erc20.mdx | 56 +++ .../03-guides/07-send-erc721.mdx | 58 +++ .../03-guides/08-send-erc1155.mdx | 57 +++ .../03-guides/09-send-batch-transactions.mdx | 55 +++ .../03-guides/10-building-backends.mdx | 33 ++ .../wallets/universal-wallet/04-platforms.mdx | 23 + .../universal-wallet/05-fiat-on-ramps.mdx | 21 + .../universal-wallet/06-key-management.mdx | 32 ++ .../universal-wallet/07-sequence-kit.mdx | 22 + .../solutions/white-label-marketplace.mdx | 1 - nav.ts | 182 +++----- 89 files changed, 4209 insertions(+), 199 deletions(-) create mode 100644 docs/pages/.DS_Store delete mode 100644 docs/pages/intro/auth.mdx delete mode 100644 docs/pages/intro/chains.mdx delete mode 100644 docs/pages/intro/eth-compat.mdx delete mode 100644 docs/pages/intro/getting-started.mdx delete mode 100644 docs/pages/intro/lets-build.mdx delete mode 100644 docs/pages/intro/marketplaces.mdx delete mode 100644 docs/pages/intro/multi-chain.mdx delete mode 100644 docs/pages/intro/open-source.mdx delete mode 100644 docs/pages/intro/payments.mdx delete mode 100644 docs/pages/intro/sequence-stack.mdx delete mode 100644 docs/pages/intro/tokens-nfts-contracts.mdx delete mode 100644 docs/pages/intro/tools.mdx delete mode 100644 docs/pages/intro/vision.mdx delete mode 100644 docs/pages/intro/wallets.mdx delete mode 100644 docs/pages/intro/welcome-to-web3.mdx create mode 100644 docs/pages/sdk/sequence-kit/02-getting-started.mdx create mode 100644 docs/pages/sdk/sequence-kit/03-configuration.mdx create mode 100644 docs/pages/sdk/sequence-kit/04-checkout.mdx create mode 100644 docs/pages/sdk/sequence-kit/05-custom-connectors.mdx create mode 100644 docs/pages/sdk/sequence-kit/_category_.json create mode 100644 docs/pages/solutions/.DS_Store delete mode 100644 docs/pages/solutions/builder.mdx create mode 100644 docs/pages/solutions/builder/contracts.mdx create mode 100644 docs/pages/solutions/builder/gas-tank.mdx create mode 100644 docs/pages/solutions/builder/indexer.mdx create mode 100644 docs/pages/solutions/builder/marketplaces.mdx create mode 100644 docs/pages/solutions/builder/node-gateway.mdx create mode 100644 docs/pages/solutions/builder/overview.mdx create mode 100644 docs/pages/solutions/builder/project-management.mdx create mode 100644 docs/pages/solutions/builder/project-settings.mdx rename docs/pages/{ => solutions}/builder/stub.mdx (100%) create mode 100644 docs/pages/solutions/builder/wallet-sdks.mdx create mode 100644 docs/pages/solutions/collectibles/contracts/900-mint-items-from-ERC1155.mdx create mode 100644 docs/pages/solutions/collectibles/contracts/902-mint-collectibles-from-ERC721.mdx create mode 100644 docs/pages/solutions/collectibles/contracts/903-mint-currency-from-ERC20.mdx create mode 100644 docs/pages/solutions/collectibles/metadata/800-manage-contract-metadata-builder.mdx delete mode 100644 docs/pages/solutions/contracts.mdx delete mode 100644 docs/pages/solutions/embedded-wallet.mdx delete mode 100644 docs/pages/solutions/ethereum-compatibility.mdx create mode 100644 docs/pages/solutions/marketplaces/.DS_Store create mode 100644 docs/pages/solutions/marketplaces/orderbook/01-overview.mdx create mode 100644 docs/pages/solutions/marketplaces/orderbook/02-quickstart.mdx create mode 100644 docs/pages/solutions/marketplaces/white-label-marketplace.mdx delete mode 100644 docs/pages/solutions/metadata-manager.mdx delete mode 100644 docs/pages/solutions/orderbook.mdx create mode 100644 docs/pages/solutions/payments/onramps/01-fiat-on-ramps.mdx create mode 100644 docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/01-why.mdx create mode 100644 docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/02-universal-deployer.mdx create mode 100644 docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/03-wallet-factory.mdx create mode 100644 docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/04-wallet-configuration.mdx create mode 100644 docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/05-modules-and-updates.mdx create mode 100644 docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/06-main-module-upgradeable.mdx create mode 100644 docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/07-transaction-encoding.mdx create mode 100644 docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/08-signature-encoding.mdx create mode 100644 docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/09-nested-transaction-batching.mdx create mode 100644 docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/10-guest-module.mdx create mode 100644 docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/11-wallet-context.mdx create mode 100644 docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/12-contract-audits.mdx delete mode 100644 docs/pages/solutions/universal-wallet.mdx create mode 100644 docs/pages/solutions/wallets/embedded-wallet/01-overview.mdx create mode 100644 docs/pages/solutions/wallets/embedded-wallet/02-quickstart.mdx create mode 100644 docs/pages/solutions/wallets/embedded-wallet/03-manage-sessions.mdx create mode 100644 docs/pages/solutions/wallets/embedded-wallet/04-use-wallets.mdx create mode 100644 docs/pages/solutions/wallets/embedded-wallet/05-validation.mdx create mode 100644 docs/pages/solutions/wallets/embedded-wallet/06-transaction-receipts.mdx create mode 100644 docs/pages/solutions/wallets/overview.mdx create mode 100644 docs/pages/solutions/wallets/universal-wallet/01-overview.mdx create mode 100644 docs/pages/solutions/wallets/universal-wallet/02-quickstart.mdx create mode 100644 docs/pages/solutions/wallets/universal-wallet/03-guides/01-connect-wallet.mdx create mode 100644 docs/pages/solutions/wallets/universal-wallet/03-guides/02-auth-address.mdx create mode 100644 docs/pages/solutions/wallets/universal-wallet/03-guides/03-sign-message.mdx create mode 100644 docs/pages/solutions/wallets/universal-wallet/03-guides/04-session-keys.mdx create mode 100644 docs/pages/solutions/wallets/universal-wallet/03-guides/05-send-transaction.mdx create mode 100644 docs/pages/solutions/wallets/universal-wallet/03-guides/06-send-erc20.mdx create mode 100644 docs/pages/solutions/wallets/universal-wallet/03-guides/07-send-erc721.mdx create mode 100644 docs/pages/solutions/wallets/universal-wallet/03-guides/08-send-erc1155.mdx create mode 100644 docs/pages/solutions/wallets/universal-wallet/03-guides/09-send-batch-transactions.mdx create mode 100644 docs/pages/solutions/wallets/universal-wallet/03-guides/10-building-backends.mdx create mode 100644 docs/pages/solutions/wallets/universal-wallet/04-platforms.mdx create mode 100644 docs/pages/solutions/wallets/universal-wallet/05-fiat-on-ramps.mdx create mode 100644 docs/pages/solutions/wallets/universal-wallet/06-key-management.mdx create mode 100644 docs/pages/solutions/wallets/universal-wallet/07-sequence-kit.mdx delete mode 100644 docs/pages/solutions/white-label-marketplace.mdx diff --git a/.DS_Store b/.DS_Store index 17517aa7519698e35fa1cb905ba2bf2fc2fa561b..cb25fd1e842bfa75c148219ef98ebabdcdb2f43c 100644 GIT binary patch delta 457 zcmZoMXmOBWU|?W$DortDU;r^WfEYvza8E20o2aMA$hR?IH}hr%jz7$c**Q2SHn1@A zP3B>-XWTW}how+cs=C_T%tA*&*U-SSR!5=Q!puZR!O+0mvbL6!LsVJcIw(FnCpRy@ zXYxZ9dB)z&jI4r8^_C1}4EYSn48;t3Kr){pk0FgAlOY|*D*=jCfay$zT!vI2uY@5H z$SPpaWiVtgXE0!}WUv5}mJG%~z9oYhg9%X10LV)PnqtC`1eCV`>M;Y0Spdz-WyoSE z_RPsoPRhwo0{N^SNH_vL&G#P+fIJ4ELDY7V8G{kf2?juCTY?>B0;COrVwMcbSlk43 y!g^#UO?DI!-|Ww`pP5U78z|=rijd8M9N(EI^NV;+_UGZ?V1&dK!{&INIm`h0>0F@z delta 133 zcmZp1XfcprU|?W$DortDU=RQ@Ie-{Mvv5r;6q~50$jGxXU^g=(&tx6}d&aGkeFO^G zMXRd~bQBCGpA?W`Y@hs0K%TKB!ku~2NHo+2aH#(>?7iv?Ji7`Zm{Fy%2$4q)cyNh&WcNXp4iVqjp{ zHQ9%$P*bY9+T6@SM?u%nz_M0Hq1wXCL`T8Uz}&L7mXkwNS>HM+K07BjFTZEB)qu~2NHo+2a1#(>?7j2xSJSn?P*XRys@+}QArX)`+qKL=3FWtpzMKP z;1}5QA^Zy~IP+*Vb|zwnP&yOM-0{pgp1J4xk(&?^>*m8Y(LNFRsKPetXe>p{i@H*_ z^vE781E2U=81oQEjTNjLa0)mDoB~b(r+`!7|4;z$Y*G9*?|n7vTBm?h;6^GSo(}=4 zupMoe%F0Iv8kqvXRxvCK`tr*^Y#;_;JK8Rl#Rv*hR9Ho2I>lf*cVLQ+`Hsdfl~r_N za%G%Hugr9Y!gT7v0tqM9QP#Ci0jI#K0wQ;>(10csJ&z0d`xDF@{FX)1G%B2>6P@M% z2q$rrX06swwpFR#+V*_Uulw(MANZ`74YEA#4yJF!(M!(b@TxxuUqz!?zj5a&PqIOj zjHZ$h4M%{yeH|r3KI`&48K#okQxks8uk{;u=kue(<7V)n-8xw`gZc5{qh`=<9i1!| zHGl8^!^bcB`jxHC+8RuXisTD2XsM0x-4n(9SBns zk3z~Rq8Qi_O^axDuY|4_(e^di=Mrn1&gB|ng|xK7uM&30#M;kKBCg+zxYn@$MDG7` z4MTWsGCYG}_u53)i)i~A(rc4dp%i->7yT7`XSa>LdkSSgCt=?ObPZ^ZSml&qPaIyC z^+d$}#@Lwa-=aq8Uf5mL%dWJD-imG+?xZssuVLWIEignRb3BD6h|82ROWZ#hajzHA z_BCYuP1X+0u%{TG5v~C19WL%!W^!=pyW$ksNChg&t9_CGKU@F%|3>=moN@{{1(X7; zdfGefqJQ;uxh#yxwFA`msG_vlaLQ*co|i literal 0 HcmV?d00001 diff --git a/docs/pages/index.mdx b/docs/pages/index.mdx index eb195e8b9da..2968f017129 100644 --- a/docs/pages/index.mdx +++ b/docs/pages/index.mdx @@ -44,7 +44,7 @@ import { HomePage } from "vocs/components";

- Easily onboard web3-native players with Embedded Wallet. + Easily onboard web3-native players with a complete Universal Wallet.

  • @@ -54,8 +54,8 @@ import { HomePage } from "vocs/components";

    - Acquire both web2 and web3 players with Sequence - Wallet-as-a-Service. + Gasless Transactions. No popups. Deliver a seamless experience for both web2 and web3 players with Sequence + Wallet-as-a-Service embedded into your game or app.

  • @@ -350,4 +350,4 @@ import { HomePage } from "vocs/components"; - + \ No newline at end of file diff --git a/docs/pages/intro/auth.mdx b/docs/pages/intro/auth.mdx deleted file mode 100644 index cd4636d3ea8..00000000000 --- a/docs/pages/intro/auth.mdx +++ /dev/null @@ -1,4 +0,0 @@ -# Authentication - -... - diff --git a/docs/pages/intro/chains.mdx b/docs/pages/intro/chains.mdx deleted file mode 100644 index a94749f5184..00000000000 --- a/docs/pages/intro/chains.mdx +++ /dev/null @@ -1,3 +0,0 @@ -# Ethereum Ecosystem of Chains - -... diff --git a/docs/pages/intro/eth-compat.mdx b/docs/pages/intro/eth-compat.mdx deleted file mode 100644 index 82c15294691..00000000000 --- a/docs/pages/intro/eth-compat.mdx +++ /dev/null @@ -1,4 +0,0 @@ -# Eth compatibility - -... - diff --git a/docs/pages/intro/getting-started.mdx b/docs/pages/intro/getting-started.mdx deleted file mode 100644 index 99b8616ea90..00000000000 --- a/docs/pages/intro/getting-started.mdx +++ /dev/null @@ -1,3 +0,0 @@ -# Get started - -Hello world! \ No newline at end of file diff --git a/docs/pages/intro/lets-build.mdx b/docs/pages/intro/lets-build.mdx deleted file mode 100644 index 8056ca21a3b..00000000000 --- a/docs/pages/intro/lets-build.mdx +++ /dev/null @@ -1,4 +0,0 @@ -# Lets build! - -... - diff --git a/docs/pages/intro/marketplaces.mdx b/docs/pages/intro/marketplaces.mdx deleted file mode 100644 index 1e700e5922f..00000000000 --- a/docs/pages/intro/marketplaces.mdx +++ /dev/null @@ -1,4 +0,0 @@ -# Marketplaces - -... - diff --git a/docs/pages/intro/multi-chain.mdx b/docs/pages/intro/multi-chain.mdx deleted file mode 100644 index a27bbf9dffb..00000000000 --- a/docs/pages/intro/multi-chain.mdx +++ /dev/null @@ -1,4 +0,0 @@ -# Multi-chain - -... - diff --git a/docs/pages/intro/open-source.mdx b/docs/pages/intro/open-source.mdx deleted file mode 100644 index e31698399ff..00000000000 --- a/docs/pages/intro/open-source.mdx +++ /dev/null @@ -1,3 +0,0 @@ -# Open Source - -... diff --git a/docs/pages/intro/payments.mdx b/docs/pages/intro/payments.mdx deleted file mode 100644 index 9f3afdd47b4..00000000000 --- a/docs/pages/intro/payments.mdx +++ /dev/null @@ -1,3 +0,0 @@ -# Payments on web3 - -... diff --git a/docs/pages/intro/sequence-stack.mdx b/docs/pages/intro/sequence-stack.mdx deleted file mode 100644 index 401e2b2aafb..00000000000 --- a/docs/pages/intro/sequence-stack.mdx +++ /dev/null @@ -1,3 +0,0 @@ -# Sequence Stack - -... diff --git a/docs/pages/intro/tokens-nfts-contracts.mdx b/docs/pages/intro/tokens-nfts-contracts.mdx deleted file mode 100644 index f9f6a4b1c78..00000000000 --- a/docs/pages/intro/tokens-nfts-contracts.mdx +++ /dev/null @@ -1,3 +0,0 @@ -# Tokens, NFTs & Contracts - -... \ No newline at end of file diff --git a/docs/pages/intro/tools.mdx b/docs/pages/intro/tools.mdx deleted file mode 100644 index 28a44770d87..00000000000 --- a/docs/pages/intro/tools.mdx +++ /dev/null @@ -1,4 +0,0 @@ -# Tools - -... - diff --git a/docs/pages/intro/vision.mdx b/docs/pages/intro/vision.mdx deleted file mode 100644 index 7b8ffcddd6e..00000000000 --- a/docs/pages/intro/vision.mdx +++ /dev/null @@ -1,4 +0,0 @@ -# Our Vision for web3 - -suasfsadf - diff --git a/docs/pages/intro/wallets.mdx b/docs/pages/intro/wallets.mdx deleted file mode 100644 index c1382b6af5d..00000000000 --- a/docs/pages/intro/wallets.mdx +++ /dev/null @@ -1,9 +0,0 @@ -# Wallets - -... - -lots of wallets out there.. - -as overview,.. EOA.. smart wallets.. - -lets do some Comparison .. etc.. \ No newline at end of file diff --git a/docs/pages/intro/welcome-to-web3.mdx b/docs/pages/intro/welcome-to-web3.mdx deleted file mode 100644 index a727af9e28b..00000000000 --- a/docs/pages/intro/welcome-to-web3.mdx +++ /dev/null @@ -1,3 +0,0 @@ -# Welcome to web3 - -... diff --git a/docs/pages/sdk/sequence-kit/02-getting-started.mdx b/docs/pages/sdk/sequence-kit/02-getting-started.mdx new file mode 100644 index 00000000000..3d64167fabb --- /dev/null +++ b/docs/pages/sdk/sequence-kit/02-getting-started.mdx @@ -0,0 +1,211 @@ +--- +sidebar_label: Getting Started +--- + +# Getting Started with Sequence Kit + +In this guide, we will walk you through installing Sequence Kit, triggering the connection modal, and displaying the embedded wallet in your application. + +## Installing Sequence Kit Packages + +Sequence Kit is modular, allowing you to install only the necessary packages. To get started, install the `kit` core package, the `connectors` package for interfacing with various wallet providers, and the `wallet` for the embedded wallet. Additionally, install other dependencies such as wagmi, viem, and 0xsequence. + +```bash +npm install @0xsequence/kit @0xsequence/kit-connectors wagmi ethers@5.7.2 viem 0xsequence @tanstack/react-query +# or +pnpm install @0xsequence/kit @0xsequence/kit-connectors wagmi ethers@5.7.2 viem 0xsequence @tanstack/react-query +# or +yarn add @0xsequence/kit @0xsequence/kit-connectors wagmi ethers@5.7.2 viem 0xsequence @tanstack/react-query +``` + +# Setting Up the Kit Wrapper +To utilize the core kit wrapper for connecting web3 wallets to your application, follow these steps: + +1. Configure wagmi for your app. Below is a basic wagmi configuration. For advanced configurations, please refer to the [wagmi documentation](https://wagmi.sh/react/WagmiConfig). + + +```jsx +import MyPage from './components/MyPage' +import { KitProvider } from '@0xsequence/kit' +import { getDefaultConnectors } from '@0xsequence/kit-connectors' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { createConfig, http, WagmiProvider } from 'wagmi' +import { mainnet, polygon, Chain } from 'wagmi/chains' + +const queryClient = new QueryClient() + +function App() { + const chains = [mainnet, polygon] as [Chain, ...Chain[]] + + const projectAccessKey = '' + + const connectors = getDefaultConnectors({ + walletConnectProjectId: 'wallet-connect-id', + defaultChainId: 137, + appName: 'demo app', + projectAccessKey + }) + + const transports = {} + + chains.forEach(chain => { + transports[chain.id] = http() + }) + + const config = createConfig({ + transports, + connectors, + chains + }) + + return ( + + + + + + + + ); +} +``` + +2. Wrap your app with the `KitProvider` within the `WagmiConfig` wrapper. + + +# Setting Up the Embedded Wallet Wrapper +To install the optional embedded wallet, add the `KitWalletProvider` below the `KitProvider` wrapper. + +```jsx +import { KitWalletProvider } from '@0xsequence/kit-wallet' + +// ... + +const App = () => { + return ( + + + + + + + + + + ) +} +``` + +The complete code will then look like this: + +```jsx +import MyPage from './components/MyPage' +import { KitProvider } from '@0xsequence/kit' +import { getDefaultConnectors } from '@0xsequence/kit-connectors' +import { KitWalletProvider } from '@0xsequence/kit-wallet' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { createConfig, http, WagmiProvider } from 'wagmi' +import { mainnet, polygon, Chain } from 'wagmi/chains' + +const queryClient = new QueryClient() + +function App() { + const chains = [mainnet, polygon] as [Chain, ...Chain[]] + + const projectAccessKey = '' + + const connectors = getDefaultConnectors({ + walletConnectProjectId: 'wallet-connect-id', + defaultChainId: 137, + appName: 'demo app', + projectAccessKey + }) + + const transports = {} + + chains.forEach(chain => { + transports[chain.id] = http() + }) + + const config = createConfig({ + transports, + connectors, + chains + }) + + return ( + + + + + + + + + + ); +} +``` + +# Triggering the Connect Modal + +
    + +
    + +Invoke the connect modal using the `useOpenConnectModal` hook. + +```jsx +import { useOpenConnectModal } from '@0xsequence/kit' +import { useDisconnect, useAccount } from 'wagmi' + + +const MyReactComponent = () => { + const { setOpenConnectModal } = useOpenConnectModal() + + const { isConnected } = useAccount() + + const onClick = () => { + setOpenConnectModal(true) + } + + return ( + <> + {!isConnected && ( + + )} + + ) +} +``` + +The modal will automatically close once the user signs in. You can utilize the `useAccount` hook from wagmi to detect the user's connection status. + +# Invoking the embedded wallet modal + +
    + +
    + +Open the embedded wallet using the `useOpenWalletModal` react hook. + +```jsx +import { useOpenWalletModal } from '@0xsequence/kit-wallet' + +const MyComponent = () => { + const { setOpenWalletModal } = useOpenWalletModal() + + const onClick = () => { + setOpenWalletModal(true) + } + + return ( + + ) +} +``` + +# React Example +The Sequence Kit [Github repository](https://github.com/0xsequence/kit) contains an [example app](https://github.com/0xsequence/kit/tree/master/examples/react) that you can use for learning and testing. diff --git a/docs/pages/sdk/sequence-kit/03-configuration.mdx b/docs/pages/sdk/sequence-kit/03-configuration.mdx new file mode 100644 index 00000000000..4448306d0a4 --- /dev/null +++ b/docs/pages/sdk/sequence-kit/03-configuration.mdx @@ -0,0 +1,130 @@ +--- +sidebar_label: Configuration +--- + +# Configuration Options +Developers can customize the Sequence Kit experience by passing configuration options to the `KitProvider` wrapper. + +Here's how you can configure the kit using these options: + + +```jsx + + const kitConfig = { + defaultTheme: 'light', + position: 'top-left', + ... + } + + + + + +``` + +# Available Options + + +## `defaultTheme` +| Type | Default | +| -------- | ------- | +| string or object | dark | + +The defaultTheme determines the color palette used for styling the modal. Possible values include: +- 'light' +- 'dark' +- object + +Specific colors can be overwritten by passing a theme override object. The [Sequence Builder](https://sequence.build/) provides a useful playground for toying with the colors in Sequence Kit. + +## `position` +| Type | Default | +| -------- | ------- | +| string | center | + +The position parameter determines the location of the various modals on the screen. Possible values include: +- center +- middle-right +- middle-left +- top-center +- top-right +- top-left +- bottom-center +- bottom-right +- bottom-left + + +## Sign In Modal Configuration (`signIn`) +The `signIn` object is used to configure the sign in modal. + +### `signIn.logoUrl` + +
    + +
    + +| Type | Default | +| -------- | ------- | +| string | undefined | + +URL of the logo to be shown in the sign in modal. + +### `signIn.projectName` + +
    + +
    + +| Type | Default | +| -------- | ------- | +| string | undefined | + +Name of the project to be shown in the sign in modal. + +### `signIn.showEmailInput` +
    + +
    + +| Type | Default | +| -------- | ------- | +| boolean | true | + +Determines whether the inline email input will be shown in the sign in modal. + +### `signIn.socialAuthOptions` +
    + +
    + +| Type | Default | +| -------- | ------- | +| string[] | ['google', 'facebook', 'twitch', 'apple'] | + +Determines which authentication options will be shown as social options in the sign in modal. +The wallets will be displayed in the order they are passed in the array. The values correspond to the connector's id and a corresponding connector must be passed down to wagmi. + +For a full list of official connectors, see the [connectors](https://github.com/0xsequence/kit/tree/master/packages/connectors) page. + +### `signIn.walletAuthOptions` +
    + +
    + +| Type | Default | +| -------- | ------- | +| string[] | ['sequence', 'metamask', 'wallet-connect', 'coinbase-wallet'] | + +Determines which authentication options will be shown in the modal as web3 wallet options. +The wallets will be displayed in the order they are passed in the array. The values correspond to the connector's id and a corresponding connector must be passed down to wagmi. + +For a full list of official connectors, see the [connectors](https://github.com/0xsequence/kit/tree/master/packages/connectors) page. + +## `displayedAssets` +| Type | Default | +| -------- | ------- | +| [\{ contractAddress: string, chainId: number \}, ...] | undefined | + +If provided, this will determine which assets are to be displayed in the embedded wallet modal main view. +By passing a list of displayed assets, only assets from the provided list will be displayed in the main view. +In the case that no assets are provided, all owned assets can be displayed in the main view. \ No newline at end of file diff --git a/docs/pages/sdk/sequence-kit/04-checkout.mdx b/docs/pages/sdk/sequence-kit/04-checkout.mdx new file mode 100644 index 00000000000..bfef07ffd66 --- /dev/null +++ b/docs/pages/sdk/sequence-kit/04-checkout.mdx @@ -0,0 +1,110 @@ +--- +sidebar_label: Checkout +--- + +# Overview +The checkout modal enables developers to easily facilitate cryptocurrency payments. + +
    + +
    + +# Integration +To integrate the checkout feature, follow these steps: +1. Install the `kit-checkout` module: + +```bash +npm install @0xsequence/kit-checkout +# or +pnpm install @0xsequence/kit-checkout +# or +yarn add @0xsequence/kit-checkout +``` + +2. Place the KitCheckoutProvider below the Sequence Kit Core provider in your app: + +```jsx +import { KitCheckoutProvider } from '@0xsequence/kit-checkout' + + +const App = () => { + return ( + + + + + + + + + + ) +} +``` +## Opening the Checkout modal +Use the `useCheckoutModal` hook to open the checkout modal and pass a settings object: + + +```jsx + import { useCheckoutModal } from '@0xsequence/kit-checkout' + + + const MyComponent = () => { + const { triggerCheckout } = useCheckoutModal() + + const onClick = () => { + const checkoutSettings = {...} + triggerCheckout(checkoutSettings) + } + + return ( + + ) + } +``` + + +## Configuring the Checkout modal +Configure the checkout modal using the `checkoutSettings` object: + + +```jsx +const checkoutSettings = { + cryptoCheckout: {...}, + orderSummaryItems: {...} +} +``` + +### Crypto Checkout Configuration (`cryptoCheckout`) +The `cryptoCheckout` field specifies settings for checking out with cryptocurrency, e.g., interacting with a minting contract or marketplace contract. + +Example configuration: + +```jsx +cons checkoutConfig = { + // ... + cryptoCheckout: { + chainId: 137, + triggerTransaction: async () => { console.log('triggered transaction') }, + coinQuantity: { + contractAddress: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174', + amountRequiredRaw: '10000000000' + }, + }, +} +``` + +### Order Summary Configuration (`orderSummaryItems`) +The `orderSummaryItems` field specifies the list of collectibles shown in the order summary. + +Example configuration: + +```jsx + orderSummaryItems: [ + { + contractAddress: '0x631998e91476da5b870d741192fc5cbc55f5a52e', + tokenId: '66597', + quantityRaw: '100' + }, + ] +``` diff --git a/docs/pages/sdk/sequence-kit/05-custom-connectors.mdx b/docs/pages/sdk/sequence-kit/05-custom-connectors.mdx new file mode 100644 index 00000000000..84171d4ccc1 --- /dev/null +++ b/docs/pages/sdk/sequence-kit/05-custom-connectors.mdx @@ -0,0 +1,84 @@ +--- +sidebar_label: Custom Connectors +--- + +# Custom Connectors in Sequence Kit + +Sequence Kit provides official connectors via the [@0xsequence/kit-connectors](https://github.com/0xsequence/kit/tree/master/packages/connectors) package. However, you can also integrate custom connectors with Sequence Kit to support additional wallets. This guide will walk you through creating and using custom connectors. + +## Creating a Custom Connector + +To create a custom connector, you can use an existing connector as a basis. For example, the [Metamask Connector](https://github.com/0xsequence/kit/blob/master/packages/connectors/src/connectors/metamask/metamask.ts) is a good starting point. Here's an example of how to create a custom connector: + +```tsx +export const myCustomConnector = (options: MyCustomConnectorOptions) => ({ + id: 'my-custom-connector', + name: 'My Custom Connector', + logoDark: MyCustomLogoDark, + logoLight: MyCustomLogoLight, + createConnector: () => { + const connector = myCustomConnector(options); + return connector; + }, +}); +``` + +Make sure to provide a unique `id` for your connector to avoid conflicts with other connectors. You can also customize fields such as `name`, `logoDark`, and `logoLight` to control how the connector appears in Sequence Kit. + +The `createConnector` function should return an initialized connector. Sequence Kit connectors are wrappers of Wagmi connectors, so you can use an official Wagmi connector if available, or create your own if needed. + +For more details on creating custom connectors, refer to [Wagmi's guide on Custom Connectors](https://wagmi.sh/examples/custom-connector). + +# Using Custom Connectors +When using custom connectors, you can't rely on the `getDefaultConnectors` utility function. Instead, you need to pass custom configurations to Sequence Kit. + +First, create a list of connectors, including your custom connector, and provide it to the Wagmi configuration: + +```tsx +import { getKitConnectWallets } from '@0xsequence/kit'; + +const connectors = getKitConnectWallets([ + google({ + defaultNetwork: 137, + connect: { + app: 'my-app', + projectAccessKey: '' + } + }), + // ... other connectors + myCustomConnector({ appName: 'my-app' }), +]); + +const config = createConfig({ + transports, + connectors, + chains +}) +``` + +Next, use your custom connector by specifying its `id` in either the `socialAuthOptions` or `walletAuthOptions` field of the Sequence Kit configuration: + +```tsx +const kitConfig = { + signIn: { + socialAuthOptions: ['google', 'facebook'], + walletAuthOptions: ['metamask', 'my-custom-connector'], + } +}; + +return ( + + + + + + + +); +``` + +# Share Your Custom Connectors + +Feel free to contribute your custom connectors by creating a [pull request](https://github.com/0xsequence/kit/pulls). This way, others can benefit from your work and enjoy seamless integration with Sequence Kit. + +Share the love ❤️ by expanding the ecosystem of custom connectors! diff --git a/docs/pages/sdk/sequence-kit/_category_.json b/docs/pages/sdk/sequence-kit/_category_.json new file mode 100644 index 00000000000..84dfe98e715 --- /dev/null +++ b/docs/pages/sdk/sequence-kit/_category_.json @@ -0,0 +1,7 @@ +{ + "label": "Sequence Kit", + "link": { + "type": "doc", + "id": "wallet/connectors/kit/overview" + } +} diff --git a/docs/pages/solutions/.DS_Store b/docs/pages/solutions/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..67126699e71af751f6f35c63548de14fa7786dc2 GIT binary patch literal 6148 zcmeHKO^ee&7=CBB+H|WBVFeL{fY)|yLG}YLv91TNM)aUklP2qiW@kc@8le<=SO0>4 z!Mi_X|I42AnU95byA=M}R+zDIeMmQ}BJ$~HC|*RD66rqg!b z2FIcfs<4`rgRpolYcGVzqVsYXy-bsO=x#p|yb4pE6pE0>30&U1N_i~mftc{PRNO#! zI4!3&bni~5d%OD`uiNh(%sSq5fA?X>>-Y8!X0w)a`~HJR&xhmegp1GW*@R!348IQouFoOc~K2mc}(7tZ%7o#_+R@@A%YUNEiyATys zYgep*d2gNe6_0C&vkF)R{(S}H{@@`=^bO86s;vW=x&iTqAm5 zOjCiH%FGpmX*$|Hq2Xo1;30!jv(Sq1*60zUz%;=M%x literal 0 HcmV?d00001 diff --git a/docs/pages/solutions/builder.mdx b/docs/pages/solutions/builder.mdx deleted file mode 100644 index 414e3a5762b..00000000000 --- a/docs/pages/solutions/builder.mdx +++ /dev/null @@ -1 +0,0 @@ -## Builder Overview diff --git a/docs/pages/solutions/builder/contracts.mdx b/docs/pages/solutions/builder/contracts.mdx new file mode 100644 index 00000000000..09bf530f184 --- /dev/null +++ b/docs/pages/solutions/builder/contracts.mdx @@ -0,0 +1,45 @@ +--- +title: Contracts +hide_title: true +slug: /builder/contracts +--- + +# Contracts in Builder + +Sequence Builder simplifies smart contract deployment and management with a suite of user-friendly features. Import, deploy, and add contract collaborators to a smart contract in the contracts dashboard and interact directly with your contract. + +##### What are my deployment options? +Deployment of contracts with Sequence Builder is simplified through a streamlined process directly within our dashboard. Choose from various contract templates (ERC1155, ERC721, ERC20). The Builder also gives you the option to upload your own custom contracts - saved to your project - and can be deployed directly to a network of your choosing. + +##### What contract interactions can I do? +Sequence Builder provides a comprehensive contract dashboard, allowing users to explore and monitor various smart contract activities like transactions, balance, and tokens. Performing read and executing write operations on contracts becomes effortless, making it easy for actions such as minting and collaborations. + +## Watch a Contract be deployed with Builder +
    + +
    + +## Add Contract Collaborators to Audited Contracts +Once you have a contract selected from one of the templates deployed, you can navigate to the specific contract and select the settings to view Permissions. + +![contract settings](/img/builder/builder_contract_specific_settings.png) + +Once you have the modal open, select the `Permissions` tab and you can `Edit`, or, `+ Add Collaborator`. + +![add collaborator](/img/builder/builder_contract_specific_permissions.png) + +Then complete the form with the user's address you want to add as a collaborator and select the dropdown to assign a new role. + +##### Possible roles +* Admin: Can update roles +* Minter: Can mint tokens +* Mint Admin: Can set minting logic +* Withdraw: Withdraw tokens from the contract +* Metadata Admin: Can update metadata + +![assign role](/img/builder/builder_contract_permissions_dropdown.png) + +Finally, complete and sign the transaction to be deployed to the network the contract is deployed on. + +![complete transaction](/img/builder/builder_contract_permissions_transaction.png) \ No newline at end of file diff --git a/docs/pages/solutions/builder/gas-tank.mdx b/docs/pages/solutions/builder/gas-tank.mdx new file mode 100644 index 00000000000..3224fbd871f --- /dev/null +++ b/docs/pages/solutions/builder/gas-tank.mdx @@ -0,0 +1,26 @@ +--- +title: Gas Tank +hide_title: true +slug: /builder/gas-tank +--- + +# Gas Tank in Builder + +Sequence wallets are controlled by smart contracts, enabling transaction fees to be abstracted away from users, a concept known in web3 as *gas*. With Sequence Builder's Gas Tank, you have a streamlined process for sponsoring gas for your users. + +##### Why would I want to sponsor gas for my game? +Obtaining the crypto needed to cover fees poses a challenge for traditional gamers. Sponsoring gas on their behalf solves this problem. + +Gas sponsoring in a web3 game provides seamless onboarding by removing gas fees, making transactions efficient and cost-effective for trading virtual assets in various in-game activities. This creates a more enjoyable gaming experience, fostering player loyalty and community engagement. + +##### Sponsoring gas with the Gas Tank +Sponsoring gas on contracts is easy, and can be done either by searching and adding a contract or selecting a contract that you have already deployed on a project. Project owners also have control over the contracts they sponsor, allowing them to temporarily disable a sponsor for a specific contract by toggling it off and updating the sponsor settings. + +There are a few options to fund sponsored gas, including a credit card checkout that makes paying for gas simple. + + +## Watch the Gas Tank in action in Builder +
    + +
    \ No newline at end of file diff --git a/docs/pages/solutions/builder/indexer.mdx b/docs/pages/solutions/builder/indexer.mdx new file mode 100644 index 00000000000..f175876dae9 --- /dev/null +++ b/docs/pages/solutions/builder/indexer.mdx @@ -0,0 +1,29 @@ +--- +title: Indexer +hide_title: true +slug: /builder/indexer +--- + +# Indexer in Builder + +Sequence Builder equips game builders with an indexer that collects data from the following networks: Ethereum (and Sepolia), Optimism, Base, Gnosis Chain, Polygon (and Polygon Mumbai), Polygon zkEVM, Arbitrum One, Arbitrum Nova, Gnosis Chain, BNB Smart Chain (and Smart Chain Testnet), Avalanche (and Avalanche Testnet), Oasys Homeverse (and Oasys Homeverse Testnet). + +#### What data can I query for my game? +Builder takes the stress out of gathering on-chain data for your game. Simply select the data you want from the indexer, and it generates the necessary code in snippets. + +Fetch different kinds of data from the indexer: +- tokens and collectibles owned by any wallet +- total supply for any token or collectible +- the transaction and transfer history for any wallet address +- contract metadata for any token or collection +- metadata for any collectible +- balance change events for any token or collection + +#### How much code will I have to write to query? +Sequence Indexer offers several features that level-up your on-chain data capabilities without writing a line of code. It boasts a user-friendly interface that you can use to fetch important data, like the tokens owned by a specific wallet under a specific contract, for instance. + +## Watch the Indexer grab on-chain data +
    + +
    \ No newline at end of file diff --git a/docs/pages/solutions/builder/marketplaces.mdx b/docs/pages/solutions/builder/marketplaces.mdx new file mode 100644 index 00000000000..e2f909cdc56 --- /dev/null +++ b/docs/pages/solutions/builder/marketplaces.mdx @@ -0,0 +1,20 @@ +# Launch your white-label marketplace + +Sequence Builder provides game builders with a white-label marketplace that can be launched in seconds. With Builder, you can customize your marketplace and integrate it directly into your game experience, all with no-coding experience necessary. + +## Try it out +:::info +Get started quickly at [Sequence Builder](https://sequence.build/) to launch your marketplace. +::: + +##### Why would I want my own Marketplace for my web3 game? +Builder gives you full control over everything in your marketplace, from enforcing royalties (with ERC-2981) to +choosing the best trading mechanism for your community, setting fees, and more. +You can also aggregate listings from major platforms like OpenSea or LooksRare, providing you with the benefit of existing liquidity without relinquishing control of the gaming experience. + + +## Watch a Marketplace be launched in minutes +
    + +
    \ No newline at end of file diff --git a/docs/pages/solutions/builder/node-gateway.mdx b/docs/pages/solutions/builder/node-gateway.mdx new file mode 100644 index 00000000000..a7483213e0e --- /dev/null +++ b/docs/pages/solutions/builder/node-gateway.mdx @@ -0,0 +1,23 @@ +--- +title: Node Gateway +hide_title: true +slug: /builder/node-gateway +--- + +# Node Gateway in Builder + +Sequence Builder offers a comprehensive Node Gateway dashboard that provides you with all the information needed to manage your node infrastructure, from compatibility with your favorite Web3 module to your requirement for real-time performant data for your game. + +##### What kind of performance can I expect for my game? +Sequence Node Gateway is engineered to power your gaming infrastructure. Node Gateway aggregates multiple node providers, auto-switching between them to ensure correct and in sync data availability — giving you the assurance that your decentralized applications run smoothly with low latency for your players. + +No need to worry about peak traffic – our node infrastructure is robust, offering higher scalability and fault tolerance. Additionally, we provide automatic node failure detection and recovery. + +##### What can you do to simplify the integration process for me? +We've designed our dashboard to automatically generate API access keys and URLs for each network you have enabled in settings. This makes it easy to import the URL into your preferred Web3 npm module. Additionally, our dashboard makes it easy to monitor your compute usage and credit consumption. + +## Watch a Node Gateway integration +
    + +
    \ No newline at end of file diff --git a/docs/pages/solutions/builder/overview.mdx b/docs/pages/solutions/builder/overview.mdx new file mode 100644 index 00000000000..ae462e7aa2d --- /dev/null +++ b/docs/pages/solutions/builder/overview.mdx @@ -0,0 +1,11 @@ +--- +slug: /builder/overview +--- + +# Sequence Builder + +[Builder](https://sequence.build/) is Sequence's all-inclusive tool for managing your projects, API keys, as well as contract and marketplace deployments. It also provides user access management so multiple people in your team can easily work on the same project. In addition to these powerful features, Builder also provides easy to use interfaces for managing sponsored wallets with your gas tank, and integration tools for SequenceKit, Node Gateway and Indexer. + +To learn more about how to leverage the powerful features of the Builder, follow the guides below. + +TODO: implement card section diff --git a/docs/pages/solutions/builder/project-management.mdx b/docs/pages/solutions/builder/project-management.mdx new file mode 100644 index 00000000000..9ca86279b17 --- /dev/null +++ b/docs/pages/solutions/builder/project-management.mdx @@ -0,0 +1,25 @@ +--- +title: Project Management +hide_title: true +slug: /builder/project-management +--- + +# Project Management +Creation of projects is seamless in just several clicks. This process requires no KYC, only that users comply with Global [regulations and policies](https://support.sequence.xyz/en/article/sequence-list-of-restricted-regions-1eked2s/), and an agreement to the platforms' terms of service. + +##### Project Name +Choose a `project name` - something playful, serious, or just something unique to distinguish your new project amongst the other projects linked to your wallet. + +##### Avatar +Upload a custom `avatar` to your project that displays aspects of your identity you want to be included as part of your project, or, something specific to the theme of what you're building. [You can always update your collaborators](/builder/settings#watch-how-to-invite-collaborators) and coordinate across the internet so Avatars can be a stepping stone to trust. + +##### Configure networks +Configure 1 or multiple `networks` for a single project from the 11 offered production / mainnet networks, or, 8 test networks, with a simple flip of a toggle. At any point, the networks for your project chosen can be updated in the settings. + +All 3 of these values: `Project name`, your `avatar`, and your configured `networks` can be changed later. + +## Watch a Project be created in the Builder +
    + +
    diff --git a/docs/pages/solutions/builder/project-settings.mdx b/docs/pages/solutions/builder/project-settings.mdx new file mode 100644 index 00000000000..0cde6deff31 --- /dev/null +++ b/docs/pages/solutions/builder/project-settings.mdx @@ -0,0 +1,399 @@ +--- +title: "Settings" +hide_title: true +slug: /builder/settings +--- + +# Settings in Builder + +## Settings Options + +There are various actions available for your project in Settings of Sequence Builder. + +The Settings section in Sequence Builder is categorized into five smaller sections: +1. **General**: Update your [project name](/builder/settings#project-name) or [avatar](/builder/settings#avatar) +2. **Collaborators**: Add [collaborators](/builder/settings#add-a-collaborator) or create [invite links](/builder/settings#create-an-invite-link) +3. **Networks**: Update the [networks](/builder/settings#3-network-settings) your project is using +4. **API Access Keys**: Create [new keys](/builder/settings#create-a-new-api-access-key) and [configure existing keys](/builder/settings#update-api-access-settings-of-a-key) +5. **Billing**: Update your [project plan](/builder/settings#update-your-project-subscription-plan) or set [overage limits](/builder/settings#set-your-overage-limit) + +The final action you can take in settings is to [delete your project](/builder/settings#delete-a-project). + +Settings are configured per project, so let's start by navigating to the settings of a specific project. + +--- +## Getting to Settings in Builder + + +#### Select a Project + +When you log into Sequence Builder, you will see a list of projects. If you haven't created a project yet, do so now. + +Begin by selecting a project. + + +![Builder select Project](/img/builder/select-project.png) + +#### Go to Settings + +Now that you are in your project dashboard, click on 'Settings' on the left side of the screen. + + +![Builder select Settings](/img/builder/select-settings.png) + +Within settings, you will find the five smaller sections covered in this guide. + + +--- +## 1. General Settings + +Open your General settings. + + +![Builder settings select General](/img/builder/settings-select-general.png) + +In General settings, you will find a couple of options. + +##### Project Name +The first option is to change your Project Name. To do so, enter a new project name in the field and hit the `Update` button to save. + +##### Avatar +The second option allows you to modify your Project Avatar, visible in the top left corner of your project on the dashboard. Click the Avatar field to choose an image and then press the `Update` button to save your changes. + + +![Builder settings General](/img/builder/settings-general.png) + +--- +## 2. Collaborator Settings + +Collaborators for any project can be added and deleted. + +You can either follow this below section, or, skip ahead to the [video](/builder/settings#watch-how-to-invite-collaborators) for inviting collaborators. + +Start, by opening your Collaborators settings. + +![Builder settings select Collaborators](/img/builder/settings-select-collaborators.png) + +In the Collaborator settings, you have two methods to add collaborators to your project. + +The first method is to directly add collaborators by entering their information and selecting their access level. + +The second method is to create an invite link. When using this option, you can specify the access level, link duration, and optional usage limits. + +Let's walk through each of these. + + +![Builder settings Collaborators](/img/builder/settings-collaborators.png) + +### Add a Collaborator + +To add a collaborator, make sure you have selected the [correct project](/builder/settings#select-a-project), accessed [Settings](/builder/settings#go-to-settings), and are in the [Collaborators](/builder/settings#2-collaborator-settings) section. + + +Start by clicking on the `Add Collaborator` button. + + +![Builder settings Collaborators select Add Collaborator](/img/builder/settings-collaborators-select-add-collaborator.png) + +Enter a wallet address in the user address field, and then select the access level you want using the role dropdown. + +Finish by clicking the `Add new Collaborator` button. + + +![Builder settings Collaborators Add Collaborator modal](/img/builder/settings-collaborators-add-collaborator-modal.png) + +To confirm, you should see your new collaborator in the dashboard, including their wallet address and access level. + + +![Builder settings Collaborators confirm collaborator](/img/builder/settings-collaborators-confirm-collaborator.png) + +### Create an Invite Link + +To create an invite link, make sure you have selected the [correct project](/builder/settings#select-a-project), accessed [Settings](/builder/settings#go-to-settings), and are in the [Collaborators](/builder/settings#2-collaborator-settings) section. + +Start by click on the the `Create Invite Link` button. + + +![Builder settings Collaborators select Create Invite Link](/img/builder/settings-collaborators-select-create-invite-link.png) + +Start by selecting the access level you want your invite link to give: Read, Write, or Admin. + +Enter the number of collaborators you want this link to be limitted to (setting a limit is optional). + +Finally, select the amount of time you want this link to be valid: a day, 3 days, or a week. + +Finish by clicking the `Create Link` button. + + +![Builder settings Collaborators Create Invite Link modal](/img/builder/settings-collaborators-create-invite-link-modal.png) + +To confirm, you should see your invite link in the dashboard, including the access level, limit, date created, and time remaining until it expires. + + +![Builder settings Collaborators confirm invite link](/img/builder/settings-collaborators-confirm-invite-link.png) + +#### Sharing an Invite Link + +To share an invite link, click the `Copy Link` button. + +Go to where you want to share the link, paste it, and send it to your collaborators. + + +![Builder settings Collaborators select copy link](/img/builder/settings-collaborators-select-copy-link.png) + + +#### Deleting an Invite Link + +To remove an invite link, click the `Delete Link` button. + + +![Builder settings Collaborators select delete link](/img/builder/settings-collaborators-select-delete-link.png) + +You will be prompted to confirm the deletion; click `Yes` to delete. + + +![Builder settings Collaborators confirm delete modal](/img/builder/settings-collaborators-confirm-delete-modal.png) + +After deleting the link, you'll get a success notification at the bottom right of your dashboard, and the link will no longer be visible. + + +![Builder settings Collaborators confirm invite deleted](/img/builder/settings-collaborators-confirm-invite-deleted.png) + +## Watch how to invite Collaborators +If you prefer to watch a video for how to invite Collaborators to join your project, watch here: +
    + +
    + +--- +## 3. Network Settings + +Open your Network settings. + + +![Builder settings select Networks](/img/builder/settings-select-networks.png) + +In the network settings, you'll see a list of supported networks in Sequence. Here, you can choose which networks you want to access through the Node Gateway and deploy smart contracts on. + +Toggle the networks you wish to use and then click the `Update` button. + + +![Builder settings Networks](/img/builder/settings-networks.png) + + + +--- +## 4. API Access Keys Settings + +Open your API Access Keys settings. + + +![Builder settings select API Access Keys](/img/builder/settings-select-api-access-keys.png) + +In the API Access Keys section, you will find a dashboard with several options: monitor the usage of each key, set your default key, or expand the details of a specific key. + +You can also add a new key or edit the details of an existing key. + + +![Builder settings API Access Keys](/img/builder/settings-api-access-keys.png) + +For each key, there are specific actions you might want to take, such as: +- [rename](/builder/settings#renaming-your-key) or [delete](/builder/settings#deleting-your-key) your key +- [copy](/builder/settings#copy-your-key) or [change](/builder/settings#rotate-your-key) the credentials of your key +- configure [how](/builder/settings#set-service-access) and [where](/builder/settings#set-domain-access) your key can be used + +### Create a new API Access Key + +To create a new API Access Key, make sure you have selected the [correct project](/builder/settings#select-a-project), accessed [Settings](/builder/settings#go-to-settings), and are in the [API Access Key](/builder/settings#4-api-access-keys-settings) section. + +Start by clicking the `Add API Access Key` button. + + +![Builder settings API Access Keys select add API Access Key](/img/builder/settings-api-access-keys-select-add-api-access-key.png) + +Provide a name for the key and click the `Add Access Key` button to generate a new key. + +If you need to configure any details of your key, you can do so by selecting and updating it from the dashboard. + +Finish by clicking the `Add Access Key` button. + + +![Builder settings API Access Keys add Api Access Key modal](/img/builder/settings-api-access-keys-add-api-access-key-modal.png) + +### Rename or delete an API Access Key + +To rename or delete one of your keys, make sure you have selected the [correct project](/builder/settings#select-a-project), accessed [Settings](/builder/settings#go-to-settings), and are in the [API Access Key](/builder/settings#4-api-access-keys-settings) section. + +Start by selecting the key you want to edit. + + +![Builder settings API Access Keys select API key for rename](/img/builder/settings-api-access-keys-select-api-key-for-rename.png) + +##### Renaming your key + +In the name field, and enter a new name. + +Then click the `Update` button. + + +![Builder settings API Access Keys rename key](/img/builder/settings-api-access-keys-rename-key.png) + +##### Deleting your key + +Click the `Delete` button in the bottom left. + + +![Builder settings API Access Keys delete key](/img/builder/settings-api-access-keys-delete-key.png) + + +You will be prompted to confirm the deletion; click `Yes` to delete. + + +![Builder settings API Access Keys delete key modal](/img/builder/settings-api-access-keys-delete-key-modal.png) + +### Access the credentials of a Key + +To access the credentials of a key, make sure you have selected the [correct project](/builder/settings#select-a-project), accessed [Settings](/builder/settings#go-to-settings), and are in the [API Access Key](/builder/settings#4-api-access-keys-settings) section. + +Start by selecting the key that you want to access the credentials for. + + +![Builder settings API Access Keys select api key](/img/builder/settings-api-access-keys-select-api-key.png) + +##### Copy your Key +Your API key is designed to be used in another location or application. To use it, you need to copy it here and paste it into your application. + +To copy your keys credentials, click `Copy` in the Access Key field. + +After clicking, you'll get confirmation when the button briefly changes to `✓ Copied`. + +Your key credentials are now copied to your clipboard. + + +![Builder settings API Access Keys copy key](/img/builder/settings-api-access-keys-copy-key.png) + +##### Rotate your Key +You may want to change your key credentials without losing all of its usage history. + +To do this, click the `Rotate` button in the Access Key field. + +After clicking, you'll see the credentials transform with a success notification in the bottom right. + + +![Builder settings API Access Keys rotate key](/img/builder/settings-api-access-keys-rotate-key.png) + +### Update API access settings of a Key + +To update API access settings of a key, make sure you have selected the [correct project](/builder/settings#select-a-project), accessed [Settings](/builder/settings#go-to-settings), and are in the [API Access Key](/builder/settings#4-api-access-keys-settings) section. + +Start by selecting the key that you want to update the access to. + + +![Builder settings API Access Keys select api key](/img/builder/settings-api-access-keys-select-api-key.png) + +##### Set domain access +You can ensure that the services linked to your API key are only utilized on domains connected to your game or app by enabling specific domains where your keys can be used. + +To do this, enter a domain you want to enable access to into the domain field. + +If you want to include another domain, click the `Add Domain` button and add it too. You should now have a list of domains your key can be used with. + +Continue adding to this list until you have included all of the domains that you need. + +Complete your update by clicking the `Update button` to save. + + +![Builder settings API Access Keys add domains](/img/builder/settings-api-access-keys-add-domains.png) + +##### Set service access +You can set your API key to enable only specific services rather than all the services we offer. + +To do this, look near the bottom right you will find several services listed with checkboxes. + +Check the box for each service that you want your key to have access to. + +Complete your update by clicking the `Update button` to save. + + +![Builder settings API Access Keys check services](/img/builder/settings-api-access-keys-check-services.png) + +--- +## 5. Billing Settings + +Open your Billing settings. + +![Builder settings select Billing](/img/builder/settings-select-billing.png) + +In here, you are given all of subscription plan information that you need. + +You can also [update your subscription](/builder/settings#update-your-project-subscription-plan), and [set your overage limits](/builder/settings#set-your-overage-limit). + +##### Billing information +In the billing section, you can quickly access key information about your subscription plan: + +- Current subscription plan +- Current billing period dates +- Monthly billing amount +- Next renewal date +- Monthly credits issued +- Credits used in the current period +- Remaining credits +- Overage settings status + + +### Update your project subscription plan +To update your project subscription plan, make sure you have selected the [correct project](/builder/settings#select-a-project), accessed [Settings](/builder/settings#go-to-settings), and are in the [Billing](/builder/settings#5-billing-settings) section. + +Start by clicking on the `Upgrade Plan` button. + +![Builder settings billing select upgrade plan](/img/builder/settings-billing-select-upgrade-plan.png) + +This will take you to our plans dashboard, where you can review the plans and select the one that works best for you. + +Once you know which plan you want, click the `Select Plan` button. + +![Builder settings billing upgrade plan dashboard](/img/builder/settings-billing-upgrade-plan-dashboard.png) + +This will take you to a checkout screen where you can enter your payment information. + +![Builder settings billing checkout](/img/builder/settings-billing-checkout.png) + +### Set your overage limit +To set your overage limit, make sure you have selected the [correct project](/builder/settings#select-a-project), accessed [Settings](/builder/settings#go-to-settings), and are in the [Billing](/builder/settings#5-billing-settings) section. you will also need a paid plan to set an overage limit. + +With a paid plan, start by clicking on the button with the gear icon. + +![Builder settings billing set overage](/img/builder/settings-billing-set-overage.png) + +Toggle the 'Set overage limit' option. + +Then enter the maximum overage amount that you would like to set. + +Finish by clicking the `Save changes` button. + +![Builder settings billing overage modal](/img/builder/settings-billing-overage-modal.png) + +--- + +## Delete a Project + +:::danger +The following instructions are destructive and irreversible, so do not follow these steps unless you intend to delete your project. +::: + +To delete your project, make sure you have selected the [correct project](/builder/settings#select-a-project) and are in the [Settings](/builder/settings#go-to-settings) section. You will also need administrative-level permissions to delete a project. + +If you are an Admin, you will notice a section labeled 'Danger Zone' under all your settings sections. + +In this area, you will also find an option to 'Delete this Project' — click that option. + + +![Builder delete project](/img/builder/delete-project.png) + +This action will prompt a modal to confirm that you want to delete your Project. + +Enter the name of your project and click the `Delete Permanently` button. + + +![Builder delete project](/img/builder/delete-project-modal.png) \ No newline at end of file diff --git a/docs/pages/builder/stub.mdx b/docs/pages/solutions/builder/stub.mdx similarity index 100% rename from docs/pages/builder/stub.mdx rename to docs/pages/solutions/builder/stub.mdx diff --git a/docs/pages/solutions/builder/wallet-sdks.mdx b/docs/pages/solutions/builder/wallet-sdks.mdx new file mode 100644 index 00000000000..f3bca702181 --- /dev/null +++ b/docs/pages/solutions/builder/wallet-sdks.mdx @@ -0,0 +1,32 @@ +--- +title: Wallet SDKs +hide_title: true +slug: /builder/wallet-sdks +--- + +# Wallet SDKs in Builder +Sequence Builder offers multiple SDK options for integrating Sequence Wallet into your project. + +### How can I integrate a Wallet into my game with these options? +In the Wallets SDK section of Builder, simply select **SequenceKit**, input wallet details, click 'save', and code snippets will be generated for you to use. The same can be done for **Web SDK** (watch the tutorial below for additional guidance). **Unity SDK** and **Unreal SDK** will help you integrate the same way, but by interacting their respective game engines. Note that both SDKs are receiving updates and will be available shortly. + +### What are the differences between these options? +**Web SDK** and **SequenceKit** both deploy our Universal Wallet. They integrate differently, but offer the similar wallet benefits. However, **SequenceKit** is also a wallet connector, providing additional benefits. + +**SequenceKit** is a powerful wallet connector, enabling existing wallet users across web3 to connect a wallet - vastly improving their user experience through embedded item views, integrated NFT checkout, and seamless wallet creation. + +**The Unity SDK** integrates Wallet & Indexer functionality into games developed with the Unity Engine. Similarly, the **Unreal SDK** is an integration for games built with the Unreal Engine. + +### What are the benefits of each and how can I leverage them? + +All integrations provide non-custodial smart contract wallets with account abstraction benefits, including email and social login, gasless transactions, and more. + +**SequenceKit** benefits from also being a wallet connector, which you can leverage to cater to both existing wallet holders and millions of potential new users. The embedded wallet views, integrated NFT checkout, and seamless wallet creation ensure that users never need to leave the game or app. + +**Unity SDK** and **Unreal SDK** give you the advantages of integrating a Sequence Wallet directly into your game. + +## Watch a Wallet integration using SequenceKit with Builder +
    + +
    \ No newline at end of file diff --git a/docs/pages/solutions/chain-support.mdx b/docs/pages/solutions/chain-support.mdx index bf0297b0f7f..cbb29b7ae4a 100644 --- a/docs/pages/solutions/chain-support.mdx +++ b/docs/pages/solutions/chain-support.mdx @@ -1 +1,10 @@ -## Test +# Multi-Chain Support + +Sequence can support all EVM compatible chains. The following networks are currently supported by Sequence Wallet, Sequence Indexer, +Sequence Relayer and all Sequence SDKs: + +**Sequence Status Page: [https://status.sequence.info](https://status.sequence.info)** + +## Networks + +TODO: import tablecomponent \ No newline at end of file diff --git a/docs/pages/solutions/collectibles/contracts/900-mint-items-from-ERC1155.mdx b/docs/pages/solutions/collectibles/contracts/900-mint-items-from-ERC1155.mdx new file mode 100644 index 00000000000..fc4145b27c8 --- /dev/null +++ b/docs/pages/solutions/collectibles/contracts/900-mint-items-from-ERC1155.mdx @@ -0,0 +1,93 @@ +--- +slug: /guides/mint-items-from-ERC1155 +--- + +# How to Mint In-Game Items and Achievements in Builder + +## Introduction + +In this guide, we're going to walk through the process of creating your own in-game assets by minting from an ERC-1155 contract. These assets are commonly used for items and achievements, but could be used for just about any game object. + +#### What is an ERC-1155? + +ERC-1155 is simply [a multi-token standard](https://eips.ethereum.org/EIPS/eip-1155) that allows the creation of fungible, non-fungible, and semi-fungible tokens all in one contract. For games, this means that you can manage all of your in-game tokens with a single contract. + +#### What can you do with it? + +Your imagination is the limit. We mentioned achievements before, you could mint each as an NFT and grant it to the player. Or let's say your game generates unique items every time a boss is killed. Those items could be minted as tokens with all attributes baked in, and held in the player's own wallet. + +Lets dive in! + +### Prerequisite: Create a Project and deploy a Smart Contract + +This guide assumes that you have already [signed up for Builder and created a Project](/guides/signup-and-create-a-project). + +Before you get started creating (minting) items, you will need to first deploy the smart contract you wish to mint from. If you have not done so already, go back and do [how to load an item collection through deploying a smart contract](/guides/deploy-an-item-collection-contract). + +## Step 1: Select the Collection for your item + +Start by selecting the contract you would like to create an item from. In this example, we are covering ERC-1155, so select you the ERC-1155 contract that you have deployed. + +Once in the project dashboard, you should see the Collection - select it. + + +![Sequence builder select contract](/img/builder/builder_select_contract_mint_achievements.png) + +## Step 2: Navigate to Write Contract + +When you open your contract, you will see several options. Everything from details like your contract address, type, the network its deployed on - to options for adding gas or help setting up an indexer. Below those details, you have more options to view contract details and interact with it. + +Within that subset of options, select `Write Contract`. + + +![Sequence builder write contract](/img/builder/builder_navigate_write_contract_mint_achievements.png) + +This will drop down several methods that you can call to the smart contract. You do this by sending a transaction to the smart contract with the included call data. + +We're here to mint some items, so we'll select the `mint` method. + + +![Sequence builder select mint](/img/builder/builder_select_mint_method_mint_achievements.png) + +## Step 3: Provide details for the Mint method + +Selecting `mint` will expand it to give you a couple of fields to fill out. Fill each of these fields out first: +- `to (address)` - the address you want these to be minted to, for this example put your own address in. +- `tokenId (uint256)` - give the collection of items an id, for a first collection enter 0 or 1 here. +- `amount (uint256)` - enter the amount of items you want to mint in this collection. +- `data (bytes)` - for this one, enter 0x + +:::note +This type of contract, ERC-1155, can have several different groups of tokens on it - each requiring its own id. +::: + +Once you have filled out all of the fields, hit `write` to send a transaction to mint. + + +![Sequence builder fill mint details](/img/builder/builder_fill_mint_details_mint_achievements.png) + +## Step 4: Mint and sign your transaction + +After you hit `write`, a modal with your wallet will pop-up. In order to create (mint) these items, you will need to send a transaction. + +Read the transaction details, then execute the transaction by hitting `confirm` on the signature. + + +![Sequence builder sign transactions](/img/builder/builder_sign_transaction_mint_achievements.png) + +After you sign the transaction, the network will take a few seconds (maybe minutes depending on the network and other factors) to confirm your transaction. + +## Step 5: Confirm your minted items + +When the transaction is complete, you will have created your items by minting them from the smart contract! + +If you click `Balances`, you should be able to see the total number of items you minted from your collection. + + +![Sequence builder confirm mint](/img/builder/builder_confirm_mint_items_mint_achievements.png) + +In the example, you can see the 5 items I created just now, along with 4k items that I created in a seperate minting earlier. + +You can also click `Tokens` to see the both of the collections that we created and minted from. + +![Sequence builder confirm nft](/img/builder/builder_confirm_nft_mint_achievements.png) \ No newline at end of file diff --git a/docs/pages/solutions/collectibles/contracts/902-mint-collectibles-from-ERC721.mdx b/docs/pages/solutions/collectibles/contracts/902-mint-collectibles-from-ERC721.mdx new file mode 100644 index 00000000000..84b07352add --- /dev/null +++ b/docs/pages/solutions/collectibles/contracts/902-mint-collectibles-from-ERC721.mdx @@ -0,0 +1,98 @@ +--- +slug: /guides/mint-collectibles-from-ERC721 +--- + +# How to Mint Digital Collectibles in Builder + +## Introduction + +This guide walks you through creating in-game assets by minting from an ERC-721 contract, commonly known as NFTs (Non-Fungible Tokens), often used for collectibles. + +For more on creating in-game items from collections, [check our guide on using ERC-1155](/guides/mint-items-from-ERC1155). + +#### ERC-721 vs. ERC-1155 + +Both contracts mint NFTs, but ERC-721, being the earlier standard, has gained widespread adoption, particularly in digital collectibles. Known for its simplicity and ease to audit for security, ERC-721 tokens are distinct, contributing to their recognition in various NFT marketplaces. + +In contrast, ERC-1155 offers versatility with efficient batch operations for both fungible and non-fungible tokens in a single contract, reducing gas costs. However, this flexibility introduces complexity, necessitating careful security attention. + +#### Choosing for Gaming + +The choice depends on your needs. ERC-1155 is efficient for creating various unique in-game items. However, If you aim to provide tradable digital collectibles recognized across marketplaces, ERC-721 may be better suited. + +Which leads us to the point of this walkthrough - digital collectibles. As such, we will focus on using ERC-721 to create in-game digital collectibles to use in your game. + +Let's get started! + +### Prerequisite: Create a Project and deploy a Smart Contract + +This guide assumes that you have already [signed up for Builder and created a Project](/guides/signup-and-create-a-project). + +Before you get started creating (minting) collectibles, you will need to first deploy the smart contract you wish to mint from. If you have not done so already, go back and do [how to load an item collection through deploying a smart contract](/guides/deploy-an-item-collection-contract). + +## Step 1: Select the contract for your digital collectibles + +Start by selecting the contract you would like to create a collectible from. + +Once in the contract dashboard, you should see the ERC-721 contract that you have deployed - select it. + + + +![Sequence builder choose contract](/img/builder/builder_choose_contract_mint_collectibles.png) + +## Step 2: Navigate to Write Contract + +When opening the contract, you will see several options. Everything from details like your contract address, type, the network its deployed on - to options for adding gas or help setting up an indexer. Below those details, you have more options to view contract details and interact with it. + +Within that subset of options, select `Write Contract`. + + + +![Sequence builder write contract](/img/builder/builder_select_write_contract_mint_collectibles.png) + +Selecting this will reveal a variety of methods on the smart contract. + +Select the `mint` method. + + + +![Sequence builder mint method](/img/builder/builder_select_mint_method_mint_collectibles.png) + +## Step 3: Provide details for the Mint method + +Selecting `mint` will expand the method, providing inputs. + +Enter the address you want these collectibles to be minted to, for this example put your own address in. + +Enter the amount of collectibles you want to create. + +Then hit `write` to send a transaction to mint. + + + +![Sequence builder mint details](/img/builder/builder_fill_mint_details_mint_collectibles.png) + +## Step 4: Mint and sign your transaction + +Once you hit `write`, a modal with your wallet will pop-up. In order to create (mint) these collectibles, you will need to send a transaction. + +Read the transaction details and execute the transaction by hitting `confirm` on the signature. + + + +![Sequence builder sign transaction](/img/builder/builder_sign_transaction_mint_collectibles.png) + +After you sign the transaction, the network will take a few seconds (maybe minutes depending on the network and other factors) to confirm your transaction. + +When the transaction is complete, you will have created your digital collectibles by minting them from the smart contract! + +## Step 5: Confirm your minted collectibles + +Click the `Tokens` subsection to see the both of the collections that we created and minted from. + + + +![Sequence builder confirm mint](/img/builder/builder_confirm_mint_collectibles.png) + +In the example, you can see the 5 collectibles that we created. + diff --git a/docs/pages/solutions/collectibles/contracts/903-mint-currency-from-ERC20.mdx b/docs/pages/solutions/collectibles/contracts/903-mint-currency-from-ERC20.mdx new file mode 100644 index 00000000000..e686f0b8e4b --- /dev/null +++ b/docs/pages/solutions/collectibles/contracts/903-mint-currency-from-ERC20.mdx @@ -0,0 +1,94 @@ +--- +slug: /guides/mint-currency-from-ERC20 +--- + +# How to Mint in-game Currency in Builder + +## Introduction + +In this guide, we’re going to walk through the process of creating your own in-game currency through minting from an ERC-20 contract. + +Currency tokens add new and interesting dimensions to in-game economies, transactions, and player interactions. + +#### What is an ERC-20 token? + +An ERC-20 token is a digital coin - what makes it special is that it follows a [set of rules called ERC-20](https://ethereum.org/en/developers/docs/standards/tokens/erc-20/), making it easy to use in different places on the internet. These tokens often represent value or be used for specific purposes. Unlike the other common token - NFT's, these tokens are fungible. + +#### Fungability vs Non-Fungibility + +This is the key distinction to understand. + +Fungible tokens (like ERC-20 tokens) are interchangeable, and each unit is the same as every other unit, just like dollars or euros. They can easily be split or combined into different quantities. + +Non-fungible tokens (like ERC-721 tokens) represent unique items with individual properties, such as digital art or collectibles. Each token is distinct and not directly exchangeable with another on a like-for-like basis. + + +### Prerequisite: Create a Project and deploy a Smart Contract + +This guide assumes that you have already [signed up for Builder and created a Project](/guides/signup-and-create-a-project). + +Before you get started creating (minting) currency, you will need to first deploy the smart contract you wish to mint from. If you have not done so already, go back and do [how to load an item collection through deploying a smart contract](/guides/deploy-an-item-collection-contract). + +## Step 1: Select the contract for your currency + +Start by selecting the contract you would like to create currency from. + +Once in the contract dashboard, you should see the ERC-20 contract that you have deployed - select it. + + +![Sequence builder choose contract](/img/builder/builder_choose_contract_mint_currency.png) + + +## Step 2: Navigate to Write Contract + +When opening the contract, you will see several options. Everything from details like your contract address, type, the network its deployed on - to options for adding gas or help setting up an indexer. Below those details, you have more options to view contract details and interact with it. + +Within that subset of options, select `Write Contract`. + + +![Sequence builder choose contract](/img/builder/builder_select_write_contract_mint_currency.png) + + +Selecting this will reveal a variety of methods on the smart contract. + +Select the `mint` method. + + +![Sequence builder choose contract](/img/builder/builder_select_mint_method_mint_currency.png) + + + +## Step 3: Provide details for the Mint method + +Selecting `mint` will expand the method, providing inputs. + +Enter the address you want your currency to be minted to, for this example put your own address in. + +Enter the amount of currency you want to create. + +Then hit `write` to send a transaction to mint. + + +![Sequence builder choose contract](/img/builder/builder_fill_mint_details_mint_currency.png) + + +## Step 4: Mint and sign your transaction + +Once you hit `write`, a modal with your wallet will pop-up. In order to create (mint) your currency, you will need to send a transaction. + +Read the transaction details and execute the transaction by hitting `confirm` on the signature. + + +![Sequence builder choose contract](/img/builder/builder_sign_transaction_mint_currency.png) + + +After you sign the transaction, the network will take a few seconds (maybe minutes depending on the network and other factors) to confirm your transaction. + +When the transaction is complete, you will have created your own currency by minting them from the smart contract! + +## Step 5: Confirm your minted currency + +Click the `Balances` subsection to see the currency that we created and minted. + + +![Sequence builder choose contract](/img/builder/builder_confirm_mint_currency.png) diff --git a/docs/pages/solutions/collectibles/metadata/800-manage-contract-metadata-builder.mdx b/docs/pages/solutions/collectibles/metadata/800-manage-contract-metadata-builder.mdx new file mode 100644 index 00000000000..fbbe0348bca --- /dev/null +++ b/docs/pages/solutions/collectibles/metadata/800-manage-contract-metadata-builder.mdx @@ -0,0 +1,101 @@ +--- +slug: /guides/manage-contract-metadata-builder +--- + +# How to Manage Item Metadata in Sequence Builder + +## Introduction +Following this guide, you can easily manage token metadata for your contract items in Sequence Builder, with a little help from [Pinata](https://www.pinata.cloud/) for IPFS hosting. + +## Step 1: Prepare Your Token Images and Metadata +First things first, gather all your token images. For each token, you'll need a metadata file named `id.json` (like `1.json`, `2.json`, etc.). These files should look something like this at a minimum: + +```json +{ + "name": "Token Name", + "description": "Token Description", + "image": "ipfs://" +} +``` + +As you can guess, you can build from these basics. You could have your unique item attributes embedded in this token and generated on the fly. + +## Step 2: Set Up on Pinata.cloud +Head over to [Pinata.cloud](https://www.pinata.cloud/) and create an account. Upload each of your token images as separate files. Next, update the metadata JSON files with the `ipfs` address for each token. To do this, simply copy the CID (Content Identifier) for each file from Pinata and paste it after `ipfs://` in your JSON files. It should look like this: + +```json +{ + "name": "Token Name", + "description": "Token Description", + "image": "ipfs://QmdJzQExj2wnNY7pNNn4KauzckjH4vA5xhoxmmis919Ev3" +} +``` + +![Configure Pinata](/img/guides/manage-contract-metadata-builder/1.jpeg) + +## Step 3: Upload Your Metadata Files +Now, gather all your JSON metadata files into a single folder on your computer. Use Pinata's 'Upload \> Folder' feature to upload this folder. Then, copy the CID for the entire folder. + +![Upload Metadata](/img/guides/manage-contract-metadata-builder/2.jpeg) + +## Step 4: Get the Folder URL +Click on name of the folder you created on Pinata. This will open a new tab showing all your uploaded JSON files. Copy the URL of this folder. + +![Get Folder URL from Pinata](/img/guides/manage-contract-metadata-builder/3.jpeg) + +## Step 5: Set Up on Sequence Builder +Navigate to [Sequence Builder](https://sequence.build/), set up your account, and create your project on the network of your choice. In the Contracts section, click on "Deploy New Contract". + +![Configure Contract on Builder](/img/guides/manage-contract-metadata-builder/4.jpeg) + +## Step 6: Deploy Your Contract +Select "Web3 Game Item Collection (ERC-1155)" and name your contract. Sequence Builder will automatically deploy your contract on-chain. + +![Deploy Contract](/img/guides/manage-contract-metadata-builder/5.jpeg) + +## Step 7: Move to Contract Details +Once you sign the transaction, your contract is ready! Click on it to view the details screen. + +![Contract Details](/img/guides/manage-contract-metadata-builder/6.jpeg) + +## Step 8: Update Contract Attributes +Navigate to the “Write Contract” section. This is where you can modify attributes of your freshly deployed ERC-1155 contract. Two methods are what you should focus on for now: +- `setBaseMetadataURI` allows the creator to set the base metadata URL for this contract. You want this to point to the JSON files you’ve created, depending on NFT ID. +- `mint` mints one of your tokens and sends it to an address of your choosing. + +## Step 9: Set the Base Metadata URI +Scroll to `setBaseMetadataURI`, expand it, and under `tokenBaseURI` paste the URL for the JSON folder preview you got from Pinata earlier. It should look something like this: + +``` +https://azure-wooden-lemur-911.mypinata.cloud/ipfs/QmW5gvYGWb98GsN8VjTRWu4pLn6jryEXNxZKNWpPhVwtDm/ +``` + +Click “Write” and you will be prompted to sign again. This will modify the contract on chain to set the metadata base. Essentially any token ID you provide will be appended to this URL, along with the `.json` suffix. So if you mint token ID 123, it will look for `tokenBaseURI + 123.json`. + +![Base Metadata Setup](/img/guides/manage-contract-metadata-builder/7.jpeg) + +## Step 10: Minting Time +Finally, it's time to mint! Scroll up to `mint`, expand it, and fill in the details: + +- `to (address)`: This is the address that the token will be sent to. Use your Sequence wallet address or any other valid address. +- `tokenId (uint256)`: This is your token ID. As long as you have a `tokenId.json` file already uploaded to pinata.cloud under the folder, it will work. +- `amount (uint256)`: The number of tokens to mint (usually 1). +- `data (bytes)`: Enter `0x00` for this simple process. + +![Mint test](/img/guides/manage-contract-metadata-builder/8.jpeg) + +## Step 11: Finalize and Admire +Click "Write" and sign the transaction. Congratulations, you've just minted a token! Head over to the "Tokens" section to see your minted tokens with their names and images. + +![Finalize Minting](/img/guides/manage-contract-metadata-builder/9.jpeg) + +## Step 12: Updating Metadata +If you make mistakes with the token metadata, you can always update it and then call the Sequence Metadata refresh endpoint to reload the specific tokens: + +``` +curl -X GET "https://metadata.sequence.app/tokens/mumbai/0xb392c99d9f8e3e0b248e5c283818be5bf5cecca7/1/refresh" +``` + +This is in the format: `https://metadata.sequence.app/tokens////refresh` + +Now that you are ready to mint, you might want to read about [how you can launch your own serverless endpoint for securely minting tokens](/relayer/mint-collectibles-serverless). diff --git a/docs/pages/solutions/contracts.mdx b/docs/pages/solutions/contracts.mdx deleted file mode 100644 index e823b36a0a0..00000000000 --- a/docs/pages/solutions/contracts.mdx +++ /dev/null @@ -1,3 +0,0 @@ -## Deploy an in-game collectibles contract -## Query contract details -## Fetch token balances of a wallet diff --git a/docs/pages/solutions/embedded-wallet.mdx b/docs/pages/solutions/embedded-wallet.mdx deleted file mode 100644 index 1956a04506b..00000000000 --- a/docs/pages/solutions/embedded-wallet.mdx +++ /dev/null @@ -1,3 +0,0 @@ -## Onboard players with an embedded wallet - -## Sign contract calls without prompts \ No newline at end of file diff --git a/docs/pages/solutions/ethereum-compatibility.mdx b/docs/pages/solutions/ethereum-compatibility.mdx deleted file mode 100644 index bf0297b0f7f..00000000000 --- a/docs/pages/solutions/ethereum-compatibility.mdx +++ /dev/null @@ -1 +0,0 @@ -## Test diff --git a/docs/pages/solutions/marketplaces/.DS_Store b/docs/pages/solutions/marketplaces/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b0b5e9114487f4a451adb69e2f25b73c726cad8f GIT binary patch literal 6148 zcmeHK%Wl&^6upxMYO6xZ0we^Rk=Q0Bkx(CEW74wd7FT5fRj_M|T5&y*<6xvHl0Tq) zOZWW{eh1E-nN~yz+lZpM(VcVWK0NUmYaT=-hO=Zq)FC1d%GmPJtPzg0u1L#z+CZV7 zQBq6_zwt@FlIgi^Hk^QSK2T*Zj;r|}ND`%4R~wH0wao!E-oc#>z+ zs^9-9T3hW$kGH*TZ^t_iFI62@Q8k+mqw*8?PL;~zJ3ETcva}v`o*t>9in1atbwQS- zNcsFRD-u-?)vQRSx;8Wc&-eUM=f!-!zjx4;y+QwQ(UtRqy*FJs=# zjX}M1pwU+VARi;Oz~%!Z*GP+j#l|2a5MfGzrc~G~hA`#uOPd#1Yz&%m687>T?8w62 zP=p>G&zCx#L}1XhjseHOG6P$t+u{BH{on8Z%SEo|7;p^yR}6^uadh#< tmC!Fx7S3x7-j~48TQPEZD}D~u0>5Mf7+7o!!UJ&!0ZoHz90MC=;5UD3Z{+|0 literal 0 HcmV?d00001 diff --git a/docs/pages/solutions/marketplaces/orderbook/01-overview.mdx b/docs/pages/solutions/marketplaces/orderbook/01-overview.mdx new file mode 100644 index 00000000000..61762416c94 --- /dev/null +++ b/docs/pages/solutions/marketplaces/orderbook/01-overview.mdx @@ -0,0 +1,3 @@ +# Overview + +The Sequence Marketplace API service offers a simple and fast way to interact with sequence marketplace protocols to build a custom marketplace while accelerating your development time. The API is designed to be easy to use and to have all the features you need to build a fully functional marketplace. diff --git a/docs/pages/solutions/marketplaces/orderbook/02-quickstart.mdx b/docs/pages/solutions/marketplaces/orderbook/02-quickstart.mdx new file mode 100644 index 00000000000..63b8835b573 --- /dev/null +++ b/docs/pages/solutions/marketplaces/orderbook/02-quickstart.mdx @@ -0,0 +1,19 @@ +# Quickstart + +## Try a Demo +:::info +Check out our [demo](https://lucky-pond-0796.on.fleek.co/) to see a custom marketplace in action. +::: + + +## Template +:::info +Get started quickly with a [template](https://github.com/moskalyk/aviator-custom-marketplace) leveraging our Orderbook API. +::: + + + + +## Getting Started + +Check out the [Orderbook API TODO: INSERT LINK](https://test.com) for an overview of the API endpoints to create your own custom marketplace \ No newline at end of file diff --git a/docs/pages/solutions/marketplaces/white-label-marketplace.mdx b/docs/pages/solutions/marketplaces/white-label-marketplace.mdx new file mode 100644 index 00000000000..17c169c1aff --- /dev/null +++ b/docs/pages/solutions/marketplaces/white-label-marketplace.mdx @@ -0,0 +1,22 @@ +# Launch your white-label marketplace + +Sequence Builder provides game builders with a white-label marketplace that can be launched in seconds. With Builder, you can customize your marketplace and integrate it directly into your game experience, all with no-coding experience necessary. + +## Try it out +:::info +Get started quickly at [Sequence Builder](https://sequence.build/) to launch your marketplace. +::: + +##### Why would I want my own Marketplace for my web3 game? +Builder gives you full control over everything in your marketplace, from enforcing royalties (with ERC-2981) to +choosing the best trading mechanism for your community, setting fees, and more. +You can also aggregate listings from major platforms like OpenSea or LooksRare, providing you with the benefit of existing liquidity without relinquishing control of the gaming experience. + + + + +## Watch a Marketplace be launched in minutes +
    + +
    \ No newline at end of file diff --git a/docs/pages/solutions/metadata-manager.mdx b/docs/pages/solutions/metadata-manager.mdx deleted file mode 100644 index 054eb11c6b1..00000000000 --- a/docs/pages/solutions/metadata-manager.mdx +++ /dev/null @@ -1,3 +0,0 @@ -## Manage collectible metadata manually -## Dynamically update collectible metadata -## Refresh cached collectible metadata \ No newline at end of file diff --git a/docs/pages/solutions/orderbook.mdx b/docs/pages/solutions/orderbook.mdx deleted file mode 100644 index f89ab417dde..00000000000 --- a/docs/pages/solutions/orderbook.mdx +++ /dev/null @@ -1 +0,0 @@ -## Leverage our Orderbook API for your custom marketplace diff --git a/docs/pages/solutions/payments/onramps/01-fiat-on-ramps.mdx b/docs/pages/solutions/payments/onramps/01-fiat-on-ramps.mdx new file mode 100644 index 00000000000..dd3d4db0d0a --- /dev/null +++ b/docs/pages/solutions/payments/onramps/01-fiat-on-ramps.mdx @@ -0,0 +1,20 @@ +--- +slug: /fiat-on-ramps +--- + +# Fiat On-Ramps +Sequence Wallet allows users to purchase cryptocurrencies directly with their credit card and debit card via on-ramp providers. Currently Sequence supports 6 on-ramp providers; + +- [Moonpay](https://www.moonpay.com/) +- [Ramp](https://ramp.network/) +- [UPI via Onmeta](https://onmeta.in/) +- [Sardine](https://www.sardine.ai/) +- [PayTrie](https://paytrie.com/) + +Only providers that support the region the users are in will be displayed. + +![Sequence on-demand sign in](/img/fiat-providers.png) + +As a developer integrating the Sequence Wallet, you can choose which payment provider can be visible to users. You can also specify which token will be available to purchase via the on-ramp providers. + +To learn more on how to configure the on-ramp options, see [Sequence Connect Options](/wallet/guides/connect-wallet#includedpaymentproviders). diff --git a/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/01-why.mdx b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/01-why.mdx new file mode 100644 index 00000000000..10120d0db60 --- /dev/null +++ b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/01-why.mdx @@ -0,0 +1,43 @@ +# Why smart contracts wallets? + + +Ethereum wallets may take two different forms, Externally owned accounts (EOAs) or Smart Contract Wallets. +The Sequence wallet is implemented as a smart contract, which allows the system to provide additional security and functionality. + +## Externally owned accounts + +Externally owned accounts are the most primitive form of wallet on Ethereum; EOAs are accounts composed of a single ECDSA key pair. + +### Pros + +- Simple to implement +- Cheap to use (in some scenarios) +- Easy to backup + +### Popular examples + +- [MetaMask](https://metamask.io/) +- [Rainbow](https://rainbow.me/) +- [MyEtherWallet](https://www.myetherwallet.com/) +- [Trust](https://trustwallet.com/) + +## Smart contract wallets + +Smart contract wallets are wallets that are implemented as smart contracts; it allows the wallets to implement arbitrary logic within the bounds of what's supported by the underlying virtual machine. +Because of this, these contracts can implement functionality that's not available for EOAs, and can also be upgraded if they are prepared to do so. + +### Pros + +- Multiple keys +- Key rotation +- Pay fees using ERC20 tokens (e.g. USDC) +- Upgradeability +- Social recovery support +- Meta-transactions +- More flexible design space + +## Examples + +- [Sequence](https://sequence.app/) +- [Gnosis Safe](https://safe.global/) +- [Argent](https://www.argent.xyz/) diff --git a/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/02-universal-deployer.mdx b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/02-universal-deployer.mdx new file mode 100644 index 00000000000..bd36c7b428d --- /dev/null +++ b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/02-universal-deployer.mdx @@ -0,0 +1,128 @@ +# Universal Deployer + +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. + +:::danger 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. +::: + +:::info 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](./wallet-context) on a new network. + +:::info 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](/multi-chain-support#networks). +::: + +### 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](./wallet-context) 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](./wallet-context) on a new network. + +:::info 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](/multi-chain-support#networks). +::: + +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) +and [Wallet Contracts repository](https://github.com/0xsequence/wallet-contracts/blob/38e0719690eee3c4d7d8fa2ceff4ea22b0409f38/utils/deploy-contracts.ts). + +### 1 - Deploy NanoUniversalDeployer + +Pre-found Nick's method address with funds required to pay for the deployment of contracts. + +``` +Address: 0x9c5a87452d4FAC0cbd53BDCA580b20A45526B3AB +Funds: 0.02170000000014 +``` + +**Do not send additional funds to the address, as funds can't be refunded.** + +Once the address is funded, you can deploy the NanoUniversalDeployer by executing the following pre-signed transaction: + +``` +0xf9010880852416b84e01830222e08080b8b66080604052348015600f57600080fd5b50609980601d6000396000f3fe60a06020601f369081018290049091028201604052608081815260009260609284918190838280828437600092018290525084519495509392505060208401905034f5604080516001600160a01b0383168152905191935081900360200190a0505000fea26469706673582212205a310755225e3c740b2f013fb6343f4c205e7141fcdf15947f5f0e0e818727fb64736f6c634300060a00331ca01820182018201820182018201820182018201820182018201820182018201820a01820182018201820182018201820182018201820182018201820182018201820 +``` + +After the transaction is confirmed, you should see the address of the NanoUniversalDeployer: + +``` +NanoUniversalDeployer: 0x9c5a87452d4FAC0cbd53BDCA580b20A45526B3AB +``` + +See more about the [NanoUniversalDeployer](https://gist.github.com/Agusx1211/de05dabf918d448d315aa018e2572031). + +### 2 - Deploy UniversalDeployer2 + +In order to deploy contracts with an instance identifier, we need to deploy the UniversalDeployer2 contract. To ensure address consistency +we use the UniversalDeployer contract to deploy the UniversalDeployer contract. + +Send the following data to the UniversalDeployer deployed in the previous step. + +``` +0x608060405234801561001057600080fd5b5061013d806100206000396000f3fe60806040526004361061001e5760003560e01c80639c4ae2d014610023575b600080fd5b6100cb6004803603604081101561003957600080fd5b81019060208101813564010000000081111561005457600080fd5b82018360208201111561006657600080fd5b8035906020019184600183028401116401000000008311171561008857600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050913592506100cd915050565b005b60008183516020850134f56040805173ffffffffffffffffffffffffffffffffffffffff83168152905191925081900360200190a050505056fea264697066735822122033609f614f03931b92d88c309d698449bb77efcd517328d341fa4f923c5d8c7964736f6c63430007060033 +``` + +After the transaction is confirmed, you should see the address of the UniversalDeployer2: + +``` +UniversalDeployer2: 0x8a5bc19e22d6ad55a2c763b93a75d09f321fe764 +``` + +### 3 - Deploy Wallet Context + +Compile and deploy the contracts in the [Sequence Wallet Context](./wallet-context) using the UniversalDeployer2. + +Refer to the [0xSequence.js test suite](https://github.com/0xsequence/sequence.js/blob/91ed0df67fc5ddc47abf727ae8b94a8ca4f66912/packages/0xsequence/tests/browser/testutils/deploy-wallet-context.ts) +or [Wallet Contracts repository](https://github.com/0xsequence/wallet-contracts/blob/38e0719690eee3c4d7d8fa2ceff4ea22b0409f38/utils/deploy-contracts.ts) +for the Wallet Contract context codebase. diff --git a/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/03-wallet-factory.mdx b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/03-wallet-factory.mdx new file mode 100644 index 00000000000..c6938ad8026 --- /dev/null +++ b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/03-wallet-factory.mdx @@ -0,0 +1,48 @@ +# Wallet Factory + +Sequence Wallets are created using the [Factory](https://github.com/0xsequence/wallet-contracts/blob/e0c5382636a88b4db4bcf0a70623355d7cd30fb4/contracts/Factory.sol) contract, when called it creates child [MinimalUpgradeableProxies](https://github.com/0xsequence/wallet-contracts/blob/e0c5382636a88b4db4bcf0a70623355d7cd30fb4/contracts/Wallet.sol) contracts, which are in essence the "boot" code of all Sequence wallets. + +## Factory API + +### deploy + +```solidity + function deploy( + address _mainModule, + bytes32 _salt + ) public payable returns (address _contract) +``` + +Creates a child MinimalUpgradeableProxy using [CREATE2](https://eips.ethereum.org/EIPS/eip-1014), the proxy initially points to the provided `_mainModule`. +No initialize code is executed. + +#### Parameters: + +| Name | Type | Description | +|-------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| _mainModule | address | Initial implementation for the new proxy contract, expected to point to a valid Sequence wallet implementation with support for counter-factual initialization. | +| _salt | bytes32 | Arbitrary value to be used as `create2` salt. Sequence's `mainModule` uses the salt to obtain a hash with the initial configuration for the wallet (See [ImageHash](#)). | + +#### Return Values: + +| Name | Type | Description | +|-----------|---------|----------------------------------------| +| _contract | address | Address of the created proxy contract. | + +:::caution Unsanitized input +The Factory contract **does not** check if the provided `_mainModule` is a valid Sequence wallet implementation, or if `_salt` is a valid Sequence configuration. + +Using invalid parameters will result on a proxy contract that **may not** be usable, and could result in loss of funds. +::: + +## Counter factual addresses + +Sequence wallets are counter-factual by design, this means that the wallet's address can be known before the wallet is deployed; any two combinations of the `mainModule` and `salt` values will result in the same wallet address. + +This property alongside the use of [SingletonDeployer](/wallet/wallet-contracts/universal-deployer) or [UniversalDeployer](/wallet/wallet-contracts/universal-deployer) is the reason why Sequence wallets can obtain the same address on multiple chains. + +:::tip Gas-free wallet creation +Sequence wallets are **100% counterfactual**, meaning that funds can be safely transferred to the wallet's address without the need for calling the `deploy` function. + +Deploying the wallet is only required before the first transaction is sent **from** the wallet. +::: diff --git a/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/04-wallet-configuration.mdx b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/04-wallet-configuration.mdx new file mode 100644 index 00000000000..6e1ad0ace85 --- /dev/null +++ b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/04-wallet-configuration.mdx @@ -0,0 +1,160 @@ + +import Tabs from '@theme/Tabs' +import TabItem from '@theme/TabItem' + + +# Wallet Configuration + +Every Sequence wallet has a configuration defined by a threshold and a list of signers with their corresponding weights. + +## Configuration layout + +| Name | Type | Range | Description | +|-----------|------------|----------------------------|-----------------------------------------------------------------------------------| +| Threshold | `uint16` | 1 - 65535 | Required combined total "weight" of signers for a signature to be considered valid. | +| Signers | `signer[]` | unlimited - bounded by gas | List of signers that with their corresponding "weight"s. | + +### Signer layout + +| Name | Type | Range | Description | +|---------|-----------|---------|-------------------------------------------------------------------------------------------------| +| "weight" | `uint8` | 0 - 255 | "weight" of every signature of the signer. | +| "address" | `"address"` | -- | "address" of the signer, it may be an EOA or another smart contract wallet with EIP-1271 support. | + +#### Example + +```json +{ + "threshold": 5, + "signers": [ + { + "address": "0x4fbf69aa2a75f9942a768dc8da7804ec965f7bea", + "weight": 2 + }, + { + "address": "0x596af90cecdbf9a768886e771178fd5561dd27ab", + "weight": 3 + }, + { + "address": "0x6192e0fdcd868b3de01c7fbc0ad98baebd7330c1", + "weight": 2 + }, + { + "address": "0xec9a7204a43d3f4a82c84fde92d25bfc9110981e", + "weight": 1 + } + ] +} +``` +This example has a threshold of 5 and 4 signers. + +#### The valid combinations of signers are: + +``` +- 0x4fbf69aa2a75f9942a768dc8da7804ec965f7bea & 0x596af90cecdbf9a768886e771178fd5561dd27ab - combined weight of 2 + 3 = 5 +- 0x6192e0fdcd868b3de01c7fbc0ad98baebd7330c1 & 0x596af90cecdbf9a768886e771178fd5561dd27ab - combined weight of 2 + 3 = 5 +- 0x4fbf69aa2a75f9942a768dc8da7804ec965f7bea, 0x6192e0fdcd868b3de01c7fbc0ad98baebd7330c1 & 0xec9a7204a43d3f4a82c84fde92d25bfc9110981e - combined weight of 2 + 2 + 1 = 5 +``` + +Any combination of signers with a combined weight under the threshold is considered invalid; any additional signers above the threshold are ignored. + +### Configuration hash - ImageHash + +The configuration is never stored directly on the contract, but instead is hashed and checked against every time a signature is validated. This allows the wallet contracts to reduce the usage of storage and therefore the gas cost. + +Wallets that never have been updated don't store the `imageHash` directly, instead the `imageHash` is used as the `salt` during the contract creation, and signatures are validated against the address of the wallet. + +#### Compute image hash + + + + +```solidity +keccak256(abi.encode( + uint8 weight_1, address signer_1, + keccak256(abi.encode( + uint8 weight_2, address signer_2, + keccak256(abi.encode( + uint8 weight_3, address signer_3, + keccak256(abi.encode( + uint256 threshold + )) + )) + )) +)) +``` + + + + +```js +let tmp = ethers.utils.solidityPack(['uint256'], [configuration.threshold]) + +for (const signer of configuration.signers) { + tmp = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ['bytes32', 'uint8', 'address'], + [tmp, signer.weight, signer.address] + ) + ) +} + +const imageHash = tmp +``` + + + + + +## Initial wallet configuration + +The initial wallet configuration determines the address of the wallet, subsequent updates don't change the address. + +The wallet address can be computed using the `imageHash`, the `factory` and `mainModule` of the wallet. + +#### Compute wallet address + +```js +// The code of the wallet proxy contract +const WalletProxyBytecode = "0x603a600e3d39601a805130553df3363d3d373d3d3d363d30545af43d82803e903d91601857fd5bf3" + +// These values are defined by the wallet context +// they must be known in order to validate the counter-factual wallet imageHash +const factory = "0xf9D09D634Fb818b05149329C1dcCFAeA53639d96" +const mainModule = "0xd01F11855bCcb95f88D7A48492F66410d4637313" + +// Append the `mainModule` to the `WalletProxyBytecode` +// this completed the creation code of the proxy contract +// used for computing the wallet address as defined by the CREATE2 opcode +const codeHash = ethers.utils.keccak256( + ethers.utils.solidityPack( + [ + 'bytes', + 'bytes32' + ], + [ + WalletContractBytecode, + ethers.utils.hexZeroPad(mainModule, 32) + ] + ) +) + +// Compute the wallet address +const hash = ethers.utils.keccak256( + ethers.utils.solidityPack( + [ + 'bytes1', + 'address', + 'bytes32', + 'bytes32' + ], [ + '0xff', + factory, + salt, + codeHash + ] + ) +) + +const address = ethers.utils.getAddress(ethers.utils.hexDataSlice(hash, 12)) +``` diff --git a/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/05-modules-and-updates.mdx b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/05-modules-and-updates.mdx new file mode 100644 index 00000000000..de3d6d68690 --- /dev/null +++ b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/05-modules-and-updates.mdx @@ -0,0 +1,218 @@ +# Modules & wallet update + +Sequence modules are the underlying program implementation of the wallets; wallets can change modules at runtime. + +The `MainModule` is the initial module of every Sequence wallet; it differs from the other modules because it doesn't store the set of signers on contract storage; it uses the [salt](/wallet/wallet-contracts/wallet-factory#deploy) provided to the Factory contract. + +## Wallet implementation + +Sequence modules can be assigned to wallets either by the factory or by updating it after the initial deployment. Only one module can be assigned to a wallet at a time. + +### _updateConfiguration + +The `updateImplementation` allows to update the underlying implementation of the wallet proxy. This implementation contains all the core code that defines the wallet's behaviour. + +:::warning Dangerous operation +Calling `updateImplementation` with an invalid implementation will result in the corruption of the wallet. + +Corrupt wallets may lead to the loss of funds. +::: + +```solidity +function updateImplementation( + address _implementation +) external override onlySelf { +``` + +#### Parameters: + +| Name | Type | Description | +|------------------|---------|-----------------------------------------------| +| _implementation | address | Address of the new wallet implementation. | + +This method has the `onlySelf` modifier, which means that it can only be called by the wallet itself using a self-referencing transaction. Calls to this method coming from other addresses, even if these addresses are signers of the wallet, will be rejected. + +### Reading current implementation + +The wallet implementation is stored on the contract storage slot defined by the address of the wallet itself. Given that every wallet has a unique address, the implementation slot varies from wallet to wallet. + +```js +import "ethers" + +const address = "0x596af90cecdbf9a768886e771178fd5561dd27ab" +const provider = new ethers.providers.JsonRpcProvider("http://localhost:8545") + +// Read storage slot address(address) +const slot = await provider.getStorageAt(address, ethers.utils.defaultAbiCoder.encode(['address'], [address])) + +// Decode bytes32 as address value +const implementation = ethers.utils.defaultAbiCoder.decode(['address'], slot)[0] + +console.log(implementation) +``` + +## Wallet configuration validation + +:::info Fixed configuration +Signer's configuration on wallets using `MainModule` can't be changed. The only way to change the set of signers or threshold is by updating the module of the wallet. +::: + +All sequence modules must implement the `ModuleAuth` interface, this interface allows the rest of the module to validate signatures for the wallet. In the case of `MainModule` this interface is implemented as a counter-factual validation of hash passed to the factory during the contract wallet creation. + +### _isValidImage + +```solidity + function _isValidImage( + bytes32 _imageHash + ) internal override view returns (bool _isValid) +``` + +Validates if the provided `imageHash` corresponds to the one configured in the wallet. This function is called internally to validate transaction and message signatures. + +The `imageHash` is a hash of the wallet configuration, which contains the wallet's threshold, signers and weights. + +#### Parameters: + +| Name | Type | Description | +|-------------|---------|-----------------------------------------------| +| _imageHash | bytes32 | Hash of wallet configuration to be validated. | + +#### Return Values: + +| Name | Type | Description | +|-----------|---------|--------------------------------------------------------------------------------| +| _isValid | bool | True if the given `imageHash` corresponds to the current wallet configuration. | + +## MainModuleUpgradeable + +`MainModuleUpgradable` is a module that mimics the behaviour of the `MainModule` but allows the wallet configuration to be updated. + +### `updateImageHash` + +Updates the wallet `imageHash`, this is the hash that defines the wallet configuration (signers, weights, threshold). + +```solidity + function updateImageHash( + bytes32 _imageHash + ) external override onlySelf { +``` + +#### Parameters: + +| Name | Type | Description | +|-------------|---------|-----------------------------------------------| +| _imageHash | bytes32 | Hash of the new configuration for the wallet. | + +:::caution Unsanitized input +The `imageHash` is not validated, it is the responsibility of the caller to ensure that the hash is correct. Reasons for incorrect hashes include: + + * The combined weight of the signers is below the threshold. + * The signers are not valid addresses. + * The signers are smart contract wallets without proper support for EIP-1271. + * The `imageHash` doesn't correspond to any wallet configuration (may be a random string). + * The `imageHash` corresponds to an unknown wallet configuration. + +In any of this cases the wallet will be **rendered unusable**. +::: + +This method has the `onlySelf` modifier, which means that it can only be called by the wallet itself using a self-referencing transaction. Calls to this method coming from other addresses, even if these addresses are signers of the wallet, will be rejected. + +## First configuration update + +When Sequence wallets are created, the factory contract doesn't call an `initialize` function. The configuration is instead defined by the `salt` provided to the factory, the `MainModule` then checks the counterfactual validity of all signatures against the wallet address. + +This means there is no direct way to update the configuration of a wallet while still using the `MainModule`. Given that the first configuration update needs to also change the wallet implementation to the `MainModuleUpgradable`, the `MainModule` is updated to the `MainModuleUpgradable` and the `updateImageHash` method is called to update the wallet configuration. + +```js +const transactions = [ + { + delegateCall: false, + revertOnError: true, + to: wallet, + data: walletInterface.encodeFunctionData( + walletInterface.getFunction('updateImplementation'), [this.context.mainModuleUpgradable] + ), + value: ethers.constants.Zero, + gasLimit: ethers.constants.Zero, + }, + { + delegateCall: false, + revertOnError: true, + to: wallet, + data: mainModuleInterface.encodeFunctionData( + mainModuleInterface.getFunction('updateImageHash'), [newImageHash] + ), + value: ethers.constants.Zero, + gasLimit: ethers.constants.Zero, + } +] +``` + +#### delegateCall: false + +`delegateCall` is used to extend the wallet functionality beyond what's allowed by the module. In this case the called methods are defined on the modules themselves, so there is no need to use `delegateCall`. + +#### revertOnError: true + +`revertOnError` is used to revert the whole transaction bundle if a transaction flagged by it fails. In this case the operation should be atomic given that a partial wallet configuration update **will** render the wallet unusable. + +#### to: wallet + +The methods being called are defined on the wallet itself, but need to be called externally, so the `to` address is the wallet itself. + +#### value: ethers.constants.Zero + +The `value` of the transaction is always zero, since the transaction is a self-referencing transaction and doesn't require transferring funds. + +#### gasLimit: ethers.constants.Zero + +The `gasLimit` of the transaction is always zero, since it represents an unlimited amount of gas. + +:::warning Dangerous operation + +When the wallet is first updated to the `MainModuleUpgradable` it doesn't have a valid `imageHash` yet. It's imperative that the `imageHash` is updated before the transaction bundle finishes executing. +If the `imageHash` is not updated before the transaction bundle finishes executing, the wallet will be rendered unusable. + +For this reason the following considerations should be taken when updating the wallet for the first time: + + * All transactions should be marked `revertOnError = true`. + * `updateImplementation` and `updateImageHash` should both be declared on the same transaction bundle. + * The `gasLimit` of both transactions should be set to unlimited (`0`). + +::: + +### Subsequent configuration updates + +Once the wallet is updated to the `MainModuleUpgradable` it can be updated by calling the `updateImageHash` method, without any additional transaction. + +```js +const transactions = [ + { + delegateCall: false, + revertOnError: true, + to: wallet, + data: mainModuleInterface.encodeFunctionData( + mainModuleInterface.getFunction('updateImageHash'), [newImageHash] + ), + value: ethers.constants.Zero, + gasLimit: ethers.constants.Zero, + } +] +``` + +### Retrieving the current configuration + +If the wallet is updated to the `MainModuleUpgradable` it can be queried for the current configuration by calling the `getImageHash` method. + +This method should return the wallet's current configuration hash, which can be compared to a list of known wallet configurations to find the correct one. + +#### Retrieving the wallet configuration + +The `imageHash` method returns `bytes32(0)` if the wallet is not yet updated to the `MainModuleUpgradable`. +In this case the wallet is in a counter-factual state and the `imageHash` can't be directly queried. + +This is also the case for non-deployed wallets. + +To find the `imageHash` of a non-deployed or non-updated wallet, a candidate known `imageHash` needs to be compared against the wallet address. + +See [Compute wallet address](/wallet/wallet-contracts/wallet-configuration#compute-wallet-address). diff --git a/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/06-main-module-upgradeable.mdx b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/06-main-module-upgradeable.mdx new file mode 100644 index 00000000000..1774c892fe6 --- /dev/null +++ b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/06-main-module-upgradeable.mdx @@ -0,0 +1,2 @@ +# MainModuleUpgradeable & configuration migration + diff --git a/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/07-transaction-encoding.mdx b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/07-transaction-encoding.mdx new file mode 100644 index 00000000000..c73f0de3d78 --- /dev/null +++ b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/07-transaction-encoding.mdx @@ -0,0 +1,2 @@ +# Transaction encoding + diff --git a/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/08-signature-encoding.mdx b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/08-signature-encoding.mdx new file mode 100644 index 00000000000..d9e730488e6 --- /dev/null +++ b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/08-signature-encoding.mdx @@ -0,0 +1,96 @@ +# Signature Encoding + +Sequence Wallets support [ERC-1271 Standard Contract Signature Verification](https://eips.ethereum.org/EIPS/eip-1271) to allow signing of transactions and messages. + +## ERC-191 Ethereum Signed Data + +Messages encoded with as [ERC-191 Ethereum Signed Data](https://eips.ethereum.org/EIPS/eip-191) are able to be created and signed as follows. + +```ts +import { Wallet } from '@0xsequence/wallet' + +// Construct your Sequence Wallet (out of scope for this section) +const wallet: Wallet + +const message = "Hello, World!" + +const prefixedMessage = "\x19Ethereum Signed Message:\n" + len(message) + message +const signature = await wallet.signMessage(prefixedMessage) +``` + +The above will iterate through local, signing the message. If the threshold is reached, the signature is returned. +Otherwise the library will iterate through the remote signers as well. +The resulting signatures are joined and encoded as a hex string. + +## ERC-712 Structured Data Signatures + +[ERC-712 Structured Data](https://eips.ethereum.org/EIPS/eip-712) can also be signed in a similar fashion. + +```ts +import { Wallet } from '@0xsequence/wallet' +import { encodeTypedDataDigest } from '@0xsequence/utils' + +// Construct your Sequence Wallet (out of scope for this section) +const wallet: Wallet + +// Encode the typed data +const chainId = 1 +const typedData = { + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + { name: 'count', type: 'uint8' } + ] + }, + primaryType: 'Person' as const, + domain: { + name: 'Ether Mail', + version: '1', + chainId: chainId, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC' + }, + message: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + count: 4 + } +} +const hashedData = encodeTypedDataDigest(typedData) + +const signature = await wallet.signMessage(hashedData) +``` + +The above will iterate through local, signing the message. If the threshold is reached, the signature is returned. +Otherwise the library will iterate through the remote signers as well. +The resulting signatures are joined and encoded as a hex string. + +## Verification + +The signature can be verified by calling the `isValidSignature` method on the wallet. + +```sol + /** + * @notice Verifies whether the provided signature is valid with respect to the provided hash + * @dev MUST return the correct magic value if the signature provided is valid for the provided hash + * > The bytes4 magic value to return when signature is valid is 0x1626ba7e : bytes4(keccak256("isValidSignature(bytes32,bytes)")) + * @param _hash keccak256 hash that was signed + * @param _signatures Signature byte array associated with _data. + * Encoded as abi.encode(Signature[], Configs) + * @return magicValue Magic value 0x1626ba7e if the signature is valid and 0x0 otherwise + */ + function isValidSignature( + bytes32 _hash, + bytes calldata _signatures + ) public override virtual view returns (bytes4) { + // Validate signatures + (bool isValid,) = _signatureValidation(_hash, _signatures); + if (isValid) { + return SELECTOR_ERC1271_BYTES32_BYTES; + } + + return bytes4(0); + } +``` + +This will iterate through the combined signatures and validate that the resulting signature breaches the wallet's threshold. diff --git a/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/09-nested-transaction-batching.mdx b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/09-nested-transaction-batching.mdx new file mode 100644 index 00000000000..63080cac6a9 --- /dev/null +++ b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/09-nested-transaction-batching.mdx @@ -0,0 +1,2 @@ +# Nested Transaction Batching + diff --git a/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/10-guest-module.mdx b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/10-guest-module.mdx new file mode 100644 index 00000000000..ff5ccfc9de1 --- /dev/null +++ b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/10-guest-module.mdx @@ -0,0 +1,2 @@ +# GuestModule and on-demand deployment + diff --git a/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/11-wallet-context.mdx b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/11-wallet-context.mdx new file mode 100644 index 00000000000..cb5851b5db4 --- /dev/null +++ b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/11-wallet-context.mdx @@ -0,0 +1,14 @@ +# Wallet Context + +```ts +export const sequenceContext: WalletContext = { + factory: '0xf9D09D634Fb818b05149329C1dcCFAeA53639d96', + mainModule: '0xd01F11855bCcb95f88D7A48492F66410d4637313', + mainModuleUpgradable: '0x7EFE6cE415956c5f80C6530cC6cc81b4808F6118', + guestModule: '0x02390F3E6E5FD1C6786CB78FD3027C117a9955A7', + sequenceUtils: '0xd130B43062D875a4B7aF3f8fc036Bc6e9D3E1B3E', + libs: { + requireFreshSigner: '0xE6B9B21C077F382333220a072e4c44280b873907' + } +} +``` \ No newline at end of file diff --git a/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/12-contract-audits.mdx b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/12-contract-audits.mdx new file mode 100644 index 00000000000..9ddf8568725 --- /dev/null +++ b/docs/pages/solutions/technical-references/wallet-contracts/10-wallet-contracts/12-contract-audits.mdx @@ -0,0 +1,14 @@ +# Contract Audits +Sequence wallet contracts underwent two independent audits by Consensys Diligence and Quantstamp. + +**Note**: Sequence Wallet was formerly known as "Arcadeum Wallet". Any references of "Arcadeum" in these reports are synonymous with "Sequence". + +## Quantstamp +- [July 2nd, 2020](https://github.com/0xsequence/wallet-contracts/blob/master/audits/Quantstamp_Arcadeum_Report_Final.pdf) +- [Feb 24th, 2021](https://github.com/0xsequence/wallet-contracts/blob/master/audits/sequence_quantstamp_audit_feb_2021.pdf) + +## Consensys Diligence +- [May 2020](https://consensys.net/diligence/audits/private/cnhjwtpa-horizon-wallet/) + +## Zellic +- [March 2023](https://github.com/0xsequence/wallet-contracts/blob/master/audits/Sequence_Wallet_-_Zellic_Audit_Report.pdf) \ No newline at end of file diff --git a/docs/pages/solutions/universal-wallet.mdx b/docs/pages/solutions/universal-wallet.mdx deleted file mode 100644 index 8d231e7e3c8..00000000000 --- a/docs/pages/solutions/universal-wallet.mdx +++ /dev/null @@ -1,3 +0,0 @@ -## Integrate universal wallet with SequenceKit - -## Sign contract calls with prompts \ No newline at end of file diff --git a/docs/pages/solutions/wallets/embedded-wallet/01-overview.mdx b/docs/pages/solutions/wallets/embedded-wallet/01-overview.mdx new file mode 100644 index 00000000000..722ff977271 --- /dev/null +++ b/docs/pages/solutions/wallets/embedded-wallet/01-overview.mdx @@ -0,0 +1,40 @@ +# Sequence Embedded Wallet + +Sequence Embedded Wallet (or Wallet as a Service) enables the creation, management and usage of fully functional EVM compatible wallets. These wallets can be created on-demand for each user and allow you to integrate an application with an Ethereum compatible blockchain, while using familiar constructions like RPC APIs. + +Sequence Embedded Wallet offers real non-custodial wallets and the system guarantees that each created wallet can only be accessed with the consent of the owner of the wallet. + +## Architecture overview + +Sequence Embedded Wallets are native smart contract multisigs, the configuration of the multisig can be seen as a 2/2, both of which are required to sign in order to operate them; each one of the signers protects the wallet from a different facet of possible threats. + +### Signer 1: Sequence Auth + +Sequence Auth provides a simple way to add account creation, login, session management, and wallet support to your app, enabling applications to provide traditional web experiences (e.g. social login, email login, etc.) while providing access to crypto wallets to interact with smart contracts. + +All user and session data is encrypted by a Hardware Security Module operated by a third party. This makes it protected from both external attackers and internal access by Sequence Team or anyone else. **Nobody** can access a user's wallet but the user themselves. + +You won't need to trust us, this is a guarantee you can verify yourself: this service is hosted in a cryptographically attested secure enclave on Amazon Nitro platform. And we offer publicly available independently audited source code (coming soon), so you can rest assured that it hasn't been tampered with. + + +### Signer 2: Sequence Guard + +Sequence Guard is a service hosted by Sequence and contains the other key of the wallets. It's meant to be another line of defense, verifying not only user's *identity* but also their *intent*. It achieves this in two different ways: + +1 - Limits and allowlists: you can (from the development dashboard) configure what kind of actions are allowed, this means that the guard will only sign transactions within these constraints. For example, you can define that only NFT contract X can be called, and the guard will enforce that no other transactions can take place. + +2 - Authenticating the user: the Sequence Guard will authenticate the user **independently of the Sequence Auth**, it performs this action either by using a 3rd party OAuth 2.0 id token (from Meta, Google, X, etc.) or by directly communicating with the user via email/phone number with an OTP code. The direct communication is not always required and, when it does happen, it's seamless and branded with your project details. + +## Threat model + +With these safeguards in place wallets are **safe** against the following scenarios: + +1) Sequence.app backend is compromised, or guard keys are leaked: in this scenario, the user's identity must still be verified by Sequence Auth. + +2) Sequence Auth is compromised: in this scenario the Sequence Guard protects the wallets, because it independently authenticates the user, an attacker in this scenario wouldn't be able to access any wallets. + +The model also provides partial protection against the scenario: + +3) Partner frontend is compromised, or MITM on the partner side: If an attacker were to be able to vulnerate the frontend of the partner, it could gain access to wallets at the time of login, but it cannot gain access to wallets of users who are currently inactive. This means that recovery from such a scenario is possible, with limited damage. + + diff --git a/docs/pages/solutions/wallets/embedded-wallet/02-quickstart.mdx b/docs/pages/solutions/wallets/embedded-wallet/02-quickstart.mdx new file mode 100644 index 00000000000..4053f8e70e4 --- /dev/null +++ b/docs/pages/solutions/wallets/embedded-wallet/02-quickstart.mdx @@ -0,0 +1,50 @@ +# Quickstart + +## Try a Demo +:::info +Try out seamless UX of our embedded wallet at our [demo](https://0xsequence.github.io/demo-waas-auth/) +::: + + +## Template +:::info +Get started quickly with a [template](https://github.com/0xsequence/demo-waas-auth) leveraging our embedded wallet. +::: + + + + +## Getting Started + +### SDK Installation + +We provide TypeScript and Unity SDKs for the Embedded Wallet authentication system. You can install the TypeScript SDK with: + +```bash +pnpm install @0xsequence/waas +``` + +For more information on the Unity Embedded Wallet SDK, please refer to the [Unity SDK documentation](/unity-waas-sdk). + +### Project Setup + +Sequence Embedded Wallet is currently only available as a closed beta. To start using the Embedded Wallet SDKs, you'll need to contact the Sequence team and acquire API credentials. Once this is done, you will be provided with two keys: + +- Project access key +- Embedded Wallet configuration key + +### Library Setup + +To start using Sequence Embedded Wallet SDK, you'll need to create a new instance of the `waas` class: + +```typescript +import { SequenceWaaS } from '@0xsequence/waas' + +const waas = new SequenceWaaS({ + projectAccessKey: `${process.env.PROJECT_ACCESS_KEY}`, + waasConfigKey: `${process.env.WAAS_CONFIG_KEY}`, + network: 'mumbai' +}, defaults.TEST) +``` + +Note that the library is operational, but it can't be used to interact with any wallet until you have authenticated **as a user**. \ No newline at end of file diff --git a/docs/pages/solutions/wallets/embedded-wallet/03-manage-sessions.mdx b/docs/pages/solutions/wallets/embedded-wallet/03-manage-sessions.mdx new file mode 100644 index 00000000000..3228373968e --- /dev/null +++ b/docs/pages/solutions/wallets/embedded-wallet/03-manage-sessions.mdx @@ -0,0 +1,256 @@ +# Session Management + +Sequence Auth + Embedded Wallet handles the following aspects of your application: + +- User creation +- User authentication +- Session management + +This means you don't need to implement an account system yourself; instead, you interact with the Auth + WaaS SDK whenever you need to authenticate a user. + +## Sign in / Sign Up + +Signing in and signing up are the same operation; the account is automatically created if it doesn't already exist. + +```ts +import { SequenceWaaS } from '@0xsequence/waas' + +const waas = new SequenceWaaS({ + projectAccessKey: `${process.env.PROJECT_ACCESS_KEY}`, + waasConfigKey: `${process.env.WAAS_CONFIG_KEY}`, + network: 'mumbai' +}, defaults.TEST) + +// Get a sessionHash +const sessionHash = await waas.getSessionHash() + +// Get an idToken using the social auth provider of your choice +// (Google, Facebook, Twitter, etc.) +// Note: remember to pass the sessionHash as a nonce! + +// Then sign in with Sequence WaaS +const res = await waas.signIn({ idToken }, "MacBook Pro - Chrome") + +console.log(res) +``` + +```json +{ + "sessionId": "0x63A21cCa14ed7454B9cF6466af422B5c597c6b57", + "wallet": "0xd6043fe6f06d90ec2cB36cA5CD1B193A8515f350", +} +``` + +:::note +Sessions opened with some providers might require a second step in order to be usable for sending transactions. + +See [Email validation](/waas/waas-auth/validation). +::: + +### Email Sign In / Sign Up + +Email sign-in is directly supported by the SDK, as long as the used `key` has been generated with the `email` scope. Email logins work similarly to social logins, except that the `idToken` is generated by the SDK itself. + +To open a session using an email, you will need to provide an email for the user. The Embedded Wallet Nitro API will then send an email to the user with a One-Time Password (OTP) that can be used to open a session. This OTP has to be provided to the SDK to obtain an `idToken`. + +Once the `idToken` is obtained, the session can be opened as usual. + +```ts +import { SequenceWaaS } from '@0xsequence/waas' + +// Define the user's email address +const email = "user@example.com" + +const waas = new SequenceWaaS({ + projectAccessKey: `${process.env.PROJECT_ACCESS_KEY}`, + waasConfigKey: `${process.env.WAAS_CONFIG_KEY}`, + network: 'mumbai' +}, defaults.TEST) + +// This will send an email to the user with an OTP +const { instance } = await waas.email.initiateAuth({ email }) + +// Obtain the OTP from the user +const answer = "123456" + +const sessionHash = await sequence.getSessionHash() +const { idToken } = await waas.email.finalizeAuth({ instance, answer, email, sessionHash }) + +// Log in using the idToken, as usual +await waas.signIn({ idToken }, "Apple Vision Pro - Chrome") +``` + +### Google / Apple Auth + +Google and Apple auth are directly supported by the SDK. The `idToken` is obtained from the social auth provider and used to open a session. You can see a sample React application using Google auth below. To see a complete application, see the [demo-waas-auth](https://github.com/0xsequence/demo-waas-auth) repository. A functional demo [is also available here](https://0xsequence.github.io/demo-waas-auth/). + +Begin with a simple `main.tsx` file that sets up the WaaS SDK, the router, and the Google OAuth provider. + +```ts +import { SequenceWaaS } from '@0xsequence/waas' +import { GoogleOAuthProvider } from '@react-oauth/google' +import { createHashRouter, RouterProvider } from 'react-router-dom' + +const waas = new SequenceWaaS({ + projectAccessKey: `${process.env.PROJECT_ACCESS_KEY}`, + waasConfigKey: `${process.env.WAAS_CONFIG_KEY}`, + network: 'mumbai' +}, defaults.TEST) + +export const router = createHashRouter([ + { + path: '/login', + element: + }, + { + path: '/', + element: + } +]) + +ReactDOM.createRoot(document.getElementById('root')!).render( + + + + + +) +``` + +The `useSessionHash` hook is used to obtain a session hash that is used to prevent replay attacks. The `sequence.getSessionHash` function is used to obtain the session hash, and the `sequence.onSessionStateChanged` function is used to update the session hash when the session state changes. + +```ts +import { sequence } from './main' +import { useEffect, useState } from "react"; + +export function useSessionHash() { + const [sessionHash, setSessionHash] = useState("") + const [error, setError] = useState(undefined) + + useEffect(() => { + const handler = async () => { + try { + setSessionHash(await sequence.getSessionHash()) + } catch (error) { + console.error(error) + setError(error) + } + } + handler() + return sequence.onSessionStateChanged(handler) + }, [setSessionHash, setError]) + + return { + sessionHash, + error, + loading: !!sessionHash, + } +} +``` + +To handle the Google login, you can use the `GoogleLogin` component from the `@react-oauth/google` package. The `handleGoogleLogin` function is called when the user successfully logs in. + +```ts +import { router, sequence } from './main' +import { CredentialResponse, GoogleLogin } from '@react-oauth/google' +import { useSessionHash } from "./useSessionHash.ts"; + +function Login() { + const { sessionHash } = useSessionHash() + const [signingIn, setSigningIn] = useState(false) + + useEffect(() => { + (async () => { + if (await sequence.isSignedIn()) { + router.navigate('/') + } + })() + }, []) + + const handleGoogleLogin = async (tokenResponse: CredentialResponse) => { + const walletAddress = await sequence.signIn({ + idToken: tokenResponse.credential! + }, "MacBook Pro - Chrome") + + console.log(`Wallet address: ${walletAddress}`) + router.navigate('/') + } + + return ( + {!!sessionHash && (<> + + )} + ) +} + +export default Login +``` + +## List Sessions + +This function returns a list of sessions for the current user and only includes sessions that are still valid. + +```ts +import { SequenceWaaS } from '@0xsequence/waas' + +const waas = new SequenceWaaS({ + projectAccessKey: `${process.env.PROJECT_ACCESS_KEY}`, + waasConfigKey: `${process.env.WAAS_CONFIG_KEY}`, + network: 'mumbai' +}, defaults.TEST) + +await waas.signIn({ idToken }, "MacBook Pro - Chrome") + +const sessions = await waas.listSessions() +console.log(sessions) +``` + +```json +[ + { + "id": "0x574372ff1A0Eede68B5358Cce7bbb93155A9dfe0", + "address": "0x574372ff1a0eede68b5358cce7bbb93155a9dfe0", + "userId": "42#https://accounts.google.com#109234880945084120673", + "projectId": 42, + "issuer": "https://accounts.google.com", + "subject": "109234880945084120673", + "friendlyName": "Pixel 3 - Brave", + "createdAt": "2023-11-02T18:22:03.102950917Z", + "refreshedAt": "2023-11-02T18:22:03.109787921Z", + "expiresAt": "2123-10-09T18:22:03.102951017Z", + "isThis": false + }, + { + "id": "0x3C4E11E4dbF23B87C14bd75d0Da9C75707392D21", + "address": "0x3c4e11e4dbf23b87c14bd75d0da9c75707392d21", + "userId": "42#https://accounts.google.com#109234880945084120673", + "projectId": 42, + "issuer": "https://accounts.google.com", + "subject": "109234880945084120673", + "friendlyName": "MacBook Pro - Chrome", + "createdAt": "2023-11-02T18:50:32.815189174Z", + "refreshedAt": "2023-11-02T18:50:32.819722082Z", + "expiresAt": "2123-10-09T18:50:32.815189234Z", + "isThis": true + } +] +``` + +## Close Session + +A session can be closed using the `id` of the session. Any session can be closed from any device with an active session. + +```ts +import { SequenceWaaS } from '@0xsequence/waas' + +const waas = new SequenceWaaS({ + projectAccessKey: `${process.env.PROJECT_ACCESS_KEY}`, + waasConfigKey: `${process.env.WAAS_CONFIG_KEY}`, + network: 'mumbai' +}, defaults.TEST) + +await waas.signIn({ idToken }, "MacBook Pro - Chrome") + +const sessions = await waas.listSessions() +await waas.dropSession({ sessionId: sessions[0].id }) +``` diff --git a/docs/pages/solutions/wallets/embedded-wallet/04-use-wallets.mdx b/docs/pages/solutions/wallets/embedded-wallet/04-use-wallets.mdx new file mode 100644 index 00000000000..455a8e78add --- /dev/null +++ b/docs/pages/solutions/wallets/embedded-wallet/04-use-wallets.mdx @@ -0,0 +1,287 @@ +# Wallets and transactions + +Once the SDK is initialized and the user has been authenticated, you can access the wallet corresponding to that user's account. The wallet is the entry point to all the operations that can be performed on the user's account. + +## Wallet address + +The wallet address is unique to each user, can't be changed, and is used to identify the user's account. It is a string of 42 characters starting with `0x`. + +```ts +import { SequenceWaaS } from '@0xsequence/waas' + +const waas = new SequenceWaaS({ + projectAccessKey: `${process.env.PROJECT_ACCESS_KEY}`, + waasConfigKey: `${process.env.WAAS_CONFIG_KEY}`, + network: 'mumbai' +}, defaults.TEST) + +await waas.signIn({ idToken }, "Session name") + +const address = await waas.getAddress() +``` +``` +0xE4b10c53aa75E19E088cfDD0cff7D46a0E4206F0 +``` + +## Sign messages + +The wallet can be used to sign messages. The signatures can later be validated onchain or offchain. + +```ts +import { SequenceWaaS } from '@0xsequence/waas' + +const waas = new SequenceWaaS({ + projectAccessKey: `${process.env.PROJECT_ACCESS_KEY}`, + waasConfigKey: `${process.env.WAAS_CONFIG_KEY}`, + network: 'mumbai' +}, defaults.TEST) + +await waas.signIn({ idToken }, "Session name") + +const signature = await waas.signMessage({ + chainId: 137, + message: 'Hello world', +}); + +console.log(signature) +``` +```json +{ + "code": "signedMessage", + "data": { + "message": "0x48656c6c6f20776f726c64", + "signature": "0x0100010000000002012128ff2dd168dc250dc3da93db3131f737e6961a0000fe0100030000000006010001000074000197013331090a763fc7ef2216502cfbff5d855530f977a0ee6db3615722ed9bad498781d8ed72d52b5c9717708ac757f7789c9567e5468566179bd03f72d1fc7b1c010400002c01011111b16c6268897233eddea98a041b326b0faef2010122229ce37ccfee1cbab2b743b22c314b5667cf1a06020001000074000100deb9091f5beb1ebd8d91a1b81e562a70cdb3a1cdafc5e61087b18d1c221c570754ecbe056bdef5f82c388a9bf53f074521aeaf5afdeed3a2ba70adb89362631b010400002c0101444444444444444444444444444444444444444401015555555555555555555555555555555555555555030100a5a91b133336e5ef1c7e23c13974535018fab1c0" + } +} +``` + +## Send transactions + +All wallets can send transactions right after creation. No extra steps are required to create the wallet, as all users have a wallet by default. + +### Raw transaction + +Raw transactions specify all the parameters of the transaction, including the `to` address, the `value` to send, and the `data` to include. + +Gas limits, prices, and nonce are always handled automatically by the Embedded Wallet. + +A network must be specified when sending a transaction. The network must be specified as the `chainId` of the network, for example `1` for Ethereum mainnet, `42161` for Arbitrum, etc. + +:::info +Notice that all **send transaction** responses need to be checked using `isSentTransactionResponse`. This is required since WaaS will validate that a given transaction does not fail *before* executing the transaction, and in case of failure, the response will be an error receipt instead of a transaction receipt. + +See more in [transaction receipts](#transaction-receipts). +::: + +```ts +import { Sequence, isSentTransactionResponse } from '@0xsequence/waas' + +const waas = new SequenceWaaS({ + projectAccessKey: `${process.env.PROJECT_ACCESS_KEY}`, + waasConfigKey: `${process.env.WAAS_CONFIG_KEY}`, + network: 'mumbai' +}, defaults.TEST) + +await waas.signIn({ idToken }, "Session name") + +const tx = await waas.sendTransaction({ + chainId: 42161, + transactions: [{ + to: '0x27CabC9700EE6Db2797b6AC1e1eCe81C72A2cD8D', + value: '200000000000000000000', // 200 ETH + data: '0x9fa2b3c4', + }] +}) + +if (isSentTransactionResponse(tx)) { + console.log(tx) +} +``` +```json +{ + "code": "transactionReceipt", + "data": { + "txHash": "0xf2e9f728abd65089f25efda5852e605ced377f4e2c89dbf143b124623ed09b2c", + "metaTxHash": "acc36ed4ef40db74137266e48d863083a5c7e85e2735d69adafcb5b362b6cfc0", + "nativeReceipt": { ... }, + "receipt": { ... }, + "request": { ... }, + "simulations": [ ... ], + } +} +``` + +### Send ERC20 tokens + +Helper methods are available for common operations, such as sending ERC20 tokens. This automatically handles the `data` field of the transaction. + +```ts +import { Sequence, isSentTransactionResponse } from '@0xsequence/waas' + +const waas = new SequenceWaaS({ + projectAccessKey: `${process.env.PROJECT_ACCESS_KEY}`, + waasConfigKey: `${process.env.WAAS_CONFIG_KEY}`, + network: 'mumbai' +}, defaults.TEST) + +await waas.signIn({ idToken }, "Session name"); + +const tx = await waas.sendERC20({ + chainId: 42161, + token: '0x6b175474e89094c44da98b954eedeac495271d0f', // DAI + to: '0x27CabC9700EE6Db2797b6AC1e1eCe81C72A2cD8D', // Recipient + value: '200000000000000000000', // 200 DAI +}) + +if (isSentTransactionResponse(tx)) { + console.log(tx) +} +``` +```json +{ + "code": "transactionReceipt", + "data": { + "txHash": "0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3", + "metaTxHash": "01a087979dccbbc49a45b72d987e5651d65bd97349ccbfdd601b0b7beee9ddc4", + "nativeReceipt": { ... }, + "receipt": { ... }, + "request": { ... }, + "simulations": [ ... ], + } +} +``` + +### Send ERC721 tokens + +Sending ERC721 tokens also has a helper method. This automatically handles the `data` field of the transaction. + +```ts +import { Sequence, isSentTransactionResponse } from '@0xsequence/waas' + +const waas = new SequenceWaaS({ + projectAccessKey: `${process.env.PROJECT_ACCESS_KEY}`, + waasConfigKey: `${process.env.WAAS_CONFIG_KEY}`, + network: 'mumbai' +}, defaults.TEST) + +await waas.signIn({ idToken }); + +const tx = await waas.sendERC721({ + chainId: 42161, + token: '0xF87E31492Faf9A91B02Ee0dEAAd50d51d56D5d4d', // Decentraland LAND + to: '0x27CabC9700EE6Db2797b6AC1e1eCe81C72A2cD8D', // Recipient + id: '33347671958251969419410711528313284722562', // Asset ID +}) + +if (isSentTransactionResponse(tx)) { + console.log(tx) +} +``` +```json +{ + "code": "transactionReceipt", + "data": { + "txHash": "0x4936962d9972a70bffc27f376f55d9c60c12e762819fa6384fdb466664122b6e", + "metaTxHash": "e6513a60b63359a365f0d3f05744d89823278ec829fc5cb4d275bb815d0f5887", + "nativeReceipt": { ... }, + "receipt": { ... }, + "request": { ... }, + "simulations": [ ... ], + } +} +``` + +### Send ERC1155 tokens + +Sending ERC1155 tokens is also supported. + +```ts +import { Sequence, isSentTransactionResponse } from '@0xsequence/waas' + +const waas = new SequenceWaaS({ + projectAccessKey: `${process.env.PROJECT_ACCESS_KEY}`, + waasConfigKey: `${process.env.WAAS_CONFIG_KEY}`, + network: 'mumbai' +}, defaults.TEST) + +await waas.signIn({ idToken }) + +const tx = await waas.sendERC1155({ + chainId: 137, + token: '0x631998e91476da5b870d741192fc5cbc55f5a52e', // Skyweaver assets + values: [{ + id: '66547', // Asset ID + value: '200', // Amount for this asset + }, { + id: '68572', + value: '1000', + }] +}) +``` + +### Call any contract + +The `callContract` method can be used to call any contract method. This is useful for calling methods that are not supported by the helper methods. To call a contract an ABI or function signature must be provided. + +#### Function signature + +Providing a function signature is the easiest way to call a contract method, as it doesn't require an ABI. The function signature can be provided with named parameters or positional parameters. + +##### Named arguments + +```ts +const tx = await sequence.callContract({ + to: '0x503388C73Ca663eA34e103c11C9F47C9433af471', // Contract address + abi: 'mint(address to, uint256 tokenId)', // Function signature + func: 'mint', // Function name + args: { + to: '0xf439e432d54c2Bf5518A1901D3791070d4192986', + tokenId: '1', + }, + value: 0 // Value to send +}) +``` + +##### Positional arguments + +Notice that passing a named function signature with positional arguments is allowed. + +```ts +const tx = await sequence.callContract({ + to: '0x503388C73Ca663eA34e103c11C9F47C9433af471', // Contract address + abi: 'mint(address,uint256)', // Function signature + func: 'mint', // Function name + args: [ + '0xf439e432d54c2Bf5518A1901D3791070d4192986', + '1', + ], + value: 0 // Value to send +}) +``` + +#### ABI + +Providing an ABI is more verbose, but allows for more flexibility, as a single ABI can be used to call multiple methods. ABIs support named arguments and positional arguments. + +```ts +const abi = `[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]` + +const tx = await sequence.callContract({ + to: '0x6b175474e89094c44da98b954eedeac495271d0f', // Contract address + abi: abi, // ABI + func: 'transfer', // Function name + args: { + _to: '0xf439e432d54c2Bf5518A1901D3791070d4192986', + _value: '1', + }, + value: 0 // Value to send +}) +``` + +:::caution +Email accounts can only send transactions after the current session has been confirmed by the Sequence guard. This is done by clicking an email link sent to the user's email address or phone number. + +Social login accounts (like Google and Facebook) can send transactions immediately after signing in. + +For more details, see [validation](/waas/waas-auth/validation). +::: \ No newline at end of file diff --git a/docs/pages/solutions/wallets/embedded-wallet/05-validation.mdx b/docs/pages/solutions/wallets/embedded-wallet/05-validation.mdx new file mode 100644 index 00000000000..800facf806c --- /dev/null +++ b/docs/pages/solutions/wallets/embedded-wallet/05-validation.mdx @@ -0,0 +1,96 @@ +# Validation + +Users with Auth + Embedded Wallet go through two distinct flows based on the login method: + +### Email login (one-time code) + +For users logging in with an email, Amazon Cognito sends a one-time code to validate their identity. This is a trusted method that does not require additional verification. + +### Social login + +Users who log in via established social auth providers like Google or Facebook don't need additional validation. However, when logging in using a custom provider, we cannot guarantee sufficient protection of user's identity. Due to this, we might require additional verification by asking the user to provide a one-time code we send to their email address. + +Please contact Sequence support if you wish to discuss whether your authentication provider can be considered trusted. + +## Validation status + +To check the validation status of the current session, use the `isSessionValid` method. This returns `true` for email login and trusted social logins and `false` for custom logins until email validation is complete. + +```ts +const isValid = await waas.isSessionValid() +console.log(isValid) +``` +``` +true +``` + +### Trigger session validation + +Manually trigger a session validation with the `validateSession` method. This will send a code to the user's email. If validated within 10 minutes, the method returns `true`; otherwise, it returns `false`. + +```ts +const result = await waas.validateSession() +``` +``` +true +``` + +Once user receives the code, he can validate the session with the `finishValidateSession` method that takes the code as an argument. If the code is valid, the method returns `true`; otherwise, it returns `false`. + +```ts +const result = await waas.finishValidateSession('123456') +``` +``` +true +``` + +#### onValidationRequired callback + +The `onValidationRequired` callback is triggered when a session validation is required. This can happen when a user tries to perform an action that requires validation, such as sending a transaction or signing a message. It determines whether the session validation should be triggered or not. If the callback returns `true`, the session validation is triggered. If it returns `false`, the action is cancelled. + +```ts +const tx = await waas.sendERC20({ + validation: { + onValidationRequired: () => true + }, + chainId: 42161, + token: '0x6b175474e89094c44da98b954eedeac495271d0f', // DAI + to: '0x27CabC9700EE6Db2797b6AC1e1eCe81C72A2cD8D', // Recipient + value: '200000000000000000000', // 200 DAI +}) +``` + +### Listen for session validations + +Events like transaction sends may silently prompt session validation. Use the `onValidationRequired` hook to catch such instances. + +```ts +waas.onValidationRequired(() => { + console.log('Session has been triggered for validation'); +}) + +await waas.sendTransaction({ chainId: 1 }, { to: '0x...', value: '1' }); +``` +``` +Session has been triggered for validation +``` + +## Automatic session validation + +Session validation is automatic when certain actions requiring validation are performed. This can be managed using the `onValidationRequired` hook. + +```ts +const tx = await waas.sendTransaction({ + chainId: 1, + validation: { + onValidationRequired: () => { + console.log('Session has been triggered for validation'); + return true; + } + }, + to: '0x061150e5574716DBb1a2cdf54b3DcE9F94395f65', + value: '1' +}) +``` + +By returning `true` or `false` from the `onValidationRequired` hook, you either continue or cancel the action, respectively. diff --git a/docs/pages/solutions/wallets/embedded-wallet/06-transaction-receipts.mdx b/docs/pages/solutions/wallets/embedded-wallet/06-transaction-receipts.mdx new file mode 100644 index 00000000000..0ddcfb7a6c7 --- /dev/null +++ b/docs/pages/solutions/wallets/embedded-wallet/06-transaction-receipts.mdx @@ -0,0 +1,143 @@ +# Transaction receipts + +Any methods that involve sending transactions will return either *successful* or *failed* transaction receipts. Failed transaction receipts are generated without executing the transaction. + +## Successful transaction response + +Any transaction that is successfully included in a block will return a `SentTransactionResponse` object. This must be checked for before accessing the transaction hash, using the `isSentTransactionResponse` type guard. + +```ts +import { Sequence, isSentTransactionResponse } from '@0xsequence/waas' + +const waas = new SequenceWaaS({ + projectAccessKey: `${process.env.PROJECT_ACCESS_KEY}`, + waasConfigKey: `${process.env.WAAS_CONFIG_KEY}`, + network: 'mumbai' +}, defaults.TEST) + +await waas.signIn({ idToken }, "Session name") + +const tx = await waas.sendTransaction({ + chainId: 42161, + transactions: [{ + to: '0xD72C236Be524Ec24F72329317e2785E687105B69', value: '0' + }] +}) + +if (isSentTransactionResponse(tx)) { + console.log(tx) +} +``` + +The relevant fields are: + +- `txHash`: The transaction hash of the transaction that was sent to the network. +- `receipt.logs`: Logs emitted by the transaction. +- `receipt.status`: The status of the transaction. `SUCCEEDED` or `FAILED`. +- `receipt.revertReason`: If the transaction was executed but reverted, it includes the reason. + +To view the full response object, see the [Transaction Receipt Response](/waas/implementation/responses#transaction-receipt-response) section. + +```json +{ + "code": "transactionReceipt", + "data": { + "txHash": "0xf2e9f728abd65089f25efda5852e605ced377f4e2c89dbf143b124623ed09b2c", + "metaTxHash": "acc36ed4ef40db74137266e48d863083a5c7e85e2735d69adafcb5b362b6cfc0", + "nativeReceipt": { ... }, + "receipt": { + "id": "acc36ed4ef40db74137266e48d863083a5c7e85e2735d69adafcb5b362b6cfc0", + "index": 0, + "logs": [ + { + "address": "0x4d4EE1b8583e31fe789eAF2e1b6e011C220c10B6", + "data": "0x0000000000000000000000001119e72b4af230becebd933d0e07f0eec51d8c2a0000000000000000000000000000000000000000000000000000000000000001", + "topics": [ + "0x1f180c27086c7a39ea2a7b25239d1ab92348f07ca7bb59d1438fcf527568f881" + ] + }, + { + "address": "0x4d4EE1b8583e31fe789eAF2e1b6e011C220c10B6", + "data": "0x0000000000000000000000000000000000000000000000000000000000000000", + "topics": [ + "0x5c4eeb02dabf8976016ab414d617f9a162936dcace3cdef8c69ef6e262ad5ae7", + "0xacc36ed4ef40db74137266e48d863083a5c7e85e2735d69adafcb5b362b6cfc0" + ] + } + ], + "receipts": [ ... ], + "revertReason": null, + "status": "SUCCEEDED" + }, + "request": { ... }, + "simulations": [ ... ] + } +} +``` + +## Failed transaction response + +An Embedded Wallet will try to catch any failing transactions before they are sent to the network. This is done by simulating the transaction on the network before sending it. If the simulation fails, the transaction will not be sent to the network and a `FailedTransactionResponse` will be returned. + +To view the full response object, see the [Transaction Receipt Response](/waas/implementation/responses#failed-transaction-response) section. + +```ts +import { Sequence, isSentTransactionResponse } from '@0xsequence/waas' + +const waas = new SequenceWaaS({ + projectAccessKey: `${process.env.PROJECT_ACCESS_KEY}`, + waasConfigKey: `${process.env.WAAS_CONFIG_KEY}`, + network: 'mumbai' +}, defaults.TEST) + +await waas.signIn({ idToken }, "Session name") + +const tx = await waas.sendTransaction({ + chainId: 137, + transactions: [{ + // This address always fails on Polygon, give it a try :D + to: '0x839eE023B21f4Ffe2294025DE0AC30Ba7278D6Fd', value: '0' + }] +}) + +if (isSentTransactionResponse(tx)) { + // ... This will never be executed +} else { + // tx can only be `SentTransactionResponse` or `FailedTransactionResponse` + console.log(tx) +} +``` +```json +{ + "code": "transactionFailed", + "data": { + "error": "This is an error message", + "request": { + "code": "sendTransaction", + "expires": 1699443005, + "identifier": "ts-sdk-1699442705965-0x153824576D03629b264683B430bBF9AcEA1d0975", + "issued": 1699442705, + "network": "137", + "transactions": [ + { + "data": "0x", + "to": "0x839eE023B21f4Ffe2294025DE0AC30Ba7278D6Fd", + "type": "transaction", + "value": "0x00" + } + ], + "wallet": "0x4d4EE1b8583e31fe789eAF2e1b6e011C220c10B6" + }, + "simulations": [ + { + "executed": true, + "gasLimit": 7908, + "gasUsed": 5931, + "reason": "This is an error message :)", + "result": null, + "succeeded": false + } + ] + } +} +``` diff --git a/docs/pages/solutions/wallets/overview.mdx b/docs/pages/solutions/wallets/overview.mdx new file mode 100644 index 00000000000..e4e22eea4d5 --- /dev/null +++ b/docs/pages/solutions/wallets/overview.mdx @@ -0,0 +1 @@ +## Comparison of wallet offerings, guides, etc \ No newline at end of file diff --git a/docs/pages/solutions/wallets/universal-wallet/01-overview.mdx b/docs/pages/solutions/wallets/universal-wallet/01-overview.mdx new file mode 100644 index 00000000000..0738a600b21 --- /dev/null +++ b/docs/pages/solutions/wallets/universal-wallet/01-overview.mdx @@ -0,0 +1,18 @@ +--- +slug: /wallet +--- + +# Wallet + +Sequence Wallet gives you a friendly, non-custodial wallet for your users with multi-chain support and seamless integration. + +
    + +
    + +Most wallets for Ethereum have a single private key that has full control over a wallet, i.e. an Externally Owned Account (EOAs). +However, a Sequence wallet is a Smart Contract that is deployed on the blockchain and which can be controlled by multiple private keys. +These keys are meant to be controlled by the wallet owner and provide added security since more than one of these keys would need to be +compromised for the wallet to be compromised. + + diff --git a/docs/pages/solutions/wallets/universal-wallet/02-quickstart.mdx b/docs/pages/solutions/wallets/universal-wallet/02-quickstart.mdx new file mode 100644 index 00000000000..a2dc7552a53 --- /dev/null +++ b/docs/pages/solutions/wallets/universal-wallet/02-quickstart.mdx @@ -0,0 +1,65 @@ +# Quickstart + +## Try a Demo +:::info +Try out the Universal Wallet leveraging SequenceKit at our [demo](https://0xsequence.github.io/kit/) +::: + + +## Template +:::info +Get started quickly with a [template](https://github.com/0xsequence/kit/tree/master/examples/react) using SequenceKit +::: + + +## Install for existing project + +We provide TypeScript and Unity SDKs for the Embedded Wallet authentication system. You can install the TypeScript SDK with: + +```bash +pnpm install @0xsequence/waas +``` + +For more information on the Unity Embedded Wallet SDK, please refer to the [Unity SDK documentation](/unity-waas-sdk). + +The sequence.js SDK is composed of several sub-packages combined into a single meta-package called `0xsequence`. +To add the SDK to your project, add a dependency on 0xsequence to your package.json: + +```sh +npm install 0xsequence ethers +``` +or + +```sh +pnpm install 0xsequence ethers +``` +or + +```sh +yarn add 0xsequence ethers +``` + +If you know that your project only requires specific sub-packages, you can also depend on those directly with +`npm add @0xsequence/`. + +Your package.json should look something like this (actual version may vary): +```json +{ + "name": "my-dapp", + ... + "dependencies": { + "0xsequence": "^1.0.0", + "ethers": ^5.7.0" + ... + } +} +``` + +#### CDN distribution as native JS + +Optionally, `0xsequence` can be installed as a JS script source (UMD distribution) via: + +```js + + +``` diff --git a/docs/pages/solutions/wallets/universal-wallet/03-guides/01-connect-wallet.mdx b/docs/pages/solutions/wallets/universal-wallet/03-guides/01-connect-wallet.mdx new file mode 100644 index 00000000000..540853519d5 --- /dev/null +++ b/docs/pages/solutions/wallets/universal-wallet/03-guides/01-connect-wallet.mdx @@ -0,0 +1,303 @@ +# Connect Wallet + +Sequence is a very flexible wallet which allow users multiple ways to connect / access their wallet. This includes: + +1. **On-demand Ethereum web wallet for new users** via [0xsequence](https://www.npmjs.com/package/0xsequence) npm package + https://sequence.app -- this option allows + developers to offer users an on-demand web3 wallet. No user install required -- any browser will _just work_, and users + can onboard with a familiar Web2 experience. Think of it like _Paypal / Stripe but for web3_. + +2. **Surf all of web3** via [Sequence Wallet Chrome Extension](https://chrome.google.com/webstore/detail/sequence-wallet/ocmccklecaalljlflmclidjeclpcpdim?hl=en) -- users + who have the Sequence Wallet Chrome Extension installed are able to access any Ethereum-compatible Dapp on the Web :) Just like how MetaMask works, + but of course with a bunch of the benefits of Sequence. + +3. **Mobile phone access** via [WalletConnect](https://walletconnect.com/) support within Sequence Wallet -- users are able to communicate with their wallets remotely + via the awesome Wallet Connect protocol. This is an excellent option if using Sequence Wallet from your mobile phone and want to connect + your wallet to a desktop dapp. + +Sequence Wallet is built on Web Browser (W3C) and Ethereum web3 standards -- and is available everywhere that a modern browser is able to run. +We've carefully designed the wallet for simple onboarding, while maintaining security for users, and allowing users to progressively +increase the level of their security through additional keys and measures. + +This means, that if you've developed a dapp to work with MetaMask, then Sequence will work too without any changes. If you're +using web3.js or ethers.js, Sequence will just work too. This is the beauty of interoperability on web3 :) + +## Connecting your dapp with `0xsequence` + +:::info A delightful wallet without requiring your users to install anything :D +By integrating `0xsequence`, users may access your dapp without having to install any special extensions, +and the wallet also works on mobile browsers! +::: + +Your dapp can connect to your user's wallet by first instantiating the Wallet provider: + +```ts +import { sequence } from "0xsequence"; + +const projectAccessKey = '' + +// This assumes your dapp runs on Ethereum mainnet +const wallet = sequence.initWallet(projectAccessKey); + +// If your dapp runs on a different EVM-compatible blockchain, you can specify its name +// const wallet = sequence.initWallet(projectAccessKey, { defaultNetwork: 'polygon' }); +``` + +Note that is possible to retrieve the above instance by using the `getWallet()` method: + +```ts +import { sequence } from "0xsequence"; +const wallet = sequence.getWallet(); +``` + +Once you have the instance, you can connect to the wallet: + +```ts +const connectDetails = await wallet.connect({ + app: "Your Dapp name", + authorize: true, + // And pass settings if you would like to customize further + settings: { + theme: "light", + bannerUrl: "https://yoursite.com/banner-image.png", // 3:1 aspect ratio, 1200x400 works best + includedPaymentProviders: ["moonpay", "ramp"], + defaultFundingCurrency: "matic", + lockFundingCurrencyToDefault: false, + }, +}); + +console.log("user accepted connect?", connectDetails.connected); +console.log( + "users signed connect proof to valid their account address:", + connectDetails.proof +); +``` + +You can pick/limit the available sign in options with `signInOptions`. Will be ignored if user is already signed in. + +```ts +const wallet = sequence.getWallet(); + +await wallet.connect({ + app: "Your Dapp name", + settings: { signInOptions: ["google"] }, +}); +``` + +After you connect, you can use `wallet.openWallet()` to open the wallet: + +```ts +const wallet = sequence.getWallet(); +wallet.openWallet(); +``` + +You can also optionally pass a path, and use `openWithOptions` intent to pass settings when you open the wallet: + +```ts +const settings: Settings = { + theme: "dark", + bannerUrl: "https://yoursite.com/banner-image.png", // 3:1 aspect ratio, 1200x400 works best + includedPaymentProviders: ["moonpay", "ramp"], + defaultFundingCurrency: "eth", + lockFundingCurrencyToDefault: false, +}; + +const intent: OpenWalletIntent = { + type: "openWithOptions", + options: { + settings: settings, + }, +}; + +const wallet = sequence.getWallet(); + +const path = "wallet/add-funds"; +wallet.openWallet(path, intent); +``` + +:::tip Check out some example Dapp source code +For a complete examples, see [Demo-Dapp](https://github.com/0xsequence/demo-dapp) and [Demo-Dapp-Web3Modal](https://github.com/0xsequence/demo-dapp-web3modal). +::: + +:::caution Avoid Browsers Blocking Sequence Popup +Most browsers will block popups if they are called outside of user-triggered event handlers like `onclick`, or when it takes too long to process between the user action and the actual window + +Read more about browser popup-blocking [here](https://javascript.info/popup-windows#popup-blocking). +::: + +![Sequence on-demand sign in](/img/sign-in-fresh.png) + +![Sequence on-demand sign in, connect](/img/sign-in-connect.png) + +## Wallet Login and Connect Options + +Dapps with direct sequence integration can specify a `ConnectOptions` object when running `wallet.connect()`. + +``` +const connectDetails = await wallet.connect(connectOptions) +``` + +The option parameters are described below. + +#### **app** + +App name of the dapp which will be announced to user on connect screen. + +Example: `await wallet.connect({ app: 'My defi app' })` + +#### **appProtocol** + +Custom protocol for auth redirect (unity/unreal). + +#### **origin** + +Origin hint of the dapp's host opening the wallet. This value will automatically be determined and verified for integrity, and can be omitted. + +#### **expiry** + +Expiry number (in seconds) that is used for ETHAuth proof. Default is 1 week in seconds. + +Example: `await wallet.connect({ expiry: 36000 })` + +#### **authorize** + +`authorize` will perform an ETHAuth eip712 signing and return the proof to the dapp. + +Example: `await wallet.connect({ authorize: true })` + +#### **authorizeNonce** + +`authorizeNonce` is an optional number to be passed as ETHAuth's nonce claim for replay protection. + +Example: `await wallet.connect({ authorizeNonce: 123 })` + +#### **refresh** + +`refresh` flag will force a full re-connect (ie. disconnect then connect again). + +Example: `await wallet.connect({ refresh: true })` + +#### **keepWalletOpened** + +`keepWalletOpened` will keep the wallet window open after connecting. The default is to automatically close the wallet after connecting. + +Example: `await wallet.connect({ keepWalletOpened: true })` + +#### **askForEmail** + +`askForEmail` will ask user whether they want to share the email they use to sign in to wallet while connecting, and will be returned in `connectDetails`. + +Example: `await wallet.connect({ askForEmail: true })` + +#### **settings.theme** + +Name of one of the available theme provided by sequence the sequence wallet will be rendered with. + +Example: `await wallet.connect({ settings: {theme: "light"}}` + +#### **settings.bannerUrl** + +URL of a banner image users will see when connecting or logging into your dapp. The banner image should follow a 3:1 aspect ration where 1200x400 works best. + +Example: `await wallet.connect({ settings: {bannerUrl: "https://yoursite.com/banner-image.png"}}` + +#### **settings.signInWith** + +Specify `signInWith` with a supported auth provider to automatically sign in the user with that provider only. Will be ignored if user is already signed in. + +Example: `await wallet.connect({ settings: {signInWith: "google"}}` + +Supported Providers: "google", "discord", "twitch", "apple", "facebook" + +#### **settings.signInWithEmail** + +Specify signInWithEmail with an email address to allow user automatically sign in with the email option. Will be ignored if user is already signed in. + +Example: `await wallet.connect({ settings: {signInWithEmail: "user@email.com"}}` + +#### **settings.signInOptions** + +Specify signInOptions to pick/limit the available sign in options. Will be ignored if user is already signed in. + +Example: `await wallet.connect({ settings: {signInOptions: ["email", "google", "apple"]}}` + +#### **settings.includedPaymentProviders** + +List of payment providers users will be able to access. By default, users can access all payment providers integrated in Sequence. + +Example: `await wallet.connect({ settings: {includedPaymentProviders: ["moonpay", "ramp"]}}` + +#### **settings.defaultFundingCurrency** + +The tag of the default currency to show when users open the payment provider page. The currency has to be supported by the payment providers integrated in sequence. + +Example: `await wallet.connect({ settings: {defaultFundingCurrency: "usdc"}}` + +#### **settings.defaultPurchaseAmount** + +Use to specify a default purchase amount, as an integer, for prefilling the funding amount. If not specified, the default is 100. + +Example: `await wallet.connect({ settings: {defaultPurchaseAmount: 200}}` + +#### **settings.lockFundingCurrencyToDefault** + +Whether to only allow users to purchase the default currency specified by the `defaultFundingCurrency` option. If set to false, users will also be able to purchase other tokens. locking the default funding currency can be useful to prevent users from purchasing the wrong currency or the currency on the wrong chain. + +Example: `await wallet.connect({ settings: {defaultFundingCurrency: true}}` + +## Connecting your dapp with `web3.js` or `ethers.js` + +For a full example of a dapp which supports Sequence (on-demand + chrome extension), Metamask, and WalletConnect +please see the [Demo-Dapp-Web3Modal repo](https://github.com/0xsequence/demo-dapp-web3modal). + +![Sequence Web3Modal Integration](/img/web3modal.png) + +## Connecting to any Ethereum dapp with the Sequence Wallet Chrome Extension + +Sequence Chrome Extension: [Install](https://chrome.google.com/webstore/detail/sequence-wallet/ocmccklecaalljlflmclidjeclpcpdim?hl=en) + +![Sequence Chrome Extension](/img/build/seq-chrome-store.png) + +## Connecting via `WalletConnect` + +Sequence already supports connecting to dapps via [WalletConnect](https://walletconnect.com). +If your dapp already supports WalletConnect, and you don't need Sequence-specific functionality, nothing more needs to be done. +From the user's perspective, the WalletConnect flow behaves as follows. + +Taking [Uniswap](https://app.uniswap.org) as an example, the user is prompted to connect their wallet using one of multiple possible protocols. + + + +The user selects the WalletConnect option. + + + +A QR code is displayed, which can be scanned by Sequence. +Alternatively, the user can also choose to copy the connection details via their OS clipboard. + + + +Back in the Sequence interface, the user chooses "Scan". + + + +The QR code from the dapp is scanned. +Alternatively, the code is pasted from the OS clipboard if the user chose that previously. + + + +The user confirms the connection request. + + + +The connection succeeded, and the dapp is updated to reflect that. + + + +While connected, the dapp is able to make signing requests to Sequence. +Sequence will always prompt for confirmation from the user for any activity initiated by the dapp. + + + +Once the user has finished using the dapp, they can disconnect the wallet via the session menu. + + diff --git a/docs/pages/solutions/wallets/universal-wallet/03-guides/02-auth-address.mdx b/docs/pages/solutions/wallets/universal-wallet/03-guides/02-auth-address.mdx new file mode 100644 index 00000000000..08dadf23fe7 --- /dev/null +++ b/docs/pages/solutions/wallets/universal-wallet/03-guides/02-auth-address.mdx @@ -0,0 +1,84 @@ +# Authenticate Users with Message Signature + +## Ask for the wallet address + +To get the user's Sequence wallet address: + +```ts +const wallet = sequence.getWallet() +const address = wallet.getAddress() +console.log(address) +``` + +## Authenticate wallet + +In many cases, you'll want your users to connect and then verify they do control this wallet address. Applications typically do this by asking the user +to sign a message with their wallet, and then verify the signature from the user to ensure its integrity. + +As this is such a common workflow, Sequence can automatically authenticate the account address at the same time +while the user is prompt to connect their wallet to your dapp. This allows the user experience to be simpler and +more seamless. + +```ts +import { sequence } from '0xsequence' + +const wallet = sequence.getWallet() + +const connectDetails = await wallet.connect({ + app: 'Your Dapp name', + authorize: true // <---<<< this will automatically sign+verify a EIP712 message when user clicks "Connect" +}) +``` + +It will look like this to your users: +Sequence on-demand sign in, connect + +In the above example, we pass `authorize: true` to the `connect()` function, which will automatically have the user +sign a **EIP712 signed message** to prove their identity. This allows you to then easily authenticate the connected +wallet address with absolute certainty. + +You can find the signed message proof returned in `connectDetails.proof`, which is an EIP712 signed object using +a simple convention from [ethauth](https://github.com/0xsequence/ethauth.js). NOTE: EIP712 allows you to use an actual object for +signing instead of just a plain-text string. + + +## Authenticate wallet server-side + +The above example demonstrates how to connect and verify the user's identity in your dapp on the client-side, +but if you'd like to authenticate the Sequence authorization proof on your server, then you can do so with the following snippet: + +```ts +import { ValidateSequenceWalletProof } from '@0xsequence/auth' +import { commons, v2 } from '@0xsequence/core' +import { ETHAuth } from '@0xsequence/ethauth' +import { trackers } from '@0xsequence/sessions' +import * as ethers from 'ethers' + +// ... + +const rpcUrl = 'https://polygon-mainnet.infura.io/v3/' +const provider = new ethers.providers.JsonRpcProvider(rpcUrl) + +// create an EIP-6492-aware ETHAuth proof validator +const validator = ValidateSequenceWalletProof( + () => new commons.reader.OnChainReader(provider), + new trackers.remote.RemoteConfigTracker('https://sessions.sequence.app'), + v2.DeployedWalletContext +) +const ethauth = new ETHAuth(validator) +await ethauth.configJsonRpcProvider(rpcUrl) + +try { + const proof = await ethAuth.decodeProof(connectDetails.proof.proofString) + console.log(`proof for address ${proof.address} is valid`) +} catch (err) { + console.log(`invalid proof -- do not trust address: ${err}`) +} +``` + +See the [Go Sequence SDK](https://github.com/0xsequence/go-sequence) on using Sequence in your Go applications. + +If your server is written in a language other than Javascript/Typescript or Go, all you have to do is validate +the signature with [EIP1271, the standard method for validating signed messages for a smart wallet](https://eips.ethereum.org/EIPS/eip-1271). + +As always, if you have any questions or require help, reach out to us on [Discord](https://discord.gg/sequence). diff --git a/docs/pages/solutions/wallets/universal-wallet/03-guides/03-sign-message.mdx b/docs/pages/solutions/wallets/universal-wallet/03-guides/03-sign-message.mdx new file mode 100644 index 00000000000..bf2424d8b4b --- /dev/null +++ b/docs/pages/solutions/wallets/universal-wallet/03-guides/03-sign-message.mdx @@ -0,0 +1 @@ +# TODO - Replace with Code Groups from Vocs diff --git a/docs/pages/solutions/wallets/universal-wallet/03-guides/04-session-keys.mdx b/docs/pages/solutions/wallets/universal-wallet/03-guides/04-session-keys.mdx new file mode 100644 index 00000000000..e35a392240c --- /dev/null +++ b/docs/pages/solutions/wallets/universal-wallet/03-guides/04-session-keys.mdx @@ -0,0 +1,85 @@ +# No-Wallet-Confirmation Signatures +It is possible to build an application where users sign messages without requiring a confirmation in their Sequence wallet every time. This is possible using *session keys*, or ephemeral keys. + +# Session Keys +Session keys are ephemeral private keys that can be generated and stored client-side, typically in a user's local storage. They provide a convenient and secure way for users to authorize specific actions in a decentralized application without requiring them to confirm each action through their primary wallet. + +By signing a message with their primary wallet (e.g., Sequence Wallet), users can authorize a session key to act on their behalf for a limited time or scope. Applications can then interpret signed messages from the session key as if they were coming directly from the user's wallet, streamlining the user experience. + +Session keys are particularly useful for applications that require frequent user interactions, as they help reduce the number of wallet confirmations needed, while still maintaining a secure and verifiable authentication process. + +# Using Session keys with Sequence + +### 1. Initialize Sequence Wallet and Connect +```javascript +import { Wallet } from '@0xsequence/wallet' +import { ethers } from 'ethers' + +const wallet = new Wallet() +await wallet.connect() + +const signer = wallet.getSigner() +const userAddress = signer.getAddress() +``` + +### 2. Generate a Session Key +Create a new ephemeral private key, store it in local storage, and derive the associated address: + +```javascript +const sessionPrivateKey = ethers.utils.randomBytes(32) +localStorage.setItem('sessionPrivateKey', ethers.utils.hexlify(sessionPrivateKey)) +const sessionWallet = new ethers.Wallet(sessionPrivateKey) +const sessionAddress = await sessionWallet.getAddress() +``` + +### 3. Sign Authorization Message +Sign a message with the user's Sequence Wallet to authorize the session key: + +```javascript +const authorizationMessage = `Authorize this device to play this game.` +const signature = await signer.signMessage(authorizationMessage) +``` + +### 4. Verify Authorization Signature + +Verify the signature on the server or client side using Sequence utility functions: + +```javascript +const provider = wallet.getProvider() +const chainId = await wallet.getChainId() + +const isValid = await wallet.utils.isValidMessageSignature( + userAddress, + authorizationMessage, + signature, + chainId +) + +if (isValid) { + console.log('Session key authorized') +} else { + console.log('Session key not authorized') +} +``` + +### 5. Sign Message with Session Key +Use the session key to sign a message client-side without user interaction: + +```javascript +const message = 'Perform action without wallet confirmation' +const sessionSignature = await sessionWallet.signMessage(message) +``` + +### 6. Verify Session Signature +Verify the session signature on the server or client side: + +```javascript +const recoveredSessionAddress = ethers.utils.verifyMessage(message, sessionSignature) +if (recoveredSessionAddress === sessionAddress) { + console.log('Session signature valid') +} else { + console.log('Session signature invalid') +} +``` + +**Note**: You should retrieve the session key stored in local storage upon loading the application and only create a new session key if none can be found. \ No newline at end of file diff --git a/docs/pages/solutions/wallets/universal-wallet/03-guides/05-send-transaction.mdx b/docs/pages/solutions/wallets/universal-wallet/03-guides/05-send-transaction.mdx new file mode 100644 index 00000000000..10edc1941b3 --- /dev/null +++ b/docs/pages/solutions/wallets/universal-wallet/03-guides/05-send-transaction.mdx @@ -0,0 +1,16 @@ +# Sending Transactions + +Signing a transaction will only retrieve the signed payload. +If you want the wallet to actually dispatch the transaction to the network as well, that requires only a small modification to the previous example (note the change from `signTransactions` to `sendTransaction`): + +```ts +const transaction = { + to: recipientAddress, + value: 1000000000000000000 +} + +const signer = wallet.getSigner() +const txnResponse = await signer.sendTransaction(transaction) +console.log(txnResponse) + +``` diff --git a/docs/pages/solutions/wallets/universal-wallet/03-guides/06-send-erc20.mdx b/docs/pages/solutions/wallets/universal-wallet/03-guides/06-send-erc20.mdx new file mode 100644 index 00000000000..861d017aa51 --- /dev/null +++ b/docs/pages/solutions/wallets/universal-wallet/03-guides/06-send-erc20.mdx @@ -0,0 +1,56 @@ +# Sending ERC-20 Tokens + +You can ask the wallet to send a single ERC-20 token transfer: + +```ts +const erc20Interface = new ethers.utils.Interface([ + 'function transfer(address _to, uint256 _value)' +]) + +// Encode an ERC-20 token transfer to recipient of the specified amount +const data = erc20Interface.encodeFunctionData( + 'transfer', [recipientAddress, amount] +) + +const transaction = { + to: daiContractAddress, + data +} + +const signer = wallet.getSigner() +const txnResponse = await signer.sendTransaction(transaction) +console.log(txnResponse) + +``` + +With batching functionality, you can send multiple token transfers in a single native transaction: + +```ts +const erc20Interface = new ethers.utils.Interface([ + 'function transfer(address _to, uint256 _value)' +]) + +// Encode two different ERC-20 token transfers +const data1 = erc20Interface.encodeFunctionData( + 'transfer', [recipient1Address, amount1] +) +const data2 = erc20Interface.encodeFunctionData( + 'transfer', [recipient2Address, amount2] +) + +const transaction1 = { + to: daiContractAddress, + data: data1 +} + +const transaction2 = { + to: daiContractAddress, + data: data2 +} + +// Send a multiple transactions as a single bundle which is executed as one transaction on chain. +const signer = wallet.getSigner() +const txnResponse = await signer.sendTransaction([transaction1, transaction2]) +console.log(txnResponse) + +``` diff --git a/docs/pages/solutions/wallets/universal-wallet/03-guides/07-send-erc721.mdx b/docs/pages/solutions/wallets/universal-wallet/03-guides/07-send-erc721.mdx new file mode 100644 index 00000000000..717b535bc65 --- /dev/null +++ b/docs/pages/solutions/wallets/universal-wallet/03-guides/07-send-erc721.mdx @@ -0,0 +1,58 @@ +# Sending ERC-721 (NFT) Tokens + +Sending an ERC-721 NFT is similar to sending an ERC-20 token. +The only notable difference is in the contract standard itself: + +```ts +const erc721Interface = new ethers.utils.Interface([ + 'function safeTransferFrom(address _from, address _to, uint256 _tokenId)' +]) + +// Encode the transfer of the NFT tokenId to recipient +const address = await wallet.getAddress() +const data = erc721Interface.encodeFunctionData( + 'safeTransferFrom', [address, recipientAddress, tokenId] +) + +const transaction = { + to: erc721TokenAddress, + data +} + +const signer = wallet.getSigner() +const txnResponse = await signer.sendTransaction(transaction) +console.log(txnResponse) + +``` + +With batching functionality, you can send multiple token transfers in a single native transaction: + +```ts +const erc721Interface = new ethers.utils.Interface([ + 'function safeTransferFrom(address _from, address _to, uint256 _tokenId)' +]) + +// Encode two different ERC-721 token transfers +const data1 = erc721Interface.encodeFunctionData( + 'safeTransferFrom', [address, recipient1Address, amount1] +) +const data2 = erc721Interface.encodeFunctionData( + 'safeTransferFrom', [address, recipient2Address, amount2] +) + +const transaction1 = { + to: erc721ContractAddress, + data: data1 +} + +const transaction2 = { + to: erc721ContractAddress, + data: data2 +} + +// Send a multiple transactions as a single bundle which is executed as one transaction on chain. +const signer = wallet.getSigner() +const txnResponse = await signer.sendTransactionBatch([transaction1, transaction2]) +console.log(txnResponse) + +``` diff --git a/docs/pages/solutions/wallets/universal-wallet/03-guides/08-send-erc1155.mdx b/docs/pages/solutions/wallets/universal-wallet/03-guides/08-send-erc1155.mdx new file mode 100644 index 00000000000..fb7f1b34fa7 --- /dev/null +++ b/docs/pages/solutions/wallets/universal-wallet/03-guides/08-send-erc1155.mdx @@ -0,0 +1,57 @@ +# Sending ERC-1155 (Collectible) Tokens + +Sending an ERC-1155 collectible is similar to sending an ERC-20 token. +The only notable difference is in the contract standard itself: + +```ts +const erc1155Interface = new ethers.utils.Interface([ + 'function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data)' +]) + +// Encode the transfer of the collectible to recipient +const address = await wallet.getAddress() +const data = erc1155Interface.encodeFunctionData( + 'safeTransferFrom', [address, recipientAddress, tokenId, amount, '0x'] +) + +const transaction = { + to: erc1155TokenAddress, + data +} + +const signer = wallet.getSigner() +const txnResponse = await signer.sendTransaction(transaction) +console.log(txnResponse) + +``` + +With batching functionality, you can send multiple token transfers in a single native transaction: + +```ts +const erc1155Interface = new ethers.utils.Interface([ + 'function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data)' +]) + +// Encode two different ERC-1155 token transfers +const data1 = erc1155Interface.encodeFunctionData( + 'safeTransferFrom', [address, recipient1Address, token1Id, amount1, '0x'] +) +const data2 = erc1155Interface.encodeFunctionData( + 'safeTransferFrom', [address, recipient2Address, token2Id, amount2, '0x'] +) + +const transaction1 = { + to: erc1155ContractAddress, + data: data1 +} +const transaction2 = { + to: erc1155ContractAddress, + data: data2 +} + +// Send a multiple transactions as a single bundle which is executed as one transaction on chain. +const signer = wallet.getSigner() +const txnResponse = await signer.sendTransactionBatch([transaction1, transaction2]) +console.log(txnResponse) + +``` diff --git a/docs/pages/solutions/wallets/universal-wallet/03-guides/09-send-batch-transactions.mdx b/docs/pages/solutions/wallets/universal-wallet/03-guides/09-send-batch-transactions.mdx new file mode 100644 index 00000000000..e19379c9523 --- /dev/null +++ b/docs/pages/solutions/wallets/universal-wallet/03-guides/09-send-batch-transactions.mdx @@ -0,0 +1,55 @@ +# Sending a Batch of Transactions + +Likewise, bundling multiple transactions to be sent in a single native transaction is equally as easy: + +```ts +const transaction1 = { + to: recipient1Address, + value: 1000000000000000000 +} + +const transaction2 = { + to: recipient2Address, + value: 1000000000000000000 +} + +const signer = wallet.getSigner() +const response = await signer.sendTransaction([transaction1, transaction2]) +console.log(response) +``` + +The transactions don't have to be the same token or even token standard either. +You can mix and match: + +```ts +const erc20Interface = new ethers.utils.Interface([ + 'function transfer(address _to, uint256 _value)' +]) +const erc721Interface = new ethers.utils.Interface([ + 'function safeTransferFrom(address _from, address _to, uint256 _tokenId)' +]) +const erc1155Interface = new ethers.utils.Interface([ + 'function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data)' +]) + +const erc20Data = erc20Interface.encodeFunctionData( + 'transfer', [recipient2Address, amount2] +) +const erc721Data = erc721Interface.encodeFunctionData( + 'safeTransferFrom', [address, recipient3Address, amount3] +) +const erc1155Data = erc1155Interface.encodeFunctionData( + 'safeTransferFrom', [address, recipient4Address, token4Id, amount4, '0x'] +) + +const transactions = [ + { to: recipient1Address, value: '1000000000000000000' }, + { to: daiContractAddress, data: erc20Data }, + { to: erc721ContractAddress, data: erc721Data }, + { to: erc1155ContractAddress, data: erc1155Data } +] + +const signer = wallet.getSigner() +const response = await signer.sendTransaction(transactions) +console.log(response) +``` diff --git a/docs/pages/solutions/wallets/universal-wallet/03-guides/10-building-backends.mdx b/docs/pages/solutions/wallets/universal-wallet/03-guides/10-building-backends.mdx new file mode 100644 index 00000000000..56e53bab171 --- /dev/null +++ b/docs/pages/solutions/wallets/universal-wallet/03-guides/10-building-backends.mdx @@ -0,0 +1,33 @@ +# Building Backends with Sequence + +### nodejs + +The [0xsequence](https://github.com/0xsequence/sequence.js) package which is available for browser / client use, also works perfectly on nodejs backends +written in Javascript or Typescript. + +### Go + +A complete Sequence SDK is also available in Go: https://github.com/0xsequence/go-sequence. + +[go-sequence](https://github.com/0xsequence/go-sequence) is the equivalent of [0xsequence](https://github.com/0xsequence/sequence.js) +but for Go / Golang backends. In fact, all of Sequence's infrastructure is written in Go and is built with [go-sequence](https://github.com/0xsequence/go-sequence). + + +### ethkit + +As part of the Sequence open source tools, our team has also built [ethkit](https://github.com/0xsequence/ethkit), which +is an Ethereum dev toolkit for Go backends. [ethkit](https://github.com/0xsequence/ethkit) supports EOA wallets, +and you can think of it like `ethers.js` but for Go. + + +### Support for other backend languages + +If your backend services are written in a language other than JS or Go, you can still easily integrate Sequence, +as Sequence is really just a standard Ethereum client library with some extra features. In many cases, the extra +features are best utilized on the client-side / dapp. + +If your situation for example is a Python or Java backend where you'd like to verify signatures from a Sequence Wallet, +well then, you can call the standard [EIP1271](https://eips.ethereum.org/EIPS/eip-1271) function for the account address +from your backend. + +If you'd like to use the Sequence's Meta-Transaction capabilities, see [Building Relaying Server with Sequence](/relayer/building-relaying-server). diff --git a/docs/pages/solutions/wallets/universal-wallet/04-platforms.mdx b/docs/pages/solutions/wallets/universal-wallet/04-platforms.mdx new file mode 100644 index 00000000000..186d6ab3e95 --- /dev/null +++ b/docs/pages/solutions/wallets/universal-wallet/04-platforms.mdx @@ -0,0 +1,23 @@ +# Platforms + +## Web Wallet + +Sequence works beautifully on all modern Web Browsers! Try it at https://sequence.app from any computer, phone or tablet. + +See [Build With Sequence](/wallet/installation) to get started. + +## Mobile Wallet + +Sequence works beautifully on your Mobile Web Browser! Try it at https://sequence.app from any phone or tablet. + +This means dapps which integrate the Sequence Wallet will automatically support users on all mobile devices, +while using standard Ethereum web3 dapp-to-wallet communication. See [Build With Sequence](/wallet/installation) to get started. + +## Browser Extension Wallet + +Sequence Chrome Extension: [Install](https://chrome.google.com/webstore/detail/sequence-wallet/ocmccklecaalljlflmclidjeclpcpdim?hl=en) + +![Sequence Chrome Extension](/img/build/seq-chrome-store.png) + +![Sequence Chrome Extension](/img/build/seq-chrome-ext-uniswap.png) + diff --git a/docs/pages/solutions/wallets/universal-wallet/05-fiat-on-ramps.mdx b/docs/pages/solutions/wallets/universal-wallet/05-fiat-on-ramps.mdx new file mode 100644 index 00000000000..03199719040 --- /dev/null +++ b/docs/pages/solutions/wallets/universal-wallet/05-fiat-on-ramps.mdx @@ -0,0 +1,21 @@ +--- +slug: /fiat-on-ramps +--- + +# Fiat On-Ramps +Sequence Wallet allows users to purchase cryptocurrencies directly with their credit card and debit card via on-ramp providers. Currently Sequence supports 6 on-ramp providers; + +- [Moonpay](https://www.moonpay.com/) +- [Ramp](https://ramp.network/) +- [UPI via Onmeta](https://onmeta.in/) +- [Sardine](https://www.sardine.ai/) +- [PayTrie](https://paytrie.com/) +- [Wyre](https://www.sendwyre.com/) (deprecated) + +Only providers that support the region the users are in will be displayed. + +![Sequence on-demand sign in](/img/fiat-providers.png) + +As a developer integrating the Sequence Wallet, you can choose which payment provider can be visible to users. You can also specify which token will be available to purchase via the on-ramp providers. + +To learn more on how to configure the on-ramp options, see [Sequence Connect Options](/wallet/guides/connect-wallet#includedpaymentproviders). diff --git a/docs/pages/solutions/wallets/universal-wallet/06-key-management.mdx b/docs/pages/solutions/wallets/universal-wallet/06-key-management.mdx new file mode 100644 index 00000000000..945a2c66926 --- /dev/null +++ b/docs/pages/solutions/wallets/universal-wallet/06-key-management.mdx @@ -0,0 +1,32 @@ +--- +slug: /key-management +--- + +# Key Management + +Each Sequence wallet can be controlled by multiple private keys, acting like a multisignature wallet. Users can either create a Sequence wallet using one of the supported social login options or create a wallet with a private key stored only on that device. + +The improved security compared to traditional blockchain wallet comes from the fact that multiple independent keys need to be compromised for a malicious actor to take control of a user’s wallet, instead of a single key. The philosophy is that the more independent private-keys the user adds to their wallet, the more secure their wallet becomes, even if each individual key is only moderately secure on their own. + + +## Social Login Wallets + +Sequence Wallet created with social logins are currently secured using three private keys: Session keys, a Guard key and a Torus key. The Session key and Torus key are both generated for the first time when a user creates their Sequence Wallet via social login or email authentication. +At least two of the three keys are needed to unlock an account. This means that if one of the three keys is lost or compromised, a user can use the two remaining keys to replace the lost/compromised key. For example, if a user lost their device containing their Session Key, they can unlock their Sequence Wallet account by email or social login for the Torus key combined with the Guard key. Once done, another session key is auto-generated and the user is back in their account with all 3 keys accessible again. + +### Session Keys +Session keys are stored in the browser's [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API). +Users should be prudent in safeguarding their devices from unauthorized access since an attacker with access to their IndexedDB effectively has control of their session key. + +### Guard Key +A Guard key is a key owned by Horizon. This key allows Horizon to help users that lost their Session key and can require additional information from the user in case of suspicious activity, if the user wants this additional protection. This key would be compromised if a malicious actor took control over Horizon servers hosting the Guard key. + +### Torus Key +A Torus key is a key generated by the [Torus network](https://tor.us/), and is generated using a user’s email or social login credentials such as Google or AppleID. Torus uses threshold cryptography to ensure that only the user can access their private key, making these keys non-custodial. A Torus key would be compromised if a malicious actor had control over the social account or email a user used to generate their Torus key. All Torus keys could be compromised if the Torus network itself was compromised. + + +:::info DEFAULTS + CUSTOMIZATION + +While this is the default setup for new Sequence Wallets, we intend to add the ability for users to add, remove and replace the keys controlling their wallet such that users can choose their preference in terms of security and user experience tradeoff. Even the Guard key will be able to be removed. Security tips and recommendations will be added to ensure users are well informed of the risks and how to protect themselves against them. + +::: diff --git a/docs/pages/solutions/wallets/universal-wallet/07-sequence-kit.mdx b/docs/pages/solutions/wallets/universal-wallet/07-sequence-kit.mdx new file mode 100644 index 00000000000..03757168ddc --- /dev/null +++ b/docs/pages/solutions/wallets/universal-wallet/07-sequence-kit.mdx @@ -0,0 +1,22 @@ +--- +slug: overview +title: Sequence Kit Documentation +--- + +# Sequence Kit: Seamlessly Integrate Web3 Wallets into Your Applications + +Sequence Kit 🧰 is the ultimate toolkit for effortlessly integrating web3 wallets into your applications, providing your users with a smooth and secure onboarding experience. With our robust tools built on the popular [wagmi](https://wagmi.sh/) library, unlock a realm of possibilities in the world of web3. + +## Key Features + +- **Universal Connections**: Seamlessly connect via popular social logins such as Facebook, Google, Discord, and more! Your users will enjoy a smooth, secure onboarding process. 🔐🪪 + +- **Web3 Wallet Integration**: Effortlessly integrate with leading web3 wallets like WalletConnect and MetaMask. Unleash the power of blockchain with just a few clicks! 🦊 ⛓️ + +- **Embedded Wallet Experience**: Provide your users with a comprehensive embedded wallet, enabling them to manage their coins and collectibles all within your own application. 👛 🖼️ 🪙 + +Explore the potential of Sequence Kit by trying out our [demo](https://0xsequence.github.io/kit)! + +# Next Steps + +Ready to integrate Sequence Kit into your application? Check out our [Getting Started guide](/wallet/connectors/kit/getting-started). If you're already familiar with Sequence Kit dive into the available [configuration options](/wallet/connectors/kit/configuration) or take a look at the [checkout](/wallet/connectors/kit/checkout). \ No newline at end of file diff --git a/docs/pages/solutions/white-label-marketplace.mdx b/docs/pages/solutions/white-label-marketplace.mdx deleted file mode 100644 index 9dfb66916ca..00000000000 --- a/docs/pages/solutions/white-label-marketplace.mdx +++ /dev/null @@ -1 +0,0 @@ -## Deploy and customize a hosted marketplace diff --git a/nav.ts b/nav.ts index 95f2a94ea93..4d3490dafac 100644 --- a/nav.ts +++ b/nav.ts @@ -1,30 +1,17 @@ import type { Sidebar, TopNav } from 'vocs' -// NOTE/TODO: below are a WIP ... just trying to think -// of the site structure, and how to organize the content. -// -// Trying to think from the perspective of the reader, that -// is a game developer or app developer. And want to speak -// into their filters, etc.. -// -// As well, we want it to be educational, easy to follow, -// how-to, etc... and comprehensive too.. -// -// We can add / link API references too (can be external links) - export const topNav = [ { text: 'Solutions', items: [ - { text: 'Wallets', link: '/solutions/embedded-wallet', match: '/solutions/embedded-wallet' }, - { text: 'Marketplace', link: '/solutions/white-label-marketplace', match: '/solutions/white-label-marketplace' }, - { text: 'Collectibles', link: '/solutions/contracts', match: '//solutions/contracts' }, + { text: 'Wallets', link: '/solutions/wallets/embedded-wallet/01-overview', match: '/solutions/wallets/embedded-wallet/01-overview' }, + { text: 'Marketplace', link: '/solutions/marketplaces/white-label-marketplace', match: '/solutions/marketplaces/white-label-marketplace' }, + { text: 'Collectibles', link: '/solutions/collectibles/contracts/900-mint-items-from-ERC1155', match: '/solutions/collectibles/contracts/900-mint-items-from-ERC1155' }, { text: 'Payments', link: '/solutions/nft-checkout', match: '/solutions/nft-checkout' }, - { text: 'No-code Builder', link: '/solutions/builder', match: '/solutions/builder' } + { text: 'No-code Builder', link: '/solutions/builder/overview', match: '/solutions/builder/overview' } ] }, - { text: 'Guides', items: [ @@ -79,56 +66,90 @@ export const sidebar = { { text: 'Wallets', items: [ - { text: 'Embedded Wallet', link: '/solutions/embedded-wallet', - - // collapsed: true, - - // items: [ - - // { text: 'Rainbow Kit', link: '/' }, - // { text: 'Web3Modal', link: '/wallet/web3modal' } - // ] - - - + { text: 'Embedded Wallet', collapsed: true, items: [ + {text: 'Overview', link: '/solutions/wallets/embedded-wallet/01-overview'}, + {text: 'Quickstart', link: '/solutions/wallets/embedded-wallet/02-quickstart'}, + {text: 'Manage Sessions', link: '/solutions/wallets/embedded-wallet/03-manage-sessions'}, + {text: 'Use Wallets', link: '/solutions/wallets/embedded-wallet/04-use-wallets'}, + {text: 'Validation', link: '/solutions/wallets/embedded-wallet/05-validation'}, + {text: 'Transaction Receipts', link: '/solutions/wallets/embedded-wallet/06-transaction-receipts'}, + ] }, - { text: 'Universal Wallet', link: '/solutions/universal-wallet' } + { text: 'Universal Wallet', collapsed: true, + items: [ + {text: 'Overview', link: '/solutions/wallets/universal-wallet/01-overview'}, + {text: 'Quickstart', link: '/solutions/wallets/universal-wallet/02-quickstart'}, + {text: 'Guides', collapsed: true, items: [ + {text: 'Connect Wallet', link: '/solutions/wallets/universal-wallet/03-guides/01-connect-wallet'}, + {text: 'Authenticate Users with Message Signature', link: '/solutions/wallets/universal-wallet/03-guides/02-auth-address'}, + {text: 'Signing & Verifying Messages', link: '/solutions/wallets/universal-wallet/03-guides/03-sign-message'}, + {text: 'No-wallet confirmation signatures', link: '/solutions/wallets/universal-wallet/03-guides/04-session-keys'}, + {text: 'Sending Transactions', link: '/solutions/wallets/universal-wallet/03-guides/05-send-transaction'}, + {text: 'Sending ERC-20 Tokens', link: '/solutions/wallets/universal-wallet/03-guides/06-send-erc20'}, + {text: 'Sending ERC-721 (NFT) Tokens', link: '/solutions/wallets/universal-wallet/03-guides/07-send-erc721'}, + {text: 'Sending ERC-1155 (Collectible) Tokens', link: '/solutions/wallets/universal-wallet/03-guides/08-send-erc1155'}, + {text: 'Sending a Batch of Transactions', link: '/solutions/wallets/universal-wallet/03-guides/09-send-batch-transactions'}, + {text: 'Building Backends with Sequence', link: '/solutions/wallets/universal-wallet/03-guides/10-building-backends'}, + ] + }, + {text: 'Supported Platforms', link: '/solutions/wallets/universal-wallet//04-platforms'}, + {text: 'Validation', link: '/solutions/wallets/universal-wallet/05-fiat-on-ramps'}, + {text: 'Transaction Receipts', link: '/solutions/wallets/universal-wallet/06-key-management'}, + {text: 'Sequence Kit', link: '/solutions/wallets/universal-wallet/07-sequence-kit'} + ] + } ] }, { text: 'Marketplace', // collapsed: true, items: [ - { text: 'White-label Marketplace', link: '/solutions/white-label-marketplace' }, - { text: 'Build your Custom Marketplace', link: '/solutions/orderbook' } - ] + { text: 'White-label Marketplace', link: '/solutions/marketplaces/white-label-marketplace' }, + { text: 'Build your Custom Marketplace', collapsed: true, items: [ + {text: 'Overview', link: '/solutions/marketplaces/orderbook/01-overview'}, + {text: 'Quickstart', link: '/solutions/marketplaces/orderbook/02-quickstart'}, + ] + } + ] }, { text: 'Collectibles', - // collapsed: true, items: [ - { text: 'Deployable Contracts', link: '/solutions/contracts' }, - { text: 'Metadata Manager', link: '/solutions/metadata-manager' }, - { text: 'Minter', link: '/solutions/minter' } + { text: 'Deployable Contracts' , collapsed: true, items: [ + {text: 'Mint In-Game Items and Achievements (ERC1155)', link: '/solutions/collectibles/contracts/900-mint-items-from-ERC1155'}, + {text: 'Mint Digital Collectibles (ERC721)', link: '/solutions/collectibles/contracts/902-mint-collectibles-from-ERC721'}, + {text: 'Mint In-Game Currency (ERC20)', link: '/solutions/collectibles/contracts/903-mint-currency-from-ERC20'}, + ], + }, + { text: 'Metadata Manager', link: '/solutions/collectibles/metadata/800-manage-contract-metadata-builder' }, + // { text: 'Minter', link: '/solutions/minter' } ] }, { text: 'Payments', items: [ { text: 'NFT Checkout', link: '/solutions/nft-checkout' }, - { text: 'Onramps', link: '/solutions/onramps' }, + { text: 'Onramps', link: '/solutions/payments/onramps/01-fiat-on-ramps' }, ] }, { text: 'No-code Builder', + collapsed: true, items: [ - { text: 'Overview', link: '/solutions/builder' } + { text: 'Overview', link: '/solutions/builder/overview' }, + {text: 'Project Management', link: '/solutions/builder/project-management'}, + {text: 'Contracts', link: '/solutions/builder/contracts'}, + {text: 'Wallet SDKs', link: '/solutions/builder/wallet-sdks'}, + {text: 'Gas Tank', link: '/solutions/builder/gas-tank'}, + {text: 'Node Gateway', link: '/solutions/builder/node-gateway'}, + {text: 'Marketplaces', link: '/solutions/builder/marketplaces'}, + {text: 'Indexer', link: '/solutions/builder/indexer'}, + {text: 'Settings', link: '/solutions/builder/project-settings'}, ] }, { text: 'Technical References', items: [ - { text: 'Ethereum Compatibility', link: '/solutions/ethereum-compatibility' }, { text: 'Chain Support', link: '/solutions/chain-support' }, ] }, @@ -219,7 +240,7 @@ export const sidebar = { }, ], - // SDKs + // apis '/api': [ { text: 'APIs', @@ -236,85 +257,6 @@ export const sidebar = { ], - - // Builder - // TODO: I just mocked below for some structure.. but - // we should change it up as we go.. - '/builder': [ - { - text: 'Introduction', - items: [ - { text: 'Overview', link: '/builder' }, - { text: 'Setting up your project', link: '/builder/stub' }, - { text: 'API Access Keys', link: '/builder/stub' }, - ] - }, - { - text: 'Contracts', - // collapsed: true, - items: [ - { text: 'Getting started', link: '/builder/contracts/getting-started' }, - { text: 'Creating a contract', link: '/builder/contracts/create' }, - ] - }, - { - text: 'Collections', - // collapsed: true, - items: [ - { text: 'Getting started', link: '/builder/collections/getting-started' }, - { text: 'Creating a collection', link: '/builder/collections/create' }, - ] - }, - { - text: 'NFT Metadata', - // collapsed: true, - items: [ - { text: 'Getting started', link: '/builder/metadata/getting-started' }, - { text: 'Creating metadata', link: '/builder/metadata/create' }, - ] - }, - { - text: 'Transactions', - // collapsed: true, - items: [ - { text: 'Getting started', link: '/builder/transactions/getting-started' }, - { text: 'Gas Tanks', link: '/builder/transactions/gas-tanks' }, // TODO .. - ] - }, - { - text: 'Payments', - // collapsed: true, - items: [ - { text: 'Getting started', link: '/builder/etc' }, - { text: 'etc', link: '/builder/etc' }, - ] - }, - { - text: 'Marketplaces', - // collapsed: true, - items: [ - { text: 'Getting started', link: '/builder/etc' }, - { text: 'etc', link: '/builder/etc' }, - ] - }, - { - text: 'Analytics', - // collapsed: true, - items: [ - { text: 'Getting started', link: '/builder/etc' }, - { text: 'etc', link: '/builder/etc' }, - ] - }, - { - text: 'Settings', - // collapsed: true, - items: [ - { text: 'Getting started', link: '/builder/etc' }, - { text: 'etc', link: '/builder/etc' }, - ] - } - ], - // Support '/support': { items: [