As with other UTXO-based blockchains like Bitcoin that lacks an "account" abstraction, Themelio requires somewhat involved logic for wallets --- software that manages on-chain assets and provides an interface roughly similar to a bank account.
In Themelio, the "canonical" wallet software is melwalletd, a headless program that internally manages wallets and exposes a local REST API for operations on the wallets. Although you can use it directly as a Themelio wallet, melwalletd is intended more as a backend to wallet apps, such as melwallet-cli, the official CLI wallet.
After installing melwalletd through cargo install --locked melwalletd
, start it by giving it a directory in which wallets are stored and a network to which you want to connect:
shell
$ melwalletd --wallet-dir ~/.themelio-wallets --network testnet
May 18 16:20:43.583 INFO melwalletd: opened wallet directory: []
If the directory doesn't exist it will be created. By default, melwalletd will start listening on localhost:11773
.
Endpoint
PUT /wallets/[wallet name]
Body fields
password
: optional field; password with which to encrypt the private key. Warning: if not given, private key will be stored in cleartext!secret
: optional field; secret key used to import an existing walletResponse
Example
shell
$ curl -s 'localhost:11773/wallets/alice' -X PUT --data '{"password": "password"}'
Endpoint
GET /wallets
Response
total_micromel
: total µMEL balance of walletdetailed_balance
: a map connecting specific coin denomiations to amountsstaked_microsym
: the amount of µSYM staked on the networknetwork
: 1 for testnet, 255 for mainnetaddress
: address-encoded covenant hashlocked
: boolean saying whether or not the wallet is locked.Example
```shell $ curl -s localhost:11773/wallets | jq { "alice": { "totalmicromel": 0, "network": 1, "address": "t607gqktd3njqewnjcvzxv2m4ta6epbcv1sdjkp0qkmztaq3wxn350", "detailedbalance": { "73": 9871, "6d": 32131, "64": 314159265 }, "staked_microsym": 2500000000,
"locked": true
}, "labooyah": { "totalmicromel": 0, "network": 255, "address": "t1jhtj4ex1n069xr8w6mbkgrt25jgzw0pam1a25redg9ykpsykbq70", "detailedbalance": { "6d": 202220, }, "stakedmicrosym": 0, "locked": true }, "testnet": { "totalmicromel": 17322999920, "network": 1, "address": "t6zf5m662ge2hwax4hcs5kzqmr1a5214fa9sj2rbtassw04n6jffr0", "detailedbalance": { "64": 10111, }, "stakedmicrosym": 0, "locked": true } } ```
Endpoint
GET /wallets/[wallet name]
Response
total_micromel
: total µMEL balance of walletdetailed_balance
: a map connecting specific coin denomiations to amountsstaked_microsym
: the amount of µSYM staked on the networknetwork
: 1 for testnet, 255 for mainnetaddress
: address-encoded covenant hashlocked
: boolean saying whether or not the wallet is locked.Example
```shell $ curl -s localhost:11773/wallets/alice | jq { "alice": { "totalmicromel": 0, "network": 1, "address": "t607gqktd3njqewnjcvzxv2m4ta6epbcv1sdjkp0qkmztaq3wxn350", "detailedbalance": { "73": 9871, "6d": 32131, "64": 314159265 }, "staked_microsym": 2500000000,
"locked": true
} } ```
Endpoint
POST /wallets/[name]/unlock
Body fields
password
: passwordResponse
None
Endpoint
POST /wallets/[name]/lock
Body fields
None
Response
None
This verb sends a faucet transaction that adds a fixed sum of 1001 MEL to the wallet. Note: obviously, this only works with testnet wallets!
Endpoint
POST /wallets/[name]/send-faucet
Body fields
None.
Response
Quoted hexadecimal transaction hash of the transaction being sent.
Example
shell
$ curl -s localhost:11773/wallets/alice/send-faucet -X POST
"86588da7863b39152105e4f78c04e07a5d3f3ebf61d799f95293372dabdb06a1"
Endpoint
GET /wallets/[name]/transactions/
Response
A JSON object containing a list with elements of type (TxHash, Option\
Example
```shell $ curl -s localhost:11773/wallets/bar/transactions | jq [ [ "d23b4240f7e02a38e8deb8a111d0ec8650a8912df50d15ec43992e3085b4ca98", null ],
[
"5b4ca98d23b4240f7e02a38e8deb8a111d0ec8650a8912df50d15ec43992e308",
48113
]
]
```
Endpoint
GET /wallets/[name]/transactions/[txhash]
Response
A JSON of a type TransactionStatus with fields:
raw
: the actual transaction in JSON formatconfirmed_height
: null if not confirmed, otherwise the height at which the transaction was confirmed.outputs
: an array of AnnCoinID objects like:
coin_data
: a CoinData objectis_change
: is this a change output that goes to myself?coin_id
: a string-represented CoinID (txhash-index)Example
shell
$ curl -s localhost:11773/wallets/alice/transactions/
442bdc353b773b8949c59cee8061545a9a89e27a2e6638fcc1d065583bb170b8 | jq
{
"raw": {
"kind": 255,
"inputs": [],
"outputs": [
{
"covhash": "t4xn73csvjxp0dvh0gs6ehpgfq0ht0akr9g6tkxywv7xvfp09cy6x0",
"value": 1001000000,
"denom": "MEL",
"additional_data": ""
}
],
"fee": 1001000000,
"covenants": [],
"data": "72a1aba97ada3d1958932244836b0c72aaedeef7f6b032c1877c83ae05e28469",
"sigs": []
},
"confirmed_height": 42633,
"outputs": [
{
"coin_data": {
"covhash": "t4xn73csvjxp0dvh0gs6ehpgfq0ht0akr9g6tkxywv7xvfp09cy6x0",
"value": 1001000000,
"denom": "MEL",
"additional_data": ""
},
"is_change": true,
"coin_id": "442bdc353b773b8949c59cee8061545a9a89e27a2e6638fcc1d065583bb170b8-0"
}
]
}
Note: This prepares a transaction to be sent from a wallet, creating a filled-in, valid transaction, but without changing the wallet state. If the you actually want to send the transaction, the send-tx call must be used.
Keep in mind, this endpoint is not useful for more advanced covenant deployment. Check send-tx
Endpoint
POST /wallets/[name]/prepare-tx
Body fields
outputs
: an array of CoinDatas, representing the desired outputs of the transaction. Any change outputs that are added are guaranteed to be added after these outputs.
kind
: optional TxKind of the transaction (defaults to Normal)
inputs
: optional an array of CoinIDs, representing inputs that must be spent by this transaction. This is useful for building covenant chains and such.
data
: optional additional data of the transaction (defaults to empty)
covenants
:nobalance
: optional vector of Denoms on which balancing --- checking that exactly the same number of coins are produce by a transaction as those consumed by it --- should not be done. Normally, this is used to exempt ERG balance from being checked when preparing a DOSC-minting transaction.signing_key
: optional an ed25519 signing key that corresponds to the wallet's covenant. WARNING: Only for advanced usecases, this can cause loss of funds if not used properlyResponse
Example
```shell $ curl -s localhost:11773/wallets/alice/prepare-tx -X POST --data '{ "outputs": [ { "covhash": "57df1dd5b067f77a177127cbe4d69aa10fe8fcac3b2f9718cb8263d5a6216ab0", "value": 1000, "denom": "6d", "additionaldata": "" } ], "signingkey": "4239e79eab9b39c49de990363197a64e1a54f0f9a0d12a936e85e69ea7fb05b006425dfe7967003e2a5362e36231730f2faaa6068979afc52784f916466e05b6" }'
{ "kind": 0, "inputs": [ { "txhash": "4950f3af9da569e1a99a7e738026a581d6e96caaf02d94b02efcd645540a2d2f", "index": 0 } ], "outputs": [ { "covhash": "57df1dd5b067f77a177127cbe4d69aa10fe8fcac3b2f9718cb8263d5a6216ab0", "value": 1000, "denom": "6d", "additionaldata": "" }, { "covhash": "41d04b65a010aaa3404e1a109c53e3190a393d7ff920fa5644969a879547d0aa", "value": 1000998977, "denom": "6d", "additionaldata": "" } ], "fee": 23, "scripts": [ "420009f100000000000000000000000000000000000000000000000000000000000000064200005050f02006425dfe7967003e2a5362e36231730f2faaa6068979afc52784f916466e05b6420001320020" ], "data": "", "sigs": [ "df3cc2795d3c9576b85c4c960501af3e44bbc490c9dc51c8422f18a3a0fa1150c2f745440206748c8205971ba0cff32b87c9797a4d1098ce3bd677db62e8560c" ] } ```
Note: This endpoint will reject any transactions that are malformed or don't belong to the wallet. For personal use recommend using melwallet-cli instead. If you must use this endpoint, consider using /prepare-tx to prepare the body of this transaction
Endpoint
POST /wallets/[name]/send-tx
Body
JSON-encoded Transaction with fields:
fee
: CoinValueResponse