# Data Publishing

Anyone can contribute to publishing updates to destination chains, ensuring a constant stream of data. To participate, use the pull-update-publisher tool. Clone the [udf-update-publisher repository](https://github.com/Entangle-Protocol/udf-update-publisher) and launch the daemon to start streaming updates to destination chains. For this, you will need [Git](https://git-scm.com/) to clone the code and [Docker](https://www.docker.com/) or [Go](https://go.dev/) to run it.

{% stepper %}
{% step %}

### Clone

Begin by cloning the [repository](https://github.com/Entangle-Protocol/udf-update-publisher) using [Git](https://git-scm.com/).

```
git clone https://github.com/Entangle-Protocol/udf-update-publisher.git
```

{% endstep %}

{% step %}

### Configure

Update the `config.yaml` file found in the repositories root directory. Ensure you select the data keys for which you want to secure updates for, set the private key, and optionally set your node URLs.

Below is an example of the configuration file, it can be used to configure: 1. the feeds to listen and push updates for, 2. push parameters (e.g., deviation and heartbeat), and 3. target chain information (i.e., where to push updates to and the publisher private key).

```yaml
finalizeSnapshotUrl: https://udfsnap.ent-dx.com
dataKeys:
  - NGL/USD
  - ETH/USD
  - BTC/USD
  - GAS-ETH
  - GAS-BSC
assets:
  - sourceID: prices-feed1
    dataKeys:
    - NGL/USD
    - ETH/USD
    - BTC/USD
  - sourceID: gas-feed1
    dataKeys:
    - GAS-ETH
    - GAS-BSC
publisher:
  updateInterval: 30 
  updateThreshold: 5m0s
  priceDiffThreshold: 100
networks:
  solana:
  eth_sepolia:
    targetChainUrl: https://ethereum-sepolia-rpc.publicnode.com
    pullOracleAddress: 0x0b2d8Ef1D9104c4Df5C89F00B645Ce8bAa56DeB5
    privateKey: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
  mantle_sepolia:
    targetChainUrl: https://rpc.sepolia.mantle.xyz
    pullOracleAddress: 0x751c47110351806e41ccDA4C181a50edfA6b63E0
    privateKey: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
```

{% endstep %}

{% step %}

### Run

If you're using [Docker](https://www.docker.com/) you can build and run the docker container using the following command:

```docker
docker compose -f ./docker/docker-compose.yml up
```

If you're using [Go](https://go.dev/) you can run the pull-update-publisher tool using the following command:

```go
go run ./cmd/pull-update-publisher
```

{% endstep %}
{% endstepper %}

## Pull Update Publisher Tool

The pull-update-publisher executable when run, tries to publish updates based on the `publisher.updateInterval` interval option, in concrete steps it does the following:

1. Fetch latest updates for keys specified in the configuration file using the "Retrieve Spotter's Assets in Detail" API endpoint of the Update Provider Service.
2. Select updates that have either of the following properties:
   1. Latest on-chain update is older than value specified by `publisher.updateThreshold` option in the configuration file.
   2. Latest on-chain update value differs by more than (`` `publisher.priceDiffThreshold` / 10000 % ``) from fetched update value.
3. Send selected updates to the PullOracle contract.

## Update Provider Service API <a href="#finalized-data-api" id="finalized-data-api"></a>

<details>

<summary>Retrieve Spotters List</summary>

**Endpoint:** `GET /spotters`

**Description:** Retrieves a list of spotters, including their IDs, supported assets, and networks.

</details>

<details>

<summary>Retrieve Spotter's Assets in Detail</summary>

**Endpoint:** `GET /spotters/{spotterID}`

**Description:** Retrieves a detailed view of a specific spotter's assets.

**Parameters:**

* `spotterID` (string): ID of the spotter.
* `assets` (string, query): Comma-separated list of asset keys (e.g., `NGL/USD, ETH/USD`).

</details>

<details>

<summary>Retrieve Calldata for Specific Network</summary>

**Endpoint:** `GET /spotters/{spotterID}/{network}/calldata`

**Description:** Retrieves a detailed view of a specific spotter's assets in calldata format for a particular network.

**Parameters:**

* `spotterID` (string): ID of the spotter.
* `network` (string): Blockchain network name.
* `assets` (string, query): Comma-separated list of asset keys (e.g., `NGL/USD, ETH/USD`).

**Response** (example in json):

```
{
  "value": {
    "timestamp": "1234567890",
    "data": "btc/usd_value"
  },
  "merkleRoot": "xxxxxxxxxxxxxxxxxxxxx", // bytes32
  "signatures": ["sig1", "sig2", "..."], // array of Signatures
  "merkleProofs": ["uncle_proof1", "uncle_proof2"] // array of strings
  "key": "btc/usd" // bytes32
}
```

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.entangle.fi/universal-data-feeds/developer-guides/data-publishing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
