# Offchain Subscriber Example

### What's off-chain Subscriber ?&#x20;

Off-chain subscriber is non-contract method to query Endpoints and receive data through events from Oracle. It can be a script to query and react on the response received from Oracles through Ethereum blockchain `events` or users can manually query and wait to see responses using zap-term cli tool

### Template

Following script includes calling query and waiting for response events

```typescript
import {ZapSubscriber} from "@zapjs/subscriber"
import {ZapBondage} from "@zapjs/bondage"
import {ZapToken} from "@zapjs/zaptoken"
import {Config} from "./Config";
const Web3 = require('web3');
const HDWalletProviderMem = require("truffle-hdwallet-provider");

export class SimpleSubscriber{
  zapSubscriber: ZapSubscriber|null
  constructor(){
    this.zapSubscriber = null
  }
  /**
    Decide what oracle and endpoint you want to interact with,
    Approve, Bond dots to be ready to query (if there is not enough dots bound)
  */
  async setup(){
      //setup subscriber, for demo reason, we use same wallet as provider's
      let web3 = new Web3(new HDWalletProviderMem(Config.mnemonic,Config.NODE_URL,1))
      let accounts = await web3.eth.getAccounts();
      let subscriberOwner = accounts[0]
      let zapSubscriber = new ZapSubscriber(subscriberOwner, {networkProvider: web3, networkId: await web3.eth.net.getId()})
      let zapToken = new ZapToken({networkProvider: web3, networkId: await web3.eth.net.getId()})
      let zapBondage = new ZapBondage({networkProvider: web3, networkId: await web3.eth.net.getId()})

      // will skip approve and bond if there is enough dots already bound
      const boundDots = await zapSubscriber.getBoundDots({provider:Config.Oracle,endpoint:Config.Endpoint})
      if(boundDots<Config.dots){
        let allowance = await zapToken.contract.methods.allowance(subscriberOwner,zapBondage.contract._address).call()
        let zapRequired = await zapBondage.calcZapForDots({provider:Config.Oracle,endpoint:Config.Endpoint,dots:Config.dots})
        if(allowance<zapRequired){
          let txid = await zapSubscriber.approveToBond({provider:Config.Oracle,zapNum:zapRequired})
        }
        let txid = await zapSubscriber.bond({provider:Config.Oracle,endpoint:Config.Endpoint,dots:Config.dots})
      }
      //start listening to incoming reponses
      zapSubscriber.listenToOffchainResponse({},(err:any,logs:any)=>{
          console.log("Response event from provider : ",logs)
          this.processResponse(logs)
      })
  }

  processResponse(response:string){
    // implement your custom logic here
    console.log("Process response from Oracle : ",response)
  }

  async queryProvider(query:string,params:string[]){

      if(this.zapSubscriber){
          return await this.zapSubscriber.queryData({
              provider: Config.Oracle,
              query: query,
              endpoint: Config.Endpoint,
              endpointParams: params
          })
      }
      else{
        return "No subscriber found"
      }

  }
}
```

Subscriber template provide a class that you can setup the function `processResponse` much as on-chain subscriber implementing `callback` function.  That will be all you need to do to have fully functional off-chain subscriber

### Using Template

{% hint style="info" %}
Source Code :  <https://github.com/zapproject/subscriber-template.git>
{% endhint %}

#### Setup environment and create off-chain subscriber

1. git clone <https://github.com/zapproject/subscriber-template.git>
2. cd `subscriber-template`
3. cd `Offchai_Subscriber_Example`
4. Fill out config file variables such as mnemonic, oracle address, endpoint, query, dots ...
5. In `Simplesubscriber.ts`, fill out the body of function `processMessage`
6. Make sure you have ZAP and ETH balances in your mnemonic's address
7. `yarn`
8. `yarn build`
9. `yarn start-offchain`&#x20;

You can modify the `index.ts` file to include logic when to trigger the query to Oracle

That's it, now you have a Zap Subscriber that interact with Zap contracts and Oracles to receive data you need.&#x20;


---

# 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://zapproject.gitbook.io/zapproject/users/templates/offchain-subscrier-example.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.
