Aztec QuickstartSDK
← Quest map

Deploy

Locally#

With your local network still running (from Getting Started):

bash
npm run deploy

It writes packages/app/src/deployments/local.json (address, election, candidates) that the frontend reads.

deploy.ts doesn't issue raw transactions — it's a declarative spec for a tiny deploy framework. You describe the contracts that must end up on-chain and the txs to send; the engine resolves deterministic addresses, takes an on-chain inventory, and runs only what's still missing, in dependency order:

typescript
steps: {
  // The voting contract is published on-chain; its initializer takes the admin address.
  voting: {
    kind: "contract",
    contract: PrivateVotingContract,
    deployer: (resolve) => resolve.account("admin"),
    initializerArgs: (resolve) => [resolve.account("admin")],
    mode: "publish",
  },
  // Off local, the frontend pays via this fully-private FPC. We only need its
  // deterministic address (no tx); the frontend rebuilds + registers it itself.
  ...(network === "local"
    ? {}
    : {
        fpc: {
          kind: "contract" as const,
          contract: PrivateFeeJuiceContract,
          deployer: (resolve) => resolve.account("admin"),
          salt: FPC_SALT,
          mode: "register" as const,
        },
      }),
  // Open the demo election so the frontend can cast votes immediately. `vote_active`
  // is the idempotency gate — `start_vote` reverts if called twice.
  startVote: {
    kind: "action",
    from: (resolve) => resolve.account("admin"),
    dependsOn: ["voting"],
    call: (ctx) => ctx.instance("voting").methods.start_vote(ELECTION),
    done: async (ctx) => {
      const { result } = await ctx
        .instance("voting")
        .methods.vote_active(ELECTION)
        .simulate({ from: ctx.account("admin") });
      return Boolean(result);
    },
  },
},

Each contract address is a deterministic function of (class, deployer, salt, args), so the run is idempotent — re-running only does what's missing (here, start_vote is gated behind its own vote_active check). On local, fees are paid by the SponsoredFPC; the JSON the frontend reads is written to packages/app/src/deployments/local.json.

Ready to go beyond local? Deploy to testnet is a side quest from here.