Giter VIP home page Giter VIP logo

walrus's Introduction

walrus

GoDoc Go Report Card

walrus is a Sia wallet server. It presents a low-level, performant API that is suitable for private, professional, and commercial use. The server itself does not store seeds or private keys, and therefore cannot sign transactions; these responsibilities are handled by the client. Accordingly, walrus works well with Sia-compatible hardware wallets such as the Ledger Nano S.

API docs for the server are available here.

A client for walrus is available here. The client facilitates constructing, signing, and broadcasting transactions, and supports both hot wallets and hardware wallets.

Running a walrus server

If you plan to expose your walrus API to the public internet, it is highly recommended that you add HTTPS and HTTP Basic Authentication via a reverse proxy. Without these security measures, an attacker would still be unable to access your private keys, but they could potentially trick you into losing funds. Better safe than sorry.

In addition, if you want to access your wallet via a browser (such as Sia Central's Lite Wallet), you will need to enable CORS. Refer to the following documentation based on your reverse proxy:

walrus's People

Contributors

eriner avatar jkawamoto avatar lukechampine avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

walrus's Issues

Prevent accidental seed mingling

Currently there are no safeguards against using multiple seeds with a single walrus server. To catch this, the server could store a hash of the user's seed. Then, the client would include this hash in each query to the server. If the hashes differ, the server can return an error.

The one twist here is with Ledger wallets. We can't hash the Ledger's seed directly, so we need to get a unique identifier some other way. (An obvious choice would be to generate an address with a very high key index.) Unfortunately, this means we need an extra setup step for Ledger users. Not a huge deal, but possibly confusing.

Include consensus info in most GET requests

For example, GET /balance would also return the current height and ID. This would allow the balance (and transactions, file contracts, etc.) to be checked "atomically" -- there is no uncertainty about which block height the reported information corresponds to. Currently, if you want that certainty, you must call /consensus, then /balance, then /consensus again, and check that the IDs match. If they don't, you must repeat the sequence until they do.

I'm wondering if there is a less intrusive way of including this information along with the response. Could it be placed in a header? It's not a big deal, but it irks me that calling /balance would return an object with a field called "balance" rather than simply returning the balance.

More transaction metadata

/transactions/:id currently reports the inflow, outflow, and feePerByte in addition to the raw transaction. Those things are nice, but having the block height, block id, and timestamp would be far more useful.

This shouldn't be too tough to implement. wallet.ProcessedConsensusChange turns a consensus change into a flat []types.Transaction, so that type would just need to be changed to include the block-specific metadata. Then the implementers of wallet.ChainStore would need to store this extra information.

The tricky part is handling future changes. It's not hard to imagine that we'll want to add additional metadata later. When we do, will all the existing stores need to run some upgrade code? Will some of their transactions end up with missing metadata? Not sure how best to handle this.

can't connect from walrus-client "http: server gave HTTP response to HTTPS client"

I can't connect to the walrus server

#./walrus -http 127.0.0.1:9999
Listening on 127.0.0.1:9999...

Server must be already sinchronized - becuase I can't see it more in the top of processes - passed near 24 hours.

.#/walrus-cli -a 127.0.0.1:9999 balance
Could not get balance: Get https://127.0.0.1:9999/balance?limbo=true: http: server gave HTTP response to HTTPS client

Before this in the terminal for walrus-cli was exported passphrase from siad wallet.
#export WALRUS_SEED= ....

Can't compile because related file NebulousLabs/Sia/crypto/merkle.go give error

Can't compile because related file from SIA give error. In the same time this file not give error if I compile SIA.

make

go install -ldflags "-X 'main.githash=git rev-parse --short HEAD' -X 'main.builddate=date'" ./cmd/...

gitlab.com/NebulousLabs/Sia/crypto

../src/gitlab.com/NebulousLabs/Sia/crypto/merkle.go:249:37: cannot use lh (type *merkletree.CachedLeafHasher) as type [][]byte in argument to merkletree.VerifyDiffProof
Makefile:6: recipe for target 'all' failed
make: *** [all] Error 2

go get fails with sk.SignHash undefined error

I got this error when go get -u lukechampine.com/walrus.

go: lukechampine.com/walrus upgrade => v0.8.1
# lukechampine.com/walrus
../../../../pkg/mod/lukechampine.com/[email protected]/client.go:359:46: sk.SignHash undefined (type ed25519.PrivateKey has no field or method SignHash)

It looks like this error is already fixed, but a new version isn't released yet. Could you release v0.8.2?

Get limbo API doesn't return transaction IDs and limboSince

Looks like Get limbo API doesn't return transaction IDs and limboSince with v0.10.5.

root@muse-0:~# curl -s http://localhost:9380/limbo | jq ".[].id"
null
null
null
null
null
null
null

root@muse-0:~# curl -s http://localhost:9380/limbo | jq ".[].limboSince"
null
null
null
null
null
null
null

Proposal: Remove hot wallet server

Currently, walrus can be used as either a "hot" wallet (allowing it to sign transactions for you) or as a "cold" watch-only wallet, where the server does not store your seed or keys and only you can sign transactions.

Hot wallets are convenient, but less secure; I certainly can't recommend that anyone use the hot wallet server today, since the API is completely unauthenticated. Even if I did add authentication, I don't like the idea of an always-on server that keeps your seed in memory. Instead, all walrus servers should be watch-only servers, and seed management + signing should be delegated to the client. This significantly simplifies the implementation and documentation of walrus. It also removes a possible point of confusion around narwal (which only provides a watch-only walrus instance, not a hot wallet).

In tandem with this change, I will replace the hot wallet client of us with a watch-only client that also stores the seed, allowing it to implement the proto.Wallet interface. The user can then be prompted to enter their seed whenever they need to sign a transaction or generate a new address, e.g. when forming a file contract. This will make it possible to use programs like user with a narwal instance, such that a person possessing only some SC on an exchange can start uploading and downloading immediately, never downloading the blockchain. They could even do so with a hardware wallet -- except that, unfortunately, the Ledger Nano S app does not support file contract transactions. So I would need to either add support for those, or the user could accept the reduced security of signing an opaque hash.

Relatedly, I would like to move the /seedindex routes to the watch-only wallet. Originally, I intended for the watch-only wallet to be highly generic, i.e. it would allow you to associate arbitrary metadata with arbitrary addresses. But my thinking has changed, and now I believe that it's best to assume that all addresses are seed-based addresses (with an associated index), and that watch-only wallets should only watch addresses for which they possess the unlock conditions. True watch-only wallets are niche enough that custom support can be added later if there is sufficient demand.

Make /filecontracts and /blockrewards consistent with other endpoints

/blockrewards returns a []wallet.BlockReward directly, unlike other endpoints which return a list of IDs. I'm not sure why. This "correct" API should be:

GET /blockrewards?max=n -> []types.BlockID
GET /blockrewards/id -> wallet.BlockReward

along with a corresponding batch query:

POST /batchquery/blockrewards [id1, id2, id3] -> []wallet.BlockReward

Arguably, /limbo should be like this as well. I think in the case of limbo, I figured that a) the response is unlikely to ever grow super large, and b) the client rarely wants to examine just a single limbo transaction -- you almost always want to work with the full limbo set. So I'll probably leave /limbo as-is, unless someone can provide a compelling reason not to.

EDIT: just realized /filecontracts is also like this ๐Ÿ˜ฌ

Add "batch query" endpoints

The current API design is simple and easy to understand, but horribly inefficient for certain operations. For example, to retrieve the last 100 transactions, you need to make 101 API calls! This is because each transaction (or address, or output, etc.) is a separate resource, and must be queried separately.

There are a few ways we could address this. One of the most popular is the "batch job" approach:

POST /batch { ... query ... } -> returns :id
GET /batch/:id -> returns result of query (or "pending", whatever)

A more exotic option also occurred to me:

GET /transactions?max=5&map=/transactions/

This would query the /transactions endpoint for the 5 most recent transactions, then "map" the resulting ids into GET /transactions/:id requests. Pretty neat, but there's a big problem, which is that you can't pass your own list of IDs to query -- they have to originate in some other API call.

Both of those options are more flexible than what we really need, so here's what I'm currently leaning towards:

POST /batchquery/transactions { ... list of ids ... } -> returns list of /transactions/ responses
POST /batchquery/addresses { ... list of addrs ... } -> returns list of /addresses/ responses
etc.

This approach should work fine, because all of the walrus resources are grouped into hierarchies and have unique identifiers.

Lastly: I think if I could wave a magic wand and convert everything to GraphQL, I'd probably do that. IIUC GraphQL would let clients make custom requests that return exactly what they need, without having to make multiple requests. Unfortunately, no such magic wand exists, so the conversion would take a lot of work.

Make transaction IDs more accessible

DELETE /limbo/:txid requires you to specify the ID of the transaction, but the ID isn't present in the response of /limbo, which means you either need to track it independently, or recompute the ID using the transaction object (which is rather difficult if you're not using Go).

PUT /limbo/:txid suffers from the same problem, although I suppose we could alleviate it by switching the endpoint to POST /limbo.

The most generic solution would be a /txid method that computes and returns the ID of the transaction supplied in the request body. But I dunno, it feels like overkill to add an endpoint that just calls a method on the provided object.

Include block height of each UTXO

Without this information, it is difficult to determine which UTXOs are "safe" to use. It might also be helpful to include the txid and/or block ID that created the output. I imagine this would be accomplished the same way as #4.

renter.HostKeyResolver

Would it be possible that walrus.Client implements renter.HostKeyResolver interface?

I think the host DB is provided by https://github.com/lukechampine/shard, and we need to run both walrus and shard. However, both of them need to have a copy of the consensus DB, and running two servers seems not efficient storage-wise and network traffic-wise.

It would be nice if walrus can provide host DB or walrus and shard servers can share one copy of the consensus DB.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.