1. Introduction

This document contains generated documentation for AMPnet identity service.

2. Authorization API

2.1. Get payload

Used to retrieve a unique nonce associated with user address.

Request
POST /authorize HTTP/1.1
Content-Type: application/json
Content-Length: 62
Host: localhost:8080

{
  "address" : "0xef678007d18427e6022059dbc264f27507cd1ffc"
}
Response
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 160

{
  "payload" : "Welcome!\nPlease sign this message to verify that you are the owner of address: 0xef678007d18427e6022059dbc264f27507cd1ffc\nNonce: 193030099"
}

2.2. Get payload by message

Used to retrieve a payload with unique ID and nonce.

Request
POST /authorize/by-message HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 144

{
  "payload" : "Please sign this message to verify your wallet ownership, unique ID: a49d63ad-44af-41db-b1f5-84d9b4387f30, nonce: 1821846565"
}

2.3. Get JWT

To get JWT the user must sign the payload received from POST /authorize route using his private key. User is created in the database on his first login. chain_id in the request body is optional, it is used for verifying smart contract signatures, e.g. Gnosis, Ambire.

Request
POST /authorize/jwt HTTP/1.1
Content-Type: application/json
Content-Length: 237
Host: localhost:8080

{
  "address" : "0xef678007d18427e6022059dbc264f27507cd1ffc",
  "signed_payload" : "0x953ab159195a52cae70f06934ea9417a25b4570f257a5d5df49ecd8aee2d62503427fccaaf103eb69605189dab6daa71765b29ed3d4dd0f4b0eb47b3e39259b21b",
  "chain_id" : 0
}
Response
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 751

{
  "access_token" : "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJBTVBuZXQiLCJhZGRyZXNzIjoiMHhlZjY3ODAwN2QxODQyN2U2MDIyMDU5ZGJjMjY0ZjI3NTA3Y2QxZmZjIiwiaWF0IjoxNjY0ODAxODc3LCJleHAiOjE2NjQ4ODgyNzd9.kAwSBbAJg4AoR15I6HUf1sh13A7YTfTTHmaY5EtgMOm7C4GFrlI8xD5d0V3EFaf8OPWfuj_wJtdYgvBZ6423BVL4f-KM1xfd012E-z1SjbKvouygiu74o6sRPb2pHsN5OB3Q0DYTLbS52tmraIvcsSQjrWSjqGTNkI7UwHJ4qiDs2oJVb2L6PgMsyGX0E6_NN-zN_Z8AnEykJAdN8zBXdw0YX6iUOgjZVKV06wX91eDjgfmGHaOzZkBw8gtP4kShG7y-GgqZXmpXuoiPnd0TVJWCmiEsgg8KADzf0pb7MNiQ7CDMOEFPNGZKDE3ogV8aCn-_I3Hxpk8IZvmB_XqoFw",
  "expires_in" : 86400000,
  "refresh_token" : "U-3-6kdUHt107FNPcQB3_4+TpHGWQs5HbZe7eMNhS2Rv77q7jF93ML_5IFaPa_PA+JPImKquFoBc5x7FA9WKaJdn-YpoZ7o4_55C2NGr564MVzLxXy7OspoA8IKQy9Zb",
  "refresh_token_expires_in" : 7776000000
}

2.4. Get JWT by message

To get JWT by message the user must sign the payload received from POST /authorize/by-message route using his private key. User is created in the database on his first login.

Request
POST /authorize/jwt/by-message HTTP/1.1
Content-Type: application/json
Content-Length: 368
Host: localhost:8080

{
  "address" : "0xef678007d18427e6022059dbc264f27507cd1ffc",
  "message_to_sign" : "Please sign this message to verify your wallet ownership, unique ID: 8b9ec2dd-626f-4444-9ae7-b4142e6e99e5, nonce: 721558130",
  "signed_payload" : "0xcbc232b66251488cc345d2ffa09b832d072863d61052d92bc285f8734249c98b4cc33fb4c1265567a5757a45b55458d30b04788e85bca8402baeeece8f4920b01b"
}
Response
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 751

{
  "access_token" : "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJBTVBuZXQiLCJhZGRyZXNzIjoiMHhlZjY3ODAwN2QxODQyN2U2MDIyMDU5ZGJjMjY0ZjI3NTA3Y2QxZmZjIiwiaWF0IjoxNjY0ODAxODc2LCJleHAiOjE2NjQ4ODgyNzZ9.hBeQ_cBxIMcpIstAvbLczSvYjbctSDm94OvMNklb5fTUizH5pmhNVVmKSAPkGFmnnZtcSs9tGYMwl8iW8b7ghStIJZn8x8lxHa8vXdwj4IvLg0zAe1MCFJvwxm4FPo48ITnLbrZszg-C8GmTlLHKiVSckMDn14KBYuYzYIOeyeIq4wFK-Z6NEsm5TDSbx1vB2j0xj3hu3TwbG9SxCdbGIeZsKysj_up-PER8ic-aGtQa8VxchSopXdNX3SEwYGSkVwUi0TOd7-qhbDP6PQ2xNufIdhm7_UAGIZS1K2V8pn0ZmqHIR5MTUvcU2lzVuRp3zNF5drVu-2kBpLhM8XOYyg",
  "expires_in" : 86400000,
  "refresh_token" : "kOaQDubnEHKTdv_LciQdUvntkIIx2qsY9g_qix9v0Z_hqtQExdlh7mf1GoZM1O7bOOAcoRVYodjl1aSnP6MjGhk0u6np3J9qWDkVBmKlmF5o9eRJkQ+DMx9CHf5JflPD",
  "refresh_token_expires_in" : 7776000000
}

2.5. Refresh token

Request
POST /authorize/refresh HTTP/1.1
Content-Type: application/json
Content-Length: 59
Host: localhost:8080

{
  "refresh_token" : "9asdf90asf90asf9asfis90fkas90fkas"
}
Response
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 656

{
  "access_token" : "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJBTVBuZXQiLCJhZGRyZXNzIjoiMHhlZjY3ODAwN2QxODQyN2U2MDIyMDU5ZGJjMjY0ZjI3NTA3Y2QxZmZjIiwiaWF0IjoxNjY0ODAxODc3LCJleHAiOjE2NjQ4ODgyNzd9.kAwSBbAJg4AoR15I6HUf1sh13A7YTfTTHmaY5EtgMOm7C4GFrlI8xD5d0V3EFaf8OPWfuj_wJtdYgvBZ6423BVL4f-KM1xfd012E-z1SjbKvouygiu74o6sRPb2pHsN5OB3Q0DYTLbS52tmraIvcsSQjrWSjqGTNkI7UwHJ4qiDs2oJVb2L6PgMsyGX0E6_NN-zN_Z8AnEykJAdN8zBXdw0YX6iUOgjZVKV06wX91eDjgfmGHaOzZkBw8gtP4kShG7y-GgqZXmpXuoiPnd0TVJWCmiEsgg8KADzf0pb7MNiQ7CDMOEFPNGZKDE3ogV8aCn-_I3Hxpk8IZvmB_XqoFw",
  "expires_in" : 86400000,
  "refresh_token" : "9asdf90asf90asf9asfis90fkas90fkas",
  "refresh_token_expires_in" : 7772400000
}

3. KYC API

For KYC procedure the system supports Veriff provider.

3.1. Get Veriff session

Get Veriff session. For code explanation on decision response, see: https://developers.veriff.com/#response-and-error-codes Request requires header: Authorization: Bearer JWT.

Request
POST /veriff/session HTTP/1.1
Content-Type: application/json
Host: localhost:8080
Response
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 423

{
  "verification_url" : "https://alchemy.veriff.com/v/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.new-url",
  "state" : "created",
  "decision" : {
    "session_id" : "44927492-8799-406e-8076-933bc9164ebc",
    "status" : "declined",
    "code" : 9102,
    "reason" : "Physical document not used",
    "reason_code" : 101,
    "decision_time" : "2020-12-04T10:45:37.907Z",
    "acceptance_time" : "2020-12-04T10:45:31.000Z"
  }
}

3.2. Handle Veriff session

Request
POST /veriff/webhook/decision HTTP/1.1
Content-Type: application/json
X-AUTH-CLIENT: a2b3005f-e324-4e7e-a328-4aecd11a091b
X-SIGNATURE: 68926f9d38568d55e043bb1c4a4a0f1770ce8af324a2f542e0b2014239601833
Content-Length: 1260
Host: localhost:8080

{
  "status" : "success",
  "verification" : {
    "id" : "12df6045-3846-3e45-946a-14fa6136d78b",
    "code" : 9001,
    "person" : {
      "gender" : null,
      "idNumber" : null,
      "lastName" : "MORGAN",
      "firstName" : "SARAH",
      "citizenship" : null,
      "dateOfBirth" : "1967-03-30",
      "nationality" : null,
      "yearOfBirth" : "1967",
      "placeOfBirth" : "MADRID",
      "pepSanctionMatch" : null
    },
    "reason" : null,
    "status" : "approved",
    "comments" : [ ],
    "document" : {
      "type" : "DRIVERS_LICENSE",
      "number" : "MORGA753116SM9IJ",
      "country" : "GB",
      "validFrom" : null,
      "validUntil" : "2222-04-20"
    },
    "reasonCode" : null,
    "vendorData" : "0xef678007d18427e6022059dbc264f27507cd1ffc",
    "decisionTime" : "2019-11-06T07:18:36.916Z",
    "acceptanceTime" : "2019-11-06T07:15:27.000Z",
    "additionalVerifiedData" : {
      "driversLicenseCategory" : {
        "B" : true
      }
    },
    "riskLabels" : [ {
      "label" : "document_crosslinked_with_fraud",
      "category" : "document"
    }, {
      "label" : "document_globally_crosslinked_with_multiple_declines",
      "category" : "document"
    } ]
  },
  "technicalData" : {
    "ip" : "186.153.67.122"
  }
}
Response
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY

3.3. Handle Veriff event

Request
POST /veriff/webhook/event HTTP/1.1
Content-Type: application/json
X-AUTH-CLIENT: a2b3005f-e324-4e7e-a328-4aecd11a091b
X-SIGNATURE: bf3da6e9aa47e6be208fec283097a5bcbdb2066dcb58f0d7c9879637700f013f
Content-Length: 231
Host: localhost:8080

{
  "id" : "cbb238c6-51a0-482b-bd1a-42a2e0b0ff1c",
  "code" : 7001,
  "action" : "submitted",
  "feature" : "selfid",
  "attemptId" : "fa3316d6-0222-407e-927d-e75545a11ce6",
  "vendorData" : "2652972e-2dfd-428a-93b9-3b283a0a754c"
}
Response
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY

4. User API

All requests need header: Authorization: Bearer JWT.

4.1. Get user data

Request
GET /user HTTP/1.1
Content-Type: application/json
Host: localhost:8080
Response
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 145

{
  "address" : "0xef678007d18427e6022059dbc264f27507cd1ffc",
  "email" : "[email protected]",
  "email_verified" : true,
  "kyc_completed" : true
}

4.2. Update user email

Request
PUT /user HTTP/1.1
Content-Type: application/json
Content-Length: 37
Host: localhost:8080

{
  "email" : "[email protected]"
}
Response
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 151

{
  "address" : "0xef678007d18427e6022059dbc264f27507cd1ffc",
  "email" : "[email protected]",
  "email_verified" : true,
  "kyc_completed" : false
}

4.3. Whitelist address for issuer

User must complete KYC to enable whitelisting his address for any issuer.

Request
POST /user/whitelist HTTP/1.1
Content-Type: application/json
Content-Length: 91
Host: localhost:8080

{
  "issuer_address" : "0xb070a65b1dd7f49c90a59000bd8cca3259064d81",
  "chain_id" : 80001
}
Response
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY

4.4. Logout

Request
POST /user/logout HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY

4.5. Pinata JWT

Generate Pinata JWT for pinning(storing) files to Pinata IPFS. JWT is generated for a limited number of usages. It is recommended to generate a new one before storing data to Pinata IPFS.

Request
GET /user/pinata HTTP/1.1
Content-Type: application/json
Host: localhost:8080
Response
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 89

{
  "pinata_api_key" : "api-key",
  "pinata_api_secret" : "api-secret",
  "JWT" : "JWT"
}

5. Test API

5.1. Verify User with Test Data

Request needs header: Authorization: Bearer JWT.

5.2. Verify user

Request
POST /test/kyc HTTP/1.1
Content-Type: application/json
Content-Length: 110
Host: localhost:8080

{
  "address" : "0xef678007d18427e6022059dbc264f27507cd1ffc",
  "first_name" : "John",
  "last_name" : "Doe"
}
Response
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 145

{
  "address" : "0xef678007d18427e6022059dbc264f27507cd1ffc",
  "email" : "[email protected]",
  "email_verified" : true,
  "kyc_completed" : true
}

6. Faucet API

6.1. Request Faucet Funds

Submits a request for faucet funds for the specified chain ID. Request needs header: Authorization: Bearer JWT.

Request
POST /faucet/80001 HTTP/1.1
Content-Type: application/json
Content-Length: 34
Host: localhost:8080

{
  "re_captcha_token" : "token"
}
Response
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY

6.1.1. Error response

If the requested chain ID does not support faucet funds, bad request response will be returned.

Response
HTTP/1.1 400 Bad Request
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY

7. Auto-invest API

7.1. Submit Auto-invest Task Request

Submits auto-invest task request which whitelists user wallet and campaign for auto-invest process. All auto-invest requests which share the same user wallet address, campaign contract address and chain ID will be merged into a single request, effectively updating the auto-invest value. This is allowed only if auto-invest is not already in process for the specified (wallet, campaign, chainId) triple. Request needs header: Authorization: Bearer JWT.

Request
POST /auto_invest/80001/campaignaddress HTTP/1.1
Content-Type: application/json
Content-Length: 22
Host: localhost:8080

{
  "amount" : "500"
}
Response
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 131

{
  "wallet_address" : "0xef678007d18427e6022059dbc264f27507cd1ffc",
  "campaign_address" : "campaignaddress",
  "amount" : "500"
}

7.1.1. Error response

If the requesting user already has auto-invest in progress for the specified campaign address, bad request response will be returned.

Response
HTTP/1.1 400 Bad Request
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY

7.2. Get Auto-invest Tasks for User

Returns pending auto-invest tasks for specified chain id and user address.

Request
GET /auto_invest/80001/0xef678007d18427e6022059dbc264f27507cd1ffc HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 167

{
  "auto_invests" : [ {
    "wallet_address" : "0xef678007d18427e6022059dbc264f27507cd1ffc",
    "campaign_address" : "campaignaddress",
    "amount" : "1000"
  } ]
}

7.3. Get Auto-invest Tasks for Campaign

Returns pending auto-invest tasks for specified chain id and campaign address.

Request
GET /auto_invest/80001/campaign/campaignaddress HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 271

{
  "auto_invests" : [ {
    "wallet_address" : "0x00",
    "campaign_address" : "campaignaddress",
    "amount" : "1000"
  }, {
    "wallet_address" : "0xef678007d18427e6022059dbc264f27507cd1ffc",
    "campaign_address" : "campaignaddress",
    "amount" : "1000"
  } ]
}