Flashnet Execution is the programmable settlement layer between Spark and your contract code. The runtime is EVM-compatible, so contracts compile with Solidity and standard tooling. The integration model is intent-based: you sign an intent, the sequencer includes it, validators sign the finality certificate, and settlement dispatches results back to Spark.Documentation Index
Fetch the complete documentation index at: https://flashnet-build.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Components
The intent path
- Client signs. The SDK builds a canonical intent message (chain id, transfers, action, expiry), SHA-256 hashes it, and signs with the identity key. See Intents.
- Gateway admits. A REST gateway authenticates the signer, validates the expiry, checks the intent isn’t a replay, and forwards to the sequencer.
- Sequencer admission and deposit oracle. The sequencer holds deposit-shaped intents in
oracle_pendingwhile the deposit oracle confirms each Spark transfer id against the Spark operator DB. Intents without deposits skip this stage. Failure here transitions torejected; expiry transitions toexpired. - Sequencer includes. Once admitted, the sequencer orders the intent into the next block as one or more EIP-1559 transactions: deposit calls to
SparkGatewayplus the user’s signed transaction. - Validators finalize. Validators run the block, compare state roots, and sign a finality certificate inside their TEE. Quorum advances the chain head.
- Settlement dispatches. Finalized
SparkWithdrawalevents are translated into Spark transfers and dispatched back to the user’s Spark wallet.
Why TEEs
All consensus signing and Spark wallet operations run inside a TEE signing server (tee-server). Validator and sequencer host processes talk to it over VSock and never hold keys themselves. In production the TEE is an AWS Nitro Enclave, with the signing key sealed via KMS and unsealed only on PCR-attested startup. Two things this buys:
- Key isolation. Finality-certificate signing keys, deposit-oracle signing keys, and Spark wallet signing keys all live inside the enclave. A compromised validator or sequencer host can’t forge a signature.
- Attestable code. The enclave produces a remote attestation that proves the running binary matches a known measurement. Operators publish the expected measurement; clients can verify the validator they’re talking to is running the code they expect.
Why intents instead of transactions
Three things plain transactions can’t express:| Need | Why intents |
|---|---|
| Atomicity across Spark and EVM | An intent commits Spark deposits and an EVM action together. Either both apply or neither does. |
| Operator-paid execution | The intent boundary is where the sequencer authorizes paying the base fee on behalf of the user. |
| Settlement back to Spark | The settlement layer reads finalized intents and translates SparkWithdrawal events into Spark transfers. The intent boundary is its input. |
Why zero gas
The operator runs the sequencer and pays for inclusion. The runtime setsbaseFeePerGas = 0 and maxPriorityFeePerGas = 0 for every block. The fee model is on the operator side, not on the user side.
This means:
- No gas token. Native sats are usable, but you don’t need to hold them just to call a contract.
- No fee market. Transactions are ordered by sequencer policy, not by bid.
- Operator policy can change. The integration is forward-compatible:
fetchEip1559Fees(rpcUrl)returns whatever the node currently reports, so a future fee change doesn’t break clients that read it.
Replay safety
Two layers of replay protection:- Spark transfer ids are recorded on
SparkGatewayafter first use. A second intent claiming the same transfer id is rejected at admission. - Withdrawal nonces are monotonic on
SparkGateway. The settlement layer reconciles by nonce, so a finalized withdrawal never settles twice on Spark even if the EVM transaction is replayed.
What’s not on chain
- The signed intent message. It’s the input the gateway and validators verify against. Only the resulting EVM transactions land on the chain.
- Spark transfer ids in their original form. They’re embedded in the deposit call’s calldata as 32-byte values for replay protection but don’t appear as chain events outside that.
- Spark addresses. Withdrawals carry the 33-byte compressed pubkey of the recipient in calldata. The chain doesn’t know it’s a Spark address; the settlement layer does.