diff --git a/docs/onboarding/0 0 Home.mdx b/docs/onboarding/0 0 Home.mdx index f2bfb10148..76a4c2796b 100644 --- a/docs/onboarding/0 0 Home.mdx +++ b/docs/onboarding/0 0 Home.mdx @@ -11,6 +11,7 @@ import LanguageCard from "@components/landing-page/LanguageCard"; import ToolCardsSection from "@components/landing-page/ToolCardsSection"; import WalletsCardsSection from "@components/landing-page/WalletsCardsSection"; import ContractsCardsSection from "@components/landing-page/ContractsCardsSection"; +import PaymentsCardsSection from "@components/landing-page/PaymentsCardsSection"; import InfrastructureCardsSection from "@components/landing-page/InfrastructureCardsSection"; import SolutionsCardsSection from "@components/landing-page/SolutionsCardsSection"; import LearnSection from "@components/landing-page/LearnSection"; @@ -25,6 +26,7 @@ import ResourcesSection from "@components/landing-page/ResourcesSection"; +

SDKs

diff --git a/docs/onboarding/12 Wallet/0 Overview.mdx b/docs/onboarding/12 Wallet/0 Overview.mdx index dad3c98c9b..03e8cf447d 100644 --- a/docs/onboarding/12 Wallet/0 Overview.mdx +++ b/docs/onboarding/12 Wallet/0 Overview.mdx @@ -161,37 +161,30 @@ The Wallet SDK comes out of the box with support for the most popular wallets th description="Connect with OKX Wallet" /> - -{" "} -
- -
- -{" "} -
- -
- -{" "} -
- -
- +
+ +
+
+ +
+
+ +
+
+ +

diff --git a/docs/onboarding/12 Wallet/4 Wallets/OneKey Wallet.mdx b/docs/onboarding/12 Wallet/4 Wallets/OneKey Wallet.mdx new file mode 100644 index 0000000000..08bd93945b --- /dev/null +++ b/docs/onboarding/12 Wallet/4 Wallets/OneKey Wallet.mdx @@ -0,0 +1,68 @@ +--- +slug: /wallet/onekey-wallet +title: OneKey Wallet +--- + +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; +import CodeBlock from "@theme/CodeBlock"; + +Prompt users to connect to their [OneKey wallet](https://onekey.so). + +## Usage + +```javascript +import { OneKeyWallet } from "@thirdweb-dev/wallets"; + +const wallet = new OneKeyWallet(); + +wallet.connect(); +``` + +## Configuration + +Optionally, provide a configuration object when instantiating the `OneKeyWallet` class. + +
+ projectId (recommended) +
+ +This is only relevant if you want to use [WalletConnect](https://walletconnect.com/) for connecting to OneKey wallet mobile app when MetaMask is not injected. + +This `projectId` can be obtained at [cloud.walletconnect.com](https://cloud.walletconnect.com/). It is highly recommended to use your own project id and only use the default one for testing purposes. + +```javascript +import { OneKeyWallet } from "@thirdweb-dev/wallets"; + +const wallet = new OneKeyWallet( + // highlight-start + { + projectId: "YOUR_WALLET_CONNECT_PROJECT_ID", + }, + // highlight-end +); +``` + +
+
+ +
+ recommended (optional) +
+ +Show this wallet as "recommended" in the [ConnectWallet Modal](/react/react.connectwallet). + +```ts +OneKeyWallet({ + // highlight-start + recommended: true, + // highlight-end +}); +``` + +
+
+ +## Methods + +Inherits all the public methods from the [`AbstractClientWallet`](interfaces/abstract-client-wallet) class. \ No newline at end of file diff --git a/docs/onboarding/20 Connect/3 Connect Wallet Component/3 Supported Wallets.mdx b/docs/onboarding/20 Connect/3 Connect Wallet Component/3 Supported Wallets.mdx index 86ac3be707..5e39a74208 100644 --- a/docs/onboarding/20 Connect/3 Connect Wallet Component/3 Supported Wallets.mdx +++ b/docs/onboarding/20 Connect/3 Connect Wallet Component/3 Supported Wallets.mdx @@ -167,6 +167,14 @@ The following wallets are supported by the SDKs: description="Connect with Defi Wallet" /> +
+ +
diff --git a/docs/onboarding/21 Embedded Wallet/0 Overview.mdx b/docs/onboarding/21 Embedded Wallet/0 Overview.mdx index 16c797c3a6..8c87db09a5 100644 --- a/docs/onboarding/21 Embedded Wallet/0 Overview.mdx +++ b/docs/onboarding/21 Embedded Wallet/0 Overview.mdx @@ -12,6 +12,8 @@ Embedded wallets are wallets that get spun up for users when they first come int Users can login using their email address, social logins (twitter, apple, discord, etc), or any Open ID Compatible authentication service. Once they authenticate they are provisioned a wallet, which they can then use to perform on-chain actions like minting NFTs and sending transactions. +Embedded wallets work with all EVM networks + ![Hero image for Embedded wallet that shows default modal with Google and verification modal](./assets/embed-overview.svg)
diff --git a/docs/onboarding/21 Embedded Wallet/4 Custom Auth/1 Bring your Auth.mdx b/docs/onboarding/21 Embedded Wallet/4 Custom Auth/1 Bring your Auth.mdx index 355e9694bb..1b11638d0b 100644 --- a/docs/onboarding/21 Embedded Wallet/4 Custom Auth/1 Bring your Auth.mdx +++ b/docs/onboarding/21 Embedded Wallet/4 Custom Auth/1 Bring your Auth.mdx @@ -1,35 +1,77 @@ --- slug: /embedded-wallet/custom-auth -title: Use your own auth +title: Overview --- -import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; +import Tabs from "@theme/Tabs"; import QuickstartCard from "@components/QuickstartCard"; -By default, the embedded wallet service handles two things: auth, and spinning up crypto wallets tied to the auth. We require -valid authentication to ensure a wallet is created for the right person. -If you already have your own auth and only want to spin up wallets, we offer a simple way to hook up any **OpenID Connect ("OIDC") compatible** auth to create embedded wallets. +Embedded wallets already support most popular login methods out of the box, but we also give app developers the flexibility to use +embedded wallets with any authentication method. If you have a valid authenticated user, you should be able to easily spin up an +embedded wallet for them irrespective of how they got authenticated. + +### Usecases + +This means that app developers can now -## How it works +- Spin up embedded wallets for users using their existing authentication service. For example, if you have a game where players log in using their username and password, you can now easily create wallets when they sign up. +- Integrate with any social login provider. For example, if you have a game where you want to let users login with their Steam or Epic games credentials, you can now use embedded wallets to enable these experiences. +- Use embedded wallets in non-frontend environments. For example, you could authenticate users with SSH and use embedded wallets with CLI tools. +- Build completely custom authentication experiences. For example, you could ask users to verify their credentials with 2FA or passkey before you consider them authenticated and provision wallets for them. -- An OIDC auth system has a public-private keypair, where the private key is used to sign auth tokens +## Configuring custom auth + +We offer two options to setup your custom auth, one that is based on the [OIDC (Open ID Connect)](https://openid.net/developers/how-connect-works/) standard, and a generic option that lets you bring your own auth server. You can also use both options together if needed. + +### Setting up OIDC compatible auth + +An OIDC auth system has a public-private keypair, where the private key is used to sign auth tokens - The public key is uploaded to a public URL in JWKS format. The standard location is `https://{domain}.com/.well-known/jwks.json` - When a user logs in, a JWT token called the idToken is generated and signed by the private key. The OIDC spec provides an interface for fields that are used in this token. -- We use the public key to verify that the JWT was signed correctly, and proceed to generate a wallet based on the `sub` (user identifier) value of the idToken. +- This JWT is then passed to the embedded wallet to generate a wallet for the user. +- We will verify the JWT against the public key to verify that the JWT was signed correctly. Upon successful verification, we will proceed to generate a wallet based on the `sub` (user identifier) value of the idToken. + + +To setup an OIDC compatible auth, enable the first option in the configuration tab of the embedded wallet dashboard +![Custom auth](../assets/customauthdb.png) + +You will be asked to enter the following values +- The URL of the JWKS file (public key): This is used to verify the token was signed by you. +- The `aud` value of the idToken: This is used to verify that thirdweb is the intended user of the token + + +### Setting up generic auth + +Generic auth is a lower level option that can be used when you have your own auth server that you use to authenticate users +- When a user logs in, you are able to generate a public identifier that allows you to identify the user. +- You can pass this identifier to the embedded wallet to generate a wallet for the user. +- When verifying the user, we will hit an endopint that you provide to verify the user's identity. +- We will then generate a wallet for the user if the provided payload is valid. + +![How generic auth works](../assets/customauth.png) + +To use generic auth, enable the second option in the configuration tab of the embedded wallet dashboard + +![Generic auth dashboard](../assets/customauthdb2.png) -## Configuration Setup +You will be asked to enter an endpoint that we can hit to verify the user's identity. This endpoint should accept a POST request with a JSON body containing the following fields: +- `payload`: This will correspont to the public identifier that was generated for your user. + +The endpoint should return a JSON body containing the following fields: + - `userId`: A uid for the user. Note that you can only create one wallet per `userId` at this point + - `email` (optional): If provided, the user will be able to access the same account outside of the platform for things like private key export // using with wallet connect etc. + - `exp` (optional): An expiration date for the user's wallet session. By default a session is 7 days long. + + +You can also pass a list of headers. These headers will be sent with every request to your verification endpoint. You can use these to authenticate the request. -In your API key settings, click edit, look for "Custom Auth" and provide the following values: -- The URL of the JWKS file (public key) - - This is used to verify the token was signed by you. -- The `aud` value of the idToken - - This is used to verify that thirdweb is the intended user of the token ## Authenticating a user -Once you've logged in with your own auth, you can pass the user's JWT to the embedded wallet to authenticate and connect. + +### OIDC auth @@ -51,7 +93,7 @@ const handlePostLogin = async (jwt: string) => { - + In other frameworks, use your own instance of the wallet to authenticate and connect. @@ -74,3 +116,53 @@ const walletAddress = await embeddedWallet.connect({ authResult }); + + + +### Generic auth + + + + + +In React and React Native, the `useEmbeddedWallet()` hook handles authentication and connection states. + +```typescript +import { useEmbeddedWallet } from "@thirdweb-dev/react"; // or /react-native + +const embeddedWallet = useEmbeddedWallet(); + +const handlePostLogin = async (jwt: string) => { + await embeddedWallet.connect({ + strategy: "auth_endpoint", + payload, + }); +}; +``` + + + + + +In other frameworks, use your own instance of the wallet to authenticate and connect. + +```typescript +import { EmbeddedWallet } from "@thirdweb-dev/wallets"; +import { Goerli } from "@thirdweb-dev/chains"; + +const embeddedWallet = new EmbeddedWallet({ + chain: Goerli, // chain to connect to + clientId: "YOUR_CLIENT_ID", // Your thirdweb client ID +}); + +const authResult = await embeddedWallet.authenticate({ + strategy: "auth_endpoint", + payload, +}); + +const walletAddress = await embeddedWallet.connect({ authResult }); +``` + + + + diff --git a/docs/onboarding/21 Embedded Wallet/4 Custom Auth/2 custom-auth-server.mdx b/docs/onboarding/21 Embedded Wallet/4 Custom Auth/2 custom-auth-server.mdx index aa8764ef3f..fed4fc4af1 100644 --- a/docs/onboarding/21 Embedded Wallet/4 Custom Auth/2 custom-auth-server.mdx +++ b/docs/onboarding/21 Embedded Wallet/4 Custom Auth/2 custom-auth-server.mdx @@ -3,101 +3,138 @@ slug: /embedded-wallet/custom-auth-server title: Custom Auth Server --- +import TabItem from "@theme/TabItem"; +import Tabs from "@theme/Tabs"; + # Create a custom auth server -Learn how to integrate your auth backend with our embedded wallets solution so you can onboard your users into web3 seamlessly. +Learn how to integrate your auth backend with our embedded wallets solution so you can onboard your users into web3 seamlessly. -This guide will show you how to create your own Auth Server. By doing so, you can have full control over user authentication and data security. This allows you to ensure that your application meets specific compliance requirements while also providing a customized sign-in experience. +This guide will show you how to create your own Auth Server that is compatible with the `auth_endpoint` strategy. By doing so, you can have full control over user authentication and data security. This allows you to ensure that your application meets specific compliance requirements while also providing a customized sign-in experience. :::caution This guide is simplified for demonstration purposes and is not ready for production use. When modifying it for production, secure your endpoints and avoid hard-coding secrets or sensitive information. We recommend using environment variables and secret managers. ::: -### Setup +## 5 minute quickstart -1. Create a new directory for your project and navigate to it in your CLI +1. Navigate to Wallets > [Embedded Wallets](https://thirdweb.com/dashboard/wallets/embedded) in the thirdweb dashboard. +2. Create a thirdweb API key if you don't have one or select an existing key to use for this project. [Learn more about API keys.](https://portal.thirdweb.com/api-keys) - ```bash - mkdir jwt-auth-server - cd jwt-auth-server - ``` + ![Embedded wallet dashboard with create key displayed](../assets/ew-create-key.png) -2. Initialize a new Node.js application +3. Allowlist domain or bundle ids in Access Restrictions. +4. Navigate to the Configuration view and enable **Custom Auth Endpoint** - ```bash - npm init -y + ![Configuration view for embedded wallet](../assets/ew-custom-auth-config.png) - yarn init -y - ``` +5. Set the Auth Endpoint URL to `https://embedded-wallet.thirdweb.com/api/2023-11-30/embedded-wallet/auth/test-custom-auth-endpoint` for testing purposes. You will replace this later with your own auth server endpoint to verify the `payload`. +6. Save the configuration. +7. Copy the client ID. +8. In your preferred thirdweb client SDK, pass the payload you retrieved from logging in to the server. -3. Install the necessary packages +You can now auth into the wallet and use it to sign transactions like so (see [use your own auth for more](/embedded-wallet/custom-auth)): - ```bash - npm install express jsonwebtoken - ``` + + -### **Generate RSA Key Pair:** +In React and React Native, the `useEmbeddedWallet()` hook handles authentication and connection states. -1. To generate a private and a public key run +```typescript +import { useEmbeddedWallet } from "@thirdweb-dev/react"; // or /react-native - ```bash - ssh-keygen -t rsa -b 2048 -m PEM -f keys/rsa.key - ``` +const embeddedWallet = useEmbeddedWallet(); -2. To create the output file run +const handlePostLogin = async () => { + await embeddedWallet.connect({ + strategy: "auth_endpoint", + // in production this would be your public identifier for the user + payload: JSON.stringify({ userId:"ANY_RANDOM_ID_HERE" }), + encryptionKey: "ANY_RANDOM_STRING_HERE" + }); +}; +``` - ```bash - openssl rsa -in keys/rsa.key -pubout -outform PEM -out keys/rsa.key.pub - ``` + + -### **Convert Public Key to JSON Web Key Set (JWKS):** +In other frameworks, use your own instance of the wallet to authenticate and connect. -1. Display the public key: +```typescript +import { EmbeddedWallet } from "@thirdweb-dev/wallets"; +import { Goerli } from "@thirdweb-dev/chains"; - ```bash - cat keys/rsa.key.pub - ``` +const embeddedWallet = new EmbeddedWallet({ + chain: Goerli, // chain to connect to + clientId: "YOUR_CLIENT_ID", // Your thirdweb client ID +}); + +const authResult = await embeddedWallet.authenticate({ + strategy: "auth_endpoint", + payload: JSON.stringify({ userId:"ANY_RANDOM_ID_HERE" }), + encryptionKey: "ANY_RANDOM_STRING_HERE"= +}); + +const walletAddress = await embeddedWallet.connect({ authResult }); +``` -2. Copy the displayed public key. -3. Convert your public key to a JWK using an online JWK Creator tool. We recommend using [JWK Creator by Russel Davies](https://github.com/russelldavies/jwk-creator). + + - 1. Paste the public key, set Key ID as `0` (arbitrary string, must match when signing JWT), and then note down the generated JWK. +A persistent, cross-platform wallet is now created for your user! - ![JWK Creator tool by Russel Davies showing key id of 0](../assets/jwk-creator-tool.png) +Of course, you would use your own auth server instead of the one we provided. The rest of this guide will show you how to create your own auth server. -4. Create a `jwks.json` in the project root and place the generated JWK in a `keys` array. +### Setup + +The following steps will show you how to create a simple auth server that can be used with the embedded wallet. + +At a high level, the auth server will: + +1. Handle login for the user into your application. +2. Have a way to get a public identifier for the user. +3. Have an endpoint to verify the public identifier and return some basic information about the user + +Steps 1 and 2 are up to you to implement. You can use any auth strategy you want. + +The endpoint in step 3 is what your register as your auth endpoint on the thirdweb dashboard. + +Here's a high level diagram: +![custom auth flow diagram](../assets/ew-custom-auth-flow.png) + +1. Create a new directory for your project and navigate to it in your CLI + + ```bash + mkdir custom-auth-server + cd custom-auth-server + ``` + +2. Initialize a new Node.js application ```bash - { - "keys": [ - { - ... JWK ... - } - ] - } + npm init -y + + yarn init -y ``` ### **Create the Server:** -1. In the `jw-auth-server` directory, create a file at the root named `server.js` and paste the following: +1. In the `custom-auth-server` directory, create a file at the root named `server.js` and paste the following: ```jsx const express = require("express"); const fs = require("fs"); - const jwt = require("jsonwebtoken"); const app = express(); const PORT = process.env.PORT || 3000; - const PRIVATE_KEY = fs.readFileSync("./keys/rsa.key", "utf8"); - const jwks = require("./jwks.json"); - const users = [ { id: 1, email: "user@example.com", password: "password123" }, ]; app.use(express.json()); + // This is what your app calls to login a user and get a public identifier for the user (otherwise known as the payload) app.post("/login", (req, res) => { const { email, password } = req.body; const user = users.find( @@ -105,24 +142,24 @@ This guide is simplified for demonstration purposes and is not ready for product ); if (!user) return res.status(401).send({ message: "Invalid credentials" }); - const payload = { - iss: "http://your-domain.com", - sub: user.id.toString(), - aud: "EpicGame", - email: user.email, - exp: Math.floor(Date.now() / 1000) + 3600, - }; - - const token = jwt.sign(payload, PRIVATE_KEY, { - algorithm: "RS256", - keyid: "0", - }); - - res.send({ token }); + res.send({ payload: user.id }); }); + // This is a sample endpoint that yuou would register on the thirdweb dashboard for us to verify the payload + app.get("/thirdweb-will-call-this", (req, res) => { + const { payload } = req.body; + if (!payload) return res.status(401).send({ message: "Invalid credentials" }); - app.get("/.well-known/jwks.json", (req, res) => { - res.json(jwks); + // you would write your own logic here to verify the payload here + const user = users.find((u) => u.id === payload); + if (!user) return res.status(401).send({ message: "Invalid credentials" }); + + // once the user is successfully verified, you can return the following field + return res.send({ + userId: user.id, + // the last two fields here are optional + email: user.email, + exp: Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 30, + }); }); app.listen(PORT, () => { @@ -130,8 +167,6 @@ This guide is simplified for demonstration purposes and is not ready for product }); ``` -2. Replace `http://your-domain.com` with the actual domain for the application. - ### **Test Locally** 1. Start the server: @@ -146,36 +181,10 @@ This guide is simplified for demonstration purposes and is not ready for product curl -X POST http://localhost:3000/login -H "Content-Type: application/json" -d '{"email": "user@example.com", "password": "password123"}' ``` -3. Test JWKS: - - ```bash - curl http://localhost:3000/.well-known/jwks.json - ``` - ### **Deploy** To deploy the server, you can use use services such as [Zeet](https://zeet.co/) or [Docker](https://www.docker.com/). -Once deployed, replace `http://localhost:3000` in the JWT payload with your actual domain - ### **Integrate Embedded Wallets** -1. Navigate to Wallets > [Embedded Wallets](https://thirdweb.com/dashboard/wallets/embedded) in the thirdweb dashboard. -2. Create a thirdweb API key if you don’t have one or select an existing key to use for this project. [Learn more about API keys.](https://portal.thirdweb.com/api-keys) - - ![Embedded wallet dashboard with create key displayed](../assets/ew-create-key.png) - -3. Allowlist domain or bundle ids in Access Restrictions. -4. Navigate to the Configuration view and enable **Custom JSON Web Token** - - ![Configuration view for embedded wallet](../assets/ew-configuration.png) - -5. Set the JWKS URI to `your-domain/.well-known/jwks.json` -6. Set the AUD to `EpicGame` or the value you set as the aud in the `server.js` file. - - ![Options for EW Configuration](../assets/ew-configuration-opt.png) - -7. Copy the client ID. -8. In your preferred thirdweb client SDK, pass the JWT you retrieved from logging in to the server. - -A persistent, cross-platform wallet is now created for your user. +Refer top the [quickstart above](#5-minute-quickstart) to integrate the embedded wallet into your application. \ No newline at end of file diff --git a/docs/onboarding/21 Embedded Wallet/4 Custom Auth/3 custom-jwt-auth-server.mdx b/docs/onboarding/21 Embedded Wallet/4 Custom Auth/3 custom-jwt-auth-server.mdx new file mode 100644 index 0000000000..06753a6b19 --- /dev/null +++ b/docs/onboarding/21 Embedded Wallet/4 Custom Auth/3 custom-jwt-auth-server.mdx @@ -0,0 +1,181 @@ +--- +slug: /embedded-wallet/custom-jwt-auth-server +title: Custom JWT Auth Server +--- + +# Create a custom JWT auth server + +Learn how to integrate your auth backend with our embedded wallets solution so you can onboard your users into web3 seamlessly. + +This guide will show you how to create your own Auth Server that is compatible with the JWT auth strategy. By doing so, you can have full control over user authentication and data security. This allows you to ensure that your application meets specific compliance requirements while also providing a customized sign-in experience. + +:::caution +This guide is simplified for demonstration purposes and is not ready for production use. When modifying it for production, secure your endpoints and avoid hard-coding secrets or sensitive information. We recommend using environment variables and secret managers. +::: + +### Setup + +1. Create a new directory for your project and navigate to it in your CLI + + ```bash + mkdir jwt-auth-server + cd jwt-auth-server + ``` + +2. Initialize a new Node.js application + + ```bash + npm init -y + + yarn init -y + ``` + +3. Install the necessary packages + + ```bash + npm install express jsonwebtoken + ``` + +### **Generate RSA Key Pair:** + +1. To generate a private and a public key run + + ```bash + ssh-keygen -t rsa -b 2048 -m PEM -f keys/rsa.key + ``` + +2. To create the output file run + + ```bash + openssl rsa -in keys/rsa.key -pubout -outform PEM -out keys/rsa.key.pub + ``` + +### **Convert Public Key to JSON Web Key Set (JWKS):** + +1. Display the public key: + + ```bash + cat keys/rsa.key.pub + ``` + +2. Copy the displayed public key. +3. Convert your public key to a JWK using an online JWK Creator tool. We recommend using [JWK Creator by Russel Davies](https://github.com/russelldavies/jwk-creator). + + 1. Paste the public key, set Key ID as `0` (arbitrary string, must match when signing JWT), and then note down the generated JWK. + + ![JWK Creator tool by Russel Davies showing key id of 0](../assets/jwk-creator-tool.png) + +4. Create a `jwks.json` in the project root and place the generated JWK in a `keys` array. + + ```bash + { + "keys": [ + { + ... JWK ... + } + ] + } + ``` + +### **Create the Server:** + +1. In the `jw-auth-server` directory, create a file at the root named `server.js` and paste the following: + + ```jsx + const express = require("express"); + const fs = require("fs"); + const jwt = require("jsonwebtoken"); + + const app = express(); + const PORT = process.env.PORT || 3000; + + const PRIVATE_KEY = fs.readFileSync("./keys/rsa.key", "utf8"); + const jwks = require("./jwks.json"); + + const users = [ + { id: 1, email: "user@example.com", password: "password123" }, + ]; + + app.use(express.json()); + + app.post("/login", (req, res) => { + const { email, password } = req.body; + const user = users.find( + (u) => u.email === email && u.password === password, + ); + if (!user) return res.status(401).send({ message: "Invalid credentials" }); + + const payload = { + iss: "http://your-domain.com", + sub: user.id.toString(), + aud: "EpicGame", + email: user.email, + exp: Math.floor(Date.now() / 1000) + 3600, + }; + + const token = jwt.sign(payload, PRIVATE_KEY, { + algorithm: "RS256", + keyid: "0", + }); + + res.send({ token }); + }); + + app.get("/.well-known/jwks.json", (req, res) => { + res.json(jwks); + }); + + app.listen(PORT, () => { + console.log(`Server started on port ${PORT}`); + }); + ``` + +2. Replace `http://your-domain.com` with the actual domain for the application. + +### **Test Locally** + +1. Start the server: + + ```bash + node server.js + ``` + +2. Test login: + + ```bash + curl -X POST http://localhost:3000/login -H "Content-Type: application/json" -d '{"email": "user@example.com", "password": "password123"}' + ``` + +3. Test JWKS: + + ```bash + curl http://localhost:3000/.well-known/jwks.json + ``` + +### **Deploy** + +To deploy the server, you can use use services such as [Zeet](https://zeet.co/) or [Docker](https://www.docker.com/). + +Once deployed, replace `http://localhost:3000` in the JWT payload with your actual domain + +### **Integrate Embedded Wallets** + +1. Navigate to Wallets > [Embedded Wallets](https://thirdweb.com/dashboard/wallets/embedded) in the thirdweb dashboard. +2. Create a thirdweb API key if you don’t have one or select an existing key to use for this project. [Learn more about API keys.](https://portal.thirdweb.com/api-keys) + + ![Embedded wallet dashboard with create key displayed](../assets/ew-create-key.png) + +3. Allowlist domain or bundle ids in Access Restrictions. +4. Navigate to the Configuration view and enable **Custom JSON Web Token** + + ![Configuration view for embedded wallet](../assets/ew-configuration.png) + +5. Set the JWKS URI to `your-domain/.well-known/jwks.json` +6. Set the AUD to `EpicGame` or the value you set as the aud in the `server.js` file. + + ![Options for EW Configuration](../assets/ew-configuration-opt.png) + +7. Copy the client ID. +8. In your preferred thirdweb client SDK, pass the JWT you retrieved from logging in to the server. + +A persistent, cross-platform wallet is now created for your user. diff --git a/docs/onboarding/21 Embedded Wallet/4 Custom Auth/3 Integrate Firebase Auth.mdx b/docs/onboarding/21 Embedded Wallet/4 Custom Auth/4 Integrate Firebase Auth.mdx similarity index 100% rename from docs/onboarding/21 Embedded Wallet/4 Custom Auth/3 Integrate Firebase Auth.mdx rename to docs/onboarding/21 Embedded Wallet/4 Custom Auth/4 Integrate Firebase Auth.mdx diff --git a/docs/onboarding/21 Embedded Wallet/5 FAQ.mdx b/docs/onboarding/21 Embedded Wallet/5 FAQ.mdx index e41b58d62c..53689f6e9c 100644 --- a/docs/onboarding/21 Embedded Wallet/5 FAQ.mdx +++ b/docs/onboarding/21 Embedded Wallet/5 FAQ.mdx @@ -76,13 +76,9 @@ Soon, developers will be able to toggle on the option for users to add a backup ### How is the private key managed? -The private key is sharded into three pieces. The first piece is stored on the customer’s device, the second piece is stored in Amazon’s KMS and encrypted by the customer’s email/social auth, and the third piece is stored on Paper. At anytime, there needs to be 2/3 pieces for the private key to be reconstructed. - -thirdweb is non-custodial because we only have access to the third piece stored on thirdweb’s servers, and we cannot access the other two shards without the user logging into your application. - -Our security architecture has been audited by HackerOne and we have an ongoing bounty program to ensure vulnerabilities are being covered. +You can learn more about the architecture of how embedded wallets are created and stored [here](https://portal.thirdweb.com/embedded-wallet/how-it-works) ### What happens if thirdweb or my database gets breached? -Using Shamir Secret Sharing technology, your customers’ assets are safe even in the event that thirdweb or you are compromised. This is because the attacker will only be able to access 1 of the 3 shards, and that is not enough to reconstruct the private key. +Using Shamir Secret Sharing technology, your customers’ assets are safe even if thirdweb or you are compromised. This is because the attacker will only be able to access 1 of the 3 shards, and that is not enough to reconstruct the private key. diff --git a/docs/onboarding/21 Embedded Wallet/assets/customauth.png b/docs/onboarding/21 Embedded Wallet/assets/customauth.png new file mode 100644 index 0000000000..d45015df4c Binary files /dev/null and b/docs/onboarding/21 Embedded Wallet/assets/customauth.png differ diff --git a/docs/onboarding/21 Embedded Wallet/assets/customauthdb.png b/docs/onboarding/21 Embedded Wallet/assets/customauthdb.png new file mode 100644 index 0000000000..7b3682e191 Binary files /dev/null and b/docs/onboarding/21 Embedded Wallet/assets/customauthdb.png differ diff --git a/docs/onboarding/21 Embedded Wallet/assets/customauthdb2.png b/docs/onboarding/21 Embedded Wallet/assets/customauthdb2.png new file mode 100644 index 0000000000..f5ca42158b Binary files /dev/null and b/docs/onboarding/21 Embedded Wallet/assets/customauthdb2.png differ diff --git a/docs/onboarding/21 Embedded Wallet/assets/ew-custom-auth-config.png b/docs/onboarding/21 Embedded Wallet/assets/ew-custom-auth-config.png new file mode 100644 index 0000000000..771d19c1f1 Binary files /dev/null and b/docs/onboarding/21 Embedded Wallet/assets/ew-custom-auth-config.png differ diff --git a/docs/onboarding/21 Embedded Wallet/assets/ew-custom-auth-flow.png b/docs/onboarding/21 Embedded Wallet/assets/ew-custom-auth-flow.png new file mode 100644 index 0000000000..7870ef8030 Binary files /dev/null and b/docs/onboarding/21 Embedded Wallet/assets/ew-custom-auth-flow.png differ diff --git a/docs/onboarding/22 Gaming/0 Overview.mdx b/docs/onboarding/22 Gaming/0 Overview.mdx new file mode 100644 index 0000000000..e2787c6001 --- /dev/null +++ b/docs/onboarding/22 Gaming/0 Overview.mdx @@ -0,0 +1,48 @@ +--- +slug: /gaming +title: Overview +hide_title: true +--- + +import QuickstartCard from "@components/QuickstartCard"; + +# Overview + +thirdweb has tools that let you easily build web3 games for any platform - Browser, Native Desktop, Mobile, Console, and VR. + +![thirdweb](./assets/preview.png) + +## Features + +- **Seamless onboarding**: Allow users to login with their wallets, email, social logins, usernames, passkeys, or build completely invisible login experiences. +- **Cross-platform support**. Build games on Unity, WebGL, or Unreal Engine. +- **Account abstraction support**. Easily integrate ERC-4337 compatible smart accounts into your games, enabling seamless user experiences and interoperability +- **Support for any EVM network.** thirdweb’s tools with any EVM-compatible network, allowing you to build games on the latest L2 chains +- **Customizable**. Our products let you control all aspects of the user experience. For example, you can our tools to bring your own authentication system and spin up in-game embedded wallets for users. +- **All-inclusive**. Our solutions come with prefabs, RPCs, Account abstraction infra (bundler and paymaster), fiat ramps, and storage out of the box. You get everything you need to build great games + +## Check Out Our Demos + +- [Speed Racer](https://github.com/thirdweb-example/unreal_demo) +- [Cat Attack](https://catattack.thirdweb.com/) +- [Web3 Warriors](https://web3warriors.thirdweb.com/) + +### Full reference + +
+
+ +
+
+ +
+
+ diff --git a/docs/onboarding/22 Gaming/1 Unreal Engine.mdx b/docs/onboarding/22 Gaming/1 Unreal Engine.mdx new file mode 100644 index 0000000000..d03bc547a4 --- /dev/null +++ b/docs/onboarding/22 Gaming/1 Unreal Engine.mdx @@ -0,0 +1,74 @@ +--- +slug: /gaming/unreal-engine +title: Unreal Engine +hide_title: true +--- +import QuickstartCard from "@components/QuickstartCard"; + +# Quickstart + +In this guide, we’ll build a demo game called Speed Racer using a template. Once setup, users will be able to connect their wallet and perform on-chain actions without signing transactions or paying gas. + +Try it out by downloading the game using the links below + + + + + + + +## Architecture + +We recommend the following architecture to build production-grade games on Unreal Engine + +![Unreal Engine](./assets/unreal-architecture.png) + +There are 2 thirdweb tools being used here + +- [Connect](https://portal.thirdweb.com/connect): This is used to link user wallets to your game. This step needs to be done in a browser environment. +- [Engine](https://portal.thirdweb.com/engine): Once you have a wallet linked to a game user, you can use engine to perform all blockchain interactions. + + + +## 1. Set up Engine + +This example makes use of thirdweb Engine, a backend HTTP server that calls smart contracts using your managed backend wallets. + +You’ll need an instance running for your server to interact with the blockchain. [Learn how to set up your own Engine instance](/engine). + +## 2. Set up website and backend + +We’ll need a website for users to sign up and link their wallets, and a backend to handle wallet authentication, user registration and interaction with engine. + +Here’s a step by step guide to deploy your client/server: + +To deploy a client/server: + +1. Clone https://github.com/thirdweb-example/engine-express/ +2. Install client dependencies `cd client` and `yarn` +3. Install server dependencies `cd server` and `yarn` +4. Navigate to the root folder and run `yarn` +5. Replace the `.env.example` in the client/server folder with your own [api key](http://thirdweb.com/create-api-key) values and engine url. Ensure your api key can be used to authenticate with your deployed engine +6. We’ll be claiming ERC20’s from Unreal in this demo. Navigate to the [engineController.ts](https://github.com/thirdweb-example/engine-express/blob/main/server/src/controllers/engineController.ts) file, and set your backend engine wallet as well as your [Token Drop](https://thirdweb.com/thirdweb.eth/DropERC20) contract details - make sure you have claim conditions set up for your drop +7. You can now run the client and server in two terminals using `yarn client` and `yarn server` +8. By default, the client runs on [localhost:3000](http://localhost:3000) and the server on [localhost:8000](http://localhost:8000) +9. Go ahead and create a user on your website, and link a wallet +10. You are now ready to head into Unreal! + +## 3. Build your Unreal Engine game + +To simplify this part, we created a template for you with a simple script to interact with your server as per the architecture illustrated above. A level blueprint instantiates the UI, which has its own blueprint to interact with your server. + +Clone https://github.com/thirdweb-example/unreal_demo and navigate to `_Thirdweb/Scenes/Scene_Game` to start the level. + +You will be able to log in and see the output as the game polls and updates your balance whenever you collect an item while driving. + +All thirdweb related assets are under the `_Thirdweb` folder in your Content Browser. \ No newline at end of file diff --git a/docs/onboarding/22 Gaming/2 Unity.mdx b/docs/onboarding/22 Gaming/2 Unity.mdx new file mode 100644 index 0000000000..da821873e4 --- /dev/null +++ b/docs/onboarding/22 Gaming/2 Unity.mdx @@ -0,0 +1,5 @@ +--- +slug: /unity +title: Unity +hide_title: true +--- \ No newline at end of file diff --git a/docs/onboarding/22 Gaming/assets/preview.png b/docs/onboarding/22 Gaming/assets/preview.png new file mode 100644 index 0000000000..88538ee0eb Binary files /dev/null and b/docs/onboarding/22 Gaming/assets/preview.png differ diff --git a/docs/onboarding/22 Gaming/assets/unreal-architecture.png b/docs/onboarding/22 Gaming/assets/unreal-architecture.png new file mode 100644 index 0000000000..4849a45d83 Binary files /dev/null and b/docs/onboarding/22 Gaming/assets/unreal-architecture.png differ diff --git a/docs/onboarding/22 NFT Checkouts/0 Overview.mdx b/docs/onboarding/22 NFT Checkouts/0 Overview.mdx new file mode 100644 index 0000000000..ae480a3648 --- /dev/null +++ b/docs/onboarding/22 NFT Checkouts/0 Overview.mdx @@ -0,0 +1,78 @@ +--- +slug: /checkouts +title: Overview +--- + +Checkouts delivers the easiest NFT payments experience for you and your buyers. Sell NFTs on any one of our supported EVM chains and allow your users to pay with +any supported payment option. You and your buyers can expect instant payouts and instant NFT processing - all done through your smart contract. + +![Checkouts overview](./assets/checkouts-overview.png) + +### Payment options for buyers + +| Payment Type | Supported Options | +| :----------- | :------------------------------------------ | +| Fiat | Credit & Debit Cards, Apple Pay, Google Pay | +| Crypto | ETH | + +Card and other fiat payments are accepted from all 50 US states and US-sanctioned countries. + +### Supported chains and currencies + +| Blockchain (Mainnet) | Supported Currencies | +| :------------------- | :------------------------------ | +| Arbitrum Nova | ETH | +| Arbitrum One | ETH, USDC.e\* | +| Avalanche | AVAX, USDC.e\* | +| Ethereum | ETH, USDC\* | +| Optimism | ETH, USDC\* | +| Polygon | MATIC, USDC\*, USDC.e\*, WETH\* | +| Zora | ETH | + +### + +| Blockchain (Testnet) | Supported Currencies | +| :------------------- | :------------------- | +| Arbitrum Sepolia | ETH | +| Avalanche Fuji | AVAX | +| Base Goerli | ETH | +| Goerli | ETH, USDC | +| Mumbai | MATIC, USDC | +| Optimism Goerli | ETH | +| Sepolia | ETH | +| Zora Testnet | ETH | + +\* - ERC-20 tokens are available for pro or enterprise customers only. + +### Fraud prevention & chargeback protection + +thirdweb deters bots and fraudulent activity by using multiple data points about the buyer's device, network, behavior, payment, and more. Only high-risk buyers will need to verify their identity with an ID and selfie. + +We protect you from these concerns by offering **full chargeback protection.** + +### Reliable NFT Delivery + +thirdweb manages a fleet of funded crypto wallets to handle blockchain transactions at scale. Queues are automated to monitor for stuck transactions, failed on-chain calls, and low funds. + +### Conversion-optimized UX + +Our checkout flow accounts for many cases to provide buyers a seamless experience with minimal steps: + +- Does the buyer need a crypto wallet or do they already have one? +- Do they exhibit bot-like or suspicious behavior? +- Do they have enough tokens to mint directly from their wallet? +- Is your user trying to purchase more than one NFT? +- Is your user allowlisted to purchase? +- Are there enough NFTs remaining to purchase? + +### Webhooks & custom metadata + +Configure webhooks to notify your backend when payments and transfers are completed. Webhooks allow you to unlock NFT-gated utilities, send customized emails, and more. + +Provide custom metadata to tag purchases with added information. + +### Analytics + +View purchases to your checkouts including breakdowns by payment method and wallet. Export your data with additional details including buyer location, transaction hash, conversion rate, and custom metadata. + +Get visibility into failed transactions to speed up debugging and resolve support questions. diff --git a/docs/onboarding/22 NFT Checkouts/1 Getting Started.mdx b/docs/onboarding/22 NFT Checkouts/1 Getting Started.mdx new file mode 100644 index 0000000000..94768c28a0 --- /dev/null +++ b/docs/onboarding/22 NFT Checkouts/1 Getting Started.mdx @@ -0,0 +1,26 @@ +--- +slug: /checkouts/getting-started +title: Getting Started +--- + +Get an end-to-end NFT checkout experience up and running in a few steps! + +## Prerequisite: Deploy your smart contract + +You can create or deploy a smart contract on thirdweb using [Deploy](https://thirdweb.com/dashboard/contracts/deploy). + +## 1. Enable your contract for Payments + +Visit the Payments dashboard or use the API to enable your contract for Payments. Start with the first step of our integration guide, [Enable Contract for Payments](enable-contract). + +## 2. Create your Checkout Link + +Generate a complete, pre-built checkout experience by [creating a Checkout Link](checkout-link). + +Want a more branded checkout embedded in your app? Visit the guide on [Embedded Checkout Elements](elements) instead. + +## 3. Launch! + +Make sure to review the [Go Live Checklist](go-live-checklist) prior to launch to ensure your setup is launch-ready. + +**Important note: you must provide personal documents (KYC) and business documents (KYB) at least 48 hours prior to launching on mainnet.** diff --git a/docs/onboarding/22 NFT Checkouts/1a Integration/0 Register Contract.mdx b/docs/onboarding/22 NFT Checkouts/1a Integration/0 Register Contract.mdx new file mode 100644 index 0000000000..a8b62b6916 --- /dev/null +++ b/docs/onboarding/22 NFT Checkouts/1a Integration/0 Register Contract.mdx @@ -0,0 +1,27 @@ +--- +slug: /checkouts/enable-contract +title: 1. Enable Contract for Payments +--- + +Enabling your contract for Payments is required to unlock Checkouts functionality. This can be done on the thirdweb dashboard or with the Payments API. + +## Prerequisites + +Before you start, ensure your contract is set up properly for Checkouts. + +- Using a thirdweb contract? [Ensure your contract is configured properly](thirdweb-contracts). +- Using your own NFT contract? [Ensure your custom contract is compatible](custom-contracts). +- Selling a token listed on a secondary marketplace? [Visit the marketplaces guide](marketplaces). + +## Enable a contract for Payments + +### Dashboard + +1. Navigate into your contract from the [Contracts > Deploy dashboard page](https://thirdweb.com/dashboard/contracts/deploy). +2. Navigate to the "Payments" page from the sidebar. +3. Click the "Enable Payments" button + ![Enable payments for contract](./assets/enable-contract/enable-payments-for-contract.jpg) + +### API + +[See the API Reference for enabling contracts for Payments](https://redocly.github.io/redoc/?url=https://payments.thirdweb.com/api/doc#tag/Contracts/paths/~1api~12022-08-12~1register-contract/post) diff --git a/docs/onboarding/22 NFT Checkouts/1a Integration/1 Shareable Checkout Link.mdx b/docs/onboarding/22 NFT Checkouts/1a Integration/1 Shareable Checkout Link.mdx new file mode 100644 index 0000000000..fa0cc65e58 --- /dev/null +++ b/docs/onboarding/22 NFT Checkouts/1a Integration/1 Shareable Checkout Link.mdx @@ -0,0 +1,34 @@ +--- +slug: /checkouts/checkout-link +title: 2. Create a Checkout Link +--- + +Checkout Links are public, reusable URLs that allow buyers to complete a purchase with thirdweb's prebuilt checkout experience. + +## Prerequisites + +Make sure you've [enabled your contract for Payments](enable-contract) first. + +## Use cases + +- Integrate a functional, prebuilt checkout experience quickly. +- Open your NFT's public sale to all buyers. +- Charge your buyers the same price. +- Request your buyer's details (email, wallet address) during checkout. + +## Create a checkout link + +### Dashboard + +1. Navigate into your contract from the [Contracts > Deploy dashboard page](https://thirdweb.com/dashboard/contracts/deploy). +2. Navigate to the "Payments" page from the sidebar. +3. Click the "Create New Checkout" button + ![Create a new checkout link from the dashboard](./assets/checkout-link/create-new-checkout-link.jpg) + +### API + +[See the API Reference for creating a checkout link](https://redocly.github.io/redoc/?url=https://payments.thirdweb.com/api/doc#tag/Checkout-Links/paths/~1api~12022-08-12~1shareable-checkout-link/post) + +## Branding + +Creating a Checkout Link is the fastest way to get started with thirdweb Checkouts. If you are looking for complete customization over branding and UX, check out the guide on [Embedded Elements](elements). diff --git a/docs/onboarding/22 NFT Checkouts/1a Integration/4 Go Live Checklist.mdx b/docs/onboarding/22 NFT Checkouts/1a Integration/4 Go Live Checklist.mdx new file mode 100644 index 0000000000..558721c993 --- /dev/null +++ b/docs/onboarding/22 NFT Checkouts/1a Integration/4 Go Live Checklist.mdx @@ -0,0 +1,44 @@ +--- +slug: /checkouts/go-live-checklist +title: 3. Go Live Checklist +--- + +Before you go live on mainnet, be sure to review this checklist to ensure your production checkout launch goes smoothly. + +## 3.1 Test your expected flow works on testnet + +Testing on mainnet is costly! Please test your contract and checkout implementation on testnet. + +- For Polygon projects, please test on Mumbai. +- For Ethereum projects, please test on Sepolia. +- Visit the [overview page](/checkouts) to see a list of supported testnets. + +You should be able to test all critical aspects of your smart contract on testnet, including allowlists, signature-based mints, your custom mint method, etc. + +## 3.2 Provide personal and business information + +In order to accept fiat payments (credit cards, debit cards) on mainnet chains, we are required by law to verify your personal (KYC) and business (KYB) information. This information is collected purely for compliance purposes and is not used or shared for any other reason. **You must provide this information at least 48 hours prior to launch.** + +## 3.3 Set up production webhook endpoints + +Testnet and mainnet transactions call a different set of webhook endpoints. Make sure to add your production endpoint(s) in the Webhooks section of the dashboard before going live. + +## 3.4 Ensure your NFT is priced under $2,000 USD + +We currently limit checkouts to be priced under $2,000 USD by default. We may be able to change this at our discretion based on your checkout's risk profile. + +To request a higher price limit, please contact support@thirdweb.com. + +## 3.5 Inform us of high volume launches + +If you are expecting very high sales volume, please reach out in Discord in advance so we can make sure the engineering team is aware and ready to support your launch. + +## 3.6 Change ERC-20 addresses (if applicable) + +Remember that ERC-20 token addresses differ between testnet and mainnet. Make sure to update your contract to point at the mainnet address for the requested token. + +## 3.7 Verify your collection on OpenSea + +If your contract is on an L2 chain like Polygon, OpenSea may hide your collection by default from buyers' profiles. To avoid this, please contact OpenSea to verify your collection before your launch. + +Buyers are still able to complete their purchase regardless of OpenSea verification, but may need to manually unhide their purchased token from their OpenSea profile if it is hidden by default. diff --git a/docs/onboarding/22 NFT Checkouts/1a Integration/_category_.json b/docs/onboarding/22 NFT Checkouts/1a Integration/_category_.json new file mode 100644 index 0000000000..ca6faf571f --- /dev/null +++ b/docs/onboarding/22 NFT Checkouts/1a Integration/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "Integration", + "collapsible": true, + "collapsed": false +} diff --git a/docs/onboarding/22 NFT Checkouts/1a Integration/assets/checkout-link/create-new-checkout-link.jpg b/docs/onboarding/22 NFT Checkouts/1a Integration/assets/checkout-link/create-new-checkout-link.jpg new file mode 100644 index 0000000000..cfe677ec92 Binary files /dev/null and b/docs/onboarding/22 NFT Checkouts/1a Integration/assets/checkout-link/create-new-checkout-link.jpg differ diff --git a/docs/onboarding/22 NFT Checkouts/1a Integration/assets/enable-contract/enable-payments-for-contract.jpg b/docs/onboarding/22 NFT Checkouts/1a Integration/assets/enable-contract/enable-payments-for-contract.jpg new file mode 100644 index 0000000000..647b652ff3 Binary files /dev/null and b/docs/onboarding/22 NFT Checkouts/1a Integration/assets/enable-contract/enable-payments-for-contract.jpg differ diff --git a/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/0 Embedded Elements/0 Overview.mdx b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/0 Embedded Elements/0 Overview.mdx new file mode 100644 index 0000000000..50cd8e168d --- /dev/null +++ b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/0 Embedded Elements/0 Overview.mdx @@ -0,0 +1,27 @@ +--- +slug: /checkouts/elements +title: Overview +--- + +Checkout Embedded Elements are modular components that can be embedded directly in your app. This allows you to fully customize the look and feel of the checkout experience within your application. + +## Prerequisites + +- Make sure you've [enabled your contract for Payments](enable-contract) +- You have the user's wallet address + - If you do not already a wallet set up for your users, use [Connect](/connect) to create a wallet first. +- Your Content Security Policy is set allowing thirdweb's domain. + - Make sure you enable the [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) directives on your server, please allow the following directives: + - `connect-src https://payments.thirdweb.com;` + - `frame-src https://payments.thirdweb.com;` + - `script-src https://payments.thirdweb.com;` + +## Integration + +### Accepting fiat payment options (credit/debit card, Apple Pay, Google Pay) + +Embed [CheckoutWithCard](/checkouts/checkout-with-card) in your app. + +### Accepting crypto payment options (ETH) + +Embed [CheckoutWithEth](/checkouts/checkout-with-eth) in your app. diff --git a/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/0 Embedded Elements/1 CheckoutWithCard.mdx b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/0 Embedded Elements/1 CheckoutWithCard.mdx new file mode 100644 index 0000000000..d5194dbae5 --- /dev/null +++ b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/0 Embedded Elements/1 CheckoutWithCard.mdx @@ -0,0 +1,168 @@ +--- +slug: /checkouts/checkout-with-card +title: CheckoutWithCard +--- + +The **CheckoutWithCard** element embeds a form on your app that accepts credit/debit card, Apple Pay, and Google Pay. + +This component also handles: + +- Apple Pay and Google Pay +- Bot and anti-fraud detection +- 3D Secure (if necessary) +- Buyer KYC (if necessary) + +## Demo + +> 👍 Try a demo! + +![CheckoutWithCard component demo](../../assets/checkout-with-card-demo.png) + +## React Integration + +1. Install the React SDK ([Install guide](/react/getting-started)): + ```Text npm + npm install @thirdweb-dev/react + ``` + ```Text yarn + yarn add @thirdweb-dev/react + ``` +2. On your frontend, render the `CheckoutWithCard` component with your configs. + +### Example code + +```typescript +import { CheckoutWithCard } from "@thirdweb-dev/react"; + + { + console.log("Payment successful:", result); + }} +/>; +``` + +### `CheckoutWithCard` props + +| Name | Type | Description | +| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| clientId **\*** | string | thirdweb client ID (Obtained from an API key which you can generate on the [Dashboard](https://thirdweb.com/dashboard)) | +| configs **\*** | object | A list of configs to create your card checkout element. Fields are the same as the ones found in the [Create Checkout Elements Client Secret](https://docs.withpaper.com/reference/create-checkout-elements-client-secret) API. | +| onPaymentSuccess **\*** | ({ transactionId: string; }) => void | This method is called after the payment has been submitted for processing. This payment may still be rejected by the cardholder's bank. | +| onError | (PaperSDKError) => void | This method is called when an error is encountered. | +| onPriceUpdate | ({ quantity: number; unitPrice: PriceDetail; networkFees: PriceDetail; serviceFees: PriceDetail; total: PriceDetail; }) => void | This method is called when the price is updated or loaded for the first time. This summary is helpful to show a granular price breakdown. Where PriceDetail is { display: string; valueInSubunits: number; currency: string; } | +| locale | enum Valid values: `en`, `fr`, `es`, `it`, `de`, `ja`, `ko`, `zh` | The language to show text in. Defaults to `en`. | +| options | object | Customize component styling. See [Customization](#customization). | + +## Javascript Integration + +1. Install the Javascript SDK with your preferred package manager. + - `npm install @thirdweb-dev/payments` + - `yarn add @thirdweb-dev/payments` +2. Call `createCheckoutWithCardElement` to insert the iframe on your page. Pass the `configs` to this component. + 1. If you don't provide `elementOrId`, this call returns an iframe element for you to insert into your page. + +### Example code + +```typescript +import { createCheckoutWithCardElement } from "@thirdweb-dev/payments"; + +// Assume a container exists: +// +//
+// +createCheckoutWithCardElement({ + clientId: "YOUR_CLIENT_ID", + configs: { + contractId: "YOUR_CONTRACT_ID", + walletAddress: "0x...", + } + elementOrId: "paper-checkout-container", + appName: "My Web3 App", + options, + onError(error) { + console.error("Payment error:", error); + }, + onPaymentSuccess({ id }) { + console.log("Payment successful."); + }, +}); + +// Alternatively, insert the iframe programmatically: +// +// const iframe = createCheckoutWithCardElement(...) +// document.getElementById('paper-checkout-container').appendChild(iframe); + +``` + +### Props + +| Name | Type | Description | +| ---------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| clientId **\*** | string | thirdweb client ID (Obtained from an API key which you can generate on the [Dashboard](https://thirdweb.com/dashboard)) | +| configs **\*** | object | A list of configs to create your card checkout element. Fields are the same as the ones found in the [Create Checkout Elements Client Secret](https://docs.withpaper.com/reference/create-checkout-elements-client-secret) API. | +| elementOrId | string \| HTMLElement | If provided, the iframe will be appended to this element. You can pass in the DOM element or the `id` associated with the element. A minimum width of 380px is recommended. | +| appName | string | If provided, the wallet card will display your `appName`. | +| locale | enum (Valid values: `en`, `fr`, `es`, `it`, `de`, `ja`, `ko`, `zh`) | The language to show text in. Defaults to `en`. | +| options | object | Customize component styling. See [Customization](#customization). | +| onLoad | () => void | This method is called when the iframe loads. | +| onError | (error: PaperSDKError) => void | This method is called when an error occurs during the payment process. | +| onPaymentSuccess | (props: { transactionId: string }) => void | This method is called when the buyer has successfully paid. | +| onReview | (props: { cardholderName: string, id: string }) => void | This method is called after the user enters their card details. | + +## Customization + +The optional `options` argument allows you to customize the component's styling. All customization fields are optional. + +#### `options` object + +| Name | Type | Description | +| -------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------- | +| colorPrimary | string (In hex, e.g. #cf3781) | The primary brand color for buttons and links. | +| colorBackground | string (In hex, e.g. #cf3781) | The background color of the page. | +| colorText | string (In hex, e.g. #cf3781) | The color for text on the page and UI elements. | +| borderRadius | number (In px, e.g. 0 for sharp corners, 12 for rounded corners, 24 for pill shape) | The roundness of buttons and input elements. | +| inputBorderColor | string (In hex, e.g. #cf3781) | The border color of the input field. | +| inputBackgroundColor | string (In hex, e.g. #cf3781) | The background color of the input field. | + +#### Examples + +Here's an example component with the following props: + +```javascript +{ + colorBackground: '#fefae0', + colorPrimary: '#606c38', + colorText: '#283618', + borderRadius: 6, + inputBackgroundColor: '#faedcd', + inputBorderColor: '#d4a373', +} +``` + +![CheckoutWithCard form customization demo](../../assets/checkout-with-card-customization-demo.png) + +## Important Notes + +### How do I prevent the 3D Secure or KYC modal from popping up behind my other frontend components? + +The SDK uses a z-index of `10000` for these modals. If they are appearing behind other components, please lower your other components' z-index values. diff --git a/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/0 Embedded Elements/2 CheckoutWithEth.mdx b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/0 Embedded Elements/2 CheckoutWithEth.mdx new file mode 100644 index 0000000000..da8d9f01d1 --- /dev/null +++ b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/0 Embedded Elements/2 CheckoutWithEth.mdx @@ -0,0 +1,138 @@ +--- +slug: /checkouts/checkout-with-eth +title: CheckoutWithEth +--- + +**CheckoutWithEth** embeds a component on your page that accepts ETH payments on Ethereum. + +This component also handles: + +- Connecting the payment wallet +- Prompting the payment wallet to switch chain, if necessary +- Informing the payment wallet they have insufficient funds + +## Example + +> 👍 Try a demo! + +The user is prompted to connect their payment wallet. This step is skipped if they've already connected their wallet to your app since this connection is established on your domain. + +![](../../assets/checkout-with-eth-demo.png) + +The user is then prompted to review their purchase, accept the Terms of Service, and complete their payment. + +![](../../assets/checkout-with-eth-demo-2.png) + +## React Integration + +1. Install the React SDK with your preferred package manager. + - `npm install @paperxyz/react-client-sdk-checkout-with-eth` + - `yarn add @paperxyz/react-client-sdk-checkout-with-eth` +2. Copy your API key from the [Developer Dashboard: Developers](https://withpaper.com/dashboard/developers) page. +3. When a buyer wants to make a purchase, create a `configs` object (see props table below). You will provide some buyer information and configure behavior via this API. +4. Instantiate a `PaperSDKProvider` provider to store Paper-specific properties. +5. Within the provider, instantiate the `CheckoutWithEth` component to render this component. Pass the SDK Client Secret to this component. + +### Example code + +```typescript +import { CheckoutWithEth } from "@paperxyz/react-client-sdk-checkout-with-eth"; + + { + console.log("Payment successful."); + }} +/>; +``` + +### `CheckoutWithEth` props + +| Name | Type | Description | +| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| configs **\*** | string | A list of configs to create your eth checkout element. Fields are the same as the ones found in the [Create Checkout Elements Client Secret](ref:create-checkout-elements-client-secret) API. | +| onPaymentSuccess **\*** | `(props : { onChainTxReceipt: TransactionReceipt; transactionId: string; }) => void` | This method is called after the payment has succeeded on-chain. | +| onPriceUpdate | `({ cryptoToFiatConversionRate: number; quantity: number; unitPrice: PriceDetail; networkFees: PriceDetail; serviceFees: PriceDetail; total: PriceDetail; }) => void` | This method is called when the price is updated or loaded for the first time. This summary is helpful to show a granular price breakdown. \* The `valueInSubunits` type here differs from the subunits for CheckoutWithCard (which is a number) | +| locale | enum (Valid values: `en`, `fr`, `es`, `it`, `de`, `ja`, `ko`, `zh`) | The language to show text in. Defaults to `en`. | +| receivingWalletType | enum (Valid values: `WalletConnect`, `MetaMask`, `Coinbase Wallet`, `Phantom`, `Preset`) | Defaults to `Preset`. The wallet type of the user wallet receiving the NFT to render the appropriate wallet icon in the component. | +| suppressErrorToast | boolean | Defaults to `false`. If `false`, there will be a toast (within the iFrame) that pops up informing the user of what went wrong. This can include canceling transactions, pending transactions, etc. | +| showConnectWalletOptions | boolean | Defaults to `true`. If `true`, a connect wallet screen will be displayed allowing users to connect their wallet. | +| payingWalletSigner | [`ethers.Signer`](https://docs.ethers.io/v5/api/signer/) | If provided, the component will request funds from this signer. | +| onWalletConnected | `(props: { userAddress: string, chainId: number }) => void` | This method is called when a payment wallet is connected. | +| onPageChange | `(currentPage: CheckoutWithEthPage) => void` | This method is called when the buyer transitions between pages. | +| onError | `(error: PaperSDKError) => void` | This method is called when an error is encountered. | +| setUpUserPayingWalletSigner | `(args: { chainId: number }) => void` | This method is called before the `payingWalletSigner` is asked to pay with the `chainId` that the `payingWalletSigner` is supposed to be on. | + +## Javascript Integration + +1. Install the Javascript SDK with your preferred package manager. + - `npm install @paperxyz/js-client-sdk` + - `yarn add @paperxyz/js-client-sdk` +2. Copy your API key from the [Developer Dashboard: Developers](https://withpaper.com/dashboard/developers) page. +3. When a buyer wants to make a purchase, create a `configs` object (see props table below). You will provide some buyer information and configure behavior via this API. +4. Call `createCheckoutWithEthElement` to insert the iframe on your page. Pass the SDK Client Secret to this component. + 1. If you don't provide `elementOrId`, this call returns an iframe element for you to insert into your page. + +### Code example + +```javascript +import type { createCheckoutWithEthElement } from "@paperxyz/js-client-sdk-checkout-with-eth"; + +// Assume a container exists: +// +//
+// +const iframe = await createCheckoutWithEthElement({ + configs: { + contractId: 'CONTRACT_ID', + walletAddress: "0x...", + } + elementOrId: "paper-checkout-container", + payingWalletSigner, + setUpUserPayingWalletSigner, + receivingWalletType, + onError(error) { + console.log("Payment error:", error); + }, + onSuccess({ transactionId }) { + console.log("Payment successful."); + }, +}); + +// Alternatively, insert the iframe programmatically: +// +// const iframe = createCheckoutWithEthElement(...) +// document.getElementById('paper-checkout-container').appendChild(iframe); +``` + +### Props + +| Name | Type | Description | +| --------------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| configs **\*** | string | A list of configs to create your eth checkout element. Fields are the same as the ones found in the [Create Checkout Elements Client Secret](ref:create-checkout-elements-client-secret) API. | +| payingWalletSigner **\*** | [ethers.Signer](https://docs.ethers.io/v5/api/signer/) | The connected wallet who is going to be paying the `ETH` required for the checkout | +| locale | enum (Valid values: `en`, `fr`, `es`, `it`, `de`, `ja`, `ko`, `zh`) | The language to show text in. Defaults to `en`. | +| options | object | Customize component styling. See [Customization](#customzation). | +| setUpUserPayingWalletSigner | `(args: { chainId: number; }) => void \| Promise` | If provided, the callback will be called before asking buyers to pay with the `chainId` that they are expected to be on. Developers must make sure that users are on the right chain (Goerli for testnets, Eth for mainnets) or risk buyers sending funds into the void. | +| receivingWalletType | enum (Valid values: `WalletConnect`, `MetaMask`, `Coinbase Wallet`, `Phantom`, `Preset`) | Defaults to `Preset`. The wallet type of the user wallet receiving the NFT to render the appropriate wallet icon in the component. | +| onError | `(error: PaperSDKError) => void` | This method is called when anything wrong happens during the checkout process. | +| onPaymentSuccess | `(props: { onChainTxReceipt: TransactionReceipt; transactionId: string; }) => void` | This method is called after the payment has succeeded on-chain. | +| suppressErrorToast | boolean | Defaults to `true`. If false, any error thrown will be displayed in a toast. | +| onLoad | `() => void` | This method is called when the iframe loads. | +| elementOrId | `string \| HTMLElement` | If provided, the iframe will be appended this element. You can pass in the DOM element or the `id` associated with the element. A minimum width of 380px is recommended. | + +## Customization + +The optional `options` argument allows you to customize the component's styling. All customization fields are optional. + +#### `options` object + +| Name | Type | Description | +| --------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------- | +| colorPrimary | string (In hex, e.g. #cf3781) | The primary brand color for buttons and links. | +| colorBackground | string (In hex, e.g. #cf3781) | The background color of the page. | +| colorText | string (In hex, e.g. #cf3781) | The color for text on the page and UI elements. | +| borderRadius | number (In px, e.g. 0 for sharp corners, 12 for rounded corners, 24 for pill shape) | The roundness of buttons and input elements. | diff --git a/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/0 Embedded Elements/_category_.json b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/0 Embedded Elements/_category_.json new file mode 100644 index 0000000000..d8d83bfa0b --- /dev/null +++ b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/0 Embedded Elements/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "Embedded Elements", + "collapsible": true, + "collapsed": true +} diff --git a/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/0 Webhooks.mdx b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/0 Webhooks.mdx new file mode 100644 index 0000000000..0b01df2625 --- /dev/null +++ b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/0 Webhooks.mdx @@ -0,0 +1,209 @@ +--- +slug: /checkouts/webhooks +title: Webhooks +--- + +Configure webhook URLs to have thirdweb notify your backend when successful or failed events occur. + +## Use cases + +- Update your database when a buyer purchases an NFT. +- Send an email to a buyer after their purchase succeeds. +- Inform your team in Slack/Discord when a payment or purchase failed. + +## Events + +The following webhook events are supported. + +| Event | Description | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `transfer:succeeded` | The NFT has been delivered to the buyer's wallet. | +| `transfer:failed` | The NFT was unable to be delivered after multiple retries. A refund will automatically be processed. | +| `payment:succeeded` | A buyer's payment has been successfully completed. | +| `payment:failed` | A buyer's payment attempt has been rejected. Extra data fields may be available with information from our payment processor on the failure reason. | +| `payment:refunded` | A buyer's payment has been refunded because the mint failed multiple attempts. Extra data fields may be available with the reason for the refund. | +| `payment:hold_created` | This is only emitted if `capturePaymentLater` is set. A buyer's payment method has a pre-authorization hold created for the given amount. They have not been charged yet. You can [capture this hold]() to complete their purchase, or [cancel it](ref:cancel-transaction-hold). | + +## Request format + +thirdweb will call your backend with an HTTPS `POST` request: + +### Headers + +```text +Content-Type: application/json +x-thirdweb-signature: +``` + +### Request body + +```json +{ + "event": "transfer:succeeded", + "result": { + "id": "5bbbada7-e864-4dac-ae4b-0ee4967f55d8", + "checkoutId": "70e08b7f-c528-46af-8b17-76b0e0ade641", + "walletAddress": "0x2086Fcd5b0B8F4aFAc376873E861DE00c67D7B83", + "walletType": "Preset", + "email": "buyer@example.com", + "quantity": 1, + "paymentMethod": "BUY_WITH_CARD", + "networkFeeUsd": 0.02, + "serviceFeeUsd": 1.79, + "totalPriceUsd": 45.99, + "createdAt": "2022-08-22T19:15:09.755375+00:00", + "paymentCompletedAt": "2022-08-22T19:16:01.673+00:00", + "transferCompletedAt": "2022-08-22T19:16:18.024+00:00", + "claimedTokens": { + "collectionAddress": "0x965550329b91b7c703a527347b613E175f38872d", + "collectionTitle": "My First NFT", + "tokens": [ + { + "transferHash": "0x076d1b496152efd2a97d0db1d558c681188a1a76a8a2c271a33e4c34cc1fa467", + "transferExplorerUrl": "https://polygonscan.com/tx/0x076d1b496152efd2a97d0db1d558c681188a1a76a8a2c271a33e4c34cc1fa467", + "tokenId": "262", + "quantity": 1 + } + ] + }, + "title": "My First Checkout", + "transactionHash": "0x076d1b496152efd2a97d0db1d558c681188a1a76a8a2c271a33e4c34cc1fa467", + "valueInCurrency": "0.05", + "currency": "ETH", + "metadata": { + "myAppUserId": "23a9fj2930gya0" + }, + "mintMethod": { ... }, + "eligibilityMethod": { ... }, + "contractArgs": { ... }, + } +} +``` + +```json JSON (Marketplace) +{ + "event": "transfer:succeeded", + "result": { + "id": "5bbbada7-e864-4dac-ae4b-0ee4967f55d8", + "checkoutId": "70e08b7f-c528-46af-8b17-76b0e0ade641", + "walletAddress": "0x2086Fcd5b0B8F4aFAc376873E861DE00c67D7B83", + "walletType": "Preset", + "email": "buyer@example.com", + "quantity": 1, + "paymentMethod": "BUY_WITH_CARD", + "networkFeeUsd": 0.02, + "serviceFeeUsd": 1.79, + "totalPriceUsd": 45.99, + "createdAt": "2022-08-22T19:15:09.755375+00:00", + "paymentCompletedAt": "2022-08-22T19:16:01.673+00:00", + "transferCompletedAt": "2022-08-22T19:16:18.024+00:00", + "claimedTokens": { + "tokens": [ + { + "transferHash": "0x076d1b496152efd2a97d0db1d558c681188a1a76a8a2c271a33e4c34cc1fa467", + "transferExplorerUrl": "https://polygonscan.com/tx/0x076d1b496152efd2a97d0db1d558c681188a1a76a8a2c271a33e4c34cc1fa467", + "tokenId": "262", + "quantity": 1, + "from": "0xce6913CA121276E550b82844A08aCB4dfDc09178", + "collectionAddress": "0x965550329b91b7c703a527347b613E175f38872d", + "collectionTitle": "My First NFT" + } + ] + }, + "title": "My First Checkout", + "transactionHash": "0x076d1b496152efd2a97d0db1d558c681188a1a76a8a2c271a33e4c34cc1fa467", + "valueInCurrency": "0.05", + "currency": "ETH", + "metadata": { + "myAppUserId": "23a9fj2930gya0" + }, + "mintMethod": { ... }, + "eligibilityMethod": { ... }, + "contractArgs": { ... }, + } +} +``` + +## Usage + +### Provide a webhook handler URL + +Webhooks are configured separately for testnet and production checkout on the dashboard. Webhook URLs must be publicly accessible `https` endpoints. + +Do not provide a `localhost` URL to test your local server. We recommend testing your development server with a service like [ngrok](https://ngrok.io/) to serve a temporary public URL. + +**Please return a `2xx` response for unexpected or unused event types to prevent unnecessary retries.** + +### Verify the signature header + +To ensure the request came from thirdweb, each webhook request signs the payload and provides this signature in the `x-thirdweb-signature` header. + +To verify this signature, create a **SHA-256 HMAC hash** with your **thirdweb payments secret key** that can be found on [your Payments Settings page](https://thirdweb.com/dashboard/payments/settings) and the **body payload as the message** (as a JSON-encoded string). + +### Example implementation + +Here's a simplified HTTP handler in Next.js: + +```typescript +import { createHmac, timingSafeEqual } from "crypto"; + +const thirdwebCheckoutsWebhookHandler = (req, res) => { + const webhookSecret = ""; // Your webhook secret key + + // Get the provided signature. + const signature = req.headers["x-thirdweb-signature"]; + // Compute the expected signature. + const hash = createHmac("sha256", apiKey) + .update(JSON.stringify(req.body)) // {"event":"transfer:succeeded","result":{"id":... + .digest("hex"); + // Confirm the provided signature matches. + if (!timingSafeEqual(Buffer.from(signature), Buffer.from(hash))) { + return res.status(400).send("Signature mismatch!"); + } + + switch (req.body.event) { + case "transfer:succeeded": + // Handle when an NFT was delivered. + case "transfer:failed": + // Handle when an NFT could not be delivered. + default: + // Ignore all other events and return 2xx. + } + + return res.status(200).send("OK"); +}; +``` + +### Test the webhook response + +Use the **Test webhook** button to send a dummy payload to your webhook URL and see response status/body. + +### View recent webhook events + +Select the **List events** button to view the recent webhook events, including the request body and response status/body from your backend. This view is useful to debug misconfigured webhook handlers. + +## FAQ + +### Why do I need to verify the signature header? + +If your server is public, a bad actor can spoof a webhook request. Verifying the signature ensures the payload has not been changed. If a bad actor changes the webhook request body, the signature would not match the signed payload. + +### Why is my signature header mismatched? + +Here are common reasons the signature header may be mismatched. + +- Check if the header is set lower-cased. Some server frameworks (e.g. Next.js) use lowercase request header names since they are case-insensitive (RFC 2616). +- Make sure you're passing the entire body as the message in the HMAC signature. Some frameworks require you to configure the HTTP handler to not parse the request body (e.g. [Next.js](https://nextjs.org/docs/api-routes/request-helpers)). +- Make sure your API key is valid. + +### What IP address will webhook requests come from? + +Webhooks will be sent from the IP address `44.225.232.73`. + +### How often will webhook requests be retried? + +Webhooks are retried every five minutes for up to one hour until a `2xx` response is returned. + +### Can I filter which webhook events are sent? + +Currently there is no way to filter which events are sent to your webhook URLs. thirdweb may add new webhook event types without notice. Please ignore events that you don't need by returning a `2xx` response. diff --git a/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/1 Translations.mdx b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/1 Translations.mdx new file mode 100644 index 0000000000..aa4ae0e44c --- /dev/null +++ b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/1 Translations.mdx @@ -0,0 +1,39 @@ +--- +slug: /checkouts/translations +title: Translations +--- + +Checkouts supports the following languages: + +- English +- French +- Italian +- Spanish +- German +- Japanese +- Korean +- Chinese + +By default, text is shown in the buyer's preferred browser language and defaults to English. Non-English languages are **only supported in the Embedded Elements implementation**. + +## Force a specific language + +To always show text in one language, set the `locale` property to the two-letter [ISO 639-1 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) when creating the Checkout Element in your frontend code. + +### React example + +```typescript + +``` + +### Javascript SDK example + +```typescript +createCheckoutWithCardElement({ + // ... + locale: "fr", +}); +``` diff --git a/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/2 Marketplaces.mdx b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/2 Marketplaces.mdx new file mode 100644 index 0000000000..a345dc7d29 --- /dev/null +++ b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/2 Marketplaces.mdx @@ -0,0 +1,65 @@ +--- +slug: /checkouts/marketplaces +title: Marketplaces +--- + +thirdweb supports marketplace contracts where a user can list an NFT and receive funds when a buyer purchases it. + +Integration is identical to a checkout using a `CUSTOM_CONTRACT` contract type. Follow the guide on integrating [custom contracts](custom-contracts), and ensure the `mintMethod` identifies the method on your smart contract that purchases the NFT (a "buy" method). + +Your contract method should do the following: + +- Accepts the wallet address where the NFT should be delivered. +- Accepts payment in the chain's native coin or [USDC / ERC-20 tokens](erc20-pricing) from the caller (`msg.sender`) of the method. +- Transfers the NFT from the seller to the recipient's wallet address. Remember: `msg.sender` is thirdweb's minter wallet and not the buyer's wallet address. Your function needs to ensure the recipient is specified in the argument list. + +## Third-party marketplaces + +Checkouts also supports purchases of tokens listed on third-party Marketplaces such as OpenSea, LooksRare, or X2Y2. + +Purchases on third-party marketplaces are facilitated by the [Reservoir](https://docs.reservoir.tools/docs) contract. You can create a Checkout for an item listed on any [supported Reservoir marketplace](https://docs.reservoir.tools/docs/supported-marketplaces). + +## Integration + +1. Register a new contract + 1. Set your **Contract Type** to **Reservoir**. + 2. Leave **Contract Address** blank. +2. Create a checkout link with the ID of the registered contract. We recommend using one-time checkout links as the underlying token listed on third-party marketplaces may sell out. + +### Code sample + +```typescript +const body = { + contractId: "REGISTERED_CONTRACT_ID", // this contract should be registered with Reservoir as the contract type + title: "My Checkout", + contractArgs: { + // TIP! You can add more than 1 token to the nfts array and we'll accept all of those listings! + nfts: [ + { token: `COLLECTION_CONTRACT_ADDRESS_1:TOKEN_ID_1` }, + { token: `COLLECTION_CONTRACT_ADDRESS_2:TOKEN_ID_2` } + ] + }, +}; + +const resp = await fetch("https://payments.thirdweb.com/api/2022-08-12/checkout-link-intent", { + method: "POST", + headers: [ + "Authorization": "Bearer MY_THIRDWEB_API_SECRET_KEY", + "Content-Type": "application/json", + ] + body: JSON.stringify(body); +}); +const { checkoutLinkIntentUrl } = await resp.body(); + +// Navigate users to this URL to purchase your NFT. + +``` + +Please update the following variables: + +- `REGISTERED_CONTRACT_ID`: The Contract ID from Step 1. +- `COLLECTION_CONTRACT_ADDRESS`: The contract address of the NFT collection. +- `TOKEN_ID`: The token ID of the NFT from the listing. This listing must exist on one of Reservoir's supported marketplaces. +- `MY_THIRDWEB_API_SECRET_KEY` found on your API Keys dashboard page. + +For a more embedded and branded checkout experience, you may also sell marketplace NFTs with [Checkout Elements](checkout-elements). diff --git a/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/3 One-Time Checkout Links.mdx b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/3 One-Time Checkout Links.mdx new file mode 100644 index 0000000000..cb3a3c5ee7 --- /dev/null +++ b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/3 One-Time Checkout Links.mdx @@ -0,0 +1,27 @@ +--- +slug: /checkouts/one-time-checkout-link +title: One-Time Checkout Links +--- + +A one-time Checkout Link is a prebuilt checkout experience that is customized per buyer by providing a fixed price, email, wallet address, quantity, and more. + +Each unique link allows at most one purchase and expires after the specified duration. + +## Prerequisites + +Make sure you've [enabled your contract for Payments](enable-contract). + +## Use cases + +- Gate purchases via an off-chain allowlist. After verifying the buyer's identity on your app, navigate them to the checkout link. +- Implement dynamic pricing by passing in the price for each checkout. This feature allows you to provide coupon codes, bulk discounts, and loyalty discounts. +- Restrict the quantity of NFTs your buyers can purchase. +- Directly email the checkout URL directly to the buyer's inbox. + +## Create a one-time checkout link + +One-time checkout links can only be created via API. + +### API + +[See the API Reference for creating a one-time checkout link](https://redocly.github.io/redoc/?url=https://payments.thirdweb.com/api/doc#tag/One-time-Checkout-Links/paths/~1api~12022-08-12~1checkout-link-intent/post) diff --git a/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/4 Custom Contracts.mdx b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/4 Custom Contracts.mdx new file mode 100644 index 0000000000..5c67ed9060 --- /dev/null +++ b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/4 Custom Contracts.mdx @@ -0,0 +1,142 @@ +--- +slug: /checkouts/custom-contracts +title: Custom Contracts +--- + +Using your own Custom Contract on Polygon, Ethereum, or another EVM blockchain? The following example shows you how to use it with thirdweb. + +## Example + +Assume that this is your contract's claim function: + +```javascript +function claimTo( + address _to, + uint256 _quantity, + uint256 _tokenId, + string CUSTOM_ARG_1, // Any additional arguments. + bool CUSTOM_ARG_2 +) + external + payable + mintCompliant(_tokenId, _quantity) + priceCompliant(_tokenId, _quantity) + tokenLive(_tokenId) + { + // YOUR MINTING LOGIC HERE + } +``` + +You will then need a **mintMethod** in order for thirdweb to call your claim function. For the example above, your mintMethod should look like this: + +```json +mintMethod: { + name: "claimTo", // Name of the function to call within the smart contract. + args: { + _to: "$WALLET", + _quantity: "$QUANTITY", + _tokenId: 0, + CUSTOM_ARG_1: "xyz", + CUSTOM_ARG_2: false + }, + payment: { + value: "0.1 * $QUANTITY", // Assuming that your NFT costs 0.1 ETH each. + currency: "ETH" + } +} +``` + +This will ensure that when thirdweb calls the smart contract during any checkout flow, under the hood, we would be calling your smart contract like so: + +```javascript +claimTo("0x...", 1, 0, "xyz", false { + value: ethers.utils.parseEther("0.1"), +}); +``` + +## Requirements + +Your smart contract method that mints the NFT must satisfy these requirements: + +1. The method must accept the buyer's wallet address as an argument. +2. The method must allow thirdweb's minter wallets to mint an unlimited amount as the `msg.sender`. Any restrictions on the minting wallet address or quantity is not allowed. +3. (If priced in USDC) The method must explicitly [request USDC token](/checkouts/erc20-pricing) from the `msg.sender`. + +## MintMethod + +The **mintMethod** is required when creating [Shareable Checkout Links](/checkouts/checkout-link), [One-Time Checkout Links](/checkouts/one-time-checkout-link), or [Checkout Elements](/checkouts/elements). Think of it as an ABI for thirdweb to know how to call your claim function. + +The generic format of the mintMethod is: + +```json +"mintMethod": { + "name": "claimTo", + "args": { + "_to": "$WALLET", + "_quantity": "$QUANTITY" + }, + "payment": { + "value": "0.1 * $QUANTITY", + "currency": "ETH" + } +} +``` + +## Template variables + +> 🚧 Don't know the values? +> +> thirdweb supports two template variables -`$WALLET` and `$QUANTITY` that you may use if you don't know the buyer's wallet address and quantity. Note that for **all other** fields such as `value` and `currency`, you would need to hardcode the actual values. + +Template variables will be replaced when calling your contract: + +| Variable | Replaced with | +| :---------- | :------------------------------ | +| `$WALLET` | The buyer's wallet address. | +| `$QUANTITY` | The quantity of tokens to mint. | + +## Payment + +The `payment` field should provide the **price per NFT in human-readable form** (not wei). + +Example: `"payment": { "value": "0.1 * $QUANTITY", "currency": "ETH" }` + +### Free NFTs + +Set the price to zero. + +Example: `"payment": { value: "0 * $QUANTITY", currency: "MATIC" }` + +### NFTs priced in USDC + +Ensure your mint method **explicitly requests USDC tokens from msg.sender**. See [USDC Pricing](/checkouts/erc20-pricing) for more details. + +### Delegate a different ERC-20 payment address + +> 📘 This is required when interacting with the [Seaport contract](https://docs.opensea.io/reference/seaport-overview). + +By default thirdweb's float wallet approves your NFT contract to request ERC-20 tokens. + +To specify a different contract address that will request ERC-20 tokens from thirdweb's float wallet, set that address in the `"spender"` field: + +```json +"payment": { + "value": "100 * $QUANTITY", + "currency": "USDC", + "spender": "" +} +``` + +## FAQ + +### I have multiple methods with the same name. Why isn't my mintMethod isn't working? + +Please provide the full signature as your mintMethod. thirdweb will not try to "guess" the correct method. + +> **Example** +> +> Your contract has methods `mint(address to)` and `mint(address to, string tokenId)` and your checkout will call the former. +> +> Provide your mintMethod as `mint(address)`. + +You **do not** need to modify your contract. diff --git a/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/5 Pre-Built Contracts.mdx b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/5 Pre-Built Contracts.mdx new file mode 100644 index 0000000000..7b50ca5396 --- /dev/null +++ b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/5 Pre-Built Contracts.mdx @@ -0,0 +1,65 @@ +--- +slug: /checkouts/pre-built-contracts +title: Pre-Built Contracts +--- + +## Integration + +For some thirdweb contracts, set `contractArgs` when creating [Shareable Checkout Links](/checkouts/checkout-link), [One-Time Checkout Links](/checkouts/one-time-checkout-link), or [Checkout Elements](/checkouts/elements). + +### NFT Drop + +This is an ERC-721A contract where the NFT metadata is unique but the claim configuration is identical for all buyers. No `contractArgs` should be set. + +### Edition Drop + +This is an ERC-1155 contract where the NFT metadata and claim configuration is identical for all buyers. Set `contractArgs` with the token ID to mint: + +```typescript +contractArgs = { tokenId: "0" }; +``` + +### Marketplace + +This is a contract that allows other users to purchase already-minted NFTs. Set `contractArgs` with an array of the marketplace listing IDs of each of the direct listing: + +```typescript +contractArgs = { + listings: [ + { listingId: "0" }, + { listingId: "1" }, + ... + ] +} +``` + +## Configure the Claim Condition + +Your thirdweb contract must have at least one active claim condition, meaning the **When will this phase start?** date is in the past. + +![Claim Condition Configuration Image](https://files.readme.io/994d683-image.png) + +Helpful tips for each field: + +| Field | Notes | +| ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **When will this phase start?** | thirdweb can only mint NFTs after this date. | +| **How many NFTs will you drop in this phase?** | Remember to create NFTs on the **NFTs** tab for NFT Drop contracts. | +| **How much do you want to charge to claim each NFT?** | For Mumbai, this price must be ≤ 0.0001 MATIC.
For Goerli, this price must be ≤ 0.0001 ETH.

On production, there is a $2,000 price limit. Please fill out [this Typeform](https://fw3786mcxwl.typeform.com/to/B0xIFoiu) to request an increase. | +| **What currency do you want to use?** | Supported currencies on thirdweb:
- Mumbai: MATIC
- Polygon: MATIC, USDC, WETH
- Goerli: ETH
- Ethereum: ETH, USDC | +| **Who can claim NFTs during this phase?** | If you have an allowlist, please add thirdweb's minter wallets.
Otherwise leave this blank. | +| **How many NFTs can be claimed per transaction?** | This value must be Unlimited. Otherwise thirdweb's minter wallets will not be able to mint more than this amount. | +| **How many seconds do wallets have to wait in-between claiming?** | This value must be 0. Otherwise thirdweb's minter wallets will fail when many mints occur at once. | + +## Debug common blockchain error responses + +| Error Message | Description | Solution | +| ------------------ | -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `!Qty` | The buyer is attempting to purchase more than allowed per wallet. | **:warning: Your Claim Condition must allow thirdweb Wallets to mint an unlimited amount.**

The **How many NFTs can be claimed per transaction?** setting must be set to Unlimited. Alternatively, allow thirdweb's minter wallets to mint the full supply in a snapshot. | +| `!MaxSupply` | The buyer is attempting to purchase more than the available supply, or the drop is sold out. | Allow more NFTs to be sold, or prevent buyers from navigating to the checkout page if sold out. | +| `cant claim yet` | There is no claim phase, or the claim phase has not started. | Wait until the claim phase has started, or set one claim phase's start date to a past date. | +| `!PriceOrCurrency` | thirdweb sent the incorrect amount or currency to the contract. | thirdweb may be auto-detecting the price incorrectly. Please reach out on [Discord](https://discord.gg/thirdweb). | + +_Source: Drop.sol from thirdweb contracts_ + +If your transactions are failing for these reasons, please update the active **Claim Condition** on your thirdweb contract. diff --git a/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/6 ERC20 Pricing.mdx b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/6 ERC20 Pricing.mdx new file mode 100644 index 0000000000..0759a3c54e --- /dev/null +++ b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/6 ERC20 Pricing.mdx @@ -0,0 +1,51 @@ +--- +slug: /checkouts/erc20-pricing +title: ERC-20 Pricing +--- + +> thirdweb supports selling NFTs that accept the USDC token **for enterprise customers only**. +> +> 👉 Read our guide on [How to Price your NFTs in USDC](https://blog.withpaper.com/how-to-price-your-nfts-in-usdc/). + +## Integration + +### For thirdweb contracts + +1. Navigate to the thirdweb dashboard for your contract +2. Set the claim condition to price the NFT in USDC. + +![In the **Claim Conditions** section](https://files.readme.io/f1bd58f-image.png "In the **Claim Conditions** section") + +### For custom contracts + +1. Add the following snippet to your contract (modify as needed): + + ```solidity + // Replace MY_USDC_ADDRESS with the address based on the blockchain below. + IERC20 public usdc = IERC20("0xe6b8a5CF854791412c1f6EFC7CAf629f5Df1c747"); + uint256 priceInUsdc = 50 * 10 ** 6 + + function mintTo(address recipient, uint256 quantity) public { + usdc.transferFrom(msg.sender, address(this), quantity * priceInUsdc); + } + ``` + +2. Configure your checkout to accept USDC payment: + 1. **Shareable Checkout Links:** When creating the checkout set the **Price per NFT** currency to **USDC**. + 2. **One-Time Checkout Links:** When [creating a One-Time Checkout Link](/checkouts/one-time-checkout-link) set `mintMethod` with `"payment": { "value": "50 * $QUANTITY", currency: "USDC" }`. + +## Accepting the correct USDC token + +Make sure your contract requests the correct USDC token address from thirdweb. These are the supported USDC token addresses. + +- USDC on Mumbai: [0x0fa8781a83e46826621b3bc094ea2a0212e71b23](https://mumbai.polygonscan.com/address/0x0fa8781a83e46826621b3bc094ea2a0212e71b23) +- USDC on Polygon: [0x3c499c542cef5e3811e1192ce70d8cc03d5c3359](https://polygonscan.com/address/0x3c499c542cef5e3811e1192ce70d8cc03d5c3359) +- USDC on Goerli: [0x07865c6E87B9F70255377e024ace6630C1Eaa37F](https://goerli.etherscan.io/address/0x07865c6E87B9F70255377e024ace6630C1Eaa37F) +- USDC on Ethereum: [0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48](https://etherscan.io/address/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48) +- USDC on Optimism: [0x7f5c764cbc14f9669b88837ca1490cca17c31607](https://optimistic.etherscan.io/address/0x7f5c764cbc14f9669b88837ca1490cca17c31607) + +## FAQ + +### Do you support other ERC-20 tokens? + +thirdweb supports popular ERC-20 (or ERC20) tokens like USDC and WETH. If your NFT is priced in a different token, [contact us](mailto:support@withpaper.com). diff --git a/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/_category_.json b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/_category_.json new file mode 100644 index 0000000000..59d71bdfcb --- /dev/null +++ b/docs/onboarding/22 NFT Checkouts/1b Advanced Guides/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "Advanced Guides", + "collapsible": true, + "collapsed": true +} diff --git a/docs/onboarding/22 NFT Checkouts/2 API Reference.mdx b/docs/onboarding/22 NFT Checkouts/2 API Reference.mdx new file mode 100644 index 0000000000..f8d5884d9d --- /dev/null +++ b/docs/onboarding/22 NFT Checkouts/2 API Reference.mdx @@ -0,0 +1,65 @@ +--- +slug: /checkouts/api-reference +title: API Reference +--- + +The Payments API enables all the functionalities needed to create checkouts. + +:::info + +[View the full API reference.](https://redocly.github.io/redoc/?url=https://payments.thirdweb.com/api/doc) + +::: + +### Usage + +You must use an API Secret Key to make authenticated calls. These calls should be +made from your backend. [Create an API Key from your thirdweb dashboard.](https://thirdweb.com/dashboard/settings/api-keys) + +Provide your secret key as a header: `thirdweb_secret_key: your_api_secret_key` + +--- + +## API Categories + +### Enable Contracts for Payments + +Enable, edit, and disable contracts for Payments. + +[View API reference.](https://redocly.github.io/redoc/?url=https://payments.thirdweb.com/api/doc#tag/Contracts) + +### Checkout Links + +Create, edit, and delete Checkout Links. + +[View API reference.](https://redocly.github.io/redoc/?url=https://payments.thirdweb.com/api/doc#tag/Checkout-Links) + +### One-time Checkout Links (Advanced) + +Create One-time Checkout Links. + +[View API reference.](https://redocly.github.io/redoc/?url=https://payments.thirdweb.com/api/doc#tag/One-time-Checkout-Links) + +### Embedded Elements + +Create SDK Client Secret used for Embedded Elements. + +[View API reference.](https://redocly.github.io/redoc/?url=https://payments.thirdweb.com/api/doc#tag/Checkout-Embedded-Elements) + +### Transaction Status + +Get the status of a transaction by transaction ID. + +[View API reference.](https://redocly.github.io/redoc/?url=https://payments.thirdweb.com/api/doc#tag/Transaction-Status) + +### Get Estimated Price + +Get the estimated price of a checkout, including fees and gas. + +[View API reference.](https://redocly.github.io/redoc/?url=https://payments.thirdweb.com/api/doc#tag/Estimated-Price) + +### Transaction Holds + +Capture or cancel a transaction hold. + +[View API reference.]() diff --git a/docs/onboarding/22 NFT Checkouts/3 FAQ.mdx b/docs/onboarding/22 NFT Checkouts/3 FAQ.mdx new file mode 100644 index 0000000000..6dce3967d2 --- /dev/null +++ b/docs/onboarding/22 NFT Checkouts/3 FAQ.mdx @@ -0,0 +1,162 @@ +--- +slug: /checkouts/faq +title: FAQ +--- + +## General + +### How much does thirdweb Checkouts cost? + +There is **no cost to sellers**! Buyers pay a 1% service fee on top of payment processing fees. + +### How long does implementation take? + +A full-featured checkout link **takes minutes to set up**: + +1. [Register your contract](enable-contract). +2. Create a [🔗 Checkout Link](checkout-link). +3. Send the link to your customers. Done ✨! + +When you're ready to customize further, you can tinker with styling, SDKs, webhooks, dynamic pricing, and more. + +### How scalable is thirdweb Checkouts? How much load can it handle? + +Our product is enterprise-ready with a 99.9% uptime. We are battle-tested with enterprises like Balmain, New York Fashion Week, Unilever, deadmau5 and Tilting Point. We can enqueue transactions up to 200 transactions/minute by default, with higher limits upon request. + +### What platforms are supported? + +Checkout links can be used anywhere webpages are supported. + +The Checkout Embedded Elements SDK is supported on Web and Mobile Web. + +## Smart contract support + +### Which blockchains and currencies are supported? + +See the [overview](/checkouts) page for a list of supported chains and currencies. We can support any EVM chain upon request. Please contact support@thirdweb.com if the chain or currency you want to sell in is not on our list. + +### Are marketplace contracts supported? + +Yes! See [Marketplace Sales](marketplaces) for more details. + +### Can I sell an NFT that is already minted? + +Yes! You'll need to "wrap" your NFT with a marketplace contract like [thirdweb marketplace](https://portal.thirdweb.com/pre-built-contracts/marketplace) or build your own. This "direct listing" approach works like this: + +- The seller has an NFT already minted and wants to sell it. +- The seller approves the marketplace contract to take this NFT from their wallet once a buyer offers a specified amount. The NFT is not moved until a sale is completed. +- A buyer agrees to pay the specified amount. They pay via your Checkout flow. +- After the buyer's payment is successful, thirdweb calls the "buy" method with the expected amount in crypto to the marketplace contract. This method transfers the NFT to the buyer's wallet. + +## Payments + +### Where does thirdweb send the funds after a customer has paid? + +thirdweb directly calls the smart contract and pays for the mint using the native currency specified in the contract function. If you are looking for FIAT payout, it is available for the enterprise customers. Please [contact sales](mailto:sales@thirdweb.com) . + +### What regions does thirdweb support credit card payments? + +thirdweb uses multiple payment processors and supports credit card payments in most countries (190+) and all 50 US states. Select countries that the US cannot conduct business with are not supported (Cuba, Iran, North Korea, Syria, and the Crimea, Donetsk, and Luhansk Regions). 10+ currencies and languages are supported. + +### What fiat payment options are accepted? + +thirdweb accepts: credit/debit cards (Visa, Mastercard, American Express, Discover, UnionPay, JCB, Diners Club), Apple Pay, Google Pay, iDEAL + +### What is the price limit for checkouts? + +thirdweb limits checkouts to be priced at $2,000 USD and reserves the right to change this limit based on your checkout's risk profile. For enterprise customers, we can support up to $15,000. + +If you need a higher price limit, please fill out [this form](https://thirdweb.com/contact-us). + +### Do you support gasless transactions? + +Yes, we support the ability for merchants to cover the gas fees related to transactions. See the guide on [Sponsored Fees](sponsored-fees). + +### When does thirdweb require identity verification (KYC)? + +thirdweb combines buyer, merchant, payment method, device, and behavioral signals from multiple vendors to compute the riskiness of a purchase. A small portion of buyers (\< 3% and varies by merchant) will be prompted to submit a photo ID and take a webcam selfie. This step is automated and takes under 1 minute. + +Reminder: thirdweb takes on **all** chargeback liability from the developer! + +## Testing + +### Is there a test credit card? + +Yes, please use the following card numbers. The expiry date, CVV, and postal code do not matter. + +| Card Number | Description | +| :--------------- | :----------------------------------- | +| 4242424242424242 | A "low risk" card. | +| 4000000000009235 | A "high risk" card that prompts KYC. | + +### Where can I get testnet funds? + +Here are some faucets to receive testnet funds: + +| Chain | Currency | Faucet link | +| :----------------- | :------- | :------------------------------------------- | +| Mumbai (Polygon) | MATIC | [Faucet](https://faucet.polygon.technology/) | +| Sepolia (Ethereum) | ETH | [Faucet](https://sepoliafaucet.com/) | +| Goerli (Optimism) | ETH | [Faucet](https://faucet.paradigm.xyz/) | + +## Customization + +### Can I customize the checkout to match my branding? + +Yes, customize colors and UI elements to fit your theme for [Checkout Links](checkout-link). Or embed [Checkout Elements](elements) in your app with granular control of colors. + +### How do allow my users to redeem utility with their NFT? + +NFTs are a great way to gate content! Once the NFT is purchased, you can provide a link to redeem their utility on the post-purchase page and email. + +Listen to [webhooks](webhooks) to update your database or send a custom email when the NFT has been transferred. + +### How do I customize the emails sent to buyers? + +See the [Email Customization](email-customization) guide. + +### Are checkouts translated into different languages? + +Yes, the checkout is localized to the buyer's browser language, or you can force a specific language. See [Translations](translations) for more details. + +### How does checkout support referral codes or discounts? + +You can use our dynamic one-time checkout links to generate payment links with discounts or referral codes for customers. For a full guide to how to implement this, refer [here](one-time-checkout-link). + +### Does Checkouts support allowlists? + +Yep, you can use our dynamic one-time checkout links to generate gated payment links for users who've verified their identity on your website. For a full guide to how to implement this, refer [here](allowlists). + +## Wallets + +### What if my users don't have a wallet? + +Buyers who don't have a wallet can create one with their email or social login. This uses thirdweb's non-custodial [Embedded Wallet](https://portal.thirdweb.com/embedded-wallet) product. + +### How does my user transfer the NFT from the Embedded Wallet? + +Buyers can visit [My Wallets](https://ews.thirdweb.com/wallet) to view and transfer NFTs in their Embedded Wallets. We cover all gas fees related to transferring and offer a way for users to export their private key. + +## Other + +### Does Checkouts support credit card payments for functions outside of minting like burning and editing NFTs? + +This feature is available upon request. Please contact us at [sales@thirdweb.com](mailto:sales@thirdweb.com). + +### What is the customer support level provided to customers? + +For developers, we have a Discord forum for questions that is checked on a daily basis. If you are looking for guaranteed support time and SLA, please contact [sales@thirdweb.com](mailto:sales@thirdweb.com). + +For customers, we respond to inquiries on our support center and to [support@thirdweb.com](mailto:support@thirdweb.com) within 24 business hours. + +### How does thirdweb handle compliance? + +We conduct KYC (know your customer) verification with driver's license and liveliness check on suspicious customers (\<3% on average and varies by merchant). We also handle dark wallet checks to ensure that flagged wallets and stolen funds are not being used in any of our transactions. + +We take on all liabilities & chargeback risks as the Merchant of Record. + +thirdweb is currently in the process of receiving our SOC II certification. + +### What are the authorization rates? + +We have industry leading authorization rates at 92%. We are able to maintain a high authorization by only operating with NFTs, and having a proprietary fraud engine that keeps our fraud rate at \<0.5%. diff --git a/docs/onboarding/22 NFT Checkouts/assets/checkout-with-card-customization-demo.png b/docs/onboarding/22 NFT Checkouts/assets/checkout-with-card-customization-demo.png new file mode 100644 index 0000000000..907a9a37cf Binary files /dev/null and b/docs/onboarding/22 NFT Checkouts/assets/checkout-with-card-customization-demo.png differ diff --git a/docs/onboarding/22 NFT Checkouts/assets/checkout-with-card-demo.png b/docs/onboarding/22 NFT Checkouts/assets/checkout-with-card-demo.png new file mode 100644 index 0000000000..4fe895275e Binary files /dev/null and b/docs/onboarding/22 NFT Checkouts/assets/checkout-with-card-demo.png differ diff --git a/docs/onboarding/22 NFT Checkouts/assets/checkout-with-eth-demo-2.png b/docs/onboarding/22 NFT Checkouts/assets/checkout-with-eth-demo-2.png new file mode 100644 index 0000000000..687ed9098b Binary files /dev/null and b/docs/onboarding/22 NFT Checkouts/assets/checkout-with-eth-demo-2.png differ diff --git a/docs/onboarding/22 NFT Checkouts/assets/checkout-with-eth-demo.png b/docs/onboarding/22 NFT Checkouts/assets/checkout-with-eth-demo.png new file mode 100644 index 0000000000..93bbba2777 Binary files /dev/null and b/docs/onboarding/22 NFT Checkouts/assets/checkout-with-eth-demo.png differ diff --git a/docs/onboarding/22 NFT Checkouts/assets/checkouts-overview.png b/docs/onboarding/22 NFT Checkouts/assets/checkouts-overview.png new file mode 100644 index 0000000000..14c7a24d9f Binary files /dev/null and b/docs/onboarding/22 NFT Checkouts/assets/checkouts-overview.png differ diff --git a/docs/react/Connecting Wallets.mdx b/docs/react/Connecting Wallets.mdx index 2538f6e39d..0a7b851cff 100644 --- a/docs/react/Connecting Wallets.mdx +++ b/docs/react/Connecting Wallets.mdx @@ -37,6 +37,7 @@ There are two ways you connect user's wallet to your application using thirdweb' | Coin98 Wallet | [`coin98Wallet`](/react/react.coin98) | | Rabby Wallet | [`rabbyWallet`](/react/react.rabby) | | Defi Wallet | [`cryptoDefiWallet`](/react/react.defiwallet) | +| OneKey Wallet | [`oneKeyWallet`](/react/react.onekey) |
diff --git a/docs/react/hooks/core/usecontractread.mdx b/docs/react/hooks/core/usecontractread.mdx index a165d98aea..0cb40123cc 100644 --- a/docs/react/hooks/core/usecontractread.mdx +++ b/docs/react/hooks/core/usecontractread.mdx @@ -119,6 +119,9 @@ function App() { If you provide an additional argument to the hook, it will be used as the `CallOverrides` object send with your request. + +To include the sender's address (msg.sender) when calling view functions within your smart contract, include the property {from: 0X123} passing the relevant address. + ```jsx import { useContractRead, useContract, Web3Button } from "@thirdweb-dev/react"; diff --git a/docs/react/wallets/oneKeyWallet.mdx b/docs/react/wallets/oneKeyWallet.mdx new file mode 100644 index 0000000000..a0a1aa90c8 --- /dev/null +++ b/docs/react/wallets/oneKeyWallet.mdx @@ -0,0 +1,91 @@ +--- +title: oneKeyWallet +slug: /react.onekey +displayed_sidebar: react +--- + +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; +import CodeBlock from "@theme/CodeBlock"; +import { CustomizeWalletConfigurator } from "@components/build-wallet/CustomizeWalletConfigurator"; + +A wallet configurator for [OneKey Wallet](/wallet/onekey-wallet) which allows integrating the wallet with React. + +```tsx +import { oneKeyWallet } from "@thirdweb-dev/react"; + +const oneKeyWalletConfig = oneKeyWallet(options); +``` + +## options + +
+ projectId (recommended) +
+ +Your project's unique identifier that can be obtained at [cloud.walletconnect.com](https://cloud.walletconnect.com). + +Defaults to a common thirdweb projectId. We recommend getting your own projectId at +[cloud.walletconnect.com](https://cloud.walletconnect.com) when launching your project. + +```javascript +import { oneKeyWallet } from "@thirdweb-dev/react"; + +oneKeyWallet( + // highlight-start + { + projectId: "", + }, + // highlight-end +); +``` + +
+
+ +
+ recommended (optional) +
+ +Show this wallet as "recommended" in the [ConnectWallet Modal](/react/react.connectwallet). + +```ts +oneKeyWallet({ + // highlight-start + recommended: true, + // highlight-end +}); +``` + +
+
+ +## Usage with `ConnectWallet` + +To allow users to connect to this wallet using the [ConnectWallet](/react/react.connectwallet) component, you can add it to [ThirdwebProvider's supportedWallets](/react/react.thirdwebprovider#supportedwallets-optional) prop. + +```tsx + + + +``` + +## Usage with `useConnect` + +you can use the `useConnect` hook to programmatically connect to the wallet without using the [ConnectWallet](/react/react.connectwallet) component. + +The wallet also needs to be added in [ThirdwebProvider's supportedWallets](/react/react.thirdwebprovider#supportedwallets-optional) if you want the wallet to auto-connect on next page load. + +```tsx +const oneKeyWalletConfig = oneKeyWallet(); + +function App() { + const connect = useConnect(); + + const handleConnect = async () => { + await connect(oneKeyWalletConfig, connectOptions); + }; + + return
...
; +} +``` \ No newline at end of file diff --git a/docs/unity/assets/connectwallet.png b/docs/unity/assets/connectwallet.png index d0e5a6528e..99277a9dba 100644 Binary files a/docs/unity/assets/connectwallet.png and b/docs/unity/assets/connectwallet.png differ diff --git a/docs/unity/assets/connectwalletinspector.png b/docs/unity/assets/connectwalletinspector.png index a5f8893fc1..d410dad0f4 100644 Binary files a/docs/unity/assets/connectwalletinspector.png and b/docs/unity/assets/connectwalletinspector.png differ diff --git a/docs/unity/assets/jwt_auth_settings.png b/docs/unity/assets/jwt_auth_settings.png index 9bf06ec739..0e8698677b 100644 Binary files a/docs/unity/assets/jwt_auth_settings.png and b/docs/unity/assets/jwt_auth_settings.png differ diff --git a/docs/unity/connecting-to-wallets/EmbeddedWallet.mdx b/docs/unity/connecting-to-wallets/EmbeddedWallet.mdx index 7e6170fc37..716437d688 100644 --- a/docs/unity/connecting-to-wallets/EmbeddedWallet.mdx +++ b/docs/unity/connecting-to-wallets/EmbeddedWallet.mdx @@ -55,6 +55,10 @@ string address = await sdk.wallet.Connect(connection); Allows the integration of a custom authentication flow, such as JWT, requiring the configuration of JWKS URI and AUD in the [API key settings](https://thirdweb.com/create-api-key). +Alternatively, allows passing a generic payload that will be authenticated against your backend Auth Endpoint set in the [API key settings](https://thirdweb.com/create-api-key). + +You must also pass in an `encryptionKey` that will be used to encrypt the recovery share. + ![Custom Auth Settings](../assets/jwt_auth_settings.png) ```csharp @@ -66,8 +70,9 @@ var connection = new WalletConnection( provider: WalletProvider.EmbeddedWallet, chainId: 1, authOptions: new AuthOptions( - authProvider: AuthProvider.CustomAuth, - authToken: "your-auth-token-here", + authProvider: AuthProvider.JWT, + jwtOrPayload: "my-jwt-token-or-payload", + encryptionKey: "my-encryption-key", ) ); @@ -83,7 +88,7 @@ If using Email OTP flow, displays a modal where you can input your OTP code. If using OAuth2 flow, opens a popup where you can login with your provider account. If successful, the popup will close and the wallet will connect. -If using Custom JWT flow, attempts to connect directly after verifying the JWT token. +If using Custom Auth flow, attempts to connect directly after verifying the auth token. ### Standalone @@ -91,7 +96,7 @@ If using Email OTP flow, displays a modal where you can input your OTP code. If using the OAuth2 flow, opens the default browser where you can login with your provider account. Connects after the login flow is complete. -If using Custom JWT flow, attempts to connect directly after verifying the JWT token. +If using Custom Auth flow, attempts to connect directly after verifying the auth token. ### Mobile @@ -99,7 +104,7 @@ If using Email OTP flow, displays a modal where you can input your OTP code. If using the OAuth2 flow, interacts with native in-app browser/authentication implementations to login with your provider account. Redirects back to the app through a deep link after the login flow is complete. Only available in builds. -If using Custom JWT flow, attempts to connect directly after verifying the JWT token. +If using Custom Auth flow, attempts to connect directly after verifying the auth token. ## Miscellaneous diff --git a/docs/unity/connecting-to-wallets/SmartWallet.mdx b/docs/unity/connecting-to-wallets/SmartWallet.mdx index 9cbe29fe94..2de7e4a83d 100644 --- a/docs/unity/connecting-to-wallets/SmartWallet.mdx +++ b/docs/unity/connecting-to-wallets/SmartWallet.mdx @@ -52,7 +52,7 @@ They also work with any wallet provider as the EOA, but it is recommended to use You would then be able to login to the exact same persistent EOA and smart wallet address across your apps, and even across different platforms. -You can also create session keys, allowing new signers to interact with the smart wallet without being the admin. +You can also create session keys (revokable), allowing new signers to interact with the smart wallet without being the admin. You may also add/remove admins. ```csharp @@ -61,16 +61,38 @@ using Thirdweb; // Reference to your Thirdweb SDK var sdk = ThirdwebManager.Instance.SDK; -// Create a session key to add a temporary signer -var createSessionResult = await sdk.wallet.CreateSessionKey("0xSignerAddress", ...options); +// Create a session key +string signerAddress = "0xSignerAddress"; +List approvedTargets = new List { "0xTargetAddress" }; +string nativeTokenLimitPerTransactionInWei = "0"; +string permissionStartTimestamp = "0"; +string permissionEndTimestamp = Utils.GetUnixTimestampIn10Years().ToString(); +string reqValidityStartTimestamp = "0"; +string reqValidityEndTimestamp = Utils.GetUnixTimestampIn10Years().ToString(); + +var createSessionResult = await sdk.wallet.CreateSessionKey( + "0xSignerAddress", + approvedTargets, + nativeTokenLimitPerTransactionInWei, + permissionStartTimestamp, + permissionEndTimestamp, + reqValidityStartTimestamp, + reqValidityEndTimestamp +); + +// Get a list of current signers with permission details +List signers = await sdk.wallet.GetAllActiveSigners(); + +// Revoke a session key +var revokeSessionResult = await sdk.wallet.RevokeSessionKey("0xSignerAddress"); -// Alternatively, you can add an admin +// Add admin var addAdminResult = await sdk.wallet.AddAdmin("0xSignerAddress"); -// Or remove an admin +// Remove admin var removeAdminResult = await sdk.wallet.RemoveAdmin("0xSignerAddress"); -// This pairs well with the `smartWalletAccountOverride` option to connect to a specific smart wallet +// These features pair well with the `smartWalletAccountOverride` option to connect to a specific smart wallet var connection = new WalletConnection( ...options, smartWalletAccountOverride: "0xSmartWalletAddress" diff --git a/docs/unity/prefabs/ConnectWallet.mdx b/docs/unity/prefabs/ConnectWallet.mdx index 21988c7a8f..5c9aaf2613 100644 --- a/docs/unity/prefabs/ConnectWallet.mdx +++ b/docs/unity/prefabs/ConnectWallet.mdx @@ -28,21 +28,16 @@ From the `Inspector` window, you can configure the options for the `ConnectWalle The list of wallets you want to support. Each wallet you provide appears as a button in the dropdown. -Supports `EmbeddedWallet`, `MetaMask`, `Coinbase`, `WalletConnect`, `MagicLink`, `LocalWallet`, `Paper`, `SmartWallet`, `HyperPlay`, `Injected` (window.ethereum). +Supports `EmbeddedWallet`, `MetaMask`, `Coinbase`, `WalletConnect`, `LocalWallet`, `HyperPlay`, `Injected` (window.ethereum). Some wallet providers may not be supported on some native platforms. -### Personal Wallet +You can turn any of these wallets into a `SmartWallet` by checking the `Use Smart Wallets` checkbox. -When using Smart Wallets, you can set the EOA Wallet Provider that you'd like to initiate them with. Defaults to `LocalWallet`. +### Use Smart Wallets -### Custom Callbacks +When checked, the wallet provider will be wrapped in a `SmartWallet` which will allow you to use [SmartWallet features](/unity/wallet/SmartWallet). -Custom logic to run whenever an event occurs on the button, including: +### Events -- `OnConnected`: Triggered when the user connects their wallet successfully. -- `OnDisconnected`: Triggered when the user disconnects their wallet successfully. -- `OnSwitchNetwork`: Triggered when the user switches networks successfully. -- `OnFailedConnect`: Triggered when the user fails to connect their wallet. -- `OnFailedDisconnect`: Triggered when an error occurs after attempting to disconnect a wallet. -- `OnFailedSwitchNetwork`: Triggered when an error occurs after attempting to switch networks. +You can set up events to be triggered when the user connects, switches network or disconnects their wallet, from the inspector. diff --git a/sidebars/onboarding.js b/sidebars/onboarding.js index 40c66e9395..950218c827 100644 --- a/sidebars/onboarding.js +++ b/sidebars/onboarding.js @@ -98,6 +98,11 @@ const sidebars = { label: "Signature Minting", href: "/signature-minting", }, + { + type: "link", + label: "Gaming", + href: "/gaming", + }, { type: "link", label: "RPC Edge", @@ -108,6 +113,11 @@ const sidebars = { label: "Wallet SDK", href: "/wallet", }, + { + type: "link", + label: "NFT Checkouts", + href: "/checkouts", + }, { type: "link", label: "Dashboard", @@ -250,6 +260,13 @@ const sidebars = { }, ], + gaming: [ + { + type: "autogenerated", + dirName: "22 Gaming", + }, + ], + smartWallet: [ { type: "autogenerated", @@ -290,6 +307,13 @@ const sidebars = { }, ], + checkouts: [ + { + type: "autogenerated", + dirName: "22 NFT Checkouts", + }, + ], + connect: [ { type: "autogenerated", diff --git a/src/components/landing-page/PaymentsCardsSection.tsx b/src/components/landing-page/PaymentsCardsSection.tsx new file mode 100644 index 0000000000..3168ba36f4 --- /dev/null +++ b/src/components/landing-page/PaymentsCardsSection.tsx @@ -0,0 +1,41 @@ +import React from "react"; +import ProductCard from "./ProductCard"; + +type Product = { + image: string; + name: string; + description: string; + link: string; +}; + +const products: Product[] = [ + { + image: "/assets/product/checkout.png", + name: "NFT Checkout", + description: + "Secure payments flows that enable your users to purchase NFTs with their credit card", + link: "/checkouts", + }, +]; + +export default function PaymentsSection() { + return ( +
+

+ Payments +

+
+ {products.map((p, i) => ( +
+ +
+ ))} +
+
+ ); +} diff --git a/src/theme/DocSidebarItem/Link/index.js b/src/theme/DocSidebarItem/Link/index.js index d21e0ad7c7..3c9db84f06 100644 --- a/src/theme/DocSidebarItem/Link/index.js +++ b/src/theme/DocSidebarItem/Link/index.js @@ -42,6 +42,8 @@ export const iconMapping = { Engine: "/assets/product/sdk.png", "Bundler & Paymaster": "/assets/wallets/smart-wallet.svg", "RPC Edge": "/assets/product/sdk.png", + "NFT Checkouts": "/assets/product/checkout.png", + Gaming: "/assets/product/sdk.png", }; export default function DocSidebarItemLink({ diff --git a/src/theme/DocSidebarItems/index.js b/src/theme/DocSidebarItems/index.js index 54b7996cb2..74cda3abda 100644 --- a/src/theme/DocSidebarItems/index.js +++ b/src/theme/DocSidebarItems/index.js @@ -54,6 +54,10 @@ function DocSidebarItems({ items, ...props }) { title: "Infrastructure", items: ["Engine", "Storage", "RPC Edge"], }, + { + title: "Payments", + items: ["NFT Checkouts"], + }, { title: "Tools", items: ["CLI", "Dashboard"], @@ -72,7 +76,7 @@ function DocSidebarItems({ items, ...props }) { }, { title: "Solutions", - items: ["Signature Minting"], + items: ["Signature Minting", "Gaming"], }, { title: "Resources", diff --git a/static/assets/languages/unreal.jpg b/static/assets/languages/unreal.jpg new file mode 100644 index 0000000000..0a5ac84354 Binary files /dev/null and b/static/assets/languages/unreal.jpg differ diff --git a/static/assets/product/checkout.png b/static/assets/product/checkout.png new file mode 100644 index 0000000000..6a4fab3659 Binary files /dev/null and b/static/assets/product/checkout.png differ diff --git a/static/assets/solutions/apple-logo.png b/static/assets/solutions/apple-logo.png new file mode 100644 index 0000000000..a9b216ef29 Binary files /dev/null and b/static/assets/solutions/apple-logo.png differ diff --git a/static/assets/solutions/windows-logo.png b/static/assets/solutions/windows-logo.png new file mode 100644 index 0000000000..5daf592d47 Binary files /dev/null and b/static/assets/solutions/windows-logo.png differ diff --git a/static/assets/wallets/onekey.png b/static/assets/wallets/onekey.png new file mode 100644 index 0000000000..009bda5370 Binary files /dev/null and b/static/assets/wallets/onekey.png differ