Build
Contract playground
Seven example contracts with a page each, on the public signet. Use them, edit their Rust source, compile it in the browser and deploy your version.
On this page
The contract playground is a page of its own, beside the signet wallet. It runs on the public signet, signs every operation in your own wallet and pays the fees in test KSA. The wallet links it from its top bar, its footer and its home, and from a contract’s page.
The examples
| Example | What it shows | Crate |
|---|---|---|
| Counter | the smallest contract: one number anyone can increase | playground-counter |
| Token | a built-in asset that wallets list: mint up to a cap, burn, send | mintable-token |
| NFT | collectibles to mint, send, approve and sell for a fixed price | nft |
| AMM | swaps between two assets, and liquidity shares that earn the fees | amm |
| Lending | supply to earn interest, borrow against collateral, liquidations | lending |
| Multisig | a wallet whose owners approve and run proposals together | multisig |
| Vesting | tokens that release over time to a beneficiary | vesting |
Each example has four tabs: App, a page made for it; Code, its Rust source; Methods, a form for every method; and Activity, the operations this browser sent. The examples build on each other: the AMM, lending and vesting pages offer to deploy a token first, and the token page links to them. The crates live in contracts/examples/ of the repository with their native tests; Example contracts lists them with the others.
Start
Connect a wallet
Use Unisat, OneKey or Xverse with a Taproot (tb1p…) account on Bitcoin signet, as for the signet wallet. The playground asks the wallet for signatures only and never sees your keys.
Get test KSA
Get test KSA asks the faucet for 100 KSA, once a day for each account. Deployments and calls are path B operations that pay their fee in KSA, and a deployment’s fee grows with the module’s size.
Deploy an example
Deploy new fills in the example’s init arguments, which you can change. Review the operation, then sign it in the wallet; the page shows the predicted contract ID until a block includes the deployment. To use a contract someone else deployed, open their link or Open by ID.
Use it
The App tab is the example’s own page: swaps and liquidity for the AMM, supply, borrow and repay for lending, proposals for the multisig. Every write goes through the same review, which runs the operation read-only against the latest state first and warns you when it would fail.
Edit and compile
The Code tab holds the example’s src/lib.rs. The editor builds that one file against ksana-contract-sdk, as the repository builds the examples.
- Compile sends the source to the compile service. Errors and warnings come back on their lines.
- Deploy this build deploys your module as a new contract, and the forms of the Methods tab follow the ABI block of your source. The example’s own App page may not match edited code, and says so.
- The example’s source, unchanged, compiles to the very module the playground ships, byte for byte (
playground/src/examples/wasm/builds.jsonholds the hashes). An example’s deployment can be checked against the source the page shows. - A copy of the playground without a compile service still deploys the published modules. Build a module yourself as Example contracts shows, and upload the
.wasmon the Code tab.
Limits of the compile service
- One source of at most 128 KiB, built as one of the seven example crates, with that crate’s dependencies and no others. The build runs without network access and stops after 120 seconds.
- The module may be at most 1 MiB, but one operation carries at most 64 KiB, so a module that deploys stays below that.
- Six builds a minute from one address. Builds wait in a short queue, and a full queue answers that the service is busy.
The ABI block
A contract describes its methods to the playground in its own documentation: a fenced block marked abi in the //! comment at the top of src/lib.rs, one declaration per line, with an optional // description. The counter’s:
//! ```abi
//! init() // starts the count at 0
//! call increment() -> u64 // adds one; returns the new count
//! call add(amount: u64) -> u64 // adds 1 to 1000 at a time; returns the new count
//! view get() -> u64 // the count
//! event changed(by: Account, value: u64)
//! ```initruns once, at deployment;calldeclares a method that changes state, sent as an operation;viewone that only reads, run without a signature.payablebeforeinitorcallmeans the method takes attached funds.structandenumdeclare the types the methods use, andeventthe events the contract emits.- Types: the integers
u8tou128andi8toi128,bool,String,Bytes,[u8; N],Account,ContractId,AssetId,Hash(32 bytes each),Option<T>,Vec<T>, tuples,(), and the declared structs and enums. Arguments and results are Borsh, as for every Ksana contract (Contracts).
The block is documentation for people as well: rustdoc shows it as a code block. A source without one still compiles and deploys, but gets no forms.
Open a contract
A contract’s page in the wallet’s explorer offers Open in the playground. A deployment of an example opens on that example’s page; any other contract gets forms once you paste its source, or just its ABI block. On the playground’s home, Any contract does the same with a contract ID.
Things to know
- The playground runs on the signet only. Signet KSA has no value, and the examples are for learning, not audited software.
- A failed operation still pays its fee and uses its nonce.
- Each write is recorded in this browser before it is sent. An operation whose answer was lost keeps its nonce reserved until the node shows it; Release this nonce removes only that local reservation and cancels nothing, since another node may still include the old operation. Clearing the site’s data loses this protection.