Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Grants, commands and routes

Grants

What an offer asks the player to let your app do without asking again:

grant.Lets your appAsked with
send(object, perRequest, total)be sent an object, within caps per request and in totalask.send
owns(objects)be shown a proof of what the wallet owns of these objects, and of any you issuedask.owns
accept()hand the player objects your account issuedask.accept, then give
contacts()read the DSM identities of the wallet's contacts, and nothing moreask.contacts
trade(a, b, caps)trade between two objects through your vaults, within capsask.price, ask.trade; a wallet receives only an object it added, so ask.accept your coin first
match(caps)take stakes in matches your app referees, within capsask.match.stake, decide, ask.match.collect
duel(programs, caps)take stakes in matches a pinned program decidesask.duel.*

ask.login and ask.sign are never in a grant: each waits for the player on the device. Requests that move nothing run without asking, up to the offer's freeRequests (64 unless the offer says otherwise); past that, each waits for the player. A payment inside the grant's caps keeps running past that count until one fails; from then on, every request waits for the player.

The wallet answers a connection's requests in order: a request that waits for the player holds up every later one on that connection. On the beta network a request settles in a few seconds to about half a minute; wait (in the clients) polls until it has.

Outcomes and facts

Outcome, the wallet's word
carried_outthe wallet did it
awaiting_approvalit waits for the player
declinedthe player said no
failedit could not be done
Fact, your account's evidence
receivedyour account took up a transfer the wallet sent
ownsa proof of what the wallet owns verified
signeda signature over the asked words checked
stakedthe wallet's stake is held under the match's terms
collectedthe match's verdict paid the wallet
nonenothing to establish: a price, a trade's notification, contacts

The app's command line

dsm-app <command> drives your app's account; dsm-app help lists the commands. From the repo, make app ARGS="<command>" runs the same. Amounts are in the object's own units.

CommandWhat it does
upstart your app's account on the beta network (a new one the first time, in .dsm-dev in this folder) and fund it; it keeps running in the background
downstop it
statuswhether it is running, and where
idthis account's identity
fundERA from the faucet, unless the account holds some
ownedwhat it owns
issue <SYMBOL> <name> <supply> [decimals]issue a new object; this account holds the supply
give <wallet> <object> <amount>give a connected wallet some of an object
offer <name> <object> <per-request> <total> [coin]a connect code: be sent <object> within those caps, be shown what the wallet owns, hand it objects this account issues, read its contacts, referee matches it stakes <object> in (1.00 a match, 2.00 in all); with [coin], sell it <coin> for <object> through this account's vault (1.00 a trade, 5.00 in all)
connectionsevery connected wallet
send <connection> <object> <amount>ask a wallet to send this account some of an object
owns <connection> <object>ask a wallet to prove what it owns of an object
accept <connection> <object>ask a wallet to accept an object this account issued
login <connection>ask a wallet to sign in (the player approves on the device)
contacts <connection>ask a wallet who its contacts are
vault <a> <reserve-a> <b> <reserve-b>open a vault that trades between two objects, funded from what this account owns (the fee is 0.30%)
vaultsthis account's vaults and their reserves
price <connection> <from> <to> <amount>ask what <amount> of <from> would get in <to> through this account's vaults (information, never a fact)
trade <connection> <from> <to> <amount> [percent]the wallet accepts <to>, this account prices the trade, then asks for it at no less than [percent] (95) of the price
stake <connection> <opponent> <match> <object> <amount> <A|B> [against]ask a wallet to stake on a match this account referees, against the wallet of <opponent> (its connection); side B passes side A's stake id as [against]
decide <stake> <A|B|void>decide a match: who the stakes pay
collect <connection> <stake>...ask the winner's wallet to collect the stakes
result <connection> <seq>what became of a request
activity [after]what calls and wallets did to this account

The terminal wallets

dsm-dev-wallet <command> drives a player's wallet in the terminal: up, down, status, connect, connections, pending, approve, decline, log, disconnect, owned. With DSM_WALLET_NAME=wallet2 in front, it drives a second one, for matches. dsm-dev-wallet help lists them. From the repo, make wallet ARGS="..." and make wallet2 ARGS="..." run the same.

What the install puts on your machine

What it is
dsm-app-hostyour app's own DSM account; --help lists its flags, --network beta joins the beta network
dsm-app, dsm-dev-walletthe commands above
dsm-connect-starterthe starter app, on http://127.0.0.1:3000; run it in your app's folder
~/.local/share/dsm/clients/the TypeScript client's package (npm install it) and the Python client's wheel (pip install it)
~/.local/share/dsm/examples/first_payment.py and account_status.py

install.sh checks every download against the release's SHA256SUMS before it unpacks anything. DSM_PREFIX installs somewhere other than ~/.local.

The make targets, from the repo

TargetWhat it does
make doctorcheck the machine's prerequisites, changing nothing
make clientsbuild the TypeScript client (both clients' protobuf types are committed)
make client-typesregenerate both clients' protobuf types after a change to proto/dsm_app.proto
make app-devyour app's own DSM account on the beta network, funded
make app-dev-localthe same, on a storage set of your own
make app-dev-downstop your app's account
make starterthe starter app, on http://127.0.0.1:3000
make dev-wallet, make dev-wallet2a player's wallet in the terminal, and a second one for matches, funded
make dev-wallet-connect CODE=...connect the terminal wallet to an app
make dev-wallet-pendingrequests waiting for the terminal wallet's approval
make phones-connect CODE=...open a connect code in the wallet on every phone
make phones-localpoint the phones' wallets at your local set
make dev-downstop the terminal wallets, your app's account and the local nodes
make dev-resetforget the accounts made on this machine, and your local set if they were on it
make developer-paththe whole developer path end to end, as CI runs it
make first-runa newcomer's first run on a clean Ubuntu with no clone and no Rust: the release's files installed with install.sh, the docs alone, to a payment received

Routes

The routes your app's account uses:

RouteKindRequestAnswerClient
connect.app.offerinvokeConnectAppOfferRequestV1ConnectAppOfferV1offer
connect.app.sessionsquerynoneConnectSessionsV1connections
connect.app.requestinvokeConnectAppRequestIntentV1ConnectRequestRefV1request
connect.app.statusinvokeConnectRequestRefV1ConnectAppStatusV1result, wait
balance.listquerynoneBalancesListResponseowned, owns
wallet.amountqueryWalletAmountRequestWalletAmountResponseamounts, both ways
token.createinvokeTokenCreateRequestTokenCreateResponseissue
wallet.sendSmartinvokeOnlineTransferSmartRequestOnlineTransferResponsegive
sofi.createVault, sofi.vaults, sofi.closeinvokeSofiCreateVaultRequest, none, SofiCloseRequestSofiVaultCreatedResponse, SofiVaultsResponseopenVault, vaults, closeVault
escrow.adjudicateinvokeEscrowOutcomeRequestEscrowVerdictResponsedecide
faucet.claiminvokeFaucetClaimRequestFaucetClaimResponsefund

And a wallet's: connect.preview (query), connect.approve, connect.sync, connect.list (query), connect.pending (query), connect.respond, connect.log (query), connect.disconnect.

GET /activity/{after} returns AppHostActivityV1: your account's identity, and a record of each call and each wallet's visit to the relay. Every plain result keeps the wire's message as raw, and pb exports every generated message, for anything the plain fields leave out.

Offline

Your app's own calls are all online. Offline transfers are the wallet's feature, between two wallets: a bearer transfer carries any object whose policy lets it move, from one wallet's offline account to another's. Today that needs a hardware board on both sides, it is available on Android (the iOS app has no board link yet, and refuses), and a trade offline is two one-way transfers.

More