schema.proto

This file defines the protocol between relays and clients. It is orthogonal to the store registry and other smart contracts.

Messages must be prefixed with their acompanying encoding number as a single byte. encoding.txt defines the number for each message.

Furthermore, we expect only one message per write/binary frame. This means no buffering of multiple messages into a single write. The protocol offers repeated fields where approriate for higher throughput. A suggested transport is WebSocket over HTTPS but the protocol is agnostic, as long as it can handle binary data and keeps the framing intact.

For upgrades there exists a VERSION file in the root of the repository. The VERSION is a single unsigned integer, incremented for each change. The client and relay must agree on the VERSION before starting the protocol. In the case of WebSocket, the VERSION can be compared via the URL. The relay must close the connection if the VERSION isn't supported.

As of this version, the protocol is grouped into 2 categories: Events, which define the content of a Store, and Request/Response methods to exchange information.

StoreManifest

First genisis message of a store. Has to be the first message that is written and can only be written once. Use UpdateManifest to make changes.

StoreManifest type fields

Field

Type

Label

Description

event_id

bytes

The event_id is a unique identifier for an event. Currently it's 32 bytes of random data. It also functions as a nonce for The events signature. The global identifier of an Item should also include the store_token_id. hash(store_token_id:signature) might suffice then with a smaller nonce.

store_token_id

bytes

The NFT Token ID used in StoreReg.registerStore(). Checkout will ownerOf() this to determine the addr for PurchaseFactory.

domain

string

Website URL of the store TODO: might change this to metdata inside the NFT URL.

published_tag_id

bytes

the system tag used to list active items

UpdateManifest

Used to update the store manifest. The Field enum determines the field to be updated and the value to be used.

UpdateManifest type fields

Field

Type

Label

Description

event_id

bytes

See StoreManifest for details

field

UpdateManifest.ManifestField

Defines the field to be updated and determines the value to be used.

string

string

value

tag_id

bytes

value

See event_id for details

erc20_addr

bytes

value

20 bytes

CreateItem

Creates an item in the store.

CreateItem type fields

Field

Type

Label

Description

event_id

bytes

See StoreManifest for details

price

string

decimal number as a string. numbers need to be always formatted to 2 decimal places. the demcimal place must use a dot ('.') as the separator.

metadata

bytes

should be valid JSON TODO: make a json schmea with minimal/required fields

UpdateItem

UpdateItem changes the price or metadata of an item. Follows the same pattern as UpdateManifest.

UpdateItem type fields

Field

Type

Label

Description

event_id

bytes

See StoreManifest for details

item_id

bytes

the event_id of the CreateItem event

field

UpdateItem.ItemField

price

string

value

decimal number. See CreateItem for formatting.

metadata

bytes

value

CreateTag

Creates a tag in the store. These can be used to group items into categories. There are also a couple of system-level tags, like published. Thse are used to filter items in the store.

CreateTag type fields

Field

Type

Label

Description

event_id

bytes

See StoreManifest for details

name

string

AddToTag

Adds an item to a tag. TODO: might change this to the Update* pattern.

AddToTag type fields

Field

Type

Label

Description

event_id

bytes

See StoreManifest for details

tag_id

bytes

item_id

bytes

RemoveFromTag

Removes an item from a tag. TODO: might change this to the Update* pattern.

RemoveFromTag type fields

Field

Type

Label

Description

event_id

bytes

See StoreManifest for details

tag_id

bytes

item_id

bytes

RenameTag

Renames a tag. TODO: might change this to the Update* pattern.

RenameTag type fields

Field

Type

Label

Description

event_id

bytes

See StoreManifest for details

tag_id

bytes

name

string

DeleteTag

Deletes a tag. TODO: might change this to the Update* pattern.

DeleteTag type fields

Field

Type

Label

Description

event_id

bytes

See StoreManifest for details

tag_id

bytes

ChangeStock

ChangeStock is used to update the stock of on or more items. Created by the relay after a cart has been paied for.

ChangeStock type fields

Field

Type

Label

Description

event_id

bytes

See StoreManifest for details

item_ids

bytes

repeated

length needs to match the length of the diff field

diffs

sint32

repeated

cart_id

bytes

(optional) only set by the relay. signals payment completion after a CommitCartRequest

tx_hash

bytes

NewKeyCard

created by the relay when a user enrolls a key card

NewKeyCard type fields

Field

Type

Label

Description

event_id

bytes

See StoreManifest for details

user_wallet_addr

bytes

card_public_key

bytes

CreateCart

CreateCart is used to create a new cart.

CreateCart type fields

Field

Type

Label

Description

event_id

bytes

See StoreManifest for details

ChangeCart

ChangeCart is used to add or remove items from a cart.

ChangeCart type fields

Field

Type

Label

Description

event_id

bytes

See StoreManifest for details

cart_id

bytes

item_id

bytes

quantity

sint32

CartFinalized

Created by the relay after a CommitCartRequest. It signals that a cart is about to be payed and can not be changed anymore.

CartFinalized type fields

Field

Type

Label

Description

event_id

bytes

See StoreManifest for details

cart_id

bytes

purchase_addr

bytes

the address the user needs to send the funds to

erc20_addr

bytes

(optional) copied from CommitCartRequest

sub_total

string

sales_tax

string

total

string

= subtotal + sales_tax

total_in_crypto

string

The exact amount to transfer to the purchase_address. bigint as string.

CartAbandoned

Either created by a relay for a carts that haven't been payed in time. Or by a clerk, for eg. when the customer steps back from the purchase. This frees up the items locked up in the finalized cart.

CartAbandoned type fields

Field

Type

Label

Description

event_id

bytes

See StoreManifest for details

cart_id

bytes

Event

Event is the transport wrapper for a single Event.

For signatures we use https://eips.ethereum.org/EIPS/eip-712. The structured data definition are specified in typedData.json. The KeyCard keypair is used to sign or verify the data. The Set of all valid keys is all NewKeyCard events plus the Relays assigned on the StoreReg smart contract.

Special care must be taken for Events with optional and union fields. Specifically these are UpdateManifest, UpdateItem and ChangeStock. Some implementations of eth_signTypedData are fine with null fields, while others aren't. Therefore, the structured data specification needs to be pruned from fields that are not set.

Event type fields

Field

Type

Label

Description

signature

bytes

store_manifest

StoreManifest

union

update_manifest

UpdateManifest

union

create_item

CreateItem

union

update_item

UpdateItem

union

create_tag

CreateTag

union

add_to_tag

AddToTag

union

remove_from_tag

RemoveFromTag

union

rename_tag

RenameTag

union

delete_tag

DeleteTag

union

create_cart

CreateCart

union

change_cart

ChangeCart

union

cart_finalized

CartFinalized

union

cart_abandoned

CartAbandoned

union

change_stock

ChangeStock

union

new_key_card

NewKeyCard

union

AuthenticateRequest

Initiates the challenge/response protocol.

AuthenticateRequest type fields

Field

Type

Label

Description

request_id

bytes

See PingRequest for details

public_key

bytes

of their keyCard

AuthenticateResponse

Returns an error if the public key is not an enrolled KeyCard. or a challenge to be signed by the KeyCard.

AuthenticateResponse type fields

Field

Type

Label

Description

request_id

bytes

error

Error

challenge

bytes

ChallengeSolvedRequest

Completes authentication by supplying the signature over the challenge.

ChallengeSolvedRequest type fields

Field

Type

Label

Description

request_id

bytes

signature

bytes

ChallengeSolvedResponse

No error means the user is authenticated.

ChallengeSolvedResponse type fields

Field

Type

Label

Description

request_id

bytes

error

Error

CommitCartRequest

Initiate check out of a cart

CommitCartRequest type fields

Field

Type

Label

Description

request_id

bytes

cart_id

bytes

erc20_addr

bytes

emtpy/unset means vanilla ETH

CommitCartResponse

Returns an error if the cart is already finalized. No error blocks further changes to a cart and starts the payment process. TODO: we might change the payload in this to an Event for longevity.

CommitCartResponse type fields

Field

Type

Label

Description

request_id

bytes

error

Error

cart_finalized_id

bytes

GetBlobUploadURLRequest

Get an URL to upload a blob to. This exists for future-proofing the protocol and reduce stress on the websocket connection.

GetBlobUploadURLRequest type fields

Field

Type

Label

Description

request_id

bytes

GetBlobUploadURLResponse

Returns a single-use URL to upload a blob to. The HTTP response will contain the blob's IPFS path.

GetBlobUploadURLResponse type fields

Field

Type

Label

Description

request_id

bytes

error

Error

url

string

EventWriteRequest

Used by the Client to write a single event to the store.

EventWriteRequest type fields

Field

Type

Label

Description

request_id

bytes

event

Event

EventWriteResponse

Might return an error if the event or its signature is invalid. If no error is returned, the new_store_hash is the hash of the store with the new event applied. The event_sequence_no is the index of the event in the stores log.

EventWriteResponse type fields

Field

Type

Label

Description

request_id

bytes

error

Error

new_store_hash

bytes

event_sequence_no

uint64

SyncStatusRequest

Sent by the relay to signal the number of unpushed events.

SyncStatusRequest type fields

Field

Type

Label

Description

request_id

bytes

unpushed_events

uint64

SyncStatusResponse

SyncStatusResponse type fields

Field

Type

Label

Description

request_id

bytes

error

Error

EventPushRequest

Used by the relay to push events to the client. Will not sent more events until the client has acknowledged the last batch.

EventPushRequest type fields

Field

Type

Label

Description

request_id

bytes

events

Event

repeated

EventPushResponse

EventPushResponse type fields

Field

Type

Label

Description

request_id

bytes

error

Error

PingRequest

Sent by the relay to check for the clients liveness. The client needs to respond with a PingResponse. The relay will close the connection if the client doesn't respond 3 times.

PingRequest type fields

Field

Type

Label

Description

request_id

bytes

16 bytes, chosen by the sender but should be random. Used to match the response to the request.

PingResponse

PingResponse type fields

Field

Type

Label

Description

request_id

bytes

error

Error

Error

Error type fields

Field

Type

Label

Description

code

string

TODO: make a list of error codes, maybe enum

message

string

UpdateItem.ItemField

Enum UpdateItem.ItemField values

Name

Number

Description

ITEM_FIELD_UNSPECIFIED

0

ITEM_FIELD_PRICE

1

ITEM_FIELD_METADATA

2

UpdateManifest.ManifestField

for now we assume the owner can't be changed

Enum UpdateManifest.ManifestField values

Name

Number

Description

MANIFEST_FIELD_UNSPECIFIED

0

needed as a side-effect of what protobuf calls "open enums"

MANIFEST_FIELD_DOMAIN

1

uses value:3 (type string)

MANIFEST_FIELD_PUBLISHED_TAG

2

uses value:4 (type event_id)

MANIFEST_FIELD_ADD_ERC20

3

add uses value:5 (addrress)

MANIFEST_FIELD_REMOVE_ERC20

4

uses value:5 (address)

Scalar Value Types

double

double language representation

.proto Type

C++

Java

Python

Go

C#

PHP

Ruby

double

double

double

float

float64

double

float

Float

float

float language representation

.proto Type

C++

Java

Python

Go

C#

PHP

Ruby

float

float

float

float

float32

float

float

Float

int32

Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead.

int32 language representation

.proto Type

C++

Java

Python

Go

C#

PHP

Ruby

int32

int32

int

int

int32

int

integer

Bignum or Fixnum (as required)

int64

Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead.

int64 language representation

.proto Type

C++

Java

Python

Go

C#

PHP

Ruby

int64

int64

long

int/long

int64

long

integer/string

Bignum

uint32

Uses variable-length encoding.

uint32 language representation

.proto Type

C++

Java

Python

Go

C#

PHP

Ruby

uint32

uint32

int

int/long

uint32

uint

integer

Bignum or Fixnum (as required)

uint64

Uses variable-length encoding.

uint64 language representation

.proto Type

C++

Java

Python

Go

C#

PHP

Ruby

uint64

uint64

long

int/long

uint64

ulong

integer/string

Bignum or Fixnum (as required)

sint32

Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s.

sint32 language representation

.proto Type

C++

Java

Python

Go

C#

PHP

Ruby

sint32

int32

int

int

int32

int

integer

Bignum or Fixnum (as required)

sint64

Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s.

sint64 language representation

.proto Type

C++

Java

Python

Go

C#

PHP

Ruby

sint64

int64

long

int/long

int64

long

integer/string

Bignum

fixed32

Always four bytes. More efficient than uint32 if values are often greater than 2^28.

fixed32 language representation

.proto Type

C++

Java

Python

Go

C#

PHP

Ruby

fixed32

uint32

int

int

uint32

uint

integer

Bignum or Fixnum (as required)

fixed64

Always eight bytes. More efficient than uint64 if values are often greater than 2^56.

fixed64 language representation

.proto Type

C++

Java

Python

Go

C#

PHP

Ruby

fixed64

uint64

long

int/long

uint64

ulong

integer/string

Bignum

sfixed32

Always four bytes.

sfixed32 language representation

.proto Type

C++

Java

Python

Go

C#

PHP

Ruby

sfixed32

int32

int

int

int32

int

integer

Bignum or Fixnum (as required)

sfixed64

Always eight bytes.

sfixed64 language representation

.proto Type

C++

Java

Python

Go

C#

PHP

Ruby

sfixed64

int64

long

int/long

int64

long

integer/string

Bignum

bool

bool language representation

.proto Type

C++

Java

Python

Go

C#

PHP

Ruby

bool

bool

boolean

boolean

bool

bool

boolean

TrueClass/FalseClass

string

A string must always contain UTF-8 encoded or 7-bit ASCII text.

string language representation

.proto Type

C++

Java

Python

Go

C#

PHP

Ruby

string

string

String

str/unicode

string

string

string

String (UTF-8)

bytes

May contain any arbitrary sequence of bytes.

bytes language representation

.proto Type

C++

Java

Python

Go

C#

PHP

Ruby

bytes

string

ByteString

str

[]byte

ByteString

string

String (ASCII-8BIT)