Using the Example Domain and CLI Wallet
the delta devnet and relevant dependencies are currently being upgraded to a new version. The below steps cannot be completed at this time. Updated versions expected 08-Dec-2025.
Overview
This tutorial will walk you through deploying our example domain (built with the domain SDK) on the delta devnet, then submitting some user-level transactions (including minting a brand-new token and transferring tokens between vaults) on that example domain.
Steps
- Configure dependencies
- Install packages
- Declare your domain agreement to the delta Base Layer
- Run the example domain locally
- Use the example wallet to transfer native tokens
- Use the example wallet to mint a new token
1. Installation
In a terminal, run the following to install the delta CLI tools, example domain, and example wallet.
cargo install --registry delta delta-cli
cargo install --registry delta delta_domain_example_bin
cargo install --registry delta delta_domain_example_wallet
Environment Variables
We recommend saving the following environment variables to simplify commands in the terminal.
The RPC URL points to the RPC endpoint of a validator which is live on the delta devnet, and the domain private key must be pre-seeded with base layer funds. These resources are provided by the delta team.
export RPC_URL="<VALIDATOR_RPC_ENDPOINT_URL>"
export DOMAIN_PRIVKEY="<PATH_TO_YOUR_PRIVKEY>"
export SHARD="<DOMAIN_SHARD_ID>"
2. Declare your domain
Adding a new domain to the delta Network is a base layer transaction, meaning it is sent directly to a validator's RPC. Base layer transactions must wait until the end of an epoch (10 minutes on devnet) to be applied.
Domain Configuration
The core configuration of a delta domain is done through a YAML configuration
file. Create a domain.yaml file in your working directory with the following
details, using the keypair, endpoint and shard as above.
shard: <DOMAIN_SHARD_ID>
keypair: <PATH_TO_YOUR_PRIVKEY>
rpc_url: <VALIDATOR_RPC_ENDPOINT_URL>
Submit Domain Agreement
In a terminal, run the following to register your domain with the devnet, using the details stored in domain.yaml
delta_domain_example_bin submit-domain-agreement
Query Domain Agreement Status
Since domain registration transactions are processed only at the end of an epoch, you must wait until the beginning of the next epoch for your domain to be active on the network.
The devnet has an epoch duration of 10 minutes. You can check the current epoch with
delta-cli epoch --url $RPC_URL
and use the following to confirm your agreement has been applied
delta-cli domain-agreement --url $RPC_URL $SHARD
3. Run the example domain
Now, that your domain is active, you can run it locally. In a new terminal, run:
delta_domain_example_bin run --api-port 3000
This will run the example domain for as long as you let the command run. Running this command has three effects:
- A web-server is launched on port
3000(as per--api-portabove). Users canPOSTsigned user-level transactions (calledVerifiables) to this server and query the current state of the domain. - Internally, a domain "runtime" is launched,that receives the verifiables from the web-server and is able to submit State Diff Lists (SDLs) of aggregated user-level transactions to the base layer.
- An admin API is launched on an auto-assigned port (default 4001). This API can be used to control SDL creation and proving.
At this point, you are now running a minimal domain (just an adapter with no frontend) which is connected to the delta devnet. If you are interested in diving deeper to customize the domain runtime, you can build with the domain SDK.
4. Use the example wallet for a native token transfer
Create two new ed25519 keypairs to represent two new users. In the terminal:
delta-cli keygen -p key1.json
delta-cli keygen -p key2.json
Save the following environment variables to easily reference the users' owner IDs in future commands.
export USER1=$(delta-cli owner-id --keypair key1.json)
export USER2=$(delta-cli owner-id --keypair key2.json)
Create token debit
Our two recently-generated users both have no funds, which also means their vaults do not exist yet on the domain nor on delta devnet.
The following command debits 200 delta native tokens from the vault owned by the domain operator, and credits them to user 1:
delta_domain_example_wallet --url localhost:3000 \
debit \
--key-path $DOMAIN_PRIVKEY \
--amount 200 \
--credited $USER1
This command has the following effects:
- A "debit allowance" verifiable is created with the specified fields.
- The verifiable is signed using the private key specified with
--key-path. - The signed verifiable is executed locally and added to an SDL.
It is important to note that the verifiable is only applied locally (within the domain) right away. This is by design, since domains can use custom logic to control when SDLs are submitted to the delta base layer, allowing them to aggregate and batch-submit a large amount of state diffs resulting from many signed verifiables after ensuring they passed some additional checks.
We can confirm that the domain’s local vault balances are now updated by querying the executor state directly using:
delta_domain_example_wallet --url localhost:3000 vault --owner $USER1
However, the transaction has not yet been finalized on the delta base layer, so querying for user 1’s balance on the devnet will result in a “vault not found” error.
User to user debit
To send 100 native tokens from user 1 to user 2:
delta_domain_example_wallet --url localhost:3000 \
debit \
--key-path key1.json \
--amount 100 \
--credited $USER2
At this point, the domain view of the balances is ahead of the base layer by two debits. Next, we will push the changes to the devnet.
Settle token debits to the base layer
The two debits are already in the SDL waiting to be submitted. We can submit the SDL with the admin API:
export ADMIN_API="http://localhost:4001"
curl -X POST $ADMIN_API/admin/sdls/submit
This will output the hash of the SDL (in quotes).
Next, we will use the /prove and /submit_proof endpoints of the admin API to
generate a proof for the SDL and then submit the proof to the base layer (when
using the example domain, this is a mock proof).
curl -X POST $ADMIN_API/admin/sdls/<SDL_HASH>/prove
curl -X POST $ADMIN_API/admin/sdls/<SDL_HASH>/submit_proof
The second command only succeeds if the proof has finished generating.
SDLs with valid proofs are applied immediately via fast-path consensus on the base layer. The devnet will now reflect our new user balances:
delta-cli vault --url $RPC_URL $USER1 $SHARD
delta-cli vault --url $RPC_URL $USER2 $SHARD
5. Use the example wallet to mint a new token
Similar to step 3, we will use the example wallet to create a new user-level transaction, execute it locally, and settle the changes to the delta devnet.
We will mint a brand new fungible token, and distribute the initial supply to user 1.
Create new private key for token mint
First, generate a new keypair mint1.json to have ownership of the token mint vault.
delta-cli keygen -p mint1.json
export MINT1=$(delta-cli owner-id --keypair mint1.json)
Create and execute mint transaction
To mint a new fungible token, we create a new Token Mint verifiable. Upon settlement, the token mint will be stored in the newly generated key's vault:
delta_domain_example_wallet --url localhost:3000 \
mint fungible \
--key-path mint1.json \
--shard $SHARD \
--token-name "Test Token" \
--token-symbol "TT" \
--credited "$USER1=100"
To execute and settle the above transactions, we use the admin API like before:
curl -X POST $ADMIN_API/admin/sdls/submit
# with the hash resulting from above
curl -X POST $ADMIN_API/admin/sdls/<SDL_HASH>/prove
curl -X POST $ADMIN_API/admin/sdls/<SDL_HASH>/submit_proof
Now, if we query the base layer for the vault of user 1
delta-cli vault --url $RPC_URL $USER1 $SHARD
we see a new token holdings section reflecting the balance from the token mint operation:
Native balance: 100 plancks
Token holdings:
TT / <token ID>: 100 plancks
Querying the vault for our token mint vault will display the token's details:
Native balance: 0 plancks
Fungible Token Mint for "Test Token" ("TT"). Total supply: 100 plancks
User to user transfer of newly minted token
To transfer some of this newly minted token from user 1 to user 2, we use the same debit command as before, specifying the token ID of "Test Token". A debit transaction with no token ID specified will default to the delta native token.
delta_domain_example_wallet --url localhost:3000 \
debit \
--key-path key1.json \
--amount 25 \
--token-id "$MINT1,$SHARD" \
--credited "$USER2,$SHARD"
As before, to execute and settle the above transaction to the Base Layer:
curl -X POST $ADMIN_API/admin/sdls/submit
# with the hash resulting from above
curl -X POST $ADMIN_API/admin/sdls/<SDL_HASH>/prove
curl -X POST $ADMIN_API/admin/sdls/<SDL_HASH>/submit_proof
Checking the vault information for user 2 on the devnet
delta-cli vault --url $RPC_URL $USER2 $SHARD
will now show they have a token holding of our recently minted token:
Native balance: 100 plancks
Token holdings:
TT / <token ID>: 25 plancks
Next Steps
The above commands can all be edited to test other variants of user-level transactions. Use the --help flag on delta_domain_example_bin and delta_domain_example_wallet in your terminal to see what is possible directly.
You have now been introduced to delta's two layer architecture by deploying a domain, submitting several user-level transactions locally, and executing and settling SDLs globally. You have also been introduced to the example domain and wallet, which serve as a great base when building a custom domain application.
To help you build your own domain application, let's walk through the code of the example domain and understand it in more detail.