PaymentProtocolWorkPage
Todo
- message signing
- public key data structure
- certificate data structure
- routing onion data structure
- releasing promises
- collecting on penalties
- delays/disputes
- third-party timestamp/relay/verifiers - how can they deliver?
- partial receipts/max receipt amount field
- fees (flat fees possible by intermediary altering path-amount?)
- max-fees limit on promise (requires specifying known path-units)
- define valid receipt
- error messages
- flesh out finalizing payment
- handle rounding
Message Format
How about:
{
"type": (message type),
(other message fields here),
("may-ignore": [
(sequence of json addresses to fields that the receiver may ignore if it does not understand them),
])
}
Of course, this, along with specifying erroneous fields in error messages, requires:
JSON Addressing
JSON addressing works like unix filesystem paths. Take the following piece of JSON:
{
"a": 1,
"b": 2,
"c": {"d": 4,"e": 5,"f":"d"},
"g": [6, 7, 8],
}
Maps (dictionaries) are easy to address -- use the key name. Array sequences (lists) are trickier. The array element at position n (first position is 0) is addressed by "[n]". A wildcard "[*]" indicates any array position.
So
/"a"is1/"c"/"e"is 5/"g"/[1]is 7/"g"/[*]may be any of 6, 7, or 8
Paths may be relative to the path of an element as well, meaning that the value "d" at /"c"/"f" may be interpreted as pointing to /"c"/"d" with is 5. (Only if you're expecting a JSON path at /"c"/"f" though, otherwise it's just the string "d" of course.)
Note that the quotations around path elements need to be escaped in JSON strings.
Ripple Payment Protocol Messages
Signed Message
{
"signed-message": {
(Ripple message)
},
"signatures": [
{
"hash": ("sha1" | "md5"),
"sign": ("rsa" | "dsa" | "elgamal"),
"signature": (base64)
}
]
}
Public Key Data Structures
{
"dsa-key": {
("p": (base64),)
("q": (base64),)
"g: (base64),
"y: (base64),
"j: (base64),
("seed": (base64),)
("p-gen-counter": (base64),)
}
}
{
"rsa-key": {
"modulus": (base64),
"exponent": (base64),
}
}
Error
{
"error": {
"code": (string),
("message": (string))
}
}
Time
{
"time": "2006-10-30 18:47:55.356000"
}
Account Data Structure
{
"account": {
"account-id": (string),
"unit": (URI),
"initiator": {
"node-id": (Ripple ID),
"key": (public key data structure)
},
"partner": {
"node-id": (Ripple ID),
"key": (public key data structure)
},
}
Account Request
{
"account-request": {
"request-id": (integer),
"account": {
"account-id": (string),
(remaining account data structure containing requested field values)
},
("note": (string))
}
}
Account Set
{
"account-set": {
"request-id": (integer - only present on responses to account-requests),
"timestamp": (date/time string),
"account": {
"account-id": (string),
(remaining account data structure containing requested field values)
},
}
}
Account Verify Request
{
"account-verify-request": {
"account-id": "550e8400-e29b-41d4-a716-446655440000"
}
}
Account Verify
{
"account-verify": {
"timestamp": "2006-11-07 02:11:28.401000",
"account": {
(...)
}
}
}
Account History Request
{
"account-history-request": {
"starting": "2006-01-01 00:00:00.000000",
"ending": "2006-11-07 02:11:28.401000"
}
}
Account History
{
"account-history": [
(a chronological order of signed messages sent and received over
this account during the requested period that have changed a piece
of shared account data, in the format they were originally sent or
received, including signatures)
]
}
Account Close
{
"account-close": {
"request-id": 14590,
"account-id": "550e8400-e29b-41d4-a716-446655440000"
}
}
Payment Request
{
"payment-request": {
"payment-id": (string),
"amount": (decimal),
"unit": (URI),
"recipient-node-id": (Ripple ID),
("note": (string))
}
}
Payment Init
{
"payment-init": {
"payment-id": (string),
"amount": (decimal),
"units": (URI),
("note": (string))
}
}
Payment Accept
{
"payment-accept": {
"payment-init": {
(...)
}
"recipient-receipt-key": (public key data structure),
"recipient-certificate": (certificate data structure)
}
}
Promise
{
"promise": {
"payment-id": (string),
"path-id": [(ordered list of strings)],
"path-amount": (decimal),
("path-units": (URI),)
"account-id": (string),
"amount": (decimal),
("onion": (routing onion data structure),)
"ttl": (date/time string),
("penalty-deadline": (date/time string),)
("penalty-rate": (decimal),)
"deadline": (date/time string),
("max-receipt": (decimal),)
"payer-receipt-key": (public key data structure),
"recipient-receipt-key": (public key data structure),
"timestamp": (date/time string)
}
}
Routing Onion Data Structure
{
"encryption-method": ("none" | "rsa" | "dsa")
("key-id": (string),)
"blob": (encrypted routing blob data structure)
}
Routing Blob Data Structure
{
(arbitrary data), "onion": (inner layers of onion)
}
Promise Received
{
"promise-received": {
"payment-id": (string),
"path-id": [(ordered list of strings)],
"deadline": (date/time string),
"amount": (decimal),
("max-receipt": (decimal))
}
}
Receipt
{
"receipt": {
"payment-id": (string),
"path-id": [(ordered list of strings)],
"path-amount": (decimal)
}
}
Receipt Redeem
{
"receipt-redeem": {
"account-id": (string),
("amount": (decimal),)
"signed-message" {
(receipt)
}
}
}
Receipt Accept
{
"receipt-accept": {
("amount": (decimal),)
"receipt-redeem" {
(...)
},
"timestamp": (date/time string),
("max-receipt": (decimal))
}
}
Notes:
- official amount may be declared in either receipt-redeem or receipt-accept
- negotiated with error messages, or set ahead of time?
Promise Release
{
"promise-release": {
"payment-id": (string),
"path-id": (string),
"path-amount": (decimal),
"amount": (decimal),
"timestamp": (date/time string)
}
}
