plugin.spec.ts 10.8 KB
Newer Older
Wyatt Barnes's avatar
Wyatt Barnes committed
1
import { beforeAll, describe, expect, test } from 'vitest'
2
import { z } from 'zod'
Wyatt Barnes's avatar
Wyatt Barnes committed
3 4 5 6 7 8 9 10
import Web3, { Contract, FMT_BYTES, FMT_NUMBER } from 'web3'
import {
  l2StandardBridgeABI,
  l2StandardBridgeAddress,
  optimistABI,
  optimistAddress,
} from '@eth-optimism/contracts-ts'

11
import { OptimismPlugin } from './plugin'
Wyatt Barnes's avatar
Wyatt Barnes committed
12

13
const defaultProvider = 'https://mainnet.optimism.io'
14 15 16 17 18 19 20 21 22
const provider = z
  .string()
  .url()
  .default(defaultProvider)
  .parse(process.env['VITE_L2_RPC_URL'])
if (provider === defaultProvider)
  console.warn(
    'Warning: Using default public provider, this could cause tests to fail due to rate limits. Set the VITE_L2_RPC_URL env to override default provider'
  )
Wyatt Barnes's avatar
Wyatt Barnes committed
23

24
describe('OptimismPlugin', () => {
Wyatt Barnes's avatar
Wyatt Barnes committed
25 26 27 28
  let web3: Web3

  beforeAll(() => {
    web3 = new Web3(provider)
29
    web3.registerPlugin(new OptimismPlugin())
Wyatt Barnes's avatar
Wyatt Barnes committed
30 31 32
  })

  test('should be registered under .op namespace', () =>
33
    expect(web3.op).toMatchInlineSnapshot(`
34
      OptimismPlugin {
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
        "_accountProvider": {
          "create": [Function],
          "decrypt": [Function],
          "encrypt": [Function],
          "hashMessage": [Function],
          "privateKeyToAccount": [Function],
          "recover": [Function],
          "recoverTransaction": [Function],
          "sign": [Function],
          "signTransaction": [Function],
          "wallet": Wallet [],
        },
        "_emitter": EventEmitter {
          "_events": {},
          "_eventsCount": 0,
          "_maxListeners": undefined,
          Symbol(kCapture): false,
        },
        "_gasPriceOracleContract": undefined,
        "_requestManager": Web3RequestManager {
          "_emitter": EventEmitter {
            "_events": {
              "BEFORE_PROVIDER_CHANGE": [Function],
              "PROVIDER_CHANGED": [Function],
            },
            "_eventsCount": 2,
            "_maxListeners": undefined,
            Symbol(kCapture): false,
          },
          "_provider": HttpProvider {
65
            "clientUrl": "https://opt-mainnet.g.alchemy.com/v2/OVlbpe9COlhG-ijOXGvL_phb5ns6p9-w",
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
            "httpProviderOptions": undefined,
          },
          "useRpcCallSpecification": undefined,
        },
        "_subscriptionManager": Web3SubscriptionManager {
          "_subscriptions": Map {},
          "registeredSubscriptions": {
            "logs": [Function],
            "newBlockHeaders": [Function],
            "newHeads": [Function],
            "newPendingTransactions": [Function],
            "pendingTransactions": [Function],
            "syncing": [Function],
          },
          "requestManager": Web3RequestManager {
            "_emitter": EventEmitter {
              "_events": {
                "BEFORE_PROVIDER_CHANGE": [Function],
                "PROVIDER_CHANGED": [Function],
              },
              "_eventsCount": 2,
              "_maxListeners": undefined,
              Symbol(kCapture): false,
            },
            "_provider": HttpProvider {
91
              "clientUrl": "https://opt-mainnet.g.alchemy.com/v2/OVlbpe9COlhG-ijOXGvL_phb5ns6p9-w",
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
              "httpProviderOptions": undefined,
            },
            "useRpcCallSpecification": undefined,
          },
          "tolerateUnlinkedSubscription": false,
        },
        "_wallet": Wallet [],
        "config": {
          "blockHeaderTimeout": 10,
          "defaultAccount": undefined,
          "defaultBlock": "latest",
          "defaultChain": "mainnet",
          "defaultCommon": undefined,
          "defaultHardfork": "london",
          "defaultMaxPriorityFeePerGas": "0x9502f900",
          "defaultNetworkId": undefined,
          "defaultTransactionType": "0x0",
          "enableExperimentalFeatures": {
            "useRpcCallSpecification": false,
            "useSubscriptionWhenCheckingBlockTimeout": false,
          },
          "handleRevert": false,
          "maxListenersWarningThreshold": 100,
          "transactionBlockTimeout": 50,
          "transactionBuilder": undefined,
          "transactionConfirmationBlocks": 24,
          "transactionConfirmationPollingInterval": undefined,
          "transactionPollingInterval": 1000,
          "transactionPollingTimeout": 750000,
          "transactionReceiptPollingInterval": undefined,
          "transactionSendTimeout": 750000,
          "transactionTypeParser": undefined,
        },
        "pluginNamespace": "op",
        "providers": {
          "HttpProvider": [Function],
          "WebsocketProvider": [Function],
        },
      }
    `))
Wyatt Barnes's avatar
Wyatt Barnes committed
132 133 134

  describe('should return a bigint by default', () => {
    test('getBaseFee', async () =>
135
      expect(await web3.op.getBaseFee()).toBeTypeOf('bigint'))
Wyatt Barnes's avatar
Wyatt Barnes committed
136 137 138 139 140

    test('getDecimals should return 6n', async () =>
      expect(await web3.op.getDecimals()).toBe(BigInt(6)))

    test('getGasPrice', async () =>
141
      expect(await web3.op.getGasPrice()).toBeTypeOf('bigint'))
Wyatt Barnes's avatar
Wyatt Barnes committed
142 143

    test('getL1BaseFee', async () =>
144
      expect(await web3.op.getL1BaseFee()).toBeTypeOf('bigint'))
Wyatt Barnes's avatar
Wyatt Barnes committed
145 146 147 148 149 150 151 152 153 154 155 156

    test('getOverhead should return 188n', async () =>
      expect(await web3.op.getOverhead()).toBe(BigInt(188)))

    test('getScalar should return 684000n', async () =>
      expect(await web3.op.getScalar()).toBe(BigInt(684000)))
  })

  describe('should return a number', () => {
    const numberFormat = { number: FMT_NUMBER.NUMBER, bytes: FMT_BYTES.HEX }

    test('getBaseFee', async () =>
157
      expect(await web3.op.getBaseFee(numberFormat)).toBeTypeOf('number'))
Wyatt Barnes's avatar
Wyatt Barnes committed
158 159 160 161 162

    test('getDecimals should return 6', async () =>
      expect(await web3.op.getDecimals(numberFormat)).toBe(6))

    test('getGasPrice', async () =>
163
      expect(await web3.op.getGasPrice(numberFormat)).toBeTypeOf('number'))
Wyatt Barnes's avatar
Wyatt Barnes committed
164 165

    test('getL1BaseFee', async () =>
166
      expect(await web3.op.getL1BaseFee(numberFormat)).toBeTypeOf('number'))
Wyatt Barnes's avatar
Wyatt Barnes committed
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191

    test('getOverhead should return 188', async () =>
      expect(await web3.op.getOverhead(numberFormat)).toBe(188))

    test('getScalar should return 684000', async () =>
      expect(await web3.op.getScalar(numberFormat)).toBe(684000))
  })

  test('getVersion should return the string 1.0.0', async () =>
    expect(await web3.op.getVersion()).toBe('1.0.0'))

  describe('Contract transaction gas estimates - optimistABI.burn', () => {
    let optimistContract: Contract<typeof optimistABI>
    let encodedBurnMethod: string

    beforeAll(() => {
      optimistContract = new web3.eth.Contract(optimistABI)
      encodedBurnMethod = optimistContract.methods
        .burn('0x77194aa25a06f932c10c0f25090f3046af2c85a6')
        .encodeABI()
    })

    describe('should return a bigint by default', () => {
      test('getL1Fee', async () => {
        expect(
192
          await web3.op.getL1Fee({
Wyatt Barnes's avatar
Wyatt Barnes committed
193 194 195
            chainId: '0xa',
            data: encodedBurnMethod,
            type: '0x2',
196
          })
197
        ).toBeTypeOf('bigint')
Wyatt Barnes's avatar
Wyatt Barnes committed
198 199 200 201 202 203 204 205 206 207 208 209 210
      })

      test('getL1GasUsed should return 1884n', async () =>
        expect(
          await web3.op.getL1GasUsed({
            chainId: '0xa',
            data: encodedBurnMethod,
            type: '0x2',
          })
        ).toBe(BigInt(1884)))

      test('estimateFees', async () =>
        expect(
211
          await web3.op.estimateFees({
Wyatt Barnes's avatar
Wyatt Barnes committed
212 213 214 215 216
            chainId: 10,
            data: encodedBurnMethod,
            type: 2,
            to: optimistAddress[10],
            from: '0x77194aa25a06f932c10c0f25090f3046af2c85a6',
217 218
          })
        ).toBeTypeOf('bigint'))
Wyatt Barnes's avatar
Wyatt Barnes committed
219 220 221

      test('getL2Fee', async () => {
        expect(
222
          await web3.op.getL2Fee({
Wyatt Barnes's avatar
Wyatt Barnes committed
223 224 225 226 227
            chainId: '0xa',
            data: encodedBurnMethod,
            type: '0x2',
            to: optimistAddress[10],
            from: '0x77194aa25a06f932c10c0f25090f3046af2c85a6',
228 229
          })
        ).toBeTypeOf('bigint')
Wyatt Barnes's avatar
Wyatt Barnes committed
230 231 232 233
      })

      test('estimateFees', async () =>
        expect(
234
          await web3.op.estimateFees(
Wyatt Barnes's avatar
Wyatt Barnes committed
235 236 237 238 239 240
            {
              chainId: 10,
              data: encodedBurnMethod,
              type: 2,
              to: optimistAddress[10],
              from: '0x77194aa25a06f932c10c0f25090f3046af2c85a6',
241
            }
242 243
          )
        ).toBeTypeOf('bigint'))
Wyatt Barnes's avatar
Wyatt Barnes committed
244 245 246 247 248 249 250
    })

    describe('should return a hexString', () => {
      const hexStringFormat = { number: FMT_NUMBER.HEX, bytes: FMT_BYTES.HEX }

      test('getL1Fee', async () => {
        expect(
251
          await web3.op.getL1Fee(
Wyatt Barnes's avatar
Wyatt Barnes committed
252 253 254 255 256 257
            {
              chainId: '0xa',
              data: encodedBurnMethod,
              type: '0x2',
            },
            hexStringFormat
258 259
          )
        ).toBeTypeOf('string')
Wyatt Barnes's avatar
Wyatt Barnes committed
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
      })

      test('getL1GasUsed should return 0x75c', async () =>
        expect(
          await web3.op.getL1GasUsed(
            {
              chainId: '0xa',
              data: encodedBurnMethod,
              type: '0x2',
            },
            hexStringFormat
          )
        ).toBe('0x75c'))

      test('estimateFees', async () =>
        expect(
276
          await web3.op.estimateFees(
Wyatt Barnes's avatar
Wyatt Barnes committed
277 278 279 280 281 282 283
            {
              chainId: 10,
              data: encodedBurnMethod,
              type: 2,
              to: optimistAddress[10],
              from: '0x77194aa25a06f932c10c0f25090f3046af2c85a6',
            },
284
            hexStringFormat
285 286
          )
        ).toBeTypeOf('string'))
Wyatt Barnes's avatar
Wyatt Barnes committed
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
    })
  })

  describe('Contract transaction gas estimates - l2StandardBridgeABI.withdraw', () => {
    let l2BridgeContract: Contract<typeof l2StandardBridgeABI>
    let encodedWithdrawMethod: string

    beforeAll(() => {
      l2BridgeContract = new Contract(
        l2StandardBridgeABI,
        l2StandardBridgeAddress[420]
      )
      encodedWithdrawMethod = l2BridgeContract.methods
        .withdraw(
          // l2 token address
          '0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000',
          // amount
          Web3.utils.toWei('0.00000001', 'ether'),
          // l1 gas
          0,
          // extra data
          '0x00'
        )
        .encodeABI()
    })

    describe('should return a bigint by default', () => {
      test('getL1Fee', async () => {
        expect(
316
          await web3.op.getL1Fee({
Wyatt Barnes's avatar
Wyatt Barnes committed
317 318 319
            chainId: '0xa',
            data: encodedWithdrawMethod,
            type: '0x2',
320 321
          })
        ).toBeTypeOf('bigint')
Wyatt Barnes's avatar
Wyatt Barnes committed
322 323 324 325 326 327 328 329 330 331 332 333 334
      })

      test('getL1GasUsed should return 2592n', async () =>
        expect(
          await web3.op.getL1GasUsed({
            chainId: '0xa',
            data: encodedWithdrawMethod,
            type: '0x2',
          })
        ).toBe(BigInt(2592)))

      test('estimateFees', async () =>
        expect(
335
          await web3.op.estimateFees({
Wyatt Barnes's avatar
Wyatt Barnes committed
336 337 338 339 340 341 342 343
            chainId: 10,
            data: encodedWithdrawMethod,
            value: Web3.utils.toWei('0.00000001', 'ether'),
            type: 2,
            to: l2StandardBridgeAddress[420],
            from: '0x6387a88a199120aD52Dd9742C7430847d3cB2CD4',
            maxFeePerGas: Web3.utils.toWei('0.2', 'gwei'),
            maxPriorityFeePerGas: Web3.utils.toWei('0.1', 'gwei'),
344 345
          })
        ).toBeTypeOf('bigint'))
Wyatt Barnes's avatar
Wyatt Barnes committed
346 347 348
    })
  })
})