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) }
}