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" is 1
  • /"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)
  }

}