# Offchain Oracle Workers

{% hint style="danger" %}
Please note that all information and code snippets provided in this section are for educational purposes only and not to be directly deployed in production.
{% endhint %}

## **Motivation for Offchain Oracle Workers**

When the Creditcoin Oracle provisions data from one chain to another, there are two transactions involved:

1. **The user submits a transaction on the source chain.** Usually this would be a source chain smart contract call emitting some event for which we want to transfer data to the execution chain.
2. **The USC contract must be called on the execution chain.** This requires generating proofs and calling the USC contract with the proofs and encoded transaction data. The USC contract verifies the proofs synchronously and executes business logic immediately.

The following diagram highlights where these two transactions take place:

<figure><img src="https://1740410107-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVp3bVdljVxZuwysnIzZ1%2Fuploads%2FHGs1zxcs39IbvbivqIRU%2FUser%20Initiated%20Steps%20in%20Creditcoin%20Oracle%20Use.png?alt=media&#x26;token=47edd84c-5512-42c1-9671-1a97c3e02b3b" alt=""><figcaption></figcaption></figure>

The first transaction must always be submitted by the end user. However, the second transaction can be initiated by an off-chain worker on behalf of the user. Using an off-chain worker provides significant UX and technical benefits:

* **Seamless user experience**: Without a worker, users would need to wait for attestation (up to a minute), manually generate proofs, format the proof data correctly, and then submit a second transaction. With a worker, users only need to sign the initial source chain transaction—everything else happens automatically in the background.
* **Eliminates technical complexity for end users**: Proof generation requires calling the Proof Generation API server, waiting for attestation, handling retries, and properly formatting complex proof structures (Merkle proofs, continuity proofs, encoded transactions). Off-chain workers handle all of this complexity transparently, so users don't need to understand the underlying oracle mechanics.
* **Reduces transaction failures and improves reliability**: Workers can implement robust retry logic, handle API failures gracefully, and ensure proper error handling. Users attempting manual proof generation are more likely to encounter failures due to timing issues (submitting before attestation completes), formatting errors, or network problems.
* **Enables better monitoring and observation**: Workers can track processing status, log events, and provide visibility into the cross-chain data flow. This helps DApp teams debug issues and monitor their DApp's health.

### Designing an Offchain Oracle Worker

Using an off-chain worker can drastically improve the UX of your Universal DApp by reducing the number of user interactions needed to trigger core business logic on the Creditcoin execution chain.

#### Worker Transaction Flow

The worker automates the following process:

1. **Monitor source chain:** The worker constantly monitors the source chain contract for events (e.g., `TokensBurned` events).
2. **Wait for attestation:** When an event is detected, the worker waits for the block containing the event to be attested on Creditcoin.
3. **Generate proofs:** The worker can generate Merkle and continuity proofs via the Proof Generation API server.
4. **Call USC contract:** The worker calls the USC contract with the proofs and encoded transaction data. The USC contract verifies the proofs synchronously and executes business logic immediately.
5. **Handle results:** The worker can listen for events from the USC contract to confirm successful execution.

All of this happens automatically - the user only needs to sign the initial source chain transaction.

{% @mermaid/diagram content="sequenceDiagram
participant User
participant SC as Source Chain<br/>(Smart Contract)
participant Worker as Oracle Worker
participant Attestors as Attestor Network
participant Oracle as Creditcoin Oracle
participant ProofAPI as Proof Generation<br/>API Server
participant USC as USC Contract
participant BusinessLogic as DApp Business Logic<br/>Contract

```
Note over User,BusinessLogic: Phase 1: User Initiates Transaction
User->>SC: Submit Transaction<br/>(e.g., burn tokens)
SC->>SC: Execute Logic & Emit Event

Note over Worker,BusinessLogic: Phase 2: Worker Monitors & Waits
Worker->>SC: Monitor Source Chain<br/>for Events
SC-->>Worker: Event Detected

Note over Attestors: Attestation Process<br/>(happens independently)
Attestors->>SC: Monitor Source Chain<br/>for Blocks
SC-->>Attestors: New Blocks Detected
Attestors->>Oracle: Submit Aggregated Attestation

Worker->>Oracle: Check if Block Attested
Oracle-->>Worker: Block Attested ✓

Note over Worker,BusinessLogic: Phase 3: Generate Proofs
Worker->>ProofAPI: Request Proofs<br/>(chainKey, blockHeight, txHash)

ProofAPI->>Oracle: Fetch Attestations
Oracle-->>ProofAPI: Attestation Data

ProofAPI->>SC: Fetch Source Chain Block
SC-->>ProofAPI: Block Data

ProofAPI->>ProofAPI: Generate Merkle & Continuity Proofs

ProofAPI-->>Worker: Return Proofs & Encoded TX

Note over Worker,BusinessLogic: Phase 4: Verify & Execute
Worker->>USC: Call processCrossChainData()<br/>(proofs + encoded tx)

USC->>Oracle: Verify Proofs<br/>(via precompile)
Oracle->>Oracle: Verify Merkle & Continuity Proofs
Oracle-->>USC: Verification Result: ✓ Valid

USC->>BusinessLogic: Execute Business Logic<br/>(e.g., mint tokens)
BusinessLogic->>BusinessLogic: Update State and Emit Event<br/>(e.g., TokensMinted)
BusinessLogic-->>USC: (optional return)

Oracle-->>User: Listens to Dapp events (optional)" %}
```

#### Worker Implementation Considerations

This has just been a starting point designed to introduce you to the use of Offchain Workers. Each DApp builder team will likely want to implement their Worker differently to fit the rest of their technology stack.

Keeping this in mind, the main goal of an Offchain Worker should always be robustness. This includes:

* **Retaining stored records of events in progress** in the event of a Worker shutdown
* **Catching up with any event that might have been missed** as a result of an unexpected shutdown
* **Avoiding submitting multiple USC calls for the same event** (replay protection is handled by the USC contract, but workers should also track processed events)
* **Following multiple source chain nodes** to listen for events in case a node experiences issues
* **Retrying failed proof generation or USC calls** in case they fail. A call can fail for many reasons: for example, the Proof Generation API server might be experiencing downtime or connectivity issues, or the USC contract call might fail due to network issues

Below is an example of the logical flow that a more advanced oracle worker might use

{% @mermaid/diagram content="---
config:
theme: neo
----------

stateDiagram
s1:Monitor source chain for events
state if\_events <<choice>>
s2:Event detected
s3:Wait for block attestation
state if\_attested <<choice>>
s4:Generate proofs via Proof Generation API
state if\_proof\_success <<choice>>
s5:Call USC contract with proofs
state if\_usc\_success <<choice>>
s6:USC verifies synchronously
s7:Business logic executed
s8:Success!
retryAttestation:Retry after delay
retryProof:Retry proof generation
retryUSC:Retry USC call

```
[*] --> s1
s1 --> if_events
if_events --> s2:Yes
if_events --> s1:No
s2 --> s3
s3 --> if_attested
if_attested --> s4:Block attested
if_attested --> retryAttestation:Not yet attested
retryAttestation --> s3
s4 --> if_proof_success
if_proof_success --> s5:Proofs generated
if_proof_success --> retryProof:API error/retry
retryProof --> s4
s5 --> if_usc_success
if_usc_success --> s6:Transaction submitted
if_usc_success --> retryUSC:Network error/retry
retryUSC --> s5
s6 --> s7
s7 --> s8
s8 --> [*]
```

" fullWidth="true" %}

## Next Steps

[usc-tutorials](https://docs.creditcoin.org/usc/dapp-builder-infrastructure/usc-tutorials "mention")

*Check out* [*this script*](https://github.com/gluwa/usc-testnet-bridge-examples/blob/main/bridge-offchain-worker/worker.ts) *for an example of an offchain worker.*
