Skip to content

Latest commit

 

History

History
1057 lines (857 loc) · 40 KB

request-logic-specification-v2.0.0.md

File metadata and controls

1057 lines (857 loc) · 40 KB

Request logic Specification v2.0.0

You can be interested in this document if:

  • You want to create your own implementation of the request protocol
  • You are curious enough to dive and see what is under the hood of the request protocol

You don't need to read this document if:

  • You want to develop an app using the request protocol (see the API library instead here)

Content table

Request

A request is the JSON object whichproperties returned from a list of actions that satisfies the following formats:

Properties

Property Type Description
requestId string ID as unique as possible
creator Identity Identity of the creator of the request
payee Identity Identity of the payee
payer Identity Identity of the payer
expectedAmount Amount Amount expected to be paid
currency String Currency of the expected amount
state Enum('created', 'accepted', 'canceled') State of the request
events Array List of the actions performed
extensionsData Array List of data used by the above layer
version String Specification version by the request (2.0.0' here)
 timestamp Number - Timestamp of the request creation in seconds
- this timestamp is given by the creator. It is not trustless.
- This timestamp is also used to differentiate between identical requests
 nonce Number Number to differentiate several identical requests with the same timestamp

Example

{
   "creator":{
      "type":"ethereumAddress",
      "value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
   },
   "currency":"ETH",
   "events":[
      {
         "name":"create",
         "parameters":{
            "expectedAmount":"123400000000000000",
            "extensionsDataAddedLength":1,
            "isSignedRequest":false
         },
         "actionSigner":{
            "type":"ethereumAddress",
            "value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
         }
      }
   ],
   "expectedAmount":"123400000000000000",
   "extensionsData":[
      {
         "id":"extension1",
         "value":"whatever1"
      }
   ],
   "payee":{
      "type":"ethereumAddress",
      "value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
   },
   "payer":{
      "type":"ethereumAddress",
      "value":"0x740fc87Bd3f41d07d23A01DEc90623eBC5fed9D6"
   },
   "requestId":"0x1c2610cbc5bee43b6bc9800e69ec832fb7d50ea098a88877a0afdcac5981d3f8",
   "state":"created",
   "timestamp": 1545224094,
   "version":"2.0.0"
}

Actions

An action is a JSON object created to modify the properties of a request. An action is performed on a request under conditions specified in the action itself. An action is ignored if there exists a previous identical action. If their normalized hashes (see How to sign a JSON object) are identical the second action is ignored. This mechanism counters a replay attack where one can replay an action already signed (e.g.: reduceExpectedAmount). If one wants to create two similar actions, he must add an arbitrary number (see nonce later in this document).

IMPORTANT :

  • The actions of a request are ordered (it means that only one action modify a request at a time)
  • An action which does not satisfy its condition will be simply ignored
Property Type Description
name Enum() Name of the action to perform (see list of possible actions)
parameters Object Parameters of the actions
signature Signature Signature of the object { name, parameters, version }

List of possible actions

Name Description Role Authorized
create create a request payee, payer
accept accept a request payer
cancel cancel a request payee, payer
reduceExpectedAmount reduce the expected amount payee
increaseExpectedAmount increase the expected amount payer
addExtensionsData add data for the extensions payee, payer, third-party

Create

Parameters
Type Description Requirement
version String specification version Mandatory
expectedAmount Amount amount expected to be paid Mandatory
currency String Currency of the expected amount Mandatory
timestamp Number - Timestamp of the request creation in seconds
- this timestamp is given by the creator. It is not trustless.
- This timestamp is also used to differentiate between identical requests
Mandatory
payee Identity identity of the payee Optional if payer given
payer Identity identity of the payer Optional if payee given
extensionsData Array list of data used by the above layer Optional
nonce Number Number to differentiate several identical requests with the same timestamp
- should be incremented by one for every new identical request
Optional
Conditions

This action is valid, if:

  • the Role of the action signer is payee or payer
Result

A request created with the following properties:

Property Value
requestId Hash of this action
creator Identity of the signer
payee payee from parameters if exists, undefined otherwise
payee payer from parameters if exists, undefined otherwise
expectedAmount expectedAmount from parameters
currency currency from parameters
state created if signer is payee, accepted if signer is payer
version versions of Request protocol for which the request has been created
extensionsData extensionsData from parameters if exists, [] otherwise
events Array with one 'create' event (see below)

the 'create' event:

Property Value
name 'create'
parameters Object
parameters.isSignedRequest false
parameters.ExpectedAmount expectedAmount from parameters
parameters.extensionsDataAddedLength length of the extensionsData from parameters   
actionSigner Identity of the signer
Example

Example of creation action:

{
  "name":"create",
  "parameters":{
      "currency":"ETH",
      "expectedAmount":"123400000000000000",
      "payee":{
        "type":"ethereumAddress",
        "value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
      },
      "timestamp": 1545224094,
  },
  "version":"2.0.0",
  "signature":{
    "method":"ecdsa",
    "value":"0x143f0965cb8628c93e6f59f39a7c86163a7de01df42c923e65e109bab336710d7b534615025ed0c285e8dcbba2f4e136afa497af792a63519c486b16f3ccabb41c"
  }
}

Example of 'create' event:

{
   "name":"create",
   "parameters":{
      "expectedAmount":"123400000000000000",
      "extensionsLength":0,
      "isSignedRequest":false
   },
   "actionSigner":{
      "type":"ethereumAddress",
      "value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
   }
}

Accept

Parameters
Type Description Requirement
requestId String ID of the request Mandatory
extensionsData Array list of data used by the above layer Optional
Conditions

This action is valid, if:

  • the request has a payer
  • the Role of the action signer is the payer
  • the request state is created
Result

Modify the following properties of the request:

Property Value
state accepted
extensionsData concat the extensionsData from parameters at its end
events add an 'accept' event (see below) at its end

the 'accept' event:

Property Value
name 'accept'
parameters Object
parameters.extensionsDataAddedLength length of the extensionsData from parameters   
actionSigner Identity of the signer
Example

Example of action creation:

{
  "name":"accept",
  "parameters":{
      "requestId":"0xd38a203d25e91ae0e0d3bcf149c44dac80e0990a812fce5ecd14bd27cb7fed2e",
  },
  "signature":{
    "method":"ecdsa",
    "value":"0x143f0965cb8628c93e6f59f39a7c86163a7de01df42c923e65e109bab336710d7b534615025ed0c285e8dcbba2f4e136afa497af792a63519c486b16f3ccabb41c"
  }
}

Example of 'accept' event:

{
   "name":"accept",
   "parameters":{
      "extensionsLength":0,
   },
   "actionSigner":{
      "type":"ethereumAddress",
      "value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
   }
}

Cancel

Parameters
Type Description Requirement
requestId String ID of the request Mandatory
extensionsData Array list of data used by the above layer Optional
Conditions

This action is valid, if:

  • the request has a payer

  • the Role of the action signer is the payer

  • the request state is created

    Or, if:

  • the request has a payee

  • the Role of the action signer is the payee

  • the request state is NOT canceled

Result

Modify the following properties of the request:

Property Value
state canceled
extensionsData concat the extensionsData from parameters at its end
events add an 'cancel' event (see below) at its end

the 'cancel' event:

Property Value
name 'cancel'
parameters Object
parameters.extensionsDataAddedLength length of the extensionsData from parameters   
actionSigner Identity of the signer
Example

Example of cancel action:

{
  "name":"cancel",
  "parameters":{
      "requestId":"0xd38a203d25e91ae0e0d3bcf149c44dac80e0990a812fce5ecd14bd27cb7fed2e",
  },
  "signature":{
    "method":"ecdsa",
    "value":"0x143f0965cb8628c93e6f59f39a7c86163a7de01df42c923e65e109bab336710d7b534615025ed0c285e8dcbba2f4e136afa497af792a63519c486b16f3ccabb41c"
}
}

Example of 'cancel' event:

{
   "name":"cancel",
   "parameters":{
      "extensionsLength":0,
   },
   "actionSigner":{
      "type":"ethereumAddress",
      "value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
   }
}

ReduceExpectedAmount

Parameters
Type Description Requirement
requestId String ID of the request Mandatory
deltaAmount Amount amount to reduce to the expectedAmount Mandatory
extensionsData Array list of data used by the above layer Optional
nonce Number Number to differentiate identical actions Optional
Conditions

This action is valid, if:

  • the request has a payee
  • the Role of the action signer is the payee
  • the request state is NOT canceled
  • the deltaAmount is smaller or equal to expectedAmount
Result

Modify the following properties of the request:

Property Value
expectedAmount expectedAmount minus deltaAmount from parameters
extensionsData concat the extensionsData from parameters at its end
events add an 'reduceExpectedAmount' event (see below) at its end

the 'reduceExpectedAmount' event:

Property Value
name 'reduceExpectedAmount'
parameters Object
parameters.deltaAmount deltaAmount from parameters   
parameters.extensionsDataAddedLength length of the extensionsData from parameters   
actionSigner Identity of the signer
Example

Example of reduceExpectedAmount action:

{
  "name":"reduceExpectedAmount",
  "parameters":{
    "requestId":"0xd38a203d25e91ae0e0d3bcf149c44dac80e0990a812fce5ecd14bd27cb7fed2e",
    "deltaAmount": "10000000",
  },
  "signature":{
    "method":"ecdsa",
    "value":"0x143f0965cb8628c93e6f59f39a7c86163a7de01df42c923e65e109bab336710d7b534615025ed0c285e8dcbba2f4e136afa497af792a63519c486b16f3ccabb41c"
  }
}

Example of 'reduceExpectedAmount' event:

{
   "name":"reduceExpectedAmount",
   "parameters":{
      "deltaAmount": "10000000",
      "extensionsLength":0,
   },
   "actionSigner":{
      "type":"ethereumAddress",
      "value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
   }
}

IncreaseExpectedAmount

Parameters
Type Description Requirement
requestId String ID of the request Mandatory
deltaAmount Amount amount to add to the expectedAmount Mandatory
extensionsData Array list of data used by the above layer Optional
nonce Number Number to differentiate identical actions Optional
Conditions

This action is valid, if:

  • the request has a payer
  • the Role of the action signer is the payer
  • the request state is NOT canceled
Result

Modify the following properties of the request:

Property Value
expectedAmount expectedAmount plus deltaAmount from parameters
extensionsData concat the extensionsData from parameters at its end
events add an 'increaseExpectedAmount' event (see below) at its end

the 'increaseExpectedAmount' event:

Property Value
name 'increaseExpectedAmount'
parameters Object
parameters.deltaAmount deltaAmount from parameters   
parameters.extensionsDataAddedLength length of the extensionsData from parameters   
actionSigner Identity of the signer
Example

Example of increaseExpectedAmount action:

{
    "name":"increaseExpectedAmount",
    "parameters":{
        "requestId":"0xd38a203d25e91ae0e0d3bcf149c44dac80e0990a812fce5ecd14bd27cb7fed2e",
        "deltaAmount": "10000000",
    },
    "signature":{
        "method":"ecdsa",
        "value":"0x143f0965cb8628c93e6f59f39a7c86163a7de01df42c923e65e109bab336710d7b534615025ed0c285e8dcbba2f4e136afa497af792a63519c486b16f3ccabb41c"
    }
}

Example of 'increaseExpectedAmount' event:

{
   "name":"increaseExpectedAmount",
   "parameters":{
      "deltaAmount": "10000000",
      "extensionsLength":0,
   },
   "actionSigner":{
      "type":"ethereumAddress",
      "value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
   }
}

AddExtensionsData

Parameters
Type Description Requirement
requestId String ID of the request Mandatory
extensionsData Array list of data used by the above layer Mandatory
nonce Number Number to differentiate identical actions Optional
Conditions

None.

Result

Modify the following properties of the request:

Property Value
extensionsData concatenate with the extensionsData from parameters
events add an 'addExtensionsData' event (see below) at its end

the 'addExtensionsData' event:

Property Value
name 'addExtensionsData'
parameters Object
parameters.extensionsDataAddedLength length of the extensionsData from parameters   
actionSigner Identity of the signer
Example

Example of addExtensionsData action:

{
    "name":"addExtensionsData",
    "parameters":{
        "requestId":"0xd38a203d25e91ae0e0d3bcf149c44dac80e0990a812fce5ecd14bd27cb7fed2e",
        "extensionsData": [{
            "id": "pn_btc_address_based",
            "action": "addPaymentAddress",
            "parameters": {
                "refundAddress": "2NEH4zBsz3za2hzjyjXsGETz4SpHzhjiSiG"
            }
        }]
    },
    "signature":{
        "method":"ecdsa",
        "value":"0x143f0965cb8628c93e6f59f39a7c86163a7de01df42c923e65e109bab336710d7b534615025ed0c285e8dcbba2f4e136afa497af792a63519c486b16f3ccabb41c"
    }
}

Example of 'addExtensionsData' event:

{
   "name":"addExtensionsData",
   "parameters":{
      "extensionsLength":1,
   },
   "actionSigner":{
      "type":"ethereumAddress",
      "value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
   }
}

Get a request from a list of actions

As mentioned above a request is an JSON object with properties modified by actions. From another perspective, you can get the properties of a request by interpreting a list of actions.


Types

Identity type

(see Identity, Role and Signature)

Signature type

(see Identity, Role and Signature)

Amount type

To have a standard format for number that avoid limitation of size number in some languages, a valid amount is a string representing a positive integer in base 10.

Examples:

"11235813213455891442333776109871597258441816765" // OK
"0" // OK
0 // not valid
11235813213455891442333776109871597258441816765 // not valid
"-1123" // not valid
"3.14159" // not valid
"NaN" // not valid
"thirteen" // not valid
"0x12324094" // not valid

Note: Decimal number are not allowed for amount. But, each currency will be defined with a number of decimal (e.g.: 2 for USD, 18 for ETH, 8 for BTC )

Examples:

"12345667890123456789"
// could mean:
// 123456678901234567.89 USD
// 123456678901.23456789 BTC
// 12.345667890123456789 ETH

Identity, Role and Signature

To manage low level identity in the request logic we use three different types of objects:

  • Identity: a public piece of information an actor uses to identify themself (e.g.: the address in ethereum)
  • Signature: a proof of acknowledgment from an Identity
  • SignatureParameters: the parameters needed for an Identity to create a Signature (e.g.: the privatekey in ethereum) And two methods:
  • sign(): generate a Signature for data from SignatureParameters
  • recover(): get the Identity from data and its Signature
                                          +----------------+
              +---------------------+     |  Signed data   |
              |/SignatureParameters/|     |                |
              +-----------+---------+     |   +--------+   |
                          |               |   |  Data  |   |
+--------+         Sign() |               |   +--------+   |     Recover()       +----------+
|  Data  +------------------------------->+                +------------------->+/Identity/|
+--------+                                |  +-----------+ |                    +----------+
                                          |  |/Signature/| |
                                          |  +-----------+ |
                                          +----------------+

Identity

this is a json object with two properties:

  • type: the type of identity (e.g.: 'ethereumAddress' for an ethereum identity like)
  • value: the actual value to recognize the identity (e.g.: for 'ethereumAddress' type, it would be something like '0x742d35cc6634c0532925a3b844bc454e4438f44e')

Note: Two identities are equal if and only if their type and value are equal

Example

{
    "type": "ethereumAddress",
    "value": "0x742d35cc6634c0532925a3b844bc454e4438f44e"
}

Roles

Any Identity have one and only one Role in each request:

Role conditions
payee the identity is equal to the request payee
payer the identity is equal to the request payer
thirdparty every other condition listed above are NOT satisfied

Signature

this is a json object with two properties:

  • method: the method to sign (e.g.: 'ecdsa' for an Elliptic Curve Signature)
  • value: the signature itself

Note: Two signatures are equal if and only if their method and value are equal

Example

{
    "method": "ecdsa",
    "value": "0xe649fdfe25c3ee33061a8159be9b941141121c5bed8d07664cb67b7912819b4539841a206636c190178ac58978926dad1fe3637a10b656705b71bda5e187510c1b"
}

SignatureParameters

this is a json object with two properties:

  • method: the method to sign (e.g.: 'ecdsa' for an Elliptic Curve Signature)
  • privateKey: the private key to sign with

Example

{
    "method": "ecdsa",
    "privateKey": "0x3a1076bf45ab87712ad64ccb3b10217737f7faacbf2872e88fdd9a537d8fe266"
}

Signature methods supported

List of the Signature methods supported in this version:

Method Signature Value SignatureParameter privateKey Identity Type from recover() Comment
ecdsa hexadecimal string (e.g.: "0xe649f..") hexadecimal string (e.g.: "0xe649f..") EthereumAddress (see "Identity types supported" below)
ecdsa-ethereum hexadecimal string (e.g.: "0xe649f..") hexadecimal string (e.g.: "0xe649f..") EthereumAddress (see "Identity types supported" below) Similar to ecdsa but the signature is made with the Ethereum padding keccak256("\x19Ethereum Signed Message:\n" + len(message) + message)). Used for signing with the web3 tools (like Metamask).

Identity types supported

List of the Identity types supported in this version:

Type Identity Value Signature Method
ethereumAddress hexadecimal string (e.g.: "0xe649f..") ecdsa (see "Signature methods supported" above)

How to sign a JSON object

The signature of an JSON object is made on the keccak256 hash of the object:

  • with its properties deeply alphabetically sorted
  • stringified
  • lowerCased

Note on Version and Backward compatibility

The versions of the Request logic specifications follow the semver 2.0.0. Every request is create with one and only one version of the specification.

By default, an implementation of the specifications will be able to handle only the requests following the specification versions with:

  • The same major version
  • A minor version equal or inferior

Some exceptions will be done for versions that need to be blacklisted (e.g.: versions with vulnerabilities)

Example of a request state actions after actions

Bob wants to request 0.12 BTC to Alice.

Bob has his private Signature parameters from which it can generate his Identity:

{
  "signatureParams": {
    "method": "ecdsa",
    "privateKey": "0x04674d2e53e0e14653487d7323cc5f0a7959c83067f5654cafe4094bde90fa8a",
  },
  "identity": {
    "type": "ethereumAddress",
    "value": "0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce",
  }
}

Alice has his own Signature parameters and Identity:

{
  "signatureParams": {
    "method": "ecdsa",
    "privateKey": "0x0906ff14227cead2b25811514302d57706e7d5013fcc40eca5985b216baeb998",
  },
  "identity": {
    "type": "ethereumAddress",
    "value": "0x740fc87Bd3f41d07d23A01DEc90623eBC5fed9D6",
  }
}
  1. Bob creates a request of 0.1234 ETH to Alice
  2. Bob makes a discount of 0.1 ETH
  3. Alice accept the request

We now follow the state of the request after each actions:

1. Bob creates a request of 0.1234 ETH to Alice

The action to create the request from Bob to Alice from Bob (signed by Bob):

{
   "data":{
      "name":"create",
      "parameters":{
         "currency":"ETH",
         "expectedAmount":"123400000000000000",
         "payee":{
            "type":"ethereumAddress",
            "value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
         },
         "payer":{
            "type":"ethereumAddress",
            "value":"0x740fc87Bd3f41d07d23A01DEc90623eBC5fed9D6"
         },
         "timestamp":1544426030
      },
      "version":"2.0.0"
   },
   "signature":{
      "method":"ecdsa",
      "value":"0xac9e9e43381d882f3edc506277b8ad74ca3fc0ed2184663b65ccbab921df114807d7e68fd03b668afffee1feb977c9082657f1a05f57c0b1f92e9b46ca22dfc31c"
   }
}

The request state after interpreting the action above:

{
   "currency":"ETH",
   "expectedAmount":"123400000000000000",
   "payee":{
      "type":"ethereumAddress",
      "value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
   },
   "payer":{
      "type":"ethereumAddress",
      "value":"0x740fc87Bd3f41d07d23A01DEc90623eBC5fed9D6"
   },
   "timestamp":1544426030,
   "requestId":"0xd251224337a268cc4c6d73e02f883827a35789f6da15050655435348452d8905",
   "version":"2.0.0",
   "events":[
      {
         "actionSigner":{
            "type":"ethereumAddress",
            "value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
         },
         "name":"create",
         "parameters":{
            "expectedAmount":"123400000000000000",
            "extensionsDataLength":0,
            "isSignedRequest":false
         }
      }
   ],
   "state":"created",
   "creator":{
      "type":"ethereumAddress",
      "value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
   }
}

2. Bob makes a discount of 0.1 ETH

The action to make a discount (signed by Bob);

{
   "data":{
      "name":"reduceExpectedAmount",
      "parameters":{
         "deltaAmount":"100000000000000000",
         "requestId":"0xd251224337a268cc4c6d73e02f883827a35789f6da15050655435348452d8905"
      },
      "version":"2.0.0"
   },
   "signature":{
      "method":"ecdsa",
      "value":"0x649c5fdd54e781dfb480f9b01cc9ac8cd9d7630e2dd3b9a8443865ee00d5015805e6b3bbce9be35ef124e92afba80db79d913cdc756fe4e911f3413ae6a24b971b"
   }
}

The request state after interpreting the new action with the previous state:

{
   "currency":"ETH",
   "expectedAmount":"23400000000000000",
   "payee":{
      "type":"ethereumAddress",
      "value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
   },
   "payer":{
      "type":"ethereumAddress",
      "value":"0x740fc87Bd3f41d07d23A01DEc90623eBC5fed9D6"
   },
   "timestamp":1544426030,
   "requestId":"0xd251224337a268cc4c6d73e02f883827a35789f6da15050655435348452d8905",
   "version":"2.0.0",
   "events":[
      {
         "actionSigner":{
            "type":"ethereumAddress",
            "value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
         },
         "name":"create",
         "parameters":{
            "expectedAmount":"123400000000000000",
            "extensionsDataLength":0,
            "isSignedRequest":false
         }
      },
      {
         "actionSigner":{
            "type":"ethereumAddress",
            "value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
         },
         "name":"reduceExpectedAmount",
         "parameters":{
            "deltaAmount":"100000000000000000",
            "extensionsDataLength":0
         }
      }
   ],
   "state":"created",
   "creator":{
      "type":"ethereumAddress",
      "value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
   }
}

3. Alice accept the request

The action to accept the request (signed by Alice):

{
   "data":{
      "name":"accept",
      "parameters":{
         "requestId":"0xd251224337a268cc4c6d73e02f883827a35789f6da15050655435348452d8905"
      },
      "version":"2.0.0"
   },
   "signature":{
      "method":"ecdsa",
      "value":"0xf94380c553c90810deb5625571649759f8591bf923f5773e436fec322d01752d676a6f822dee2c2097f4bb70b16273b4826e6026f9f98a31cfafab8f1bdda2eb1b"
   }
}

The request state after interpreting the new action with the previous state:

{
   "currency":"ETH",
   "expectedAmount":"23400000000000000",
   "payee":{
      "type":"ethereumAddress",
      "value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
   },
   "payer":{
      "type":"ethereumAddress",
      "value":"0x740fc87Bd3f41d07d23A01DEc90623eBC5fed9D6"
   },
   "timestamp":1544426030,
   "requestId":"0xd251224337a268cc4c6d73e02f883827a35789f6da15050655435348452d8905",
   "version":"2.0.0",
   "events":[
      {
         "actionSigner":{
            "type":"ethereumAddress",
            "value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
         },
         "name":"create",
         "parameters":{
            "expectedAmount":"123400000000000000",
            "extensionsDataLength":0,
            "isSignedRequest":false
         }
      },
      {
         "actionSigner":{
            "type":"ethereumAddress",
            "value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
         },
         "name":"reduceExpectedAmount",
         "parameters":{
            "deltaAmount":"100000000000000000",
            "extensionsDataLength":0
         }
      },
      {
         "actionSigner":{
            "type":"ethereumAddress",
            "value":"0x740fc87Bd3f41d07d23A01DEc90623eBC5fed9D6"
         },
         "name":"accept",
         "parameters":{
            "extensionsDataLength":0
         }
      }
   ],
   "state":"accepted",
   "creator":{
      "type":"ethereumAddress",
      "value":"0xAf083f77F1fFd54218d91491AFD06c9296EaC3ce"
   }
}