rvasp

package
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Apr 10, 2024 License: MIT Imports: 40 Imported by: 0

README

rVASP

Robot VASP for TRISA demonstration and integration

This is a simple gRPC server that implements a UI workflow and messaging framework to demonstrate sending and receiving transactions using the TRISA InterVASP protocol. The server was built to support a demonstration UI that requires a streaming interface so that a live message flow is achieved. However, the communication protocol between rVASPs also demonstrates how implementers might go about writing InterVASP services in their own codebases.

Generating Protocol Buffers

To regenerate the Go and Python code from the protocol buffers:

$ go generate ./...

This will generate the Go code in pkg/rvasp/pb/v1 and the Python code in lib/python/rvaspy/rvaspy. Alternatively you can manually generate the code to specify different directories using the following commands:

$ protoc -I . --go_out=plugins=grpc:. api.proto
$ python -m grpc_tools.protoc -I . --python_out=./rvaspy --grpc_python_out=./rvaspy api.proto

Note: After generating the Python protocol buffers you must edit the import line in lib/python/rvaspy/rvaspy/api_pb2_grpc.py to the following in order to correctly use the library.

import rvaspy.api_pb2 as api__pb2

Quick Start

To get started using the rVASP, you can run the local server as follows:

$ go run ./cmd/rvasp serve

Alternatively, multiple rVASPs can be run concurrently using docker compose.

$ ./scripts/generate-fixtures.sh
$ ./containers/build.sh
$ docker compose -f ./containters/docker-compose.yml up

The server should now be listening for TRISADemo RPC messages. To send messages using the python API, make sure you can import the modules from rvaspy - the simplest way to do this is to install the package in editable mode as follows:

$ pip install -e ./rvaspy/

This will use the setup.py file in the rvaspy directory to install the package to your $PYTHON_PATH. Because it is in editable mode, any time you regenerate the protocol buffers or pull the repository, the module should be updated on the next time you import. An example script for using the package is as follows:

import rvaspy

api = rvaspy.connect("localhost:6434")

cmds = [
    api.account_request("robert@bobvasp.co.uk"),
    api.transfer_request("robert@bobvasp.co.uk", "mary@alicevasp.us", 42.99)
]

for msg in api.stub.LiveUpdates(iter(cmds)):
    print(msg)

Note that the RVASP api client is not fully implemented yet.

Configuration

The identity and operation of the rVASPs is defined in the pkg/rvasp/fixtures directory. This must contain two files, vasps.json and wallets.json.

vasps.json

This defines how rVASPs are addressed and their ivms101 identity information. It consists of a list of JSON objects with the fields:

common_name: Common name of the rVASP legal_person: ivms101 identity information of the rVASP

wallets.json

This defines the wallets and accounts in the rVASP database. It consists of a list of ordered entries for each wallet:

  1. The wallet address
  2. The email address of the associated account
  3. The index of the VASP in vasps.json, starting at 1
  4. The originator policy for outgoing transfers
  5. The beneficiary policy for incoming transfers
  6. The ivms101 information for the associated account
Wallet Policies

The rVASPs are designed to support different configured transfer policies without having to rebuild them. This is implemented by associating wallets with policies. The supported policies are defined below:

Originator (Outgoing) Policies

send_partial: Send a transfer request to the beneficiary containing partial beneficiary identity information.

send_full: Send a transfer request to the beneficiary containing the full beneficiary identity information.

send_error: Send a TRISA error to the beneficiary.

Beneificiary (Incoming) Policies

sync_repair: Complete the beneficiary identity information in the received payload and return the payload to the originator.

sync_require: Send a synchronous response to the originator if the full beneficiary identity information exists in the payload, otherwise send a TRISA rejection error.

async_repair: Send a pending response to the originator with ReplyNotBefore and ReplyNotAfter timestamps. After a period of time within that time range, initiate a transfer to the originator containing the full beneficiary identity information to complete the transaction.

async_reject: Send a pending response to the originator with ReplyNotBefore and ReplyNotAfter timestamps. After a period of time within that time range, send a TRISA rejection error to the originator.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func StreamTraceInterceptor added in v1.0.1

func StreamTraceInterceptor(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) (err error)

This streaming interceptor traces gRPC requests, adds zerolog logging and panic recovery.

func UnaryTraceInterceptor added in v1.0.1

func UnaryTraceInterceptor(ctx context.Context, in interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (out interface{}, err error)

This unary interceptor traces gRPC requests, adds zerolog logging and panic recovery.

func ValidateIdentityPayload added in v1.1.0

func ValidateIdentityPayload(identity *ivms101.IdentityPayload, requireBeneficiary bool) *protocol.Error

Validate an identity payload, returning an error if the payload is not valid.

Types

type Server

type Server struct {
	pb.UnimplementedTRISADemoServer
	pb.UnimplementedTRISAIntegrationServer
	// contains filtered or unexported fields
}

Server implements the GRPC TRISAIntegration and TRISADemo services.

func New

func New(conf *config.Config) (s *Server, err error)

New creates a rVASP server with the specified configuration and prepares it to listen for and serve GRPC requests.

func NewServerMock added in v1.0.0

func NewServerMock(conf *config.Config) (s *Server, mockDB sqlmock.Sqlmock, err error)

NewServerMock returns a mock rVASP server that can be used for testing.

func (*Server) AccountStatus

func (s *Server) AccountStatus(ctx context.Context, req *pb.AccountRequest) (rep *pb.AccountReply, err error)

AccountStatus is a demo RPC to allow demo clients to fetch their recent transactions.

func (*Server) LiveUpdates

func (s *Server) LiveUpdates(stream pb.TRISADemo_LiveUpdatesServer) (err error)

LiveUpdates is a demo bidirectional RPC that allows demo clients to explicitly show the message interchange between VASPs during the InterVASP protocol. The demo client connects to both sides of a transaction and can push commands to the stream; any messages received by the VASP as they perform the protocol are sent down to the UI.

func (*Server) Serve

func (s *Server) Serve() (err error)

Serve GRPC requests on the specified address.

func (*Server) Shutdown

func (s *Server) Shutdown() (err error)

Shutdown the rVASP Service gracefully

func (*Server) Status added in v1.2.0

func (s *Server) Status(context.Context, *pb.Empty) (_ *pb.ServerStatus, err error)

func (*Server) Transfer

func (s *Server) Transfer(ctx context.Context, req *pb.TransferRequest) (reply *pb.TransferReply, err error)

Transfer accepts a transfer request from a beneficiary and begins the InterVASP protocol to perform identity verification prior to establishing the transaction in the blockchain between crypto wallet addresses.

type TRISA

type TRISA struct {
	protocol.UnimplementedTRISANetworkServer
	protocol.UnimplementedTRISAHealthServer
	// contains filtered or unexported fields
}

TRISA implements the GRPC TRISANetwork and TRISAHealth services.

func NewTRISA

func NewTRISA(parent *Server) (svc *TRISA, err error)

NewTRISA from a parent server.

func NewTRISAMock added in v1.0.0

func NewTRISAMock(conf *config.Config) (s *TRISA, remotePeers *peers.Peers, mockDB sqlmock.Sqlmock, certs *trust.Provider, chain trust.ProviderPool, err error)

NewTRISAMock returns a mock TRISA server that can be used for testing.

func (*TRISA) AsyncHandler added in v1.0.0

func (s *TRISA) AsyncHandler(stop <-chan struct{})

AsyncHandler is a go routine that periodically reads pending messages off the rVASP database and initiates TRISA transfers back to the originator. This allows the rVASPs to simulate asynchronous transactions.

func (*TRISA) ConfirmAddress

func (s *TRISA) ConfirmAddress(ctx context.Context, in *protocol.Address) (out *protocol.AddressConfirmation, err error)

ConfirmAddress allows the rVASP to respond to proof-of-control requests.

func (*TRISA) KeyExchange

func (s *TRISA) KeyExchange(ctx context.Context, in *protocol.SigningKey) (out *protocol.SigningKey, err error)

KeyExchange facilitates signing key exchange between VASPs.

func (*TRISA) Run added in v1.0.0

func (s *TRISA) Run(sock net.Listener)

Run the gRPC server. This method is extracted from the Serve function so that it can be run in its own go routine and to allow tests to Run a bufconn server without starting a live server with all of the various go routines and channels running.

func (*TRISA) Serve

func (s *TRISA) Serve() (err error)

Serve initializes the GRPC server and returns any errors during initialization, it then kicks off a go routine to handle requests. Not thread safe, should not be called multiple times.

func (*TRISA) Shutdown

func (s *TRISA) Shutdown() (err error)

Shutdown the TRISA server gracefully

func (*TRISA) Status

func (s *TRISA) Status(ctx context.Context, in *protocol.HealthCheck) (out *protocol.ServiceState, err error)

Status returns a directory health check status as online and requests half an hour checks.

func (*TRISA) Transfer

func (s *TRISA) Transfer(ctx context.Context, in *protocol.SecureEnvelope) (out *protocol.SecureEnvelope, err error)

Transfer enables a quick one-off transaction between peers.

func (*TRISA) TransferStream

func (s *TRISA) TransferStream(stream protocol.TRISANetwork_TransferStreamServer) (err error)

TransferStream allows for high-throughput transactions.

type UpdateManager

type UpdateManager struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

UpdateManager sends update messages to all connected clients.

func NewUpdateManager

func NewUpdateManager() *UpdateManager

NewUpdateManager creates a new update manager ready to work. For thread safety, this is the only object that can send messages on update streams.

func (*UpdateManager) Add

func (u *UpdateManager) Add(client string, stream pb.TRISADemo_LiveUpdatesServer) (err error)

Add a new client update stream.

func (*UpdateManager) Broadcast

func (u *UpdateManager) Broadcast(requestID uint64, update string, cat pb.MessageCategory) (err error)

Broadcast a message to all streams.

func (*UpdateManager) Del

func (u *UpdateManager) Del(client string)

Del an old client update stream. No-op if client odesn't exist.

func (*UpdateManager) Send

func (u *UpdateManager) Send(client string, msg *pb.Message) (err error)

Send a message to a specific stream

func (*UpdateManager) SendTransferError

func (u *UpdateManager) SendTransferError(client string, id uint64, err *pb.Error) error

SendTransferError to client

Directories

Path Synopsis
* Package jsonpb uses protojson (not the deprecated jsonpb module) to set defaults for * marshaling and unmarshaling rVASP protobuf messages to and from JSON format.
* Package jsonpb uses protojson (not the deprecated jsonpb module) to set defaults for * marshaling and unmarshaling rVASP protobuf messages to and from JSON format.
pb
v1

Jump to

Keyboard shortcuts

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