Getting Started
Engine is self-hosted with minimal configuration.
Setup
Requirements
- Docker
- A thirdweb secret key from the API Keys page
Start the database
A Postgres DB instance is required to run Engine. AWS RDS/Google Cloud SQL is recommended for production use.
Or run Postgres locally to get started quickly:
docker run -p 5432:5432 -e POSTGRES_PASSWORD=postgres -d postgres
This step provides a local Postgres DB URL for the next step:
POSTGRES_CONNECTION_URL="postgresql://postgres:postgres@host.docker.internal:5432/postgres?sslmode=disable"
Start the server
Download and run the Docker container:
docker run \
-e THIRDWEB_API_SECRET_KEY="<thirdweb_secret_key>" \
-e ADMIN_WALLET_ADDRESS="<admin_wallet_address>" \
-e POSTGRES_CONNECTION_URL="<postgres_connection_url>" \
-e ENABLE_HTTPS=true \
-p 3005:3005 \
--pull=always \
--cpus="0.5" \
thirdweb/engine:latest
Provide the following environment variables:
Variable | Description |
---|---|
THIRDWEB_SECRET_KEY | A thirdweb secret key created on the API Keys page. |
ADMIN_WALLET_ADDRESS | The wallet address that will configure Engine from the thirdweb dashboard. |
POSTGRES_CONNECTION_URL | Postgres connection string: postgresql://[user[:password]@][host][:port][/dbname][?param1=value1&...] |
ENABLE_HTTPS | Self-sign a certificate to serve API requests on HTTPS. Set to true if running Engine locally to manage it from the thirdweb dashboard. (Default: false ) |
Your server is running when this log line appears:
Server listening on: https://0.0.0.0:3005
Here's a few pointers:
ENABLE_HTTPS=true
is only required when running Engine locally. Remove this line for production use.- Make sure your Engine instance port (default:
3005
) is publicly accessible. All configuration and API requests require authentication. - The
nightly
Docker image may contain new, undocumented, and possibly breaking changes. We appreciate feedback!
Use the dashboard
Sign in
To manage your Engine instance from the dashboard:
Navigate to https://localhost:3005/json.
- The "Your connection is not private" page will appear.
- Select Show advanced and select Proceed to localhost (unsafe) to render the JSON file.
- This one-time step allows your browser to connect to your local Engine instance.
Navigate to the Engine dashboard page.
Sign in with the
<admin_wallet_address>
wallet.Select Set Engine instance URL to get started.
Add your publicly accessible Engine URL.
- If Engine is running locally, provide the URL
https://localhost:3005
.
- If Engine is running locally, provide the URL
Overview
In the Overview dashboard section:
- View your backend wallets.
- Create a backend wallet.
- View recent transactions.
- Cancel a queued transaction.
Explorer
In the Explorer dashboard section:
- Interactively view and call your Engine API.
Configuration
In the Configuration dashboard section:
- Change backend wallet types.
- View webhooks.
- Add and remove webhooks.
Permissions
In the Permissions dashboard section:
- View admin users.
- Add and remove admin users.
- View access tokens.
- Create and revoke access tokens.
Use Engine
Use Engine to manage your backend wallets and call contract methods with one API call. Here's some examples:
Get a wallet's balance
const resp = await fetch(
"<engine_url>/backend-wallet/<chain>/<backend_wallet_address>/get-balance",
{
headers: {
Authorization: "Bearer <access_token>",
},
},
);
const { result } = await resp.json();
console.log("Balance:", result.value);
Read from a contract
This code example does not require gas funds and returns the function result.
const resp = await fetch(
"<engine_url>/contract/<chain>/<contract_address>/read?functionName=balanceOf&args=0x3EcDBF3B911d0e9052b64850693888b008e18373",
{
headers: {
Authorization: "Bearer <access_token>",
},
},
);
const { result } = await resp.json();
console.log("ERC-20 balance:", result);
Write to a contract
This code example calls a write method on a contract. It requires gas funds and returns a queueId
to query for the result.
const resp = await fetch(
"<engine_url>/contract/<chain>/<contract_address>/write",
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer <access_token>",
"x-backend-wallet-address": "<backend_wallet_address>",
},
body: JSON.stringify({
functionName: "transferFrom",
args: [
"0x1946267d81Fb8aDeeEa28e6B98bcD446c8248473",
"0x3EcDBF3B911d0e9052b64850693888b008e18373",
"0",
],
}),
},
);
const { result } = await resp.json();
// queueId is a reference to the transaction queued by Engine.
console.log("Queue ID:", result.queueId);
Deploy a contract
This code example deploys a thirdweb NFT drop contract. It requires gas funds and returns a queueId
to query for the result.
const resp = await fetch("<engine_url>/deploy/<chain>/prebuilts/nft-drop", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer <access_token>",
"x-backend-wallet-address": "<backend_wallet_address>",
},
body: JSON.stringify({
contractMetadata: {
name: "thirdweb Engine example",
symbol: "eng",
primary_sale_recipient: "0x3EcDBF3B911d0e9052b64850693888b008e18373",
},
}),
});
const { result } = await resp.json();
// queueId is a reference to the transaction queued by Engine.
console.log("Queue ID:", result.queueId);
Engine can enable your application to airdrop NFTs, send funds between wallets, update on-chain game state, and more.
Wait for a transaction to complete
Trigger an action when transactions complete by configuring webhooks to call your backend server.
Alternatively, query or poll the transaction/status/<queue_id>
endpoint:
const resp = await fetch("<engine_url>/transaction/status/<queue_id>", {
method: "GET",
headers: {
Authorization: "Bearer <access_token>",
},
});
const { result } = await resp.json();
// status can be: processed, queued, sent, errored, mined, cancelled, retried
const isComplete = ["mined", "errored", "cancelled"].includes(result.status);