github.com/ethereum-optimism/optimism@v1.7.2/packages/core-utils/src/optimism/op-provider.ts (about)

     1  import EventEmitter from 'events'
     2  
     3  import { BigNumber } from '@ethersproject/bignumber'
     4  import { deepCopy } from '@ethersproject/properties'
     5  import { ConnectionInfo, fetchJson } from '@ethersproject/web'
     6  
     7  const getResult = (payload: {
     8    error?: { code?: number; data?: any; message?: string }
     9    result?: any
    10  }): any => {
    11    if (payload.error) {
    12      const error: any = new Error(payload.error.message)
    13      error.code = payload.error.code
    14      error.data = payload.error.data
    15      throw error
    16    }
    17    return payload.result
    18  }
    19  
    20  export interface BlockDescriptor {
    21    hash: string
    22    number: BigNumber
    23    parentHash: string
    24    timestamp: BigNumber
    25  }
    26  
    27  export interface L2BlockDescriptor extends BlockDescriptor {
    28    l1Origin: {
    29      hash: string
    30      number: BigNumber
    31    }
    32    sequencerNumber: BigNumber
    33  }
    34  
    35  export interface SyncStatusResponse {
    36    currentL1: BlockDescriptor
    37    headL1: BlockDescriptor
    38    unsafeL2: L2BlockDescriptor
    39    safeL2: L2BlockDescriptor
    40    finalizedL2: L2BlockDescriptor
    41  }
    42  
    43  export class OpNodeProvider extends EventEmitter {
    44    readonly connection: ConnectionInfo
    45    private _nextId: number = 0
    46  
    47    constructor(url?: ConnectionInfo | string) {
    48      super()
    49  
    50      if (typeof url === 'string') {
    51        this.connection = { url }
    52      } else {
    53        this.connection = url
    54      }
    55    }
    56  
    57    async syncStatus(): Promise<SyncStatusResponse> {
    58      const result = await this.send('optimism_syncStatus', [])
    59  
    60      return {
    61        currentL1: {
    62          hash: result.current_l1.hash,
    63          number: BigNumber.from(result.current_l1.number),
    64          parentHash: result.current_l1.parentHash,
    65          timestamp: BigNumber.from(result.current_l1.timestamp),
    66        },
    67        headL1: {
    68          hash: result.head_l1.hash,
    69          number: BigNumber.from(result.head_l1.number),
    70          parentHash: result.head_l1.parentHash,
    71          timestamp: BigNumber.from(result.head_l1.timestamp),
    72        },
    73        unsafeL2: {
    74          hash: result.unsafe_l2.hash,
    75          number: BigNumber.from(result.unsafe_l2.number),
    76          parentHash: result.unsafe_l2.parentHash,
    77          timestamp: BigNumber.from(result.unsafe_l2.timestamp),
    78          l1Origin: {
    79            hash: result.unsafe_l2.l1origin.hash,
    80            number: BigNumber.from(result.unsafe_l2.l1origin.number),
    81          },
    82          sequencerNumber: BigNumber.from(result.unsafe_l2.sequenceNumber),
    83        },
    84        safeL2: {
    85          hash: result.safe_l2.hash,
    86          number: BigNumber.from(result.safe_l2.number),
    87          parentHash: result.safe_l2.parentHash,
    88          timestamp: BigNumber.from(result.safe_l2.timestamp),
    89          l1Origin: {
    90            hash: result.safe_l2.l1origin.hash,
    91            number: BigNumber.from(result.safe_l2.l1origin.number),
    92          },
    93          sequencerNumber: BigNumber.from(result.safe_l2.sequenceNumber),
    94        },
    95        finalizedL2: {
    96          hash: result.finalized_l2.hash,
    97          number: BigNumber.from(result.finalized_l2.number),
    98          parentHash: result.finalized_l2.parentHash,
    99          timestamp: BigNumber.from(result.finalized_l2.timestamp),
   100          l1Origin: {
   101            hash: result.finalized_l2.l1origin.hash,
   102            number: BigNumber.from(result.finalized_l2.l1origin.number),
   103          },
   104          sequencerNumber: BigNumber.from(result.finalized_l2.sequenceNumber),
   105        },
   106      }
   107    }
   108  
   109    // TODO(tynes): turn the response into a stronger type
   110    async rollupConfig() {
   111      const result = await this.send('optimism_rollupConfig', [])
   112      return result
   113    }
   114  
   115    send(method: string, params: Array<any>): Promise<any> {
   116      const request = {
   117        method,
   118        params,
   119        id: this._nextId++,
   120        jsonrpc: '2.0',
   121      }
   122  
   123      this.emit('debug', {
   124        action: 'request',
   125        request: deepCopy(request),
   126        provider: this,
   127      })
   128  
   129      const result = fetchJson(
   130        this.connection,
   131        JSON.stringify(request),
   132        getResult
   133      ).then(
   134        (res) => {
   135          this.emit('debug', {
   136            action: 'response',
   137            request,
   138            response: res,
   139            provider: this,
   140          })
   141  
   142          return res
   143        },
   144        (error) => {
   145          this.emit('debug', {
   146            action: 'response',
   147            error,
   148            request,
   149            provider: this,
   150          })
   151  
   152          throw error
   153        }
   154      )
   155  
   156      return result
   157    }
   158  }