Become a Data Provider

Setting up and docking a DP service

Please refer to Go and Java code samples from respective links.

Prerequisites

ONT ID

Each DP must have a unique decentralized identifier (DID) for signing and encrypting data contained in response messages, so the MP can confirm the authenticity and security of the data. At present, it must be an ONT ID. You can get one by creating a wallet using ONTO app.

You can use one and the same DID to set up a DP and an MP.

Orange Provider SDK

The SDK in Go or Java is needed for signature and data encryption. Below instructions are illustrated in Go.

Wallet

You need to include a wallet file in the local directory of your project for signature and data encryption.

Compose Datasets and Build Methods

Note that as a Data Provider, the method of synchronization or collection you choose to compose datasets is entirely up to you. The Orange system uses the interface defined and shared by you to fetch and then process any data.

Discrete useful data can be combined to create datasets. Each dataset can contain mutually related data that can be processed in specific ways to generate specific elements of reputation. Both on-chain and off-chain data are accepted.

One DP can provide multiple datasets to Orange users. Every dataset must have an associated method. A method is an abstract definition or reference to a dataset that is useful when querying and fetching data.

Each method needs to have a name, and a parameter and result schema associated with it.

  • The name is used to refer to a particular method

  • The parameter schema defines the useful data that needs to be passed as input to fetch any relevant data pertaining to the particular method

  • The result schema defines the structure of the response that will be generated and returned when a certain method is selected

Create Interfaces for Data Access

As a DP, you need to set up an externally accessible interface with specific endpoints that can be used to fetch data. These endpoints will be called when the MP makes data requests to the Orange system.

Currently Orange supports DPs to use RESTful and GraphQL API formats.

Parameters

The interface can retrieve data using these parameters:

"$API_KEY"		    // The API key assigned to DP when registered
"$ARRAY"                    // Array type, see details below   
"$CHAIN_NAME"               // Network that user's wallet is connected to. E.g., "eth","bsc"  
"$USER_ADDRESS"             // User wallet address
"$ENCRYPTED"                // See details below
"$USER_DID"                 // DID of API caller, by default it's the DID of the WASM execution environment
"$DEFAULT_CHAIN_NAME"       // Name of the network that "$DEFAULT_USER_ADDRESS" is on
"$DEFAULT_USER_ADDRESS"     // See details below 
"$AP_DID"                   // DID of MP
"$ORANGE_DID"               // DID of Orange system  

$ARRAY

You can pass multiple values for $CHAIN_NAME and $USER_ADDRESS in the form of an array using $ARRAY in the following structure:

assets:$ARRAY[{chain:$CHAIN_NAME,address:$USER_ADDRESS}]6

Then it will be automatically converted to this format:

assets:[{chain:"<chainname>",address:"<addr>"},{chain:"<chainname>",address:"<addr>"},...]

$ENCRYPTED

To configure whether to encrypt the data in the response. The default value is true. The MP will pass false if data should not be encrypted.

$DEFAULT_USER_ADDRESS

When user DID conforms to the method for Ethereum (did:etho), it's the address used for login; when user DID conforms to the method for Ontology (did:ont), it's the first wallet address added to Orange

Request

RESTful POST

For POST requests, parameters should be included in the request body in JSON:

{"user_did": $AP_DID,"address": $DEFAULT_USER_ADDRESS,"chain": $DEFAULT_CHAIN_NAME,"encrypt": $ENCRYPTED}

RESTful GET

For GET requests, parameters should be included in the request URL:

?user_did=$AP_DID&address=$DEFAULT_USER_ADDRESS&chain=$DEFAULT_CHAIN_NAME&encrypt=$ENCRYPTED

GraphQL

Orange's DP uses GraphQL API format. An example of parameters in a request:

{
  "query":"query{
    queryUserNFTAssets(input:{
      key:$API_KEY,
      user_did:$USER_DID,
      address:$DEFAULT_USER_ADDRESS,
      require_chains:[\"eth\",\"bsc\"],
      xdays:180,
      encrypt:$ENCRYPTED
    }){
      data{
        data{
          first_nft_days,    
          trade_counts_opensea_in_xdays,
          has_nft_in_opensea,
          nft_kinds_in_xdays,
          bsc_first_nft_days,
          bsc_nft_kinds_in_xdays
        },
        sig
      },
      encrypted
      }
  }",
  "variables":{}
}

Request Authentication (in development)

You can choose to authenticate API requests by requiring the MP to include a signature created using Orange system DID in requests. This is an example of a signature:

f, err := didsdk.VerifySig(requestJson.CallererDID, msgbytes, sigbytes)
if err != nil || !f {
        fmt.Printf("VerifySig  failed:%s\n", err.Error())
        c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("invalid signature")})
        return
}

Response

{
	"data":{
		"data":{},
		"sig":<string>
	}
	"encrypted":<string>
}

If in the request, the value for $ENCRYPTED is true, then in the response the data field (at the same level with theencrypted field) is empty, and the encrypted field takes the encrypted result of the data.

If the value for $ENCRYPTED is false, the data field takes the data itself without encryption and the encrypted field is empty.

Publish Interface

When your interface is ready to be accessed on the mainnet, you can publish it on the Orange platform for developers to discover and use it. You can do it in the Reputation Studio.

Step 1: Click on the "Connect Wallet" button on the top right to connect your wallet. You can find a detailed guide here.

Step 2: Click on the Menu button and select "Management". Choose "My Datasets".

Step 3: Click on the "Create Profile" button and fill out the form to create your profile as an MP.

Step 4: Click on the "Create Dataset" and fill out the information following the steps indicated on the page. Then you can either click "Save" to save the draft, or click "Publish" to submit your dataset for review and publication.

Receive Requests

When a user wants to generate a reputation score using your data, the Orange system sends a request to the associated MP first, and then the MP sends a request to your DP API to fetch the data.

Sign Requested Data

When you send a response to the MP, you need to to sign the response using your DID. To do so, you need the Orange Go SDK and a wallet.

Import SDK

import(
	orangeSDK "github.com/orange-protocol/orange-provider-go-sdk"
	orangeOnt "github.com/orange-protocol/orange-provider-go-sdk/ont"
)

Initialize SDK

didsdk, err := orangeOnt.NewOrangeProviderOntSdk("./wallet.dat", "123456", "TESTNET")
if err != nil {
    panic(err)
}

Parameters

  • path of the wallet file

  • wallet password

  • network info: TESTNET or MAINNET

Example

For example, a data API returns the token balance of an address:

{
	"balance":"<balance value>"
}

Sign the balance data:

balanceData := BalanceData{Balance:"1000000"}   //mock result
//1. Marshal json into bytes
dataToSign ,err:= json.Marshal(balanceData)
if err != nil{
	c.JSON(http.StatusInternalServerError,gin.H{"error":err.Error()})
	return
}
//2. Sign the bytes with your DID using the wallet
sig, err := didsdk.SignData(dataToSign)
if err != nil {
	c.JSON(http.StatusInternalServerError,gin.H{"error":err.Error()})
	return
}
//3. Combine the data and signature
dataWithSig := RespData{
	Data: balanceData,
	Sig:  hex.EncodeToString(sig),
}

Encrypt Requested Data

To ensure that only the MP can access the datasets, you need to encrypt the datasets passed in response messages using the public key associated to the MP's DID. The Orange system does not decrypt or store datasets.

if requestJson.Encrypt {
//1. Marshal json into bytes
	databytes, err := json.Marshal(dataWithSig)
	if err != nil {
		c.JSON(http.StatusInternalServerError,gin.H{"error":err.Error()})
		return
	}
			
//2. Encrypt bytes using MP DID 
	enctrypted, err := didsdk.EncryptDataWithDID(databytes, requestJson.UserDID)
	if err != nil {
		c.JSON(http.StatusInternalServerError,gin.H{"error":err.Error()})
		return
	}

//3. Encode the encrypted data to Hex string
	enhex := hex.EncodeToString(enctrypted)
	c.JSON(200, gin.H{
		"provider_did":selfDID,
		"data": nil,
		"encrypted":enhex,
	})
}else{
	c.JSON(200, gin.H{
		"provider_did":selfDID,
		"data": dataWithSig,
		"encrypted":nil,
	})
}

After the signing and encryption, the response message is ready for sending to the MP. You can read about how an MP works in the next section.

Last updated