# Become a Data Provider

{% hint style="info" %}
Please refer to [Go ](https://github.com/orange-protocol/orange-dp-sample)and [Java ](https://github.com/orange-protocol/orange-java-dp-example)code samples from respective links.&#x20;
{% endhint %}

## 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](https://onto.app/en/download/?mode=app).

> You can use one and the same DID to set up a DP and an MP.&#x20;

### Orange Provider SDK

The SDK in [Go](https://github.com/orange-protocol/orange-provider-go-sdk) or [Java ](https://github.com/orange-protocol/orange-provider-java-sdk)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.&#x20;

## Compose Datasets and Build Methods

{% hint style="info" %}
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.
{% endhint %}

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.&#x20;

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](#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:

```http
{"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:

```http
?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:

```graphql
{
  "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:

```go
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

```go
{
	"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 the`encrypted` field) is empty, and the `encrypted` field takes the encrypted result of the data.&#x20;

If the value for `$ENCRYPTED` is `false`, the `data` field takes the data itself without encryption and the `encrypted` field is empty.&#x20;

## 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](https://app.orangeprotocol.io/).

**Step 1:** Click on the **"Connect Wallet"** button on the top right to connect your wallet. You can find a detailed guide [here](https://docs.orangeprotocol.io/support/reputation-studio-guide).

**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&#x20;

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&#x20;

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](https://github.com/orange-protocol/orange-provider-go-sdk) and a wallet.

### Import SDK

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

### Initialize SDK

```go
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:

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

Sign the balance data:

```go
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&#x20;

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.

```go
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.
