service

package
v0.8.0 Latest Latest
Warning

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

Go to latest
Published: Jul 6, 2021 License: MIT Imports: 31 Imported by: 0

README

Wallet

This package provides the basic cryptography to sign vega transactions, and a basic key management system: wallet service. It can be run alongside the core, but is not required for the operation of a Vega node, and API clients are free to implement their own transaction signing.

A wallet takes the form of a file saved on the file system and is encrypted using the passphrase chosen by the user. A wallet is composed of a list of key pairs (Ed25519) used to sign transactions for the user of a wallet.

Generate configuration

The package provides a way to generate the configuration of the service before starting it, it can be used through the vega command line like so:

vega wallet service init --genrsakey -f

Where --genrsakey generates an RSA key that will be used to sign your JWT (JSON web token), and -f overwrites any existing configuration files (if found). In short: this command will generate the RSA key, and the configuration files required by the wallet service.

Start the vega wallet service with:

vega wallet service run

Create a wallet

Creating a wallet is done using a name and passphrase. If a wallet already exists, the action is aborted. New wallets are marshalled, encrypted (using the passphrase) and saved to a file on the file system. A session and accompanying JWT is created, and the JWT is returned to the user.

  • Request:

    {
      "wallet": "walletname",
      "passphrase": "supersecret"
    }
    
  • Command:

    curl -s -XPOST -d 'requestjson' http://127.0.0.1:1789/api/v1/wallets
    
  • Response:

    {
      "token": "verylongJWT"
    }
    

Logging in to a wallet

Logging in to a wallet is done using the wallet name and passphrase. The operation fails should the wallet not exist, or if the passphrase used is incorrect (i.e. the passphrase cannot be used to decrypt the wallet). On success, the wallet is loaded, a session is created and a JWT is returned to the user.

  • Request:

    {
      "wallet": "walletname",
      "passphrase": "supersecret"
    }
    
  • Command:

    curl -s -XPOST -d 'requestjson' http://127.0.0.1:1789/api/v1/auth/token
    
  • Response:

    {
      "token": "verylongJWT"
    }
    

Logging out from a wallet

Using the JWT returned when logging in, the session is recovered and removed from the service. The wallet can no longer be accessed using the token from this point on.

  • Request: n/a

  • Command:

    curl -s -XDELETE -H 'Authorization: Bearer verylongJWT' http://127.0.0.1:1789/api/v1/auth/token
    
  • Response:

    {
      "success": true
    }
    

List keys

Users can list all their public keys (with taint status, and metadata), if they provide the correct JWT. The service extracts the session from this token, and uses it to fetch the relevant wallet information to send back to the user.

  • Request: n/a

  • Command:

    curl -s -XGET -H "Authorization: Bearer verylongJWT" http://127.0.0.1:1789/api/v1/keys
    
  • Response:

    {
      "keys": [
        {
          "pub": "1122aabb...",
          "algo": "ed25519",
          "tainted": false,
          "meta": [
            {
              "key": "somekey",
              "value": "somevalue"
            }
          ]
        }
      ]
    }
    

Generate a new key pair

The user submits a valid JWT, and a passphrase. We recover the session of the user, and attempt to open the wallet using the passphrase. If the JWT is invalid, the session could not be recovered, or the wallet could not be opened, an error is returned. If all went well, a new key pair is generated, saved in the wallet, and the public key is returned.

  • Request:

    {
      "passphrase": "supersecret",
      "meta": [
        {
          "key": "somekey",
          "value": "somevalue"
        }
      ]
    }
    
  • Command:

    curl -s -XPOST -H 'Authorization: Bearer verylongJWT' -d 'requestjson' http://127.0.0.1:1789/api/v1/keys
    
  • Response:

    {
      "key": {
        "pub": "1122aabb...",
        "algo": "ed25519",
        "tainted": false,
        "meta": [
          {
            "key": "somekey",
            "value": "somevalue"
          }
        ]
      }
    }
    

Sign a transaction

Sign a transaction using the specified keypair.

  • Request:

    {
      "tx": "dGVzdGRhdGEK",
      "pubKey": "1122aabb...",
      "propagate": false
    }
    
  • Command:

    curl -s -XPOST -H "Authorization: Bearer verylongJWT" -d 'requestjson' http://127.0.0.1:1789/api/v1/messages
    
    
  • Response:

    {
      "signedTx": {
        "data": "dGVzdGRhdGEK",
        "sig": "...",
        "pubKey": "1122aabb..."
      }
    }
    
Propagate

As you can see the request payload has a field propagate (optional) if set to true, then the wallet service, if configured with a correct vega node address will try to send the transaction on your behalf to the node after signing it successfully. The node address can be configured via the wallet service configuration file, by default it will point to a local instance of a vega node.

Taint a key

  • Request:

    {
      "passphrase": "supersecret"
    }
    
  • Command:

    curl -s -XPUT -H "Authorization: Bearer verylongJWT" -d 'requestjson' http://127.0.0.1:1789/api/v1/keys/1122aabb/taint
    
    
  • Response:

    {
      "success": true
    }
    

Update key metadata

Overwrite all existing metadata with the new metadata.

  • Request:

    {
      "passphrase": "supersecret",
      "meta": [
        {
          "key": "newkey",
          "value": "newvalue"
        }
      ]
    }
    
  • Command:

    curl -s -XPUT -H "Authorization: Bearer verylongJWT" -d 'requestjson' http://127.0.0.1:1789/api/v1/keys/1122aabb/metadata
    
    
  • Response:

    {
      "success": true
    }
    

Issue a transaction

  • Request:

    {
      "pubKey": "8d06a20eb717938b746e0332686257ae39fa3d90847eb8ee0da3463732e968ba",
      "propagate": true,
      "orderCancellation": {
        "marketId": "YESYESYES"
      }
    }
    
  • Command:

    curl -s -XPOST -H "Authorization: Bearer verylongJWT" -d 'requestjson' http://127.0.0.1:1789/api/v1/command
    
  • Response:

    {
      "transaction": {
        "inputData": "dGVzdGRhdG9837420b4b3yb23ybc4o1ui23yEK",
        "signature": {
          "value": "7f6g9sf8f8s76dfa867fda",
          "algo": "vega/ed25519",
          "version": 1
        },
        "from": {
          "pubKey": "1122aabb..."
        },
        "version": 1
      }
    }
    

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidOrMissingToken  = newErrorResponse("invalid or missing token")
	ErrCouldNotReadRequest    = errors.New("could not read request")
	ErrCouldNotGetBlockHeight = errors.New("could not get last block height")
)
View Source
var (
	ErrSessionNotFound = errors.New("session not found")
)

Functions

func ExtractToken

ExtractToken this is public for testing purposes

func NewAuth

func NewAuth(log *zap.Logger, cfgStore RSAStore, tokenExpiry time.Duration) (*auth, error)

Types

type Auth

type Auth interface {
	NewSession(name string) (string, error)
	VerifyToken(token string) (string, error)
	Revoke(token string) error
}

Auth ...

type Claims

type Claims struct {
	jwt.StandardClaims
	Session string
	Wallet  string
}

type CreateLoginWalletRequest

type CreateLoginWalletRequest struct {
	Wallet     string `json:"wallet"`
	Passphrase string `json:"passphrase"`
}

CreateLoginWalletRequest describes the request for CreateWallet, LoginWallet.

func ParseCreateLoginWalletRequest

func ParseCreateLoginWalletRequest(r *http.Request) (*CreateLoginWalletRequest, commands.Errors)

type ErrorResponse

type ErrorResponse struct {
	ErrorStr string   `json:"error"`
	Details  []string `json:"details"`
}

func (ErrorResponse) Error

func (e ErrorResponse) Error() string

type ErrorsResponse

type ErrorsResponse struct {
	Errors commands.Errors `json:"errors"`
}

type GenKeyPairRequest

type GenKeyPairRequest struct {
	Passphrase string        `json:"passphrase"`
	Meta       []wallet.Meta `json:"meta"`
}

GenKeyPairRequest describes the request for GenerateKeypair

func ParseGenKeyPairRequest

func ParseGenKeyPairRequest(r *http.Request) (*GenKeyPairRequest, commands.Errors)

type KeyResponse

type KeyResponse struct {
	Key wallet.PublicKey `json:"key"`
}

KeyResponse describes the response to a request that returns a single key.

type KeysResponse

type KeysResponse struct {
	Keys []wallet.PublicKey `json:"keys"`
}

KeysResponse describes the response to a request that returns a list of keys.

type RSAStore

type RSAStore interface {
	GetRsaKeys() (*wallet.RSAKeys, error)
}

type Service

type Service struct {
	*httprouter.Router
	// contains filtered or unexported fields
}

func NewService

func NewService(log *zap.Logger, cfg *config.Config, rootPath string) (*Service, error)

func NewServiceWith

func NewServiceWith(log *zap.Logger, cfg *config.Config, h WalletHandler, a Auth, n NodeForward) (*Service, error)

func (*Service) CreateWallet

func (s *Service) CreateWallet(w http.ResponseWriter, r *http.Request, _ httprouter.Params)

func (*Service) DownloadWallet

func (s *Service) DownloadWallet(token string, w http.ResponseWriter, r *http.Request, _ httprouter.Params)

func (*Service) GenerateKeypair

func (s *Service) GenerateKeypair(t string, w http.ResponseWriter, r *http.Request, _ httprouter.Params)

func (*Service) GetPublicKey

func (s *Service) GetPublicKey(t string, w http.ResponseWriter, r *http.Request, ps httprouter.Params)

func (*Service) ListPublicKeys

func (s *Service) ListPublicKeys(t string, w http.ResponseWriter, r *http.Request, _ httprouter.Params)

func (*Service) Login

func (*Service) Revoke

func (s *Service) Revoke(t string, w http.ResponseWriter, _ *http.Request, _ httprouter.Params)

func (*Service) SignAny

func (s *Service) SignAny(t string, w http.ResponseWriter, r *http.Request, _ httprouter.Params)

func (*Service) SignTx

func (s *Service) SignTx(t string, w http.ResponseWriter, r *http.Request, p httprouter.Params)

func (*Service) SignTxAsync

func (s *Service) SignTxAsync(t string, w http.ResponseWriter, r *http.Request, p httprouter.Params)

func (*Service) SignTxCommit

func (s *Service) SignTxCommit(t string, w http.ResponseWriter, r *http.Request, p httprouter.Params)

func (*Service) SignTxCommitV2

func (s *Service) SignTxCommitV2(token string, w http.ResponseWriter, r *http.Request, p httprouter.Params)

func (*Service) SignTxSyncV2

func (s *Service) SignTxSyncV2(token string, w http.ResponseWriter, r *http.Request, p httprouter.Params)

func (*Service) SignTxV2

func (s *Service) SignTxV2(token string, w http.ResponseWriter, r *http.Request, p httprouter.Params)

func (*Service) Start

func (s *Service) Start() error

func (*Service) Stop

func (s *Service) Stop() error

func (*Service) TaintKey

func (s *Service) TaintKey(t string, w http.ResponseWriter, r *http.Request, ps httprouter.Params)

func (*Service) UpdateMeta

func (s *Service) UpdateMeta(t string, w http.ResponseWriter, r *http.Request, ps httprouter.Params)

func (*Service) VerifyAny

func (s *Service) VerifyAny(t string, w http.ResponseWriter, r *http.Request, _ httprouter.Params)

type SignAnyRequest

type SignAnyRequest struct {
	// InputData is the payload to generate a signature from. I should be
	// base 64 encoded.
	InputData string `json:"inputData"`
	// PubKey is used to retrieve the private key to sign the InputDate.
	PubKey string `json:"pubKey"`
}

SignAnyRequest describes the request for SignAny.

func ParseSignAnyRequest

func ParseSignAnyRequest(r *http.Request) (*SignAnyRequest, commands.Errors)

type SignAnyResponse

type SignAnyResponse struct {
	HexSignature    string `json:"hexSignature"`
	Base64Signature string `json:"base64Signature"`
}

SignAnyResponse describes the response for SignAny.

type SignTxRequest

type SignTxRequest struct {
	Tx        string `json:"tx"`
	PubKey    string `json:"pubKey"`
	Propagate bool   `json:"propagate"`
}

SignTxRequest describes the request for SignTx.

type SignTxResponse

type SignTxResponse struct {
	SignedTx     wallet.SignedBundle `json:"signedTx"`
	HexBundle    string              `json:"hexBundle"`
	Base64Bundle string              `json:"base64Bundle"`
}

SignTxResponse describes the response for SignTx.

type SuccessResponse

type SuccessResponse struct {
	Success bool `json:"success"`
}

SuccessResponse describes the response to a request that returns a simple true/false answer.

type TaintKeyRequest

type TaintKeyRequest struct {
	Passphrase string `json:"passphrase"`
}

TaintKeyRequest describes the request for TaintKey.

func ParseTaintKeyRequest

func ParseTaintKeyRequest(r *http.Request, keyID string) (*TaintKeyRequest, commands.Errors)

type TokenResponse

type TokenResponse struct {
	Token string `json:"token"`
}

TokenResponse describes the response to a request that returns a token.

type UpdateMetaRequest

type UpdateMetaRequest struct {
	Passphrase string        `json:"passphrase"`
	Meta       []wallet.Meta `json:"meta"`
}

UpdateMetaRequest describes the request for UpdateMeta.

func ParseUpdateMetaRequest

func ParseUpdateMetaRequest(r *http.Request, keyID string) (*UpdateMetaRequest, commands.Errors)

type VerifyAnyRequest

type VerifyAnyRequest struct {
	// InputData is the payload to be verified. It should be base64 encoded.
	InputData string `json:"inputData"`
	// Signature is the signature to check against the InputData. It should be
	// base64 encoded.
	Signature string `json:"signature"`
	// PubKey is the public key used along the signature to check the InputData.
	PubKey string `json:"pubKey"`
}

VerifyAnyRequest describes the request for VerifyAny.

func ParseVerifyAnyRequest

func ParseVerifyAnyRequest(r *http.Request) (*VerifyAnyRequest, commands.Errors)

type WalletHandler

type WalletHandler interface {
	CreateWallet(name, passphrase string) error
	LoginWallet(name, passphrase string) error
	LogoutWallet(name string)
	SecureGenerateKeyPair(name, passphrase string) (string, error)
	GetPublicKey(name, pubKey string) (*wallet.PublicKey, error)
	ListPublicKeys(name string) ([]wallet.PublicKey, error)
	SignTx(name, tx, pubKey string, height uint64) (wallet.SignedBundle, error)
	SignTxV2(name string, req *walletpb.SubmitTransactionRequest, height uint64) (*commandspb.Transaction, error)
	SignAny(name, inputData, pubKey string) ([]byte, error)
	VerifyAny(name, inputData, sig, pubKey string) (bool, error)
	TaintKey(name, pubKey, passphrase string) error
	UpdateMeta(name, pubKey, passphrase string, meta []wallet.Meta) error
	GetWalletPath(name string) (string, error)
}

WalletHandler ...

Directories

Path Synopsis
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.

Jump to

Keyboard shortcuts

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