The PaySwarm Web platform is an open web standard that enables Web browsers and Web devices to perform Universal Web Payment. PaySwarm enables the people that create digital content such as blog posts, music, film, episodic content, photos, virtual goods, and documents to distribute their creations through their website and receive payment directly from their fans and customers. The technology is designed to be integrated directly into blogging platforms, content management systems and general purpose websites. The standard can be applied to the entire content distribution lifecycle, from asset description, to product listings, to licenses, contracts and financial transactions. Features include the ability to exchange money, transact individual sales, subscriptions and micropayments.

Introduction

The PaySwarm Web platform is an open web standard that enables Web browsers and Web devices to perform Universal Web Payment. PaySwarm enables the people that create digital content such as blog posts, music, film, episodic content, photos, virtual goods, and documents to distribute their creations through their website and receive payment directly from their fans and customers. The technology is designed to be integrated directly into blogging platforms, content management systems and general purpose websites.

The technology is provided as an open web platform, which is a combination of technology that is patent-free, royalty-free, published in a free specification, using well-defined protocols and other open technologies. The entire PaySwarm standard, like HTML, HTTP, and JavaScript, is an open web platform. Almost every successful Web technology is built and released in this way.

PaySwarm supports Micropayments. The standard assumes that customers do not want to be bothered to reach for their wallet every time they need to spend a couple of cents, or even a couple of dollars. Micropayment in this case, specifically refers to the ability to automatically distribute payments in increments of up to 1/100,000th of a cent to anybody listed in PaySwarm digital contracts.

It is the goal of this specification to create an environment that is friendly to content creators and customers alike. Distribution of digital goods is becoming an increasing part of the Web and therefore compensation for these digital goods must be as easy to perform as downloading the digital goods. The PaySwarm specification works with the architecture of the Web to deliver a solution that is universal across websites, industries and countries.

The Conceptual Model

There are three primary participants in a PaySwarm transaction; the buyer, the vendor, and the authority.

Identity and Identifiers

In order for a universal payment system to work seamlessly, there must be a universal way of identifying things in the environment. This specification uses Internationalized Resource Identifiers [[!IRI]] to refer to things on the network. These things can be a personal identity (https://example.com/people/bob), financial account information (https://example.com/people/bob/accounts/42), public cryptography keys (https://example.com/people/bob/keys/14), assets, licenses and a variety of other pieces of long-lived information that exists on the Web. By naming these things with long-lived unique identifiers, it becomes possible to create a decentralized but stable universal payment architecture.

Participants

Agent

An agent is any software that is capable of requesting an action to be performed in a way that is compliant with the PaySwarm specification. The software is usually controlled by a person or an organization that would like to perform some action on a PaySwarm-conformant network.

Participants

A participant is an entity that is capable of performing a transaction or acquiring the rights to a particular asset via a contract. The entity is typically a person or an organization that would like to transact, view, copy or otherwise utilize an asset that is being sold.

Vendors

A vendor is the entity providing an asset for sale. Typically, the vendor is the legal owner of the asset that is being listed for sale. Ownership of an asset can manifest in a variety of different forms. Copyright ownership, physical ownership, and sub-leased property or services are just a few of the types of ownership that apply to vendors.

PaySwarm Authorities

A authority is used to store money, process and store contracts, and transfer monetary amounts between financial accounts. While a PaySwarm Authority may hold a great deal of financial data, they are built with data portability in mind. PaySwarm participants may move their money and purchase history from one authority to another. Data portability is a mandatory part of this specification.

Commerce Model

Transactions

A transaction is the exchange of value from one or more source accounts into one or more destination accounts.

Assets

An asset describes a particular item that is provided as a part of a commercial transaction. It is usually an item that can be accessed or acquired on the basis of a sale or rental under the terms of a particular license. Examples of assets include web pages, crowd-funded loans or grants, music files, video streams, use of virtual machines by the hour, 3D printer files for on-demand manufacturing, radio spectrum and many other items that are capable of being transacted.

Licenses

A license is a legal description of a licensee's rights to a particular asset. Licenses are usually included as a part of a contract to express what a buyer may do with the asset that has been purchased.

Listings

A listing describes the combination of an asset that is for sale under a specific license and a set of payment terms that must be fulfilled in order to access the asset. Listings are often published on websites that sell assets via PaySwarm as a way to express wares for sale in a decentralized manner.

Contracts

A contract is the result of a commercial transaction in PaySwarm and contains information such as the listing, the asset that was purchased, the parties involved in the transaction, the license outlining the rights to the asset, and payment information associated with the transaction.

Base Technologies

PaySwarm builds on a number of successful Internet and Web technologies. These technologies are introduced in this section.

Representational State Transfer

REpresentational State Transfer [[REST]] is the architectural style that underpins the World Wide Web. It consists of a set of constraints to ensure that servers, gateways, proxies and clients may interact in a way that is predictable. Systems that are designed with this architecture in mind are called RESTful systems. PaySwarm is designed to be RESTful by ensuring that the constraints of REST are applied to all transactions performed via PaySwarm systems.

JavaScript Object Notation for Linking Data

JavaScript Object Notation for Linking Data [[!JSON-LD]] is a lightweight Linked Data format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on the already successful JSON format and provides a way to help JSON data interoperate at Web-scale. If you are already familiar with JSON, writing JSON-LD is very easy. There is a smooth migration path from the JSON you use today, to the JSON-LD you will use in the future. These properties make JSON-LD an ideal Linked Data interchange language for JavaScript environments, Web services, and JSON document-based databases.

The Advanced Encryption Standard

The Advanced Encryption Standard (AES) [[!AES]] is a world standard adopted by the United States Government and used to secure a vast majority of the commercial transactions over the Internet via OpenSSL. Since much of the data exchanged over PaySwarm participants is sensitive, it is important that a strong cryptography suite is utilized to digitally sign and transfer the messages.

HTML+RDFa

Web sites are largely implemented on top of the HyperText Markup Language (HTML). This format is known to be fairly easy to author and publish on the Web. In addition to being easy to publish, it is also important that data published via HTML can be easily read by machines without placing an undue burden on Web authors. Publishing structured data in a decentralized manner also requires a language that is capable of being both expressive and deterministic. The Resource Description Framework in attributes [[!RDFA-CORE]] extends HTML [[!HTML-RDFA]] to allow structured data to be expressed via HTML, but in a way that is easy for Web developers to author.

Communication

All communication between software operating under this specification is intended to perform according to REST [[REST]] principles. Additionally, since PaySwarm implements a financial system, the security of messages and data is of paramount importance. A security breach at certain points during the algorithms described in the following sections may introduce attack vectors that criminals could utilize to steal from or cause financial harm to the systems or people involved. However, excellent security does not have to come at a high cost. PaySwarm has been designed so that many parts of the system can be implemented in a way that does not incur significant effort, recurring costs, or financial outlay.

Requests and Responses

This specification requires that a authority have a trusted security certificate and operate many of the API services over Transport Layer Security version 1.0 or later. Unless otherwise specified, all API requests MUST be made over HTTPS to the authority.

An invalid certificate or TLS error of any kind MUST result in the API call exiting immediately and not performing the requested action. All API requests sent to the authority on behalf of a participant of the network that results in any modification to an internal database MUST be digitally signed by the requestor using the steps provided in the Request Signature Algorithm. All responses to network participants from a authority MUST be encrypted according to the steps provided in the Response Encryption Algorithm.

Communication Terms

The following terminology is used to describe concepts used to generate and secure messages in the system. Many of these terms are borrowed from public/private key cryptography. A more complete description of public/private cryptography can be found in The Advanced Encryption Standard [[AES]].

message
A JSON-LD byte stream that is used to convey a request or a response in the system.
public key
A cryptographic mechanism that can be used to verify digital signatures or encrypt small messages such that only the software with access to the corresponding private key can decrypt the small message.
private key
A cryptographic mechanism that can be used to generate digital signatures and decrypt encrypted data.
signed message
A type of message that has a digital signature attached to it, generated using a private key, that is verifiable and incredibly difficult to forge.
intermediate value
A cryptographic input to an encryption algorithm. This is typically a 16-byte value in AES.
encrypted message
A type of message that has been obfuscated using a public key, which is incredibly difficult to decode by any person except for the one that holds the associated private key.

Request Signature Algorithm

The following algorithm ensures that the originator of an API call can be verified as long as the public key can be retrieved by the receiver. A message is provided as input and, using a private key and a public key IRI, a signed message is produced as output.

  1. Remove any sec:signature key-value pair from the top-level of the message. Copy the message to the signed message.
  2. Generate the normalized message by normalizing the message according to the JSON-LD Universal Graph Normalization Algorithm (UGNA2011).
  3. Generate the signature value by:
    1. Create a timestamped message and initialize it to the empty string. Generate an ISO8601 combined date and time string containing the current date and time, accurate to at least one second, in Universal Time Code format. For example: 2011-09-23T20:21:34Z. Append the combined date and time string to the timestamped message. Append the normalized message to the timestamped message.
    2. Digitally sign the timestamped message using the private key and then base-64 encode the resulting value. The resulting base-64 encoded string is the signature value.
  4. Add a sec:signature key to the signed message with a JSON object containing the following key-value pairs:
    @type
    sec:JsonLdSignature
    dc:created
    The string value of the combined date and time string generated by this algorithm.
    sec:responseToken
    A string value that will be encoded in the encrypted response to the requesting agent. It is RECOMMENDED that this value is a session identifier that is associated with the user agent that initiated the request, plus a hyphen, plus a cryptographically secure random string used as a one-time pad. For example, jf793ksj72jkf-78p82qpj87dnd2f839. See The Response Token section to understand more about how this value is used to prevent replay attacks and its accepted limitations.
    sec:publicKey
    The value of the input public key IRI.
    sec:signatureValue
    The value of the signature value generated by this algorithm.

The following example shows an input message and the resulting signed message:

*** message
{
   "@context": "https://w3id.org/payswarm/v1",
   "dc:title": "Hello World!"
}

*** signed message
{
   "@context": "https://w3id.org/payswarm/v1",
   "dc:title": "Hello World!",
   "sec:signature":
   {
      "@type": "sec:JsonLdSignature",
      "dc:created": "2011-09-23T20:21:34Z",
      "sec:signer": "http://payswarm.example.com/i/john/keys/5",
      "sec:signatureValue": "OGQzNGVkMzVm4NTIyZTkZDYMmMzQzNmExMgoYzI43Q3ODIyOWM32NjI="
   }
}
        

Request Signature Verification Algorithm

In order to ensure a secure communication environment the following algorithm SHOULD be used to verify all request signatures in the system. A signed message is provided as input and an indication of whether the signature is valid or a forgery is produced as output.

  1. Generate the original message by copying the signed message and removing the sec:signature value from the original message.
  2. Generate the original normalized message by normalizing the original message according to the JSON-LD Universal Graph Normalization Algorithm (UGNA2011).
  3. Verify the original signature value:
    1. Generate the original timestamped message by setting its value to the value of the dc:created key in the signed message. Append the original normalized message to the original timestamped message.
    2. Retrieve the PEM-encoded public key from the public key IRI provided in sec:signer value. The public key MAY also be retrieved from a cache. ???Verify the original nonced message using the public key???
      We need to be more explicit about what is happening here.

Response Encryption Algorithm

The following algorithm ensures that a message intended for a particular recipient can be obfuscated such that only the intended recipient can read the message. A message is provided as input and, using a public key and a public key IRI, a encrypted message is produced as output.

  1. Generate a cryptographically secure symmetric key that is exactly 16 bytes in length.
  2. Generate a cryptographically secure initialization vector that is exactly 16 bytes in length.
  3. Generate the encrypted initialization vector by using the public key to encrypt the initialization vector.
  4. Generate the encrypted data by encrypting the message using the RSA with AES 128-bit Cyclic Block Chaining algorithm, using the symmetric key and the initialization vector generated previously in this algorithm.
  5. Generate the encrypted symmetric key by using the public key to encrypt the symmetric key.
  6. Generate the encrypted message by creating a JSON object containing the following key-value pairs:
    @type
    sec:EncryptedMessage
    sec:data
    The base-64 encoded value of the encrypted data.
    sec:encryptionKey
    The base-64 encoded value of the encrypted key.
    sec:cipher
    The value rsa-aes-128-cbc.
    sec:iv
    The base-64 encoded value of the encrypted initialization vector.
    sec:publicKey
    The public key IRI associated with the public key that was used to encrypt the symmetric key in this algorithm.

The following example shows a typical input message and what an encrypted message looks like when generated using the algorithm above.

*** message
{
   "@type": "ps:Preferences"
   "com:currency": "USD",
   "com:minimumAmount": "0.05",
   "com:maximumRate": "10.0",
   "com:destination": "https://example.com/people/manu/accounts/article-sales",
   "sec:publicKey": "http://payswarm.example.com/i/manu/keys/23",
   "ps:license": "https://w3id.org/payswarm/licenses/blogging",
   "ps:licenseHash": "961ec496092bf6ee08d6255d96069b5186332689",
}

*** encrypted message
{
   "@type": "sec:EncryptedMessage",
   "sec:data": "VTJGc2RHVmtYMThOY3h2dnNVN290Zks1dmxWc3labi9sYkU0TGloRTdxY0dpblE4OHgrUXFNNi9l\n↩
a1JMWjdXOApRSGtrbzh6UG5XOFo3WWI4djJBUG1abnlRNW5CVGViWkRGdklpMEliczNWSzRQTGdB\n↩
UFhxYTR2aWFtemwrWGV3Cmw0eFF4ancvOW85dTlEckNURjMrMDBKMVFubGdtci9abkFRSmc5UjdV\n↩
Rk55ckpYalIxZUJuKytaQ0luUTF2cUwKcm5vcDU1eWk3RFVqVnMrRXZZSkx6RVF1VlBVQ0xxdXR4\n↩
L3lvTWd4bkdhSksxOG5ZakdiekJxSGxOYm9pVStUNwpwOTJ1Q0Y0Q2RiR1NqL0U3OUp4Vmh6OXQr\n↩
Mjc2a1V3RUlNY3o2Z3FadXZMU004KzRtWkZiakh6K2N5a1VVQ2xHCi9RcTk3b2o3N2UrYXlhZjhS\n↩
ZmtEZzlUeWk3Q2szREhSblprcy9WWDJWUGhUOEJ5c3RiYndnMnN4eWc5TXhkbHoKUkVESzFvR0FJ\n↩
UDZVQ09NeWJLTGpBUm0zMTRmcWtXSFdDY29mWFNzSGNPRmM2cnp1Wko0RnVWTFNQMGROUkFRRgpB\n↩
bFQ0QUpPbzRBZHpIb2hpTy8vVGhNOTl1U1ZER1NPQ3graFAvY3V4dGNGUFBSRzNrZS8vUk1MVFZO\n↩
YVBlaUp2Ckg4L1ZWUVU4L3dLZUEyeTQ1TzQ2K2lYTnZsOGErbGg0NjRUS3RabktFb009Cg==",
   "sec:encryptionKey": "uATtey0c4nvZIsDIfpFffuCyMYGPKRLIVJCsvedE013SpEJ+1uO7x6SK9hIG9zLWRlPpwmbar2bt\n↩
gTX5NBzYC5+c5ZkXtM1O8REwIJ7wmtLdumRYEbr/TghFl3pAgXhv0mVt8XZ+KLWlxMqXnrT+ByNw\n↩
z7u3IxpqNVcXHExjXQE=",
   "sec:cipher": "rsa-aes-128-cbc",
   "sec:iv": "vcDU1eWTy8vVGhNOszREhSblFVqVnGpBUm0zMTRmcWtMrRX==",
   "sec:publicKey": "http://payswarm.example.com/i/manu/keys/23"
}
        

Response Decryption Algorithm

The following algorithm is used to decrypt an encrypted response. The input is an encrypted message and the result is the original unencrypted message.

  1. Generate the decryption key by base-64 decoding the sec:encryptionKey value and using the private key associated with the public key IRI in sec:publicKey to decrypt the base-64 decoded value.
    Refer to the exact algorithm that is used to do the decryption in the AES spec.
  2. Generate the intermediate value by base-64 decoding the sec:iv value and then using the private key associated with the public key IRI in sec:publicKey to decrypt the base-64 decoded value.
  3. Generate the original unencrypted message by applying the sec:cipher to the sec:data value. Use the decryption key and intermediate value generated in this algorithm as inputs to the cipher algorithm.

Security Considerations

Since this specification describes a financial system, the security of the communication in the system is of utmost importance. The following section describes security considerations that developers implementing this specification should be aware of in order to create secure software.

The Response Token

The sec:responseToken mechanism is used in order to prevent replay attacks, but implementers must be aware that it is not capable of preventing man-in-the-middle attacks. Only a full end-to-end encryption channel is capable of accomplishing that feat and if implementers are concerned about man-in-the-middle attacks, they are strongly advised to run all callbacks over HTTPS.

While implementation of the response token to prevent replay attacks is left as an exercise to the developer, it is advised that it is treated as a one-time token. That is, when a response token is sent from one peer to another peer, the sender must note the response token in an internal database. When the response token is returned in an encrypted message, the response token must be deleted from the internal database so all successive calls using the same response token will fail. This simple behavior prevents replay attacks and is simpler to implement than a security nonce.

To further increase security, it is advised that the response token is tied to the originating client's IP address in some way. The resulting response callback should be executed by the same client's IP address, thus many classes of man-in-the-middle attacks can be prevented, requiring quite a sophisticated attack in order to hijack the response. Note that the hijacker will not be able to modify the response, but merely callback-jack the response. The result of the callback-jack would be fairly benign in most cases - gaining access to an article that was purchased by the original user agent that initiated the request. The original purchaser will still have access to the article, so the only damage done is the ability to view or download an article as someone else. If this is a concern to implementers, they are advised to purchase a valid SSL certificate and ensure that all callbacks to their site occur over SSL.

The Registration Process

The registration process is necessary in order to specify details about the participants in a PaySwarm transaction.

Registration Terms

There are a number of terms that are used during the course of the registration process.

user agent
The piece of software operating on behalf of the participant. This is typically a Web Browser, but could be some other piece of Web-aware automated software acting on behalf of a person.
publishing agent
A software agent acting on behalf of the vendor that publishes assets for sale. Typically, this is blogging software, content distribution software, online merchant software or a Web-based game.
configuration service
A Web service that is used to publish the public Web service end-points and other public configuration information for a authority. An authority MUST publish this service at a top-level IRI named payswarm-v1-config. The document MUST be available in JSON-LD compacted form and MUST use the https://w3id.org/payswarm/v1 JSON-LD context. The following keys MUST be present in the published document; ps:publicKeyService, ps:licenseService, and ps:transactionService.
public key registration service
An interactive Web service used to register PEM-encoded X.509 public keys with the authority.
license service
A utility service is used by a publishing agents to retrieve license hashes, which are used when listing assets for sale.
contracts service
The contract service is used to process purchases by submitting and retrieving digital contracts.

Buyer Registration

In order for a participant to transact, they must have an account on a authority. Typically, this account must also contain a positive amount of funds that may be used to acquire goods or services. How this account is created and funds are deposited are outside of the scope of this specification. However, the end result of this sign up process MUST result in the following items being created for the participant:

  1. An identity IRI that will be used to identify the entity that is transacting. For example: https://example.com/people/jane.
  2. A financial account IRI that is associated with the identity IRI above. For example: https://example.com/people/jane/accounts/primary.
  3. A positive amount of funds in the financial account mentioned above.

Vendor Registration

In order for a vendor to transact, they must have an account on a authority. How this account is created and managed is outside of the scope of this specification. However, the end result of this sign up process MUST result in the following items being created for the vendor:

  1. An identity IRI that will be used to identify the entity that is transacting. For example: https://example.com/people/manu.
  2. A financial account IRI that is associated with the identity IRI above. For example: https://example.com/people/manu/accounts/article-sales.

Since all assets and listings are digitally signed, a public key MUST be registered for the vendor with the authority. This is typically performed by the publishing agent software that is publishing the assets and listings for sale on behalf of the vendor. The registration is accomplished by executing the following algorithm:

  1. The publishing agent generates and stores a public/private keypair that will be used to associate the publishing agent with the vendor.
  2. The publishing agent retrieves the authority configuration from the configuration service IRI.
    1. The configuration service IRI is generated by concatenating a base IRI for the authority, such as https://example.com/ with the payswarm-v1-config suffix. For example, the previous authority IRI concatenated with the configuration suffix would result in the following configuration service IRI: https://example.com/payswarm-v1-config.
    2. An HTTPS GET is performed on the configuration service IRI with the HTTP Accept header set to application/ld+json; form=compacted. The authority MUST respond with a compacted JSON-LD document using the context specified at https://w3id.org/payswarm/v1.
    3. The result MUST be a JSON-LD document containing a flat set of key-value pairs defined in the configuration service section above.
  3. The publishing agent initiates an HTTP 302 redirect for the user agent. An HTTPS GET request is performed to the public key registration service IRI with the addition of two IRI query parameters. The first parameter, public-key, is the URL-encoded X.509 PEM-encoded public key. The second parameter, registration-callback, is the URL-encoded registration callback service IRI for the publishing agent.
  4. The authority associates the publishing agent with the vendor based on the provided public key. Note that this process MUST authenticate the vendor via a login process if the vendor does not have an active login session. Other configuration steps may be performed at this stage, including the specification of defaults for the particular publishing agent.
  5. The authority specifies a set of publishing agent configuration values and encrypts the message according to the steps outlined in the Response Encryption Algorithm section. The result is sent back to the registration-callback IRI via a POST initiated by the user agent.
    1. The following configuration values MUST be included in the JSON-LD response to the publishing agent; com:currency, com:minimumAmount, com:maximumRate, com:destination, sec:publicKey, ps:license and ps:licenseHash.
    2. The JSON-LD response is compacted and encrypted using the public key associated with the registration request according to the algorithm defined in Response Encryption Algorithm.
    3. The encrypted response is transmitted to the registration-callback via an HTTP POST request that is initiatited by the user agent. This is most commonly accomplished by having the authority generate an HTML form that can be submitted to the publishing agent when a form submission button is clicked via the user agent.
    4. The publishing agent decrypts the base-64 encoded byte stream, extracts the configuration values and stores each value for use during the latter parts of the publishing and purchase process.

The example below shows the full protocol-level exchange between the publishing agent and the authority. For the sake of brevity, not every optional parameter is included, just the bare minimum necessary to perform the vendor registration.

--------------------------------- Step #1 -----------------------------------

*** Request: user agent -> publishing agent

POST /register-blog HTTP/1.1
Host: publisher.example.org
Content-Length: 47
Content-Type: application/x-www-form-urlencoded

payswarm-authority=http%3A%2F%2Fpayswarm.example.com%2F

*** publishing agent generates and stores public/private keypair

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDptIkqrXhx7YVGsBZ5fY/Lz0il
0LXJrhUY43V/lLWdRf7JXY6tcgA5AmwNGZtJRyH79QXCJn+BAHUtl6gX2gvjs8N2
B5u4m0LtXyaFWtbQV9+hY3JRLOBiydPeXLgsnLwKiJ9v4CNXSNA5wT8vYGXiqq0B
US89y0M909ZTj2zDQwIDAQAB
-----END PUBLIC KEY-----

-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDptIkqrXhx7YVGsBZ5fY/Lz0il0LXJrhUY43V/lLWdRf7JXY6t
cgA5AmwNGZtJRyH79QXCJn+BAHUtl6gX2gvjs8N2B5u4m0LtXyaFWtbQV9+hY3JR
LOBiydPeXLgsnLwKiJ9v4CNXSNA5wT8vYGXiqq0BUS89y0M909ZTj2zDQwIDAQAB
AoGALNmBrVgHEk4T0qH+XihTjThlZ7Tq/h5TXChipy5BwEHriHdU50JGeqpVVBpC
68gj5Hd8OGss8vPEiRBeqN0mhJlRaX5ijyFp2n8+7DhfOIVhCd1MXCGQPTrdXIo5
OOQECSplnALZfKr0VC4TBeW+oUZGMoG4rRSM5DfyPFJtlzECQQD8DkWBkhRsP1An
3qfZR8oUkvbaVg9jsCNvoBazYSS3OhsZ96ZSTyf9hJn28wGJmShuZA2eL5XjuTY4
m0fQDhj5AkEA7VzAqKOx5zlFTWXMIzn29uB59m4yJ7UwCyc7tisQA16I8B2HzJzZ
saipkpU2RUYaBrjtWaiVNtyXvZ7mccJpGwJBAMyE4/8bwfiHcwm2z+ktKBqDmUtW
E0ynKkmz01ef1kPaIQ1z9f/JfMBnrOpFCZVVsgnIo4gcQnox2X4a+S0nkzkCQBre
xCSTG2Gclx7S5lAakL2T3dqq0Nyz4zNwBo9xwodPHVtpTGU6YF5/RGsGnzUqYWnf
Z2cd8X5bbIYXxeic5H8CQQCcBOtOdrq9FXsEnyhG5gQXvGdxEAmM2eUs1g8E8kgx
KBTHOaBRQMgvjsdA/obrs7D0HrEbQqGOy7JBYGWZTsiI
-----END RSA PRIVATE KEY-----

--------------------------------- Step #2 -----------------------------------

*** Request: publishing agent -> authority

GET /payswarm-v1-config HTTP/1.1
Host: payswarm.example.com
Accept: application/ld+json,*/*;q=0.1

*** Response: publishing agent <- authority

HTTP/1.1 200 OK
Connection: close
Content-Length: 6075
Content-Type: application/ld+json
Date: Wed, 21 Sep 2012 22:30:16 GMT
Host: payswarm.example.com
Server: Apache/2.2.19 (Debian)

{
   "@context": "https://w3id.org/payswarm/v1",
   "@id": "http://payswarm.example.com/i/authority",
   "ps:registrationService": "http://payswarm.example.com/api/v1/applications",
   "ps:publicKeyService": "http://payswarm.example.com/api/v1/keys",
   "ps:licenseService": "http://payswarm.example.com/api/v1/licenses",
   "ps:transactionService": "http://payswarm.example.com/api/v1/contracts"
}

--------------------------------- Step #3 -----------------------------------

*** Redirect: user agent <- publishing agent

HTTP/1.1 303 See Other
Location: https://payswarm.example.com/api/v1/keys?public-key=↩
-----BEGIN+PUBLIC+KEY-----%0A↩
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDptIkqrXhx7YVGsBZ5fY%2FLz0il%0A↩
0LXJrhUY43V%2FlLWdRf7JXY6tcgA5AmwNGZtJRyH79QXCJn%2BBAHUtl6gX2gvjs8N2%0A↩
B5u4m0LtXyaFWtbQV9%2BhY3JRLOBiydPeXLgsnLwKiJ9v4CNXSNA5wT8vYGXiqq0B%0A↩
US89y0M909ZTj2zDQwIDAQAB%0A↩
-----END+PUBLIC+KEY-----↩
&registration-callback=http%3A%2F%2Fpublisher.example.org%2Fregistration-complete?nonce=pn9sueh43jefa
Content-Type: text/html
Content-Length: 174

<html>
 <head>
  <title>Identity Registration</title>
 </head>
 <body>
  <h1>Public Key Registration</h1>
   <p>You must now go to your authority and 
    <a href="http://payswarm.example.com/api/v1/keys?public-key=↩
-----BEGIN+PUBLIC+KEY-----%0A↩
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDptIkqrXhx7YVGsBZ5fY%2FLz0il%0A↩
0LXJrhUY43V%2FlLWdRf7JXY6tcgA5AmwNGZtJRyH79QXCJn%2BBAHUtl6gX2gvjs8N2%0A↩
B5u4m0LtXyaFWtbQV9%2BhY3JRLOBiydPeXLgsnLwKiJ9v4CNXSNA5wT8vYGXiqq0B%0A↩
US89y0M909ZTj2zDQwIDAQAB%0A↩
-----END+PUBLIC+KEY-----↩
&registration-callback=http%3A%2F%2Fpublisher.example.org%2Fregistration-complete?nonce=pn9sueh43jefa">
    register your identification information</a> 
    there.</p>
 </body>
</html>

--------------------------------- Step #4 -----------------------------------

*** This step consists of a series of UI interactions and is thus not
*** specified in this specification.

--------------------------------- Step #5 -----------------------------------

*** The authority creates a configuration object to return back
*** to the publishing agent

{
   "@type": "ps:Preferences"
   "com:currency": "USD",
   "com:minimumAmount": "0.05",
   "com:maximumRate": "10.0",
   "com:destination": "https://example.com/people/manu/accounts/article-sales",
   "sec:publicKey": "http://payswarm.example.com/i/manu/keys/23",
   "ps:license": "https://w3id.org/payswarm/licenses/blogging",
   "ps:licenseHash": "961ec496092bf6ee08d6255d96069b5186332689",
}

*** The configuration object is then encrypted and sent to the 
*** registration-callback specified in the registration request above.

POST registration-complete?nonce=pn9sueh43jefa HTTP/1.1
Host: publisher.example.org
Content-Length: 47
Content-Type: application/ld+json

{
   "@type": "sec:EncryptedMessage",
   "sec:data": "VTJGc2RHVmtYMThOY3h2dnNVN290Zks1dmxWc3labi9sYkU0TGloRTdxY0dpblE4OHgrUXFNNi9l\n↩
a1JMWjdXOApRSGtrbzh6UG5XOFo3WWI4djJBUG1abnlRNW5CVGViWkRGdklpMEliczNWSzRQTGdB\n↩
UFhxYTR2aWFtemwrWGV3Cmw0eFF4ancvOW85dTlEckNURjMrMDBKMVFubGdtci9abkFRSmc5UjdV\n↩
Rk55ckpYalIxZUJuKytaQ0luUTF2cUwKcm5vcDU1eWk3RFVqVnMrRXZZSkx6RVF1VlBVQ0xxdXR4\n↩
L3lvTWd4bkdhSksxOG5ZakdiekJxSGxOYm9pVStUNwpwOTJ1Q0Y0Q2RiR1NqL0U3OUp4Vmh6OXQr\n↩
Mjc2a1V3RUlNY3o2Z3FadXZMU004KzRtWkZiakh6K2N5a1VVQ2xHCi9RcTk3b2o3N2UrYXlhZjhS\n↩
ZmtEZzlUeWk3Q2szREhSblprcy9WWDJWUGhUOEJ5c3RiYndnMnN4eWc5TXhkbHoKUkVESzFvR0FJ\n↩
UDZVQ09NeWJLTGpBUm0zMTRmcWtXSFdDY29mWFNzSGNPRmM2cnp1Wko0RnVWTFNQMGROUkFRRgpB\n↩
bFQ0QUpPbzRBZHpIb2hpTy8vVGhNOTl1U1ZER1NPQ3graFAvY3V4dGNGUFBSRzNrZS8vUk1MVFZO\n↩
YVBlaUp2Ckg4L1ZWUVU4L3dLZUEyeTQ1TzQ2K2lYTnZsOGErbGg0NjRUS3RabktFb009Cg==",
   "sec:encryptionKey": "uATtey0c4nvZIsDIfpFffuCyMYGPKRLIVJCsvedE013SpEJ+1uO7x6SK9hIG9zLWRlPpwmbar2bt\n↩
gTX5NBzYC5+c5ZkXtM1O8REwIJ7wmtLdumRYEbr/TghFl3pAgXhv0mVt8XZ+KLWlxMqXnrT+ByNw\n↩
z7u3IxpqNVcXHExjXQE=",
   "sec:cipher": "aes-128-cbc",
   "sec:iv": "vcDU1eWTy8vVGhNOszREhSblFVqVnGpBUm0zMTRmcWtMrRX==",
   "sec:publicKey": "http://payswarm.example.com/i/manu/keys/23"
}

Security Concerns for Registration

The Transaction Process

The simplest exchange of value that can happen in the PaySwarm system is a transaction.

Transaction Terms

There are a number of terms that are used during the course of processing a transaction.

transaction service
The service endpoint identified by the ps:transactionService key in the domain's PaySwarm configuration file. The configuration file can be fetched by performing an HTTP GET request on the configuration service IRI.
transaction request
A JSON-LD formatted object that contains all of the necessary information required to initiate a transaction on a PaySwarm-conformant network.
transfer
A JSON-LD formatted object that specifies the movement of value from a source account to a destination account.

The Transaction Algorithm

There are two ways in which a Transaction may be initiated via a authority; Payment Link initiated and agent initiated. The first approach is where a publishing agent may initiate a transaction by constructing a URL targeted to the authority's transaction service using the Payment Links specification. The second approach is where an agent may initiate a transaction by performing an HTTPS POST of JSON-LD object expressing a ps:Transaction. The normative algorithm for performing this operation is detailed below. In both approaches, the authority processing the request MUST note the ps:Transaction entry in all of the accounts associated in the transaction and ensure that all accounts external to the authority are notified via the Decentralized Settlement Algorithm.

The normative algorithm for performing an agent-initiated transaction is expressed below.

  1. An agent MUST construct a transaction request in JSON-LD format containing at least the following:
    @context
    A single value containing the string https://w3id.org/payswarm/v1 or a list containing that context IRI as the first member, where subsequent context declarations MUST NOT override any values in the first member.
    @type
    The value ps:Transaction.
    com:transfer
    One or more transfers in JSON-LD format containing at least the following:
    @type
    The value ps:Transfer.
    com:amount
    A string value of the total amount of the transfer.
    com:currency
    The currency associated with the amount of the transfer. The value MUST be an ISO-4217 currency or a dereference-able IRI to a monetary system that is not specified in ISO-4217 but follows the specification of a Currency Mint.
    com:source
    The source account from which the funds listed in com:amount will be withdrawn.
    com:destination
    The destination account to which the funds listed in com:amount will be deposited.
    rdfs:comment
    A string specifying the purpose of the transfer as well as other details intended to be read by a human.
  2. The transaction request is digitally signed by the agent according to the Request Signature Algorithm using a private key associated with the public key that was previously registered with the authority according to the Vendor Registration Algorithm.
  3. The transaction request is sent to the authority of the agent via an HTTPS connection. The HTTPS protocol MUST be used for transmission of the request and retrieval of the response to prevent replay attacks.
  4. The authority processes the transaction request. Additional transfers MAY be added to the finalized transaction request by the authority, such as transaction fees, pursuant to existing agreements between the authority and the entity operating the agent. The following properties MUST be added to the transaction request:
    @id
    The finalized transaction identifier IRI. The value MUST be dereferenceable and return at least the transaction information returned at the end of this algorithm when accessed using a mechanism that proves authorization to access the resource.
    com:amount
    The total amount of the transaction which is calculated by adding up all of the transfers.
    com:currency
    The currency associated with the total amount of the transaction. The value MUST be an ISO-4217 currency or a dereference-able IRI to a monetary system that is not specified in ISO-4217 but follows the specification of a Currency Mint.
    com:date
    The date and time at which the transaction was recorded in the system.

The example below shows the full protocol-level exchange between the agent and the authority when performing a Transaction:

--------------------------------- Step #1 -----------------------------------

*** Agent creates a Transaction object

{
   "@type": "ps:Transaction"
   "ps:transfer":
   {
      "@type": "ps:Transfer",
      "com:amount": "7.50",
      "com:currency": "USD",
      "com:source": "https://bluebank.com/people/john/accounts/party-funds",
      "com:destination": "https://redbank.com/people/jane/accounts/hosting",
      "rdfs:comment": "Chipping in for the Pizza Party tomorrow."
   }
}

--------------------------------- Step #2 -----------------------------------

*** Agent signs the Transaction object

{
   "@type": "ps:Transaction"
   "ps:transfer":
   {
      "@type": "ps:Transfer",
      "com:amount": "7.50",
      "com:currency": "USD",
      "com:source": "https://bluebank.com/people/john/accounts/party-funds",
      "com:destination": "https://redbank.com/people/jane/accounts/hosting",
      "rdfs:comment": "Chipping in for the Pizza Party tomorrow."
   },
   "sec:signature":
   {
      "@type": "sec:JsonLdSignature",
      "dc:created": "2011-09-23T20:21:34Z",
      "sec:signer": "http://payswarm.example.com/i/john/keys/5",
      "sec:signatureValue": "ExMgoDIyOGQzNGVkMzVmmMzYzI43Q3OQzNmOWM32Nj4NTIyZTkZDYMI="
   }
}


---------------------------------- Step #3 ----------------------------------

*** Agent HTTPS POSTs the Transaction object to the authority

POST transactions HTTP/1.1
Host: bluebank.com
Content-Length: 634
Content-Type: application/ld+json

{
   "@type": "ps:Transaction"
   "ps:transfer":
   {
      "@type": "ps:Transfer",
      "com:amount": "7.50",
      "com:currency": "USD",
      "com:source": "https://bluebank.com/people/john/accounts/party-funds",
      "com:destination": "https://redbank.com/people/jane/accounts/hosting",
      "rdfs:comment": "Chipping in for the Pizza Party tomorrow."
   },
   "sec:signature":
   {
      "@type": "sec:JsonLdSignature",
      "dc:created": "2011-09-23T20:21:34Z",
      "sec:signer": "http://bluebank.com/people/john/keys/5",
      "sec:signatureValue": "ExMgoDIyOGQzNGVkMzVmmMzYzI43Q3OQzNmOWM32Nj4NTIyZTkZDYMI="
   }
}

---------------------------------- Step #4 ----------------------------------

*** authority processes the transaction and returns the finalized
*** transaction to the Agent

Cache-Control:no-cache, must-revalidate, max-age=0
Content-Length: 728
Content-Type: application/ld+json

{
   "@id": "https://bluebank.com/transactions/20110923f72b8ca3",
   "@type": "ps:Transaction",
   "com:amount": "7.65",
   "com:currency": "USD",
   "com:date": "2011-09-23T20:21:35Z",
   "ps:transfer":
   [{
      "@type": "ps:Transfer",
      "com:amount": "7.50",
      "com:currency": "USD",
      "com:source": "https://bluebank.com/people/john/accounts/party-funds",
      "com:destination": "https://redbank.com/people/jane/accounts/hosting",
      "rdfs:comment": "Chipping in for the Pizza Party tomorrow."
   },
   {
      "@type": "ps:Transfer",
      "com:amount": "0.15",
      "com:currency": "USD",
      "com:source": "https://bluebank.com/people/john/accounts/party-funds",
      "com:destination": "https://bluebank.com/accounts/processing-fees",
      "rdfs:comment": "Chipping in for the Pizza Party tomorrow."
   }]
}

The Purchase Process

The simplest purchase process includes four distinct steps; publishing an asset, publishing a license, publishing a listing and performing the purchase. Typically, the vendor publishes the asset description and the listing. Anyone may publish a license that is used in a listing. The purchase is performed via a authority.

While it is possible to express assets, licenses, and listings on the Web in many different machine-readable formats, to ensure that implementations do not become more complicated than necessary, all assets, licenses and listing MUST be expressed in HTML+RDFa [[!HTML-RDFA]] format. The example markup that is expressed in many of the following sections below will use [[!JSON-LD]] for the sake of brevity. In many cases, the information expressed via JSON-LD is expected to be express via RDFa on a Web page. There is a clear mapping from RDFa to JSON-LD, so the data expressed in the sections below can be losslessly expressed via RDFa on an HTML Web page.

Publishing an Asset

An asset describes a particular item that is provided as a part of a commercial transaction. It is usually an item that can be accessed or acquired on the basis of a sale or rental under the terms of a particular license. Examples of assets include web pages, music files, video streams, virtual machines intended to be paid for by the CPU-hour, 3D printer files for on-demand manufacturing, radio spectrum and crowd-funded loans and grants.

The following example describes a web page asset with the title "PaySwarm in Practice". The article was created by "Digital Bazaar, Inc." and the information in the asset is valid from November 28th, 2010 to November 28th, 2011. The asset is digitally signed by the organization providing it and thus can be cached, stored and then presented to someone else in a manner that is verifiable by the receiving party.

{
   "@context": "https://w3id.org/payswarm/v1",
   "@id": "http://example.org/articles/1#asset",
   "@type": ["ps:Asset", "ps:WebPage"],
   "dc:title": "PaySwarm in Practice",
   "dc:description": "This article covers how to use PaySwarm on your Website.",
   "dc:creator": 
   {
      "@type": "foaf:Organization",
      "foaf:name": "Digital Bazaar, Inc.",
   }
   "ps:contentUrl": "http://example.org/articles/1",
   "ps:validFrom": "2010-11-28T00:00:00Z",
   "ps:validUntil": "2011-11-28T00:00:00Z"
   "sec:signature": 
   {
       "@type": "sec:JsonLdSignature",
       "dc:created": "2010-11-28T00:00:00Z",
       "sec:signer": "https://payswarm.example.com/i/digital-bazaar#key-5",
       "sec:signatureValue": "OWM3YzI4OGQzNGVkMzV...IyZTk2MzQzNmExMgo="
   }
}
        

In order to publish this asset on a Web page, a vendor MUST mark the data up in RDFa and place it into an HTML file. For example, assume that the following file is served from the http://example.org/articles/1-purchase IRI:

<html>
 <head>
   <title>Buy: PaySwarm in Practice</title>
 </head>
 <body prefix="dc: http://purl.org/dc/terms/ 
               foaf: http://xmlns.com/foaf/0.1/ 
               ps: https://w3id.org/payswarm#
               sec: https://w3id.org/security#
               xsd: http://www.w3.org/2001/XMLSchema#">

   <article about="http://example.org/articles/1#asset" typeof="ps:Asset ps:WebPage">
     <h1 property="dc:title">PaySwarm in Practice</h1>
     by
     <h2 property="dc:creator" typeof="foaf:Organization">
       <span property="foaf:name">Digital Bazaar, Inc.</span>
     </h2>

     <p property="dc:description">This article covers how to use PaySwarm on your Website.</p>
     <a property="ps:contentUrl" href="http://example.org/articles/1">permalink</a>
     
     <input type="button" onclick="doPurchase();">Purchase Access to the Article</input>
     
     <input type="button" onclick="toggleDetails();">Details</input>
     <div class="article-details hidden-by-default">
       This asset publication is valid from
       <span property="ps:validFrom" content="2010-11-28T00:00:00Z" datatype="xsd:dateTime">today</span>
       until a 
       <span property="ps:validTo" content="2011-11-28T00:00:00Z" datatype="xsd:dateTime">year from today</span>.
       <div property="sec:signature" typeof="sec:JsonLdSignature">
         Signed on 
         <span property="dc:created" content="2010-11-28T00:00:00Z" datatype="xsd:dateTime">November 28th 2010</span>
         by
         <a property="sec:signer" href="https://payswarm.example.com/i/digital-bazaar#key-5">Digital Bazaar</a>:
         <span property="sec:signatureValue">OWM3YzI4OGQzNGVkMzV...IyZTk2MzQzNmExMgo=</span>
       </div>
      </div>
   </article>
 </body>
</html>
        

It may not initially be clear why an asset would need to be digitally signed. There are two major reasons that assets MUST be digitally signed in order to take part in a secure financial system. The first is to ensure, from a legal standpoint, that the person or organization claiming ownership over the asset is clear. The second is to ensure that forgery cannot occur on any of the asset information claimed by the owner of the asset. For example, if the asset were listed on an non-secure HTTP-based Web site, the information could be easily modified in transit.

The example above demonstrates how the information expressed as [[!JSON-LD]] earlier in this section can be expressed as HTML+RDFa [[!HTML-RDFA]]. The rest of this specification will not express information using both mechanisms, but will use [[!JSON-LD]] markup for the sake of brevity even if the information being expressed is meant to be expressed in RDFa.

Publishing a License

A license is a legal description of a licensee's rights to a particular asset. Licenses are usually included as a part of a contract to express what a buyer may do with an asset that has been purchased. A license can include a number of rights bestowed upon the licensesee as well as further limitations on those rights. For example, how an asset may be re-broadcast, how often a digital asset may be physically reproduced, what an asset may specifically not be used for, and liability limitations when using the asset are but a few of the rights and obligations expressible via a license.

The following example describes a very simple license for personal use.

{
   "@context": "https://w3id.org/payswarm/v1",
   "@id": "http://payswarm.example.com/licenses/personal-use",
   "@type": "ps:License",
   "dc:format": "text/html",
   "ps:licenseTemplate": "This personal use license allows you to save the 
      purchased asset onto any device that you own for your personal enjoyment
      and make up to <span property=\"ex:physicalCopies\" /> printed
      copies of the work for personal use."
   "ps:licenseTerms": 
   {
      "ex:physicalCopies": 5
   }
}
        

Licenses do not need to be created for each site on the Web. In many cases, common licenses can be placed on a website and re-used by a large number of sites that sell assets under similar license terms.

Publishing a Listing

A listing describes the combination of an asset that is for sale under a specific license and a set of payment terms that must be fulfilled in order to access the asset. Listings are often published on websites that sell assets via PaySwarm as a way to express things that are for sale, in a decentralized manner.

The following example describes an asset for sale for $0.05 USD under a license that covers acceptable use of blog posts. The offer is valid from March 2nd 2011 to March 3rd 2011. The only restriction on additional payees is that the authority (the organization processing the payment) may only take a maximum of 10% of the final sale price to cover their fees.

{
   "@context": "https://w3id.org/payswarm/v1",
   "@id": "http://example.com/articles/1#listing",
   "@type": ["gr:Offering", "ps:Listing"],
   "com:payee": 
   [
      {
         "@id": "http://example.com/articles/1#listing-payee",
         "@type": "com:Payee",
         "com:currency": "USD",
         "com:destination": "https://payswarm.example.com/i/bob/accounts/primary",
         "com:rate": "0.05",
         "com:rateType": "com:FlatAmount",
         "rdfs:comment": "Payment for PaySwarm in Practice by Digital Bazaar."
      }
   ],
   "com:payeeRule": 
   [
      {
         "@type": "com:PayeeRule",
         "com:destinationOwnerType": "ps:Authority",
         "com:maximumRate": "10",
         "com:rateType": "com:InclusivePercentage"
      }
   ],
   "ps:asset": "http://example.com/articles/1#asset",
   "ps:assetHash": "14618b56ff597a2fed560db9aa0610fe442106a4",
   "ps:license": "http://payswarm.example.com/licenses/blogging",
   "ps:licenseHash": "0d8866836917f8ef58af44accb6efab9a10610ad",
   "sec:signature": 
   {
      "@type": "ps:JsonLdSignature",
      "dc:created": "2011-03-02T00:00:00Z",
      "dc:creator": "https://payswarm.example.com/i/bob/keys/4",
      "sec:signatureValue": "KXtwA5kXZBJzj1rkPMJmGDROjM+fpi2cJIB+Xqf10="
   },
   "ps:validFrom": "2011-03-02T00:00:00+0000",
   "ps:validUntil": "2011-03-03T00:00:00+0000"
}
        

Performing a Purchase

A normal purchase, as opposed to an automatic purchase, is typically performed via a Web browser-based user agent when the participant has never performed a purchase with the vendor's website. The process consists of re-directing the Web browser to the buyer's PaySwarm Authority for the purposes of authorizing payment to the vendor for a particular listing. If a payment authorization is not approved, the user agent is re-directed back to the vendor's website with an error. If the payment authorization is approved, the user agent is re-directed back to the vendor's website with a short-form contract, which is used as a proof-of-purchase for the vendor's listing.

Purchase Terms

There are a number of terms that are used during the course of the purchase process.

listing hash
An identifier created by processing a listing expressed as JSON-LD through the JSON-LD Universal Graph Normalization Algorithm (UGNA2011) and then generating a SHA-1 hash of the result.
purchase callback
An IRI that will be on the receiving end of an HTTP POST from the authority with the result of a purchase request.
reference identifier
A string value that MUST be greater than one character and less than 256 characters used by the vendor to track purchases. These identifiers can be used to ensure that asset that can be purchased multiple times, like game tokens, can be tracked by the vendor. These identifiers also allow the vendor to protect against unintended double-purchasing due to network failures.
receipt
The resulting value of a purchase request, typically sent from the authority to the publishing agent. The object typically contains a short-form contract as well as other information that may be pertinent to the transaction.

The Purchase Algorithm

The normative algorithm for performing a purchase is expressed below.

  1. The publishing agent initiates a purchase request for a specific listing by re-directing the user agent to the contracts service endpoint:
    1. Generate the purchase request IRI by concatenating the contracts service and the following IRI parameters:
      listing
      The URL-encoded listing IRI.
      listing-hash
      A SHA-1 hash of the listing after being normalized using the JSON-LD Universal Graph Normalization Algorithm (UGNA2011).
      callback
      A de-referenceable IRI that MUST be able to process an HTTP POST request from the authority with the result of a purchase request.
      reference
      An optional, internal reference identifier used by the publishing agent to keep track of the purchase.
      nonce
      An optional cryptographic value that will be used in the encrypted response to the vendor. The response nonce is utilized to prevent replay attacks on the vendor.
    2. Perform an HTTP 303 redirect via the user agent to the purchase request IRI.
  2. The authority processes the purchase request ending in either an error message or a short-form contract:
    1. If the purchase was denied or failed for any reason, the authority performs an HTTP POST via the user agent back to the callback IRI supplied by the vendor during the initiation of the purchase request.
    2. If the purchase was successful, then a receipt is generated and transmitted to the vendor:
      1. To generate the receipt in JSON-LD format, the following pieces of information MUST be expressed:
        @context
        A single value containing the string https://w3id.org/payswarm/v1 or a list containing that context IRI as the first member, where subsequent context declarations MUST NOT override any values in the first member.
        @type
        The value ps:Receipt.
        ps:preference
        An array of preferences that are requested by either the authority or the participant. All valid options are listed below:
        ps:preAuthorization - The participant has pre-authorized future purchases for the vendor and thus the Automatic Purchasing Algorithm MAY be used for future purchases. If this preference setting is mentioned, the publishing agent SHOULD store the participant's information, including the authority IRI, for use in future automatic transactions.
        ps:contract
        The contract used in the receipt is a summary of the digital contract that was finalized via the authority. It includes the minimum amount of information necessary for the publishing agent to correctly identify the listing that was transacted:
        @type
        The value ps:Contract.
        ps:asset
        An IRI to the asset that was purchased.
        ps:assetHash
        The SHA-1 hash of the asset information after being normalized using the JSON-LD Universal Graph Normalization Algorithm (UGNA2011).
        com:reference
        The reference identifier, if one was suppied via the purchase request.
        ps:license
        An IRI to the license describing the rights associated with the asset that was purchased.
        ps:licenseHash
        The SHA-1 hash of the license information after being normalized using the JSON-LD Universal Graph Normalization Algorithm (UGNA2011).
        ps:listing
        An IRI to the listing that was purchased.
        ps:listingHash
        The SHA-1 hash of the listing information after being normalized using the JSON-LD Universal Graph Normalization Algorithm (UGNA2011).
        ps:assetAcquirer
        An IRI to the identity that acquired the asset.
      2. The authority initiates an HTTP POST via the user agent back to the callback IRI supplied by the publishing agent during the initiation of the purchase request. The POST data is digitally signed according to the Request Signature Algorithm, using the public key of the authority.
    3. The publishing agent acts upon the callback by granting access to the asset if the purchase was successful, or providing a page detailing why the purchase failed. The publishing agent SHOULD note any preferences in the receipt and utilize those preferences when processing future purchases from the participant.

Performing Automatic Purchases

An automatic purchase is one where a vendor has been previously authorized by a participant to perform purchases with the buyer's pre-authorized consent. This is typically used when the vendor is trusted, or when the participant has set a spending limit with the vendor and does not want to be bothered unless that spending limit is reached. Automatic purchases are designed to get out of the way of the participant and make the transactional flow as friction-free as possible.

Purchase Terms

There are a number of terms that are used during the course of the purchase process.

purchase request
A message consisting of a listing IRI, a listing hash, a participant identity IRI, and an optional reference identifier. The message is typically sent by a publishing agent to a participant's authority for processing.

The Automatic Purchase Algorithm

The automatic purchase algorithm is outlined below:

  1. The publishing agent prepares a purchase request by constructing a JSON-LD message. The following pieces of information MUST be expressed:
    @context
    A single value containing the string https://w3id.org/payswarm/v1 or a list containing that context IRI as the first member, where subsequent context declarations MUST NOT override any values in the first member.
    @type
    The value ps:PurchaseRequest.
    ps:listing
    An IRI to the listing that was purchased.
    ps:listingHash
    The SHA-1 hash of the listing information after being normalized using the JSON-LD Universal Graph Normalization Algorithm (UGNA2011).
    ps:assetAcquirer
    An IRI to the identity that acquired the asset.
    com:reference
    The reference identifier, if one was supplied via the purchase request.
  2. The purchase request is digitally signed by the publishing agent according to the Request Signature Algorithm using the private key associated with the listing in the purchase request. The purchase request is sent to the authority of the participant via an HTTPS connection. The HTTPS protocol MUST be used for transmission of the request and retrieval of the response to prevent replay attacks.
  3. The authority checks to ensure that the publishing agent is authorized to perform an automatic purchase on behalf of the provided participant identity IRI and responds to the publishing agent:
    1. If the transaction fails, the exception details are placed into a JSON-LD message and sent to the publishing agent.
      Determine how PaySwarm will handle response exceptions.
    2. If the transaction is successful, a receipt is generated for the publishing agent. The following fields MUST be placed into the response:
      @context
      A single value containing the string https://w3id.org/payswarm/v1 or a list containing that context IRI as the first member, where subsequent context declarations MUST NOT override any values in the first member.
      @type
      The value ps:Receipt.
      ps:contract
      The contract used in the receipt is a summary of the digital contract that was finalized via the authority. It includes the minimum amount of information necessary for the publishing agent to correctly identify the listing that was transacted:
      @type
      The value ps:Contract.
      ps:asset
      An IRI to the asset that was purchased.
      ps:assetHash
      The SHA-1 hash of the asset information after being normalized using the JSON-LD Universal Graph Normalization Algorithm (UGNA2011).
      com:reference
      The reference identifier, if one was suppied via the purchase request.
      ps:license
      An IRI to the license describing the rights associated with the asset that was purchased.
      ps:licenseHash
      The SHA-1 hash of the license information after being normalized using the JSON-LD Universal Graph Normalization Algorithm (UGNA2011).
      ps:listing
      An IRI to the listing that was purchased.
      ps:listingHash
      The SHA-1 hash of the listing information after being normalized using the JSON-LD Universal Graph Normalization Algorithm (UGNA2011).
      ps:assetAcquirer
      An IRI to the identity that acquired the asset.
    3. The receipt is encrypted according to the Response Encryption Algorithm, using the public key associated with the private key that digitally signed the listing. The encrypted receipt is sent to the publishing agent.
  4. The publishing agent receives the response, which will either be an exception or a receipt, and responds accordingly to the user agent.

The Contract

A contract is the result of a commercial transaction in PaySwarm and contains information such as the listing, the asset that was purchased, the parties involved in the transaction, the license outlining the rights to the asset, and payment information associated with the transaction.

The following example describes a purchase that occurred on March 2nd 2011 for a Web-based article called "PaySwarm in Practice". The article was authored and listed for sale by Bob Smith and a personal use license was acquired by Jane, who may now peruse the article.

{
   "@context": "https://w3id.org/payswarm/v1",
   "@id": "http://payswarm.example.com/contracts/28394729347",
   "@type": ["ps:Transaction", "ps:Contract"],
   "com:amount": "0.05",
   "com:currency": "USD",
   "dc:created": "2011-03-02T03:00:53Z",
   "com:payee": 
   [
      {
         "@type": "com:Payee",
         "com:currency": "USD",
         "com:destination": "https://payswarm.example.com/i/authority/accounts/main",
         "com:payeePosition": 0,
         "com:rate": "10.00",
         "com:rateContext": "com:TaxExempt",
         "com:rateType": "com:InclusivePercentage",
         "rdfs:comment": "authority Transaction Processing"
      }
   ],
   "com:transfer": 
   [
      {
         "@type": "com:Transfer",
         "com:amount": "0.045",
         "com:currency": "USD",
         "com:destination": "https://payswarm.example.com/i/bob/accounts/primary",
         "com:forTransaction": "http://payswarm.example.com/contracts/28394729347",
         "com:source": "https://payswarm.example.com/i/jane/accounts/primary",
         "rdfs:comment": "Payment for PaySwarm in Practice by Bob Smith."
      },
      {
         "@type": "com:Transfer",
         "com:amount": "0.005",
         "com:currency": "USD",
         "com:destination": "https://payswarm.example.com/i/authority/accounts/main",
         "com:forTransaction": "http://payswarm.example.com/contracts/28394729347",
         "com:source": "https://payswarm.example.com/i/jane/accounts/primary",
         "rdfs:comment": "authority Transaction Processing"
      }
   ],
   "dc:created": "2011-03-02T03:00:53Z",
   "ps:asset": 
   {
      "@id": "http://example.com/articles/1#asset",
      "@type": ["ps:Asset", "ps:WebPage"],
      "dc:creator": 
      {
         "foaf:name": "Bob Smith"
      },
      "dc:title": "PaySwarm in Practice",
      "ps:assetProvider": "https://payswarm.example.com/i/bob",
      "ps:authority": "https://payswarm.example.com/client-config",
      "ps:contentUrl": "http://example.com/articles/1",
      "sec:signature": 
      {
         "@type": "ps:JsonLdSignature",
         "dc:created": "2011-03-02T00:00:00Z",
         "dc:creator": "https://payswarm.example.com/i/bob/keys/4",
         "sec:signatureValue": "XuLEGuq+ne56Qsc5Nic8I="
      }
   },
   "ps:assetAcquirer": "https://payswarm.example.com/i/jane",
   "ps:assetProviderIdentity": 
   {
      "ps:identityHash": "df913752be56fe0d37dcedc2d7f44708373d2a68"
   },
   "ps:license": 
   {
      "@id": "http://payswarm.example.com/licenses/blogging",
      "@type": "ps:License",
      "dc:format": "text/html",
      "ps:licenseTemplate": "Personal Use License ..."
   },
   "ps:listing": 
   {
      "@id": "http://example.com/articles/1#listing",
      "@type": ["gr:Offering", "ps:Listing"],
      "com:payee": 
      [
         {
            "@id": "http://example.com/articles/1#listing-payee",
            "@type": "com:Payee",
            "com:currency": "USD",
            "com:destination": "https://payswarm.example.com/i/bob/accounts/primary",
            "com:rate": "0.05",
            "com:rateType": "com:FlatAmount",
            "rdfs:comment": "Payment for PaySwarm in Practice by Digital Bazaar."
         }
      ],
      "com:payeeRule": 
      [
         {
            "@type": "com:PayeeRule",
            "com:destinationOwnerType": "ps:Authority",
            "com:maximumRate": "10",
            "com:rateType": "com:InclusivePercentage"
         }
      ],
      "ps:asset": "http://example.com/articles/1#asset",
      "ps:assetHash": "14618b56ff597a2fed560db9aa0610fe442106a4",
      "ps:license": "http://payswarm.example.com/licenses/blogging",
      "ps:licenseHash": "0d8866836917f8ef58af44accb6efab9a10610ad",
      "sec:signature": 
      {
         "@type": "ps:JsonLdSignature",
         "dc:created": "2011-03-02T00:00:00Z",
         "dc:creator": "https://payswarm.example.com/i/bob/keys/4",
         "sec:signatureValue": "KXtwA5kXZBJzj1rkPMJmGDROjM+fpi2cJIB+Xqf10="
      },
      "ps:validFrom": "2011-03-02T00:00:00+0000",
      "ps:validUntil": "2011-03-03T00:00:00+0000"
   },
   "ps:listingHash": "1acbd23c3a7d8827270a959a2760f7c4ded98022",
   "sec:signature": 
   {
      "@type": "ps:JsonLdSignature",
      "dc:created": "2011-03-02T03:00:53Z",
      "dc:creator": "https://payswarm.example.com/i/authority/keys/1",
      "sec:signatureValue": "ZnGaAs0QCIfEAvCsj2TxRTs8ekQrbbQUXvTLWcQ0kQ=="
   }
}
        

Verifying a Purchase

The Decentralized Settlement Process

The decentralized settlement process is used to ensure the immediate and smooth transition of funds from an account on one authority to an account on another authority.

Decentralized Settlement Terms

The following terminology is used to describe concepts used to perform the settling of accounts between multiple PaySwarm Authorities.

disbursing authority
An authority that is disbursing a set of funds to one or more receiving PaySwarm authorities.
receiving authority
An authority that is receiving a set of funds from a disbursing authority.
escrow transfer log
A log of transfers that are either in the process of being disbursed or received for a particular particular financial account. The log is used to ensure that double-entries are not accidentally recorded due to network errors or other fatal errors associated with hardware or software failures.

The Decentralized Settlement Algorithm

The following algorithm ensures that funds transferred as a part of a transaction can be transmitted to one or more authority payment processors in an interoperable fashion such that there are no dangers that the value exchange is lost or mis-applied to the wrong accounts.

  1. The disbursing authority contacts each receiving authority listed in the list of transfers contained in the transaction being processed and retrieves the ps:TransactionBackhaul service from each configuration service endpoint. If any receiving authority is not available now or at any point during this process, or if the receiving authority is blacklisted for any reason, the transaction MUST fail.
  2. The disbursing authority processes transfers intended for financial accounts that are local to the system, noting outgoing and incoming transfer amounts in each financial account's escrow transfer log.
  3. The disbursing authority processes transfers intended for financial accounts that are on receiving authorities noting outgoing transfer amounts in each source financial account's escrow transfer log.
  4. The disbursing authority transmits the transaction to each receiving authority. The receiving authority processes transfers intended for financial accounts that are on the receiving authority noting incoming transfer amounts in each target financial account's escrow transfer log. If all amounts were not successfully marked in escrow, the transaction MUST fail.
  5. The disbursing authority moves all funds from escrow into all local financial accounts. The disbursing authority contacts all receiving authorities and instructs them to move all funds from escrow into all destination financial accounts. This two-stage commit process ensures that in the event of a failure while contacting multiple receiving authorities, that transactions can be backed out.
    While this algorithm outlines how transfer records are transmitted and recorded in a decentralized fashion, it does not outline how each authority ensures that currencies are exchanged between financial institutions. One such possibility is an ACH banking transfer, but such a transfer is not necessary if the banks adopt this protocol for clearing transactions across financial systems.

Data Portability

One of the freedoms that is ensured by this specification is the freedom to own your data and move it to an authority of your choosing. That is, your transaction history is your property and therefore you must be able to move it to a location of your choosing at will. In order to ensure that this freedom is protected, data portability MUST be implemented by all conforming implementations of this specification.

Authority Migration

In order to ensure data portability from one authority to another authority, the following objects MUST be transferred:

Once the transfer is complete, the new authority MUST provide the old authority with new IRIs for each public key, identity and financial account. The old authority MUST setup HTTP 301 redirects from the old IRIs to the new IRIs. Any transaction migrated from the old authority to the new authority MUST be honored and any request to purchase the item again MUST NOT result in a debit to any financial account.

Authority Migration Terms

The following terminology is used to describe concepts used to transfer all accounts from an old authority to a new authority.

releasing authority
The authority that is the source for all of the data in the data portability transfer.
acquiring authority
The authority that is the destination for all of the data in the data portability transfer.
porting service
A Web service that is used to port data from a releasing authority to an acquiring authority. The service is used to initiate and finalize the transfer of all public keys, identities, financial accounts, and transactions.
porting token
A random string that must be at least 32 bytes long and no less than 128 bytes long. It serves as a temporary value that must be copied from the releasing authority to the acquiring authority for two reasons; 1) as a security measure against automatic transferral of financial data and 2) as a temporary value that is used to denote all identities being transferred as a part of the migration process.

The Authority Migration Algorithm

The following algorithm ensures that all public keys, identities, financial accounts, and transactions are moved from a releasing authority to an acquiring authority such that a person or organization may start using the acquiring authority as their primary authority without any major interruption in service. The algorithm is initiated when an agent marks their account on a authority for migration. A random porting token MUST be created and displayed to the person or organization performing the port. A flag on all associated identities, MUST be set to MIGRATION_STARTED.

  1. The acquiring authority utilizes the configuration service of the releasing authority to discover the porting service IRI.
  2. The acquiring authority performs an HTTPS GET request to the acquiring authority's porting service. The URL MUST include the porting token as a query parameter with the name token.
  3. The releasing authority MUST set a flag on all associated identities to MIGRATION_IN_PROGRESS. All transactions involving the previously flagged identities MUST be denied while the MIGRATION_IN_PROGRESS flag is active.
  4. The releasing authority builds a JSON-LD object containing a list of @id values for all identities, financial accounts, public keys, and transactions, in that order. For each object, it MUST contain at least the following properties:
    ps:Identity
    @id, @type, foaf:name, rdfs:label, vcard:adr
    com:Account
    @id, @type, rdfs:label, rdfs:comment, com:amount, com:currency, ps:owner
    sec:Key
    @id, @type, rdfs:label, rdfs:comment, sec:publicKeyPem, ps:owner
    ps:Transaction
    The entire object on record.
    This section needs to show examples of exactly what the array and details should look like.
  5. The acquiring authority processes the array generated in the previous step and creates new IRIs for all identities, financial accounts, and public keys. Each identity, financial account, and public key object is collected into an array and HTTPS POSTed back to the releasing authority with a new property (rdfs:seeAlso) set to the newly generate IRI for the object. The URL MUST include the porting token as a query parameter with the name token.
  6. A transaction MUST be performed from the releasing authority to the acquiring authority transferring all remaining funds from all the old financial accounts to all of the new financial accounts.
  7. The releasing authority MUST use the rdfs:seeAlso value to setup HTTP 301 response codes for all migrated identities, financial accounts, and public keys. At this point, any transactions that would result in the old IRIs being used MUST fail. The releasing authority MUST set a flag on all associated identities to MIGRATION_COMPLETE.

The Transaction Intent Process

A transaction intent is the agreement to execute a transaction once a pre-defined set of external parameters have been met. The most direct example of this is when a group of funders promises to fund a project if the project can raise a minimum amount of capital by a certain date.

Transaction Intent Terms

The following terminology is used to describe concepts used when processing transaction intents.

promisor
A participant that has created a parameterized listing that will result in a transaction intent if transacted.
promisee
A participant that is making a promise to enter into a contract if the terms of the parameterized listing are met before a certain date and time.

The Transaction Intent Algorithm

The following algorithm describes the transaction intent process, which consists of three distinct phases. The first phase is the publication of the parameterized listing by the promisor. The second phase is the submission of transaction intents from promisees. The third phase is the finalization of transaction intents into contracts.

This section still needs a ton of work: specify the JSON-LD messages that are transmitted in detail, examples, and cover error conditions and exceptions.

  1. The promisor creates an asset describing the asset provided if the parameters in the parameterized listing are met. The promisor also creates a parameterized listing containing at least the following two fields:
    ps:constraint
    A set of parameters that must be met in order to complete the transaction.
    com:minimumAmount
    The minimum amount necessary, in aggregate, to finalize all transaction intents before the deadline.
    com:currency
    The currency associated with the minimum amount field.
  2. When an authority processes the parameterized listing, per The Purchase Algorithm, a ps:Contract and ps:Receipt are generated as specified in the algorithm, but funds MUST NOT be disbursed at that time. Instead of the ps:Receipt's ps:contract's property being of @type ps:Contract, it MUST instead be of type ps:TransactionIntent. All other fields must remain the same both in the short-form contract and the long-form contract. The promisor's publishing agent is notified of the intent in the same way as it would be notified of a purchase except that the resulting receipt will be the modified object as described in this step.
  3. The promisee's authority then notifies the promisor's authority of the transaction intent by retrieving the transaction service IRI from the configuration service. The ps:TransactionIntent is sent to the promisor's authority via an HTTPS POST.
  4. The promisor's authority keeps track of all ps:TransactionIntent's for the parameterized listing until the end of the ps:validUntil date in the listing or until the com:minimumAmount in the ps:constraint property in the listing has been met in aggregate.
  5. If the authority detects that the com:minimumAmount in the ps:constraint property in the listing has been met in aggregate, it submits all ps:TransactionIntents for the parameterized listing to each promisee's authority. That is, for every com:source financial account intended to transfer money to the com:destination in each ps:TransactionIntents, the source financial accounts authority is contacted.
  6. The promisor's authority MUST determine if all promisee's can meet their obligation. It does so by contacting each promisee's authority and performing an HTTP POST of all ps:TransactionIntents intended for the authority to the transaction service with an additional query parameter where the key is mode and the value is query. Each promisee's authority responds with a total amount of funds that are available to be committed.
  7. If the previous step is successful and there are enough funds to meet the com:minimumAmount constraint, then the promisor's authority MUST then place all amounts listed in all ps:TransactionIntent on hold. It does this by contacting each promisee's authority by performing an HTTP POST of all ps:TransactionIntent's intended for the authority to the transaction service with an additional query parameter where the key is mode and the value is hold. Each promisee's authority responds with a total amount of funds placed on hold.
  8. If the previous step is successful and enough funds were placed on hold to meet the com:minimumAmount constraint, then the promisor's authority MUST then retrieve all amounts listed in all ps:TransactionIntents. It does this by contacting each promisee's authority by performing an HTTP POST of all ps:TransactionIntent's intended for the authority to the transaction service with an additional query parameter where the key is mode and the value is finalize. Each promisee's authority responds with a finalized contract for each ps:TransactionIntent and disburses the funds according to the Decentralized Settlement Algorithm.
  9. The promisor's authority marks the parameterized listing as being fulfilled and any further ps:TransactionIntents submitted before the ps:validUntil date are automatically processed according to the previous step.

The PaySwarm API

Implementation Details

Digital Signatures

Signing

Verifying

Security Concerns

Identity Management

Digital Signatures

Identifying and Removing Troublemakers

Halting Asset Distribution