Messages Service
The messages service provides HTTP URLs for a client to receive messages. Since most users won’t have domain names or want to host web services this is required for peer to peer and two-way client to service communication. The messages should be signed and encrypted whenever possible so little to no trust is required for the messaging service. The service must simply stay up and deliver messages to the appropriate recipients.
A client authenticates with the service using a Bitcoin (secp256k1) key. Then the client can create channels to receive messages. Each channel is associated with a specific key and contains that in the URL to post to that channel. This enables a client to simply provide the URL to someone else and they can parse the public key from the URL to know the public key to use to communicate with them.
To encrypt a message to a channel the sender parses the recipient’s public key from the channel URL then calculates the ECDH secret between the sender’s private key and the channel’s public key and uses that to encrypt the message. The message should also include the sender’s unencrypted public key so the recipient knows how to decrypt the encrypted contents of the message.
The messages service supports the standard service functionality.
Channels
A channel is a specific URL that can be posted to via an HTTP post request. The owner of the channel will receive the HTTP request body contents and ‘Content-Type’ header value.
This is an example channel URL. It can have any host and prefix path at the beginning but must end with “/channels/” followed by the hex encoding of the compressed public key. A compressed public key is 66 hex characters, representing 33 bytes, starting with ‘02’ or ‘03’. This ensures the public key can always be easily parsed from the URL.
https://messages.nextcash.tech/channels/<public_key>
Authentication
No authentiation is required to post messages to a channel URL. Authentication is required to connect to the service as a client that can create channels and receive messages.
Documentation for authentication is provided here.
Administration
When an account is created a private channel will be established with the account/authentication key. Posting to this channel via an HTTP URL will result in an HTTP status 404 (Not found). Only the service can post messages to this channel. The channel will be used for messages from the service to the client, like payment requests. The client can respond to these messages on the channel corresponding to the service’s key.
Fees
Fees will be charged for certain actions within an account. The client is responsible for maintaining a balance on the account and if they do not then their services will be disabled until a payment is made.
When an account’s balance is getting low the service will post a payment request on the account’s administration channel so the client can keep the account in good standing. The client should respond by completing the payment request and posting it to the service’s channel. If the client wants to pay a different amount they can modify the payment request with the endpoint for creating a specific payment request. If the account’s balance gets too low then messages can no longer be received. The admin channel will remain functional to facilitate payments to the service to re-activate the account.
API (Application Programming Interface)
Post Message
HTTP POST Request to URL - https://<hostname><path_prefix>/channels/<channel_key>
The HTTP request Content-Type
header value and the contents of the body will be delivered to the owner of the channel.
A success response will be an HTTP status 201 (Created) and an empty body.
Acknowledge Message
HTTP POST Request to URL - https://<hostname><path_prefix>/channels/<channel_key>/<sequence>
The account is determined via the token in the HTTP request header Authorization
value.
Messages at or below the specified sequence value will be discarded.
A success response will be an HTTP status 200 (OK) and no body.
Listen for Messages
HTTP POST Request to URL - wss://<hostname><path_prefix>/listen
The account to listen for is determined via the token in the HTTP request header Authorization
value.
A websocket will be opened between the client and service to deliver any available messages. At first all unacknowledged messages will be fed through the websocket and then as new messages are posted to the account’s channels they will be fed through.
The data structure of the messages will be in JSON or BSOR depending on the Accept
header value of the request. JSON messages will be “websocket text” and BSOR will be “websocket binary”.
ChannelKey bitcoin.PublicKey `json:"channel_key" bsor:"1"`
Sequence uint64 `json:"sequence" bsor:"2"`
DateTime uint64 `json:"datetime" bsor:"3"`
ContentType string `json:"content_type" bsor:"4"`
Body []byte `json:"body" bsor:"5"`
ChannelKey
is the public key of the channel the message was posted to.
Sequence
increments with each consecutive message posted to a channel. It is independent for each channel.
DateTime
is the nanoseconds since the UNIX epoch.
ContentType
is the Content-Type
header of the HTTP request that posted the message.
Body
is the raw HTTP request body of the HTTP request that posted the message.
Account Information
HTTP GET Request to URL - https://<hostname><path_prefix>/accounts
The account is determined via the token in the HTTP request header Authorization
value.
The success response will be an HTTP status 200 (OK) with the following data structure in the body:
ChannelKeys []bitcoin.PublicKey `json:"channels" bsor:"1"`
ChannelKeys
is a list of public keys that are associated with current channels.
Create Channel
HTTP POST Request to URL - https://<hostname><path_prefix>/channels
The account is determined via the token in the HTTP request header Authorization
value.
The data structure of the request body must be the following:
ChannelKey bitcoin.PublicKey `json:"channel_key" bsor:"1"`
TimeStamp uint64 `json:"timestamp" bsor:"2"`
Signature bitcoin.Signature `json:"signature" bsor:"3"` // to prove the private key is known
ChannelKey
is the public key to associate with the channel.
TimeStamp
must be the current time (within 10 seconds of server time).
Signature
is a signature generated using the channel key and a SHA256 hash of the following data:
Account Key - 33 byte compressed value
Channel Key - 33 byte compressed value
TimeStamp - 8 byte little endian integer
The signature is required so that the service will only create channels for keys that it knows are owned by the account and a client can’t “camp” on public keys it knows belong to other people.
The success response is an HTTP status 201 (Created) with an empty body.
Remove Channel
HTTP DELETE Request to URL - https://<hostname><path_prefix>/channels/<channel_key>
The account is determined via the token in the HTTP request header Authorization
value.
The success response is an HTTP status 200 (OK) with an empty body.
Create Specific Payment Request
HTTP GET Request to URL - https://<hostname><path_prefix>/payments/<value>
The account is determined via the token in the HTTP request header Authorization
value.
If value is left empty then the service will determine how much to request based on the current balance and minimum balances.
The success response will be an HTTP status 201 (Created) and the body will be an Envelope containing a payment request.