Skip to content

Commit d388476

Browse files
feat: add devnet support
1 parent f65c0a4 commit d388476

7 files changed

Lines changed: 273 additions & 37 deletions

File tree

README.md

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ ACURAST_MNEMONIC=abandon abandon about ...
119119

120120
- `projectName`: The name of the project.
121121
- `fileUrl`: The path to the bundled file, including all dependencies (e.g., `dist/bundle.js`).
122-
- `network`: The network on which the project will be deployed. (e.g. `mainnet`)
122+
- `network`: The network on which the project will be deployed. One of `mainnet`, `canary`, or `devnet`. See [Networks](#networks) for endpoint defaults and how to override them via env vars.
123123
- `onlyAttestedDevices`: A boolean to specify if only attested devices are allowed to run the app.
124124
- `enableDevtools`: A boolean to enable [DevTools](#devtools) for the deployment. When enabled, console logs from processor executions are forwarded to the DevTools dashboard. Defaults to `false`.
125125
- `startAt`: The start time of the deployment.
@@ -172,7 +172,65 @@ ACURAST_MNEMONIC=abandon abandon about ...
172172
`ACURAST_MNEMONIC`: The mnemonic used to deploy the app. Make sure the account has some ACU (or cACU for canary network)! You can claim cACU on the [faucet](https://faucet.acurast.com) for canary testing.
173173
`ACURAST_IPFS_URL` (optional): The URL of the IPFS gateway, eg. `https://api.pinata.cloud`.
174174
`ACURAST_IPFS_API_KEY` (optional): The API key to access the IPFS gateway. You can [register here](https://pinata.cloud/) to get an API key.
175-
`ACURAST_RPC` (optional): Set an RPC URL to connect to.
175+
`ACURAST_RPC` (optional, deprecated): Set an RPC URL to connect to. Kept for backward compatibility — prefer `ACURAST_MAINNET_RPC`.
176+
177+
#### Networks
178+
179+
The CLI supports three networks: `mainnet` (default), `canary`, and `devnet`. Set `"network"` in your `acurast.json` project entry, or pass `--network` to commands that accept it (`acurast deployments ...`).
180+
181+
Each network resolves an RPC endpoint, a matcher URL, and an indexer (with API key). The defaults below ship with the CLI; set the matching env var to override.
182+
183+
| Network | Purpose | RPC default | Faucet |
184+
| ------- | -------------------------------- | ----------------------------------------------------- | ---------------------------- |
185+
| mainnet | Production, real ACU | `wss://archive.mainnet.acurast.com` | n/a (see docs to get ACU) |
186+
| canary | Public test network | `wss://canarynet-ws-1.acurast-h-server-2.papers.tech` | `https://faucet.acurast.com` |
187+
| devnet | Internal/staging dev environment | `wss://acurast-devnet-ws.prod.gke.papers.tech` | n/a (request from Acurast) |
188+
189+
##### RPC overrides
190+
191+
| Env var | Network applied to | Default |
192+
| --------------------- | ------------------ | -------------------------------------------------------- |
193+
| `ACURAST_MAINNET_RPC` | mainnet | `wss://archive.mainnet.acurast.com` |
194+
| `ACURAST_RPC` | mainnet (legacy) | same as above; honoured when `ACURAST_MAINNET_RPC` unset |
195+
| `ACURAST_CANARY_RPC` | canary | `wss://canarynet-ws-1.acurast-h-server-2.papers.tech` |
196+
| `ACURAST_DEVNET_RPC` | devnet | `wss://acurast-devnet-ws.prod.gke.papers.tech` |
197+
198+
The connected RPC URL is written to `.acurast/acurast.log` (file log) on every connection — useful when debugging which endpoint a command actually used.
199+
200+
##### Matcher overrides
201+
202+
The matcher API provides live processor pricing. If unset (or unreachable), the CLI falls back to a static fee estimate.
203+
204+
| Env var | Network | Default |
205+
| ------------------------- | ------- | --------------------------------------------------- |
206+
| `ACURAST_MAINNET_MATCHER` | mainnet | `https://matcher.mainnet.acurast.com` |
207+
| `ACURAST_CANARY_MATCHER` | canary | `https://matcher.canary.acurast.com` |
208+
| `ACURAST_DEVNET_MATCHER` | devnet | _unset_ — set this if a devnet matcher is available |
209+
210+
##### Indexer overrides
211+
212+
The indexer powers `acurast deployments ls`. Devnet has no public default — set the env vars below if you need to list deployments on devnet.
213+
214+
| Env var | Network | Default |
215+
| --------------------------------- | ------- | -------------------------------------------------------- |
216+
| `ACURAST_MAINNET_INDEXER` | mainnet | `https://dev.indexer.mainnet.acurast.com/api/v1/rpc` |
217+
| `ACURAST_MAINNET_INDEXER_API_KEY` | mainnet | _shipped default_ |
218+
| `ACURAST_CANARY_INDEXER` | canary | `https://dev.indexer.canary.acurast.com/api/v1/rpc` |
219+
| `ACURAST_CANARY_INDEXER_API_KEY` | canary | _shipped default_ |
220+
| `ACURAST_DEVNET_INDEXER` | devnet | _unset — required for `deployments ls --network devnet`_ |
221+
| `ACURAST_DEVNET_INDEXER_API_KEY` | devnet | _unset_ |
222+
223+
##### Example `.env` for devnet
224+
225+
```
226+
ACURAST_MNEMONIC=abandon abandon about ...
227+
ACURAST_DEVNET_RPC=wss://acurast-devnet-ws.prod.gke.papers.tech
228+
ACURAST_DEVNET_MATCHER=https://matcher.devnet.acurast.com
229+
ACURAST_DEVNET_INDEXER=https://dev.indexer.devnet.acurast.com/api/v1/rpc
230+
ACURAST_DEVNET_INDEXER_API_KEY=<your-key>
231+
```
232+
233+
Then in `acurast.json` set `"network": "devnet"` on the project entry.
176234

177235
## Live Code Feature
178236

@@ -323,7 +381,7 @@ acurast deployments 123456 --cleanup
323381

324382
**Options**:
325383

326-
- `-n, --network <network>`: Network to use (`mainnet` or `canary`). Defaults to `mainnet`. When working with a specific deployment ID, the network is automatically detected from the deployment file if available.
384+
- `-n, --network <network>`: Network to use (`mainnet`, `canary`, or `devnet`). Defaults to `mainnet`. When working with a specific deployment ID, the network is automatically detected from the deployment file if available. Devnet requires `ACURAST_DEVNET_INDEXER` (and optional API key) for `ls`/`cleanup` flows.
327385
- `-e, --update-env-vars`: Update environment variables for a deployment.
328386
- `-c, --cleanup`: Remove old, finished deployments and return unused funds.
329387

@@ -509,7 +567,11 @@ To use it, set `runtime` to `"Shell"` and provide an `image` (URL + SHA256). The
509567
"assignmentStrategy": { "type": "Single" },
510568
"execution": { "type": "onetime", "maxExecutionTimeInMs": 60000 },
511569
"maxAllowedStartDelayInMs": 10000,
512-
"usageLimit": { "maxMemory": 0, "maxNetworkRequests": 0, "maxStorage": 0 },
570+
"usageLimit": {
571+
"maxMemory": 0,
572+
"maxNetworkRequests": 0,
573+
"maxStorage": 0
574+
},
513575
"numberOfReplicas": 1,
514576
"requiredModules": [],
515577
"minProcessorReputation": 0,

src/commands/deploy.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ import {
1818
isStartAtTimestamp,
1919
} from '@acurast/sdk/chain'
2020
import {
21-
validateConfig,
2221
DeploymentStatus,
2322
AssignmentStrategyVariant,
2423
} from '@acurast/sdk/types'
24+
import { validateCliConfig } from '../util/validateCliConfig.js'
2525
import type {
2626
JobRegistration,
2727
AcurastProjectConfig,
@@ -279,7 +279,7 @@ export const addCommandDeploy = (program: Command) => {
279279
throw new Error('No project found')
280280
}
281281

282-
const configResult = validateConfig(config)
282+
const configResult = validateCliConfig(config)
283283

284284
if (!configResult.success) {
285285
log('')
@@ -341,6 +341,9 @@ export const addCommandDeploy = (program: Command) => {
341341
})
342342

343343
const rpcEndpoint = getRpcForNetwork(config.network)
344+
filelogger.info(
345+
`Connecting to ${config.network} RPC: ${rpcEndpoint}`
346+
)
344347
const wsProvider = new WsProvider(rpcEndpoint)
345348
const api = await ApiPromise.create({
346349
provider: wsProvider,

src/commands/deployments.ts

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ import {
2020
getProjectEnvVars,
2121
getRpcForNetwork,
2222
getSymbolForNetwork,
23+
type CliNetwork,
2324
} from '../config.js'
25+
import { filelogger } from '../util/fileLogger.js'
2426
import * as ora from '../util/ora.js'
2527
import { ACURAST_DEPLOYMENTS_PATH } from '../constants.js'
2628
import { LocalStorage } from '../util/LocalStorage.js'
@@ -43,8 +45,11 @@ export const addCommandDeployments = (program: Command) => {
4345
)
4446
)
4547
.addOption(
46-
new Option('-n, --network <network>', 'Network to use (mainnet or canary)')
47-
.choices(['mainnet', 'canary'])
48+
new Option(
49+
'-n, --network <network>',
50+
'Network to use (mainnet, canary, or devnet)'
51+
)
52+
.choices(['mainnet', 'canary', 'devnet'])
4853
.default('mainnet')
4954
)
5055
.action(
@@ -53,7 +58,7 @@ export const addCommandDeployments = (program: Command) => {
5358
options: {
5459
updateEnvVars?: boolean
5560
cleanup?: boolean
56-
network: 'mainnet' | 'canary'
61+
network: CliNetwork
5762
}
5863
) => {
5964
const wallet = await walletFromMnemonic(getEnv('ACURAST_MNEMONIC'), {
@@ -151,10 +156,14 @@ export const addCommandDeployments = (program: Command) => {
151156
const deploymentId = Number(arg)
152157

153158
if (options.cleanup) {
154-
const network =
155-
(deploymentId && readDeploymentFile(deploymentId)?.config.network) ||
156-
options.network
157-
const acurast = new AcurastService(getRpcForNetwork(network))
159+
const network = ((deploymentId &&
160+
readDeploymentFile(deploymentId)?.config.network) ||
161+
options.network) as CliNetwork
162+
const rpcForCleanup = getRpcForNetwork(network)
163+
filelogger.info(
164+
`Connecting to ${network} RPC: ${rpcForCleanup}`
165+
)
166+
const acurast = new AcurastService(rpcForCleanup)
158167

159168
if (deploymentId) {
160169
const spinner = ora.default(
@@ -182,6 +191,9 @@ export const addCommandDeployments = (program: Command) => {
182191
console.log(`Found ${filteredJobs.length} deployments to clean up`)
183192

184193
const rpcEndpoint = getRpcForNetwork(network)
194+
filelogger.info(
195+
`Connecting to ${network} RPC: ${rpcEndpoint}`
196+
)
185197
const wsProvider = new WsProvider(rpcEndpoint)
186198
const api = await ApiPromise.create({
187199
provider: wsProvider,
@@ -222,8 +234,9 @@ export const addCommandDeployments = (program: Command) => {
222234
return
223235
}
224236

225-
const network = deploymentFileData.config.network
237+
const network = deploymentFileData.config.network as CliNetwork
226238
const rpcEndpoint = getRpcForNetwork(network)
239+
filelogger.info(`Connecting to ${network} RPC: ${rpcEndpoint}`)
227240

228241
const job: Job & { envVars?: EnvVar[] } = {
229242
id: deploymentFileData.deploymentId!,
@@ -332,16 +345,19 @@ export const addCommandDeployments = (program: Command) => {
332345
'IPFS hash of the new script (e.g., "ipfs://QmNewScriptHash")'
333346
)
334347
.addOption(
335-
new Option('-n, --network <network>', 'Network to use (mainnet or canary)')
336-
.choices(['mainnet', 'canary'])
348+
new Option(
349+
'-n, --network <network>',
350+
'Network to use (mainnet, canary, or devnet)'
351+
)
352+
.choices(['mainnet', 'canary', 'devnet'])
337353
.default('mainnet')
338354
)
339355
.addOption(new Option('--dry-run', 'Preview the update without applying'))
340356
.action(
341357
async (
342358
deploymentId: string,
343359
scriptIpfs: string,
344-
options: { dryRun?: boolean; network: 'mainnet' | 'canary' }
360+
options: { dryRun?: boolean; network: CliNetwork }
345361
) => {
346362
const parsed = parseDeploymentId(deploymentId)
347363
if (!parsed) return
@@ -364,7 +380,9 @@ export const addCommandDeployments = (program: Command) => {
364380
name: 'AcurastCli',
365381
})
366382

367-
const acurast = new AcurastService(getRpcForNetwork(options.network))
383+
const rpcForUpdate = getRpcForNetwork(options.network)
384+
filelogger.info(`Connecting to ${options.network} RPC: ${rpcForUpdate}`)
385+
const acurast = new AcurastService(rpcForUpdate)
368386
const spinner = ora.default(
369387
`Updating script for deployment [${parsed.origin}, ${parsed.address}, ${parsed.number}]...`
370388
)
@@ -403,8 +421,11 @@ export const addCommandDeployments = (program: Command) => {
403421
'The AccountId32 address of the new editor'
404422
)
405423
.addOption(
406-
new Option('-n, --network <network>', 'Network to use (mainnet or canary)')
407-
.choices(['mainnet', 'canary'])
424+
new Option(
425+
'-n, --network <network>',
426+
'Network to use (mainnet, canary, or devnet)'
427+
)
428+
.choices(['mainnet', 'canary', 'devnet'])
408429
.default('mainnet')
409430
)
410431
.addOption(
@@ -414,7 +435,7 @@ export const addCommandDeployments = (program: Command) => {
414435
async (
415436
deploymentId: string,
416437
newEditorAddress: string,
417-
options: { dryRun?: boolean; network: 'mainnet' | 'canary' }
438+
options: { dryRun?: boolean; network: CliNetwork }
418439
) => {
419440
const parsed = parseDeploymentId(deploymentId)
420441
if (!parsed) return
@@ -437,7 +458,9 @@ export const addCommandDeployments = (program: Command) => {
437458
name: 'AcurastCli',
438459
})
439460

440-
const acurast = new AcurastService(getRpcForNetwork(options.network))
461+
const rpcForUpdate = getRpcForNetwork(options.network)
462+
filelogger.info(`Connecting to ${options.network} RPC: ${rpcForUpdate}`)
463+
const acurast = new AcurastService(rpcForUpdate)
441464
const spinner = ora.default(
442465
`Transferring editor permissions for deployment [${parsed.origin}, ${parsed.address}, ${parsed.number}]...`
443466
)

src/commands/estimate-fee.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { Command, Option } from 'commander'
22
import { loadAcurastConfig } from '@acurast/sdk/deploy'
33
import { walletFromMnemonic } from '@acurast/sdk/chain'
4-
import { validateConfig } from '@acurast/sdk/types'
54

5+
import { validateCliConfig } from '../util/validateCliConfig.js'
66
import { consoleOutput } from '../util/console-output.js'
77
import { filelogger } from '../util/fileLogger.js'
88
import * as ora from '../util/ora.js'
@@ -36,7 +36,7 @@ export const addCommandEstimateFee = (program: Command) => {
3636
throw new Error('No project found')
3737
}
3838

39-
const configResult = validateConfig(config)
39+
const configResult = validateCliConfig(config)
4040

4141
if (!configResult.success) {
4242
log('')

src/commands/live.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ export const addCommandLive = (program: Command) => {
121121
const job = convertConfigToJob(config)
122122

123123
const rpcEndpoint = getRpcForNetwork(config.network)
124+
filelogger.info(
125+
`Connecting to ${config.network} RPC: ${rpcEndpoint}`
126+
)
124127

125128
;(async () => {
126129
const wallet = await walletFromMnemonic(getEnv('ACURAST_MNEMONIC'), {

0 commit comments

Comments
 (0)