payment

package module
v0.0.0-...-a232057 Latest Latest
Warning

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

Go to latest
Published: Apr 23, 2021 License: Apache-2.0 Imports: 31 Imported by: 0

README


Perun

Perun Ethereum Payment Client

pkg.go.dev docs

This project provides a simplified interface to the go-perun framework. It enables developers to get started quickly with go-perun by using a condensed API.
If you just want to create a go-perun payment application on Ethereum, this is for you.

Security Disclaimer

Do not use this software with real funds.

go-perun is still in development. The authors take no responsibility for any loss of digital assets or other damage caused by the use of this software.

Primer

You can import perun-eth-payment as go module:

import "github.com/perun-network/perun-eth-payment"

Here is an example with the most important functions.
It sets up the framework, opens a channel to Bob, sends him 0.5 ETH, waits for a return payment and shuts down.

package main

import (
	"context"
	"fmt"
	"math/big"
	"time"

	"github.com/ethereum/go-ethereum/common"
	ethwallet "perun.network/go-perun/backend/ethereum/wallet"
	payment "github.com/perun-network/perun-eth-payment"
)

func main() {
	// Initialize mnemonic wallet
	wallet, err := payment.NewWalletHD(big.NewInt(5), "your mnemonic", 1)
	if err != nil { /* handle error */ }
	
	// Setup config struct and client
	config := payment.MakeConfig("127.0.0.1:6444", "ws://127.0.0.1:8454", 60 * time.Second)
	client, err := payment.NewClient(wallet, config)
	if err != nil { /* handle error */ }
	// Long context that will be used from now on
	ctx, cancel := context.WithTimeout(context.Background(), 10 * time.Minute)
	defer cancel()

	// Set the contract addresses of the Adjudicator and Assetholder
	client.Init(ctx, common.HexToAddress("0x20e1D1642284AdB74520f0e91835bbc6d5ec3415"),
			         common.HexToAddress("0x3f6629d37E84E6Da88978198c9A1B228C5722085"))
	
	// Register the peer that we want to open a channel with.
	bobAddr := ethwallet.AsWalletAddr(common.HexToAddress("0xB5d05705c467bfEd944B6769A689c7766CC1f805"))
	bob, err := client.RegisterPeer(bobAddr, "192.168.2.100:6444", "Bob")
	if err != nil { /* handle error */ }

	// Set the initial balance for the channel and open it.
	initBals := payment.MakeBals(payment.MakeAmountFromETH(1), payment.MakeAmountFromETH(1))
	channel, err := client.ProposeChannel(ctx, bob, initBals)
	if err != nil { /* handle error */ }

	// Send 0.5 ETH to Bob
	err = channel.Send(ctx, payment.MakeAmountFromETH(0.5))
	if err != nil { /* handle error */ }
	// Wait for Bob to send us something back
	received := <-channel.Received()
	fmt.Printf("Received %v ETH from Bob", received.ETH())

	// Close the channel and client at the end
	err = channel.Close(ctx)
	if err != nil { /* handle error */ }
	err = client.Close(ctx)
	if err != nil { /* handle error */ }
}

Architecture

The following UML diagram shows the complete interface in abbreviated form:

Payment client architecture

Copyright 2021 PolyCrypt GmbH
Use of the source code is governed by the Apache 2.0 license that can be found in the LICENSE file.

Contact us at info@perun.network.

Documentation

Overview

Package payment contains a simplified API of go-perun.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DeployContracts

func DeployContracts(ctx context.Context, wallet *Wallet, chainURL string) (common.Address, common.Address, error)

DeployContracts deploys the Adjudicator and Assetholder contract and returns their addresses. The context timeout must be at least twice the block time to allow for the transactions to be mined. To be safe, put it higher.

func SetLogLevel

func SetLogLevel(level logrus.Level, formatter logrus.Formatter)

SetLogLevel can be used to define how verbose the log output should be. The default value is `WarnLevel` with disabled console colors. Set it to `Debug` or even `Trace` if you are debugging an error. Example: `SetLogLevel(logrus.DebugLevel, &logrus.TextFormatter{})`.

Types

type Balance

type Balance struct {
	My, Other ETHAmount
}

Balance represents the balance of funds in a channel.

func MakeBals

func MakeBals(my, other ETHAmount) Balance

MakeBals creates a new Balance struct containing the given balances.

type Channel

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

Channel is a payment channel. Can send and receive funds from a single peer. The current balance is available via `Balance()`. Payments on a channel cannot happen in both directions at once. The same applies to channel closing; one of the participants has to go first.

func (*Channel) Balance

func (c *Channel) Balance() Balance

Balance returns the balance of a channel.

func (*Channel) Close

func (c *Channel) Close(ctx context.Context) error

Close gracefully closes the channel. All funds will be distributed on-chain.

func (*Channel) HandleAdjudicatorEvent

func (c *Channel) HandleAdjudicatorEvent(_e channel.AdjudicatorEvent)

HandleAdjudicatorEvent DO NOT CALL. It is called by the framework for adjudicator events.

func (*Channel) Received

func (c *Channel) Received() <-chan *ETHAmount

Received returns a channel from which all received payments can be read. The buffer size can be configured via the config `UpdateBufferSize`. It is advised to always read from this channel to avoid blocking client operation.

func (*Channel) Send

func (c *Channel) Send(ctx context.Context, amount ETHAmount) error

Send sends a payment over the channel. The amount is in Wei. Payments cannot be sent simultaneously.

type ChannelProposal

type ChannelProposal struct {
	From    Peer    // Peer that sent it.
	Balance Balance // Initial balance of the channel.
	// contains filtered or unexported fields
}

ChannelProposal models a proposal for a channel that was received by the Client from a known Peer. Can be accepted or rejected. Fully thread-safe. Should not be copied.

func (*ChannelProposal) Accept

func (p *ChannelProposal) Accept(ctx context.Context) (*Channel, error)

Accept accepts the channel proposal. Errors if the proposal was already accepted or rejected.

It is important that the passed context does not cancel before twice the block time has passed (at least for real blockchain backends with wall time), or the channel cannot be settled if a peer times out funding.

func (*ChannelProposal) Reject

func (p *ChannelProposal) Reject(ctx context.Context, reason string) error

Reject rejects the channel proposal with a reason. Errors if the proposal was already accepted or rejected.

type Client

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

The Client is the central object for opening payment channels.

It is completely thread safe and should not be copied. Always `Close()` a client when your application shuts down to avoid losing funds.

func NewClient

func NewClient(wallet *Wallet, cfg Config, opts ...ClientOption) (*Client, error)

NewClient creates a new client. The account from `wallet` will be used to send on-chain transactions. Pass one or more `ClientOption`s to modify the default behaviour.

func (*Client) Close

func (c *Client) Close(ctx context.Context) error

Close gracefully closes the Client and all open Channels.

func (*Client) HandleProposal

func (c *Client) HandleProposal(_prop client.ChannelProposal, responder *client.ProposalResponder)

HandleProposal DO NOT CALL. It is called by the framework for incoming channel proposals.

func (*Client) HandleUpdate

func (c *Client) HandleUpdate(update client.ChannelUpdate, responder *client.UpdateResponder)

HandleUpdate DO NOT CALL. It is called by the framework for incoming channel updates.

func (*Client) Init

func (c *Client) Init(ctx context.Context, adj, ah common.Address) error

Init sets and verifies the addresses of the Adjudicator and Assetholder contracts.

func (*Client) OnChainBalance

func (c *Client) OnChainBalance(ctx context.Context, addrs ...wallet.Address) ([]*big.Int, error)

OnChainBalance returns the on-chain balances for the passed addresses in WEI.

func (*Client) Proposals

func (c *Client) Proposals() <-chan *ChannelProposal

Proposals returns a channel that all incoming channel proposals can be read from. The buffer size can be configured via the config `ProposalBufferSize`. It is advised to always read from this channel to avoid blocking client operation.

func (*Client) ProposeChannel

func (c *Client) ProposeChannel(ctx context.Context, peer Peer, bals Balance) (*Channel, error)

ProposeChannel proposes a channel to `peer`. `bals` is the initial balance of the channel. It must be lower than the on-chain balance since both participants will use their on-chain balance to fund the channel.

func (*Client) RegisterPeer

func (c *Client) RegisterPeer(addr wire.Address, host, alias string) (Peer, error)

RegisterPeer registers a peer in the client. This is necessary to be able to send or receive a channel proposal from a peer. `addr` is the peers address. `host` is the ip:port that the peer listens on. `alias` a nickname for the peer. Does not need to be unique.

type ClientOption

type ClientOption func(*Client)

ClientOption is an option that can be passed to `NewClient` to change the default behaviour of a client.

func WithDialer

func WithDialer(dialer Dialer) ClientOption

WithDialer can be used to pass a custom dialer into the Client. The configuration option `DialTimeout` will be unused in this case.

func WithListener

func WithListener(listener net.Listener) ClientOption

WithListener can be used to pass a custom listener into the Client. The configuration option `Host` will be unused in this case.

type Config

type Config struct {
	Host, ChainURL     string
	ChallengeDuration  time.Duration
	DialTimeout        time.Duration
	ProposalBufferSize uint
	UpdateBufferSize   uint
}

Config contains all configuration options that are needed to create a Client. Should be created with `MakeConfig`.

func MakeConfig

func MakeConfig(host, chainURL string, challengeDuration time.Duration) Config

MakeConfig returns a new Config. All options that are not passed as arguments are set to default values. You can still modify them manually. `host` is the ip:port that the client should listen on for connections. `chainURL` is the URL of your Ethereum node. In the local ganache-cli case this would be: ws://0.0.0.0:8545 `challengeDuration` is the time in seconds that an on-chain challenge will last. This should be at least 3 times the average block time.

type Dialer

type Dialer interface {
	net.Dialer
	// Register will be called by the Payment client's `RegisterPeer`
	// function.
	Register(wire.Address, string)
}

Dialer wraps a go-perun wire/net.Dialer and adds a `Register` function to it.

type ETHAmount

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

ETHAmount represents an amount of Ethereum.

func MakeAmountFromETH

func MakeAmountFromETH(eth float64) ETHAmount

MakeAmountFromETH creates an `ETHAmount` with the given amount of ethereum set. Floating-point imprecision may apply.

func MakeAmountFromWEI

func MakeAmountFromWEI(wei *big.Int) ETHAmount

MakeAmountFromWEI creates an `ETHAmount` with the given amount of WEI set.

func (ETHAmount) ETH

func (a ETHAmount) ETH() float64

ETH returns the amount in Ethereum. Floating-point imprecision may apply.

func (ETHAmount) WEI

func (a ETHAmount) WEI() *big.Int

WEI returns the amount in WEI.

type Peer

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

Peer identifies a known peer. Can only be created with Client.RegisterPeer.

type Wallet

type Wallet struct {
	Address wallet.Address
	// contains filtered or unexported fields
}

Wallet contains a single account that will be used to send on-chain transactions. Its address is public.

func NewWalletHD

func NewWalletHD(chainID *big.Int, mnemonic string, index uint) (*Wallet, error)

NewWalletHD creates a new single-account HD-wallet with the given mnemonic. `index` is the index of the account that will be used.

func NewWalletSK

func NewWalletSK(chainID *big.Int, sk string) (*Wallet, error)

NewWalletSK creates a new single-account wallet from a secret key.

Jump to

Keyboard shortcuts

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