|
| 1 | +import { Callout } from "@doc"; |
| 2 | +import { createMetadata, DocImage } from "@doc"; |
| 3 | +import lifecycleImage from "../assets/tx-lifecycle.webp"; |
| 4 | + |
| 5 | +export const metadata = createMetadata({ |
| 6 | + title: "Getting started with Engine | thirdweb Infrastructure", |
| 7 | + description: |
| 8 | + "Learn how to use Engine to manage your backend wallets and call contract methods", |
| 9 | +}); |
| 10 | + |
1 | 11 | # Get Started |
2 | 12 |
|
3 | | -Manage Engine from the dashboard |
4 | | -Check if Engine is set up |
5 | | -Tip: Navigate to your Engine URL. You should see the following response: Engine is set up successfully. |
| 13 | +Once you have Engine set up, learn the basics of Engine. |
| 14 | + |
| 15 | +## Learn how transactions work |
| 16 | + |
| 17 | +Blockchain **read** calls (e.g. get token balance) are synchronous and will return the value read. |
| 18 | + |
| 19 | +Blockchain **write** calls (e.g. transfer tokens) are asynchronous: |
| 20 | + |
| 21 | +- Your app backend sends a write transaction to Engine. |
| 22 | +- Engine enqueues the job and returns a reference to the job: `queueId`. |
| 23 | + - If `queueId` is returned, this transaction will be attempted. |
| 24 | + - If `queueId` is not returned, this transaction failed to be added to the queue and will not be attempted. |
| 25 | +- Engine will attempt to submit the transaction from your specified backend wallet. |
| 26 | + - If there is an error (failed simulation, out of gas), the transaction is set to `errored` and will not be re-attempted. |
| 27 | +- Engine polls to check if the transaction is mined. If it is, the transaction is set to `mined`. |
| 28 | +- If the transaction is not mined after some duration, Engine re-submits the transaction with aggressive gas settings. This transaction is sent with the same nonce and will be mined at most once. |
| 29 | + |
| 30 | +<DocImage |
| 31 | + src={lifecycleImage} |
| 32 | + alt="Transaction lifecycle" |
| 33 | + className="max-w-[800px] mx-auto" |
| 34 | +/> |
| 35 | + |
| 36 | +## Learn what each transaction status means |
| 37 | + |
| 38 | +- **Queued**: The transaction was received by Engine and waiting in the transaction queue. |
| 39 | +- **Sent**: The transaction was successfully sent to RPC. |
| 40 | +- **Mined**: The transaction was successfully mined onchain. |
| 41 | +- **Cancelled**: The transaction was cancelled by the user. |
| 42 | +- **Errored**: The transaction failed to be sent to RPC or to the chain's nodes. This can happen for many reasons (malformed transaction, failed simulation, too low gas). |
| 43 | + |
| 44 | +## Manage Engine from the dashboard |
| 45 | + |
| 46 | +<Callout variant='info' title="Check if Engine is set up"> |
6 | 47 |
|
7 | | -Navigate to the thirdweb Engine dashboard to manage your Engine instances. |
| 48 | +Tip: Navigate to your Engine URL. You should see the following response: `Engine is set up successfully.` |
8 | 49 |
|
9 | | -Overview |
| 50 | +</Callout> |
10 | 51 |
|
11 | | -View your backend wallets. |
12 | | -Create a backend wallet. |
13 | | -View recent transactions. |
14 | | -View transaction details (e.g. error messages, gas used). |
15 | | -Cancel a queued transaction. |
16 | | -Explorer |
| 52 | +Navigate to the [thirdweb Engine dashboard](https://thirdweb.com/team/~/~/engine) to manage your Engine instances. |
17 | 53 |
|
18 | | -Interactively view and call your Engine API. |
19 | | -Relayer |
| 54 | +**Overview** |
20 | 55 |
|
21 | | -View relayers. |
22 | | -Add or remove relayers. |
23 | | -Configuration |
| 56 | +- View your backend wallets. |
| 57 | +- Create a backend wallet. |
| 58 | +- View recent transactions. |
| 59 | +- View transaction details (e.g. error messages, gas used). |
| 60 | +- Cancel a queued transaction. |
24 | 61 |
|
25 | | -Change backend wallet types. |
26 | | -View webhooks. |
27 | | -Add and remove webhooks. |
28 | | -Permissions |
| 62 | +**Explorer** |
| 63 | + |
| 64 | +- Interactively view and call your Engine API. |
| 65 | + |
| 66 | +**Relayer** |
| 67 | + |
| 68 | +- View relayers. |
| 69 | +- Add or remove relayers. |
| 70 | + |
| 71 | +**Configuration** |
| 72 | + |
| 73 | +- Change backend wallet types. |
| 74 | +- View webhooks. |
| 75 | +- Add and remove webhooks. |
| 76 | + |
| 77 | +**Permissions** |
| 78 | + |
| 79 | +- View admin users. |
| 80 | +- Add and remove admin users. |
| 81 | +- View access tokens. |
| 82 | +- Create and revoke access tokens. |
| 83 | + |
| 84 | +## Manage permissions |
29 | 85 |
|
30 | | -View admin users. |
31 | | -Add and remove admin users. |
32 | | -View access tokens. |
33 | | -Create and revoke access tokens. |
34 | | -Manage permissions |
35 | 86 | Engine endpoints require authentication. |
36 | 87 |
|
37 | | -Add other admins for other users to manage Engine from the dashboard. |
38 | | -Create access tokens for your backends to call the Engine API. These are secrets that should be stored securely. |
39 | | -Revoke permissions at any time. |
40 | | -Learn more about admins and access tokens. |
| 88 | +- Add other **admins** for other users to manage Engine from the dashboard. |
| 89 | +- Create **access tokens** for your backends to call the Engine API. _These are secrets that should be stored securely._ |
| 90 | +- Revoke permissions at any time. |
| 91 | + |
| 92 | +Learn more about [admins](/engine/features/admins) and [access tokens](/engine/features/access-tokens). |
| 93 | + |
| 94 | +## Create backend wallets |
41 | 95 |
|
42 | | -Create backend wallets |
43 | | -Backend wallet are your wallets managed by Engine. Engine will send blockchain transactions from these wallets. |
| 96 | +**Backend wallet** are your wallets managed by Engine. Engine will send blockchain transactions from these wallets. |
44 | 97 |
|
45 | | -Configure how to back up wallets. |
46 | | -Create or import a backend wallet. |
47 | | -Specify the backend wallet to use when calling the Engine API. |
48 | | -Learn more about backend wallets. |
| 98 | +- Configure how to back up wallets. |
| 99 | +- Create or import a backend wallet. |
| 100 | +- Specify the backend wallet to use when calling the Engine API. |
| 101 | + |
| 102 | +[Learn more about backend wallets.](/engine/features/backend-wallets) |
| 103 | + |
| 104 | +## Interact with the blockchain |
49 | 105 |
|
50 | | -Interact with the blockchain |
51 | 106 | Here are a few example API calls. |
52 | 107 |
|
53 | | -Tip: Use the TypeScript SDK for type-safety. |
| 108 | +<Callout variant='info'> |
| 109 | + |
| 110 | +Tip: Use the [TypeScript SDK](/engine/references/typescript) for type-safety. |
| 111 | + |
| 112 | +</Callout> |
| 113 | + |
| 114 | +### Get a wallet's balance |
54 | 115 |
|
55 | | -Get a wallet's balance |
| 116 | +```ts |
56 | 117 | const resp = await fetch( |
57 | | - "<engine_url>/backend-wallet/<chain>/<backend_wallet_address>/get-balance", |
58 | | - { |
59 | | - headers: { |
60 | | - Authorization: "Bearer <access_token>", |
61 | | - }, |
62 | | - }, |
| 118 | + "<engine_url>/backend-wallet/<chain>/<backend_wallet_address>/get-balance", |
| 119 | + { |
| 120 | + headers: { |
| 121 | + Authorization: "Bearer <access_token>", |
| 122 | + }, |
| 123 | + }, |
63 | 124 | ); |
64 | | - |
| 125 | + |
65 | 126 | const { result } = await resp.json(); |
66 | 127 | console.log("Balance:", result.value); |
| 128 | +``` |
| 129 | + |
| 130 | +### Read from a contract |
67 | 131 |
|
68 | | -Read from a contract |
69 | 132 | This code example does not require gas funds and returns the function result. |
70 | 133 |
|
| 134 | +```ts |
71 | 135 | const resp = await fetch( |
72 | | - "<engine_url>/contract/<chain>/<contract_address>/read?functionName=balanceOf&args=0x3EcDBF3B911d0e9052b64850693888b008e18373", |
73 | | - { |
74 | | - headers: { |
75 | | - Authorization: "Bearer <access_token>", |
76 | | - }, |
77 | | - }, |
| 136 | + "<engine_url>/contract/<chain>/<contract_address>/read?functionName=balanceOf&args=0x3EcDBF3B911d0e9052b64850693888b008e18373", |
| 137 | + { |
| 138 | + headers: { |
| 139 | + Authorization: "Bearer <access_token>", |
| 140 | + }, |
| 141 | + }, |
78 | 142 | ); |
79 | | - |
| 143 | + |
80 | 144 | const { result } = await resp.json(); |
81 | 145 | console.log("ERC-20 balance:", result); |
| 146 | +``` |
82 | 147 |
|
83 | | -Write to a contract |
84 | | -This code example calls a write method on a contract. It requires gas funds and returns a queueId to query for the result. |
| 148 | +### Write to a contract |
85 | 149 |
|
| 150 | +This code example calls a write method on a contract. It requires gas funds and returns a `queueId` to query for the result. |
| 151 | + |
| 152 | +```ts |
86 | 153 | const resp = await fetch( |
87 | | - "<engine_url>/contract/<chain>/<contract_address>/write", |
88 | | - { |
89 | | - method: "POST", |
90 | | - headers: { |
91 | | - "Content-Type": "application/json", |
92 | | - Authorization: "Bearer <access_token>", |
93 | | - "x-backend-wallet-address": "<backend_wallet_address>", |
94 | | - }, |
95 | | - body: JSON.stringify({ |
96 | | - functionName: "transferFrom", |
97 | | - args: [ |
98 | | - "0x1946267d81Fb8aDeeEa28e6B98bcD446c8248473", |
99 | | - "0x3EcDBF3B911d0e9052b64850693888b008e18373", |
100 | | - "0", |
101 | | - ], |
102 | | - }), |
103 | | - }, |
| 154 | + "<engine_url>/contract/<chain>/<contract_address>/write", |
| 155 | + { |
| 156 | + method: "POST", |
| 157 | + headers: { |
| 158 | + "Content-Type": "application/json", |
| 159 | + Authorization: "Bearer <access_token>", |
| 160 | + "x-backend-wallet-address": "<backend_wallet_address>", |
| 161 | + }, |
| 162 | + body: JSON.stringify({ |
| 163 | + functionName: "transferFrom", |
| 164 | + args: [ |
| 165 | + "0x1946267d81Fb8aDeeEa28e6B98bcD446c8248473", |
| 166 | + "0x3EcDBF3B911d0e9052b64850693888b008e18373", |
| 167 | + "0", |
| 168 | + ], |
| 169 | + }), |
| 170 | + }, |
104 | 171 | ); |
105 | | - |
| 172 | + |
106 | 173 | const { result } = await resp.json(); |
107 | 174 | // queueId is a reference to the transaction queued by Engine. |
108 | 175 | console.log("Queue ID:", result.queueId); |
| 176 | +``` |
| 177 | + |
| 178 | +### Deploy a contract |
| 179 | + |
| 180 | +This code example deploys a [thirdweb NFT drop contract](https://thirdweb.com/thirdweb.eth/DropERC721). It requires gas funds and returns a `queueId` to query for the result. |
| 181 | + |
| 182 | +```ts |
| 183 | +const resp = await fetch("<engine_url>/deploy/<chain>/prebuilts/nft-drop", { |
| 184 | + method: "POST", |
| 185 | + headers: { |
| 186 | + "Content-Type": "application/json", |
| 187 | + Authorization: "Bearer <access_token>", |
| 188 | + "x-backend-wallet-address": "<backend_wallet_address>", |
| 189 | + }, |
| 190 | + body: JSON.stringify({ |
| 191 | + contractMetadata: { |
| 192 | + name: "thirdweb Engine example", |
| 193 | + symbol: "eng", |
| 194 | + primary_sale_recipient: "0x3EcDBF3B911d0e9052b64850693888b008e18373", |
| 195 | + }, |
| 196 | + }), |
| 197 | +}); |
109 | 198 |
|
110 | | -Deploy a contract |
111 | | -This code example deploys a thirdweb NFT drop contract. It requires gas funds and returns a queueId to query for the result. |
112 | | - |
113 | | -const resp = await fetch( |
114 | | - "<engine_url>/deploy/<chain>/prebuilts/nft-drop", |
115 | | - { |
116 | | - method: "POST", |
117 | | - headers: { |
118 | | - "Content-Type": "application/json", |
119 | | - Authorization: "Bearer <access_token>", |
120 | | - "x-backend-wallet-address": "<backend_wallet_address>", |
121 | | - }, |
122 | | - body: JSON.stringify({ |
123 | | - contractMetadata: { |
124 | | - name: "thirdweb Engine example", |
125 | | - symbol: "eng", |
126 | | - primary_sale_recipient: |
127 | | - "0x3EcDBF3B911d0e9052b64850693888b008e18373", |
128 | | - }, |
129 | | - }), |
130 | | - }, |
131 | | -); |
132 | | - |
133 | 199 | const { result } = await resp.json(); |
134 | 200 | // queueId is a reference to the transaction queued by Engine. |
135 | 201 | console.log("Queue ID:", result.queueId); |
| 202 | +``` |
136 | 203 |
|
137 | 204 | Engine can enable your application to airdrop NFTs, send funds between wallets, update onchain game state, and more. |
138 | 205 |
|
139 | | -Check the status of a transaction |
140 | | -const resp = await fetch( |
141 | | - "<engine_url>/transaction/status/<queue_id>", |
142 | | - { |
143 | | - method: "GET", |
144 | | - headers: { |
145 | | - Authorization: "Bearer <access_token>", |
146 | | - }, |
147 | | - }, |
148 | | -); |
149 | | - |
| 206 | +### Check the status of a transaction |
| 207 | + |
| 208 | +```ts |
| 209 | +const resp = await fetch("<engine_url>/transaction/status/<queue_id>", { |
| 210 | + method: "GET", |
| 211 | + headers: { |
| 212 | + Authorization: "Bearer <access_token>", |
| 213 | + }, |
| 214 | +}); |
| 215 | + |
150 | 216 | const { result } = await resp.json(); |
151 | 217 | // status can be: processed, queued, sent, errored, mined, cancelled, retried |
152 | | -const isComplete = ["mined", "errored", "cancelled"].includes( |
153 | | - result.status, |
154 | | -); |
| 218 | +const isComplete = ["mined", "errored", "cancelled"].includes(result.status); |
| 219 | +``` |
| 220 | + |
| 221 | +## Configure webhooks |
155 | 222 |
|
156 | | -Configure webhooks |
157 | 223 | Get notified when a transaction is mined, in addition to other wallet and transaction events. |
158 | 224 |
|
159 | | -Navigate to the Webhooks tab on the Engine dashboard. |
160 | | -Create a new webhook URL. |
161 | | -Learn more about webhooks. |
| 225 | +- Navigate to the **Webhooks** tab on the Engine dashboard. |
| 226 | +- Create a new webhook URL. |
| 227 | + |
| 228 | +[Learn more about webhooks.](/engine/features/webhooks) |
0 commit comments