starlight

package
v0.1.0-alpha.0...-0b1224c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 5, 2019 License: Apache-2.0, Apache-2.0 Imports: 40 Imported by: 0

README

Header image

Starlight

Starlight is a demo implementation of payment channels on Stellar.

Payment channels allow parties to transact privately, instantly, and securely, while paying zero fees. They are also a first step toward constructing and connecting to payment channel networks like Lightning and Interledger.

This release includes the Starlight wallet, a user interface that lets you create bilateral payment channels and use them to transact in lumens (the native asset of the Stellar protocol) on the Stellar testnet.

You can learn more about the Starlight protocol by reading the specification, or you can try out the wallet by following the installation instructions below.

If you encounter any bugs, want to request a feature, or have any questions about the software, you can open an issue or pull request on GitHub, or talk to us in the #starlight channel on the Interstellar Slack.

Please note that this software is still in development and will likely contain multiple security and functional bugs and issues. This code is for testing only on the Stellar testnet. It is not compatible with the Stellar mainnet. Attempting to modify it for use on the Stellar mainnet may result in permanent XLM loss. Any use of this software is strictly at your own risk, and we will not be liable for any losses or damages.

Demo

Demo

Setup

Installation

You can download the appropriate binary for your platform from the releases page. Move the binary to somewhere on your executable path (for example, with sudo mv starlightd /usr/local/bin).

Alternatively, instructions for installing from source are below.

You can run a Starlight instance using the starlightd command. This will set up a data directory, called starlight-data, in your current directory. You can then open the wallet by going to http://localhost:7000 in your browser.

If, at any time, you want to reset your agent completely, you can clear your data directory:

$ rm -rf starlight-data
Running a second instance on the same computer

To try out starlightd for the first time, you'll want to run two instances on the same computer and create a payment channel between them, as described in the tutorial. You can run a second instance on your computer by listening on a different port, and using a separate data directory.

$ starlightd --listen=localhost:7001 --data=starlight-data-2

To log in to this wallet, go to http://localhost:7001, using an incognito or private window (to avoid logging out your other session).

Connecting to instances on other computers

If you are running your Starlight instance on your personal computer and want to connect it with instances on other computers or servers, you'll need to give your instance a publicly-accessible URL. One way to do so is by using a service like Serveo or ngrok. For example, you can run the following command:

$ ssh -R 80:localhost:7000 serveo.net

Your Starlight address will then be served on a subdomain of serveo.net (so your Stellar address will be something like alice*something.serveo.net).

Running an instance on AWS

Alternatively, you can run your Starlight instance on a cloud computing platform like Amazon Web Services or DigitalOcean. This more closely resembles how future production versions of Starlight would likely be hosted.

You can find instructions for setting up a Starlight instance on AWS here.

Tutorial

Start by installing starlightd, setting up two instances locally, and opening two browser windows to http://localhost:7000 and http://localhost:7001 (one of which should be in a private or incognito window, to prevent the sessions from interfering with each other).

Configure each wallet, picking "alice" and "bob" as the respective usernames.

Wallet

Starlight provides a simple lumen wallet, which manages an account that is funded with 10,000 testnet lumens upon setup.

The wallet gives you a Stellar address, e.g., "alice*localhost:7000".

You can use this wallet to make on-network payments to users' Stellar addresses (i.e., alice*stellar.org) or their Stellar account IDs (e.g., GAIH3ULLFQ4DGSECF2AR555KZ4KNDGEKN4AFI4SU2M7B43MGK3QJZNSR).

Try having Alice send a 100 XLM payment to Bob.

Channels

The core feature of Starlight is payment channels. Payment channels allow two parties to make payments to each other using free, private, and secure off-network transactions.

Try having Alice create a 500 XLM payment channel with Bob (bob*localhost:7001).

The channel will take a few seconds to open. Once the channel is open, try having Alice send 100 XLM to Bob, then try having Bob send 50 XLM back to Alice. Note that since these payments happened in the payment channel rather than on the public network, they were almost instant, and the parties paid no fee.

Channel capacity

Examine the Capacity graph, which shows how much each party can currently send and receive in the channel. The total capacity of the channel is limited to the amount that has been deposited in it. While the parties can make payments back and forth as long as they like, no party can make a payment that would exceed the channel's capacity.

The party that created the channel can deposit additional funds into the channel. This moves funds from their wallet account to their balance in the channel, and increases the total capacity of the channel. Try having Alice deposit 500 XLM into the channel, by clicking Deposit on the channel page.

Closing a channel

The funds that are locked in this channel can be paid back and forth between Alice and Bob instantly. However, if Alice or Bob want to make payments to anyone else, or use those lumens in any other channel, they will need to withdraw the funds by closing the channel.

Try having Bob close the channel by clicking Close on the channel page. After a few seconds, the channel should close, and the parties' funds should be withdrawn to their wallet accounts.

This worked because Bob's instance was online, and it automatically cooperated with the channel close request. If Bob's instance was offline or did not cooperate, Alice would need to "force close" the channel, which would mean that there would be some delay before she would receive her funds.

Development

Build starlightd from source

To build the starlightd agent from source, you'll need to install Go version 1.11, and set up a properly configured $GOPATH directory, with $GOPATH/bin added to your PATH:

export PATH=$PATH:$GOPATH/bin

Install starlightd from its GitHub repository.

$ go get github.com/interstellar/starlight/...

You can now run the command starlightd from anywhere. This will create a data directory called starlight-data in your current directory, and will run a wallet, which you can access at http://localhost:7000.

Build wallet from source

When running the starlightd binary, it automatically downloads and serves the latest version of the front-end wallet.

If you want to make changes to the wallet source code, you can rebuild and run it independently:

$ cd $GOPATH/github.com/interstellar/starlight/wallet
$ npm install
$ npm start

The wallet should now be running at port 5000:

$ open http://localhost:5000

To run a second development wallet on port 5001, connecting to a starlightd running on port 7001:

$ PORT=5001 STARLIGHTD_URL=http://localhost:7001 npm start
Running tests

The Starlight project has unit tests and integration tests for the starlight server and the wallet frontend.

To run the Starlight server unit tests:

$ cd $I10R/starlight
$ go test -short ./...

To run the Starlight wallet unit tests:

$ cd $I10R/starlight/wallet
$ ./bin/tests

To run the Starlight integration tests:

$ cd $I10R/starlight/starlighttest
$ go test

Roadmap

Starlight is under active development at Interstellar. Our top priorities for the coming year include:

  • Stabilization and final specification of protocol and API
  • Channels for non-native assets
  • Cross-channel atomic payments
  • Cross-currency atomic payments
  • Compatibility with Interledger and Lightning
  • Peer-to-peer connectivity
  • Stellar mainnet launch

To learn more about these projects, or to let us know what features you would most like to see, you can join the discussion in the #starlight channel on the Interstellar Slack.

Documentation

Overview

Package starlight exposes a payment channel agent on the Stellar network.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrAuthFailed   = errors.New("authentication failed")
	ErrUnauthorized = errors.New("unauthorized")
	ErrUnmarshaling = errors.New("error unmarshaling input")
)

Defines the exported errors that are used by the Starlight wallet RPC handler.

Functions

func WriteError

func WriteError(req *http.Request, w http.ResponseWriter, err error)

WriteError formats an error with the correct message and status from the starlight error formatter and writes the result to w.

Types

type Agent

type Agent struct {
	// contains filtered or unexported fields
}

An Agent acts on behalf of the user to open, close, maintain, and use payment channels. Its methods are safe to call concurrently. Methods 'Do*' initiate channel operations.

An Agent serializes all its state changes and stores them in a database as Update records. Methods Wait and Updates provide synchronization and access (respectively) for updates.

func StartAgent

func StartAgent(ctx context.Context, boltDB *bolt.DB) (*Agent, error)

StartAgent starts an agent using the bucket "agent" in db for storage and returns it.

func (*Agent) AddAsset

func (g *Agent) AddAsset(assetCode, issuer string) error

AddAsset creates a trustline for a non-native Asset.

func (*Agent) AfterFunc

func (g *Agent) AfterFunc(t time.Time, f func())

func (*Agent) Authenticate

func (g *Agent) Authenticate(name, password string) bool

Authenticate authenticates the given user name and password. If they're valid, it also decrypts the secret entropy seed if necessary, allowing private-key operations to proceed.

It returns whether name and password are valid.

func (*Agent) Close

func (g *Agent) Close()

Close releases resources associated with the Agent. It does not wait for its subordinate goroutines to exit.

func (*Agent) CloseWait

func (g *Agent) CloseWait()

CloseWait releases resources associated with the Agent. It waits for its subordinate goroutines to exit.

func (*Agent) ConfigEdit

func (g *Agent) ConfigEdit(c *Config) error

ConfigEdit edits g's configuration. Only Password and HorizonURL can be changed; attempting to change another field is an error.

func (*Agent) ConfigInit

func (g *Agent) ConfigInit(c *Config, hostURL string) error

ConfigInit sets g's configuration, generates a private key for the wallet, and performs any other necessary setup steps, such as obtaining free testnet lumens. It is an error if g has already been configured.

func (*Agent) Configured

func (g *Agent) Configured() bool

Configured returns whether ConfigInit has been called on g.

func (*Agent) DoCloseAccount

func (g *Agent) DoCloseAccount(dest string) error

DoCloseAccount will merge the agent's wallet account into the specified destination account. If the agent has any channels that are not closed, it will fail. While the agent is shutting down, it will not accept any other commands. If the transaction fails, the agent will alert the user and return to an Active state. Otherwise, the agent transitions to an empty initial state on merge success.

func (*Agent) DoCommand

func (g *Agent) DoCommand(channelID string, c *fsm.Command) error

DoCommand executes c on channel channelID.

func (*Agent) DoCreateChannel

func (g *Agent) DoCreateChannel(guestFedAddr string, hostAmount xlm.Amount) (*fsm.Channel, error)

DoCreateChannel creates a channel between the agent host and the guest specified at guestFedAddr, funding the channel with hostAmount

func (*Agent) DoWalletPay

func (g *Agent) DoWalletPay(dest string, amount uint64, assetCode, issuer string) error

DoWalletPay implements the wallet-pay command.

func (*Agent) FindAccount

func (g *Agent) FindAccount(target string) (accountID, starlightURL string, err error)

FindAccount looks up the account ID and Starlight URL for the Stellar account named by target.

The target must be a Stellar address in the form of a federation address, e.g.

kr*mywallet.example.com

Or a valid Stellar account ID.

If given a federation account, FindAccount will use the Stellar TOML file and the Stellar federation server protocol to look up the additional info, returning the account ID and Starlight URL.

If given an Account ID, FindAccount will look up the account's home domain, returning the account's federation address and Starlight URL.

func (*Agent) LoadAccount

func (g *Agent) LoadAccount(accountID string) (worizon.Account, error)

func (*Agent) Messages

func (g *Agent) Messages(chanID string, a, b uint64) []*fsm.Message

Messages returns all messages sent by the agent on channel chanID in the half-open interval [a, b). The returned slice will have length less than b-a if a or b is out of range.

func (*Agent) Now

func (g *Agent) Now() time.Time

func (*Agent) PeerHandler

func (g *Agent) PeerHandler() http.Handler

PeerHandler handles RPCs (such as ProposeChannel, AcceptChannel, Payment, etc.) from remote channel endpoints.

func (*Agent) RemoveAsset

func (g *Agent) RemoveAsset(assetCode, issuer string) error

RemoveAsset deletes a trustline for a non-native Asset.

func (*Agent) SetDebug

func (g *Agent) SetDebug(debug bool, name string)

func (*Agent) Updates

func (g *Agent) Updates(a, b uint64) []*Update

Updates returns all updates in the half-open interval [a, b). The returned slice will have length less than b-a if a or b is out of range.

func (*Agent) WaitMsg

func (g *Agent) WaitMsg(ctx context.Context, chanID string, i uint64)

WaitMsg blocks until a message with number i is available for the channel chanID

func (*Agent) WaitUpdate

func (g *Agent) WaitUpdate(ctx context.Context, i uint64)

WaitUpdate returns after an update at index i has occurred, or the ctx becomes done, whichever happens first.

type Config

type Config struct {
	Username string `json:",omitempty"`
	Password string `json:",omitempty"`
	// WARNING: this software is not compatible with Stellar mainnet.
	HorizonURL string `json:",omitempty"`

	// OldPassword is required from the client in ConfigEdit
	// when changing the password.
	// It's never included in Updates.
	OldPassword string `json:",omitempty"`

	MaxRoundDurMins   int64      `json:",omitempty"`
	FinalityDelayMins int64      `json:",omitempty"`
	ChannelFeerate    xlm.Amount `json:",omitempty"`
	HostFeerate       xlm.Amount `json:",omitempty"`

	// KeepAlive, if set, indicates whether or not the agent will
	// send 0-value keep-alive payments on its channels
	KeepAlive *bool `json:",omitempty"`

	// Public indicates whether the agent is running on a
	// publicly-accessible URL. If the agent is public, then it is
	// able to propose and receive incoming channel requests.
	// Private agents can only propose channels
	// and see incoming messages on their local network.
	Public bool
}

Config has user-facing, primary options for the Starlight agent

type TbMsg

type TbMsg struct {
	RemoteURL string
	Msg       fsm.Message
	// contains filtered or unexported fields
}

TbMsg is a taskbasket message-sending task.

func (*TbMsg) Run

func (m *TbMsg) Run(ctx context.Context) error

Run implements taskbasket.Task.

type TbTx

type TbTx struct {
	ChanID string // Starlight channel ID, or "wallet" for wallet txs
	E      xdr.TransactionEnvelope
	// contains filtered or unexported fields
}

TbTx is a taskbasket transaction-submitting task.

func (*TbTx) Run

func (t *TbTx) Run(ctx context.Context) error

Run implements taskbasket.Task.Run.

type Update

type Update = update.Update

Update describes a change made to an agent's state.

Directories

Path Synopsis
db
Package fsm implements the state transition logic in the Starlight spec.
Package fsm implements the state transition logic in the Starlight spec.
internal
Package starlighttest contains agent-level integration tests for starlight.
Package starlighttest contains agent-level integration tests for starlight.
Package taskbasket is a persistent task manager.
Package taskbasket is a persistent task manager.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL