Commit 0c54e60e authored by kf's avatar kf

feat(sdk): add approval fns to the SDK

parent 67a0414d
---
'@eth-optimism/sdk': patch
---
Add approval functions to the SDK
/* eslint-disable @typescript-eslint/no-unused-vars */
import { ethers, Overrides } from 'ethers'
import { ethers, Contract, Overrides, BigNumber } from 'ethers'
import { TransactionRequest, BlockTag } from '@ethersproject/abstract-provider'
import { predeploys } from '@eth-optimism/contracts'
import { predeploys, getContractInterface } from '@eth-optimism/contracts'
import { hexStringEquals } from '@eth-optimism/core-utils'
import {
......@@ -17,6 +17,14 @@ import { StandardBridgeAdapter } from './standard-bridge'
* Bridge adapter for the ETH bridge.
*/
export class ETHBridgeAdapter extends StandardBridgeAdapter {
public async approval(
l1Token: AddressLike,
l2Token: AddressLike,
signer: ethers.Signer
): Promise<BigNumber> {
throw new Error(`approval not necessary for ETH bridge`)
}
public async getDepositsByAddress(
address: AddressLike,
opts?: {
......@@ -104,6 +112,17 @@ export class ETHBridgeAdapter extends StandardBridgeAdapter {
}
populateTransaction = {
approve: async (
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
overrides?: Overrides
}
): Promise<TransactionRequest> => {
throw new Error(`approvals not necessary for ETH bridge`)
},
deposit: async (
l1Token: AddressLike,
l2Token: AddressLike,
......
......@@ -185,6 +185,38 @@ export class StandardBridgeAdapter implements IBridgeAdapter {
}
}
public async approval(
l1Token: AddressLike,
l2Token: AddressLike,
signer: ethers.Signer
): Promise<BigNumber> {
if (!(await this.supportsTokenPair(l1Token, l2Token))) {
throw new Error(`token pair not supported by bridge`)
}
const token = new Contract(
toAddress(l1Token),
getContractInterface('L2StandardERC20'), // Any ERC20 will do
this.messenger.l1Provider
)
return token.allowance(await signer.getAddress(), this.l1Bridge.address)
}
public async approve(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
signer: Signer,
opts?: {
overrides?: Overrides
}
): Promise<TransactionResponse> {
return signer.sendTransaction(
await this.populateTransaction.approve(l1Token, l2Token, amount, opts)
)
}
public async deposit(
l1Token: AddressLike,
l2Token: AddressLike,
......@@ -217,6 +249,31 @@ export class StandardBridgeAdapter implements IBridgeAdapter {
}
populateTransaction = {
approve: async (
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
overrides?: Overrides
}
): Promise<TransactionRequest> => {
if (!(await this.supportsTokenPair(l1Token, l2Token))) {
throw new Error(`token pair not supported by bridge`)
}
const token = new Contract(
toAddress(l1Token),
getContractInterface('L2StandardERC20'), // Any ERC20 will do
this.messenger.l1Provider
)
return token.populateTransaction.approve(
this.l1Bridge.address,
amount,
opts?.overrides || {}
)
},
deposit: async (
l1Token: AddressLike,
l2Token: AddressLike,
......@@ -288,6 +345,19 @@ export class StandardBridgeAdapter implements IBridgeAdapter {
}
estimateGas = {
approve: async (
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
overrides?: Overrides
}
): Promise<BigNumber> => {
return this.messenger.l1Provider.estimateGas(
await this.populateTransaction.approve(l1Token, l2Token, amount, opts)
)
},
deposit: async (
l1Token: AddressLike,
l2Token: AddressLike,
......
......@@ -109,7 +109,7 @@ export class CrossChainMessenger implements ICrossChainMessenger {
if (Provider.isProvider(this.l1SignerOrProvider)) {
return this.l1SignerOrProvider
} else {
return this.l1SignerOrProvider.provider
return this.l1SignerOrProvider.provider as any
}
}
......@@ -117,7 +117,7 @@ export class CrossChainMessenger implements ICrossChainMessenger {
if (Provider.isProvider(this.l2SignerOrProvider)) {
return this.l2SignerOrProvider
} else {
return this.l2SignerOrProvider.provider
return this.l2SignerOrProvider.provider as any
}
}
......@@ -844,6 +844,36 @@ export class CrossChainMessenger implements ICrossChainMessenger {
)
}
public async approval(
l1Token: AddressLike,
l2Token: AddressLike,
opts?: {
signer?: Signer
}
): Promise<BigNumber> {
const bridge = await this.getBridgeForTokenPair(l1Token, l2Token)
return bridge.approval(l1Token, l2Token, opts?.signer || this.l1Signer)
}
public async approveERC20(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
signer?: Signer
overrides?: Overrides
}
): Promise<TransactionResponse> {
return (opts?.signer || this.l1Signer).sendTransaction(
await this.populateTransaction.approveERC20(
l1Token,
l2Token,
amount,
opts
)
)
}
public async depositERC20(
l1Token: AddressLike,
l2Token: AddressLike,
......@@ -986,6 +1016,18 @@ export class CrossChainMessenger implements ICrossChainMessenger {
)
},
approveERC20: async (
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
overrides?: Overrides
}
): Promise<TransactionRequest> => {
const bridge = await this.getBridgeForTokenPair(l1Token, l2Token)
return bridge.populateTransaction.approve(l1Token, l2Token, amount, opts)
},
depositERC20: async (
l1Token: AddressLike,
l2Token: AddressLike,
......@@ -1082,6 +1124,24 @@ export class CrossChainMessenger implements ICrossChainMessenger {
)
},
approveERC20: async (
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
overrides?: Overrides
}
): Promise<BigNumber> => {
return this.l1Provider.estimateGas(
await this.populateTransaction.approveERC20(
l1Token,
l2Token,
amount,
opts
)
)
},
depositERC20: async (
l1Token: AddressLike,
l2Token: AddressLike,
......
......@@ -78,6 +78,41 @@ export interface IBridgeAdapter {
l2Token: AddressLike
): Promise<boolean>
/**
* Queries the account's approval amount for a given L1 token.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @param signer Signer to query the approval for.
* @returns Amount of tokens approved for deposits from the account.
*/
approval(
l1Token: AddressLike,
l2Token: AddressLike,
signer: Signer
): Promise<BigNumber>
/**
* Approves a deposit into the L2 chain.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @param amount Amount of the token to approve.
* @param signer Signer used to sign and send the transaction.
* @param opts Additional options.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the approval transaction.
*/
approve(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
signer: Signer,
opts?: {
overrides?: Overrides
}
): Promise<TransactionResponse>
/**
* Deposits some tokens into the L2 chain.
*
......@@ -131,6 +166,25 @@ export interface IBridgeAdapter {
* Follows the pattern used by ethers.js.
*/
populateTransaction: {
/**
* Generates a transaction for approving some tokens to deposit into the L2 chain.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @param amount Amount of the token to approve.
* @param opts Additional options.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction that can be signed and executed to deposit the tokens.
*/
approve(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
overrides?: Overrides
}
): Promise<TransactionRequest>
/**
* Generates a transaction for depositing some tokens into the L2 chain.
*
......@@ -181,6 +235,25 @@ export interface IBridgeAdapter {
* Follows the pattern used by ethers.js.
*/
estimateGas: {
/**
* Estimates gas required to approve some tokens to deposit into the L2 chain.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @param amount Amount of the token to approve.
* @param opts Additional options.
* @param opts.overrides Optional transaction overrides.
* @returns Gas estimate for the transaction.
*/
approve(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
overrides?: Overrides
}
): Promise<BigNumber>
/**
* Estimates gas required to deposit some tokens into the L2 chain.
*
......
......@@ -411,6 +411,44 @@ export interface ICrossChainMessenger {
}
): Promise<TransactionResponse>
/**
* Queries the account's approval amount for a given L1 token.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @param opts Additional options.
* @param opts.signer Optional signer to get the approval for.
* @returns Amount of tokens approved for deposits from the account.
*/
approval(
l1Token: AddressLike,
l2Token: AddressLike,
opts?: {
signer?: Signer
}
): Promise<BigNumber>
/**
* Approves a deposit into the L2 chain.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @param amount Amount of the token to approve.
* @param opts Additional options.
* @param opts.signer Optional signer to use to send the transaction.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the approval transaction.
*/
approveERC20(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
signer?: Signer
overrides?: Overrides
}
): Promise<TransactionResponse>
/**
* Deposits some ERC20 tokens into the L2 chain.
*
......@@ -517,6 +555,25 @@ export interface ICrossChainMessenger {
}
): Promise<TransactionRequest>
/**
* Generates a transaction for approving some tokens to deposit into the L2 chain.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @param amount Amount of the token to approve.
* @param opts Additional options.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the approval transaction.
*/
approveERC20(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
overrides?: Overrides
}
): Promise<TransactionRequest>
/**
* Generates a transaction for depositing some ETH into the L2 chain.
*
......@@ -652,6 +709,25 @@ export interface ICrossChainMessenger {
}
): Promise<BigNumber>
/**
* Estimates gas required to approve some tokens to deposit into the L2 chain.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @param amount Amount of the token to approve.
* @param opts Additional options.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the approval transaction.
*/
approveERC20(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
overrides?: Overrides
}
): Promise<BigNumber>
/**
* Estimates gas required to deposit some ETH into the L2 chain.
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment