Mysten Incubation
Configure your stack

Accounts and wallet

Named identities, funding, and the dev wallet.

Declare the identities your app and tests sign with using account(name, opts?). The bare form gives you a ready-to-use account: it creates an ephemeral key and funds it with the default SUI amount on faucet-bearing local networks, so you can publish and transact straight away.

To bring your own key — a CI secret, or a fixed identity you want to reuse — use the signer variant and pass any @mysten/sui Signer or Keypair. Load a secret from an env var or an inline suiprivkey1... literal by constructing the keypair yourself:

import { account } from '@mysten-incubation/devstack';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';

const alice = account('alice');
const ci = account('ci', {
	kind: 'signer',
	signer: Ed25519Keypair.fromSecretKey(process.env.ALICE_PRIVATE_KEY!),
});
const demo = account('demo', {
	kind: 'signer',
	signer: Ed25519Keypair.fromSecretKey('suiprivkey1...'),
});

The kind field selects one of three account variants: ephemeral (the default — a fresh generated key), signer (bring your own keypair, as above), and impersonate — fork-mode only — account('whale', { kind: 'impersonate', address: '0x…' }), which acts as an existing on-chain address by paying from a seeded reserve rather than signing.

To fund an account with specific coins and amounts, pass a funding list of { coin, amount } entries:

import { account } from '@mysten-incubation/devstack';

const alice = account('alice', {
	funding: [{ coin: 'sui', amount: 2_000_000_000n }],
});

Add a wallet() member to make your accounts available in the app as a dev wallet — connect and sign without standing up a real wallet. In dev, devstack injects the wallet onto the page and dApp Kit auto-discovers it via wallet-standard, so it's ready to connect with no extra wiring. Use wallet() to expose every account, or wallet({ accounts }) to scope it to a chosen set:

import {
	defineDevstack,
	account,
	HOST_SERVICE_PORT_TOKEN,
	hostService,
	sui,
	wallet,
} from '@mysten-incubation/devstack';

const DEV_PORT = 5173;

const localnet = sui();
const alice = account('alice');
const bob = account('bob');
const devWallet = wallet({
	accounts: [alice, bob],
});
const app = hostService({
	name: 'app',
	script: `pnpm exec vite --host 127.0.0.1 --strictPort --port ${HOST_SERVICE_PORT_TOKEN}`,
	port: DEV_PORT,
	ready: { kind: 'http' },
	after: [devWallet] as const,
});

export default defineDevstack({ members: [localnet, app], stackName: 'main' });

wallet({ accounts: 'all' }) expands to every account member in the final defineDevstack(...) call. Either way, the dev wallet is injected and ready to connect in dev, and a production build carries no dev wallet.

Under the hood

The wallet runs a small local server (bound to 0.0.0.0 by default) that the injected page talks to. It keeps its pairing token and dApp Kit handles under the per-stack gitignored runtime output at .devstack/stacks/<stack>/, and accepts the stack-scoped dev-server origin — http://dev.<app>.localhost:5175 for the default stack, or http://dev.<stack>.<app>.localhost:5175 for a named stack. Add allowedOrigins for nonstandard browser origins.

On this page