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 }