Skip to main content

Ethereum

Reference

Ethereum (TypeDoc)

Initializing the Ethereum class requires:

  1. a network - either a Ren network ("mainnet", "testnet" or "devnet"), or a EVMmNetworkConfig.
  2. a provider - either an ethers provider, a Web3 provider or a string.
  3. an optional signer - an ethers signer. If no signer is provided, the provider's signer will be used if available, or it can be provided later with .withSigner.

Examples of initializing:

MetaMask or other web3 browser

After calling eth_requestAccounts, you can then pass window.ethereum directly to the Ethereum class:

await window.ethereum.request({ method: "eth_requestAccounts" });

new Ethereum({
network: "testnet",
provider: window.ethereum,
});

If you are using TypeScript, you can add this anywhere in your code to avoid getting an type error when accessing window.ethereum.

declare global {
interface Window {
ethereum: any;
}
}

Because the Ethereum constructor is synchronous, it won't immediately check that the provider is connected to the right network. In a front-end dApp, you should check the network by doing:

const { chainId } = await provider.getNetwork();
if (chainId !== parseInt(ethereum.network.network.chainId)) {
throw new Error(
`Wrong network - please change to ${ethereum.network.network.chainName}`
);
}
Public endpoint with MetaMask signer
new Ethereum({
network: "mainnet",
provider: "https://cloudflare-eth.com",
});

await window.ethereum.request({ method: "eth_requestAccounts" });
const web3Provider = new ethers.providers.Web3Provider(
(window as any).ethereum
);
chain.withSigner(web3Provider.getSigner());
Public endpoint with private key signer
import { Wallet } from "ethers";

new Ethereum({
network: "mainnet",
provider: "https://cloudflare-eth.com",
signer: Wallet.fromMnemonic(
"apple bank cargo ...",
);
});

Payloads

The available input payloads are:

Account
ethereum.Account allows you to specify the user's connected address as the origin of assets to be burnt or locked.
renJS.gateway({
asset: "BTC",
from: ethereum.Account({ amount: "0.1", convertUnit: true }),
...
})

Required parameters:

  • amount - the asset amount to lock or burn

Optional parameters:

  • convertUnit - convert the amount to the chain's smallest unit.
  • account - specify the account that the user should have connected when they submit.

You can specify a specific account by providing an account field in the options - this account should be connected when the user is prompted to submit the transaction.

Transaction
ethereum.Transaction allows you to specify a specific Ethereum transaction, instead of watching for deposits to the gateway address. Note that the recipient address of the transaction should still match the gateway address generated from the to-chain's parameters.

The transaction should be of type Partial<ChainTransaction>, with at least one of the txid or txidFormatted is defined.

renJS.gateway({
asset: "BTC",
from: ethereum.Transaction({
// The transaction's hash in the usual Ethereum hex encoding.
txidFormatted: "0xa1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d",
// The transaction's hash in URL-base64 encoding.
txid: "oQddtV1BbTyhmfVbYITiEVuTReFsXPMC_IDp1fv11I0",
}),
...
})
Contract
ethereum.Contract allows you to specify a call to a contract as the input transaction. The contract call should make a call to `burn` or `lock` on a Ren Gateway contract.
renJS.gateway({
asset: "BTC",
from: ethereum.Contract({
to: "0x1234",
method: "testBurnFunction",
withRenParams: false,
params: {
{
name: "message",
type: "string",
value: "Hello world.",
},
},
}),
...
})

withRenParams should be false for inputs - see the output Contract payload for details.

The available output payloads are:

Account
ethereum.Account allows you to specify the user's account as the recipient of the minted or released funds.
renJS.gateway({
asset: "BTC",
...
to: ethereum.Account(),
})

Optional parameters:

  • account - specify the account that the user should have connected when they submit.
  • anyoneCanSubmit - by default, only the specified account can submit the output transaction. Set anyoneCanSubmit to true to allow anyone to submit the transaction for the user.
Address
ethereum.Address allows you to specify an Ethereum address for receiving the minted/released funds.
renJS.gateway({
asset: "BTC",
...
to: ethereum.Address("0x1234..."),
})
Contract
ethereum.Contract allows you to specify a call to a contract as the output transaction. The contract call should make a call to `mint` or `release` on a Ren Gateway contract.
renJS.gateway({
asset: "BTC",
from: ethereum.Contract({
to: "0x1234...",
method: "testMintFunction",
withRenParams: true,
params: {
{
name: "message",
type: "string",
value: "Hello world.",
},
},
}),
...
})

withRenParams should be set to true if the contract function expected the Ren params amount, nHash and signature as its last three parameters.

It adds the following three parameters to the contract call:

Ren Params
{
name: "amount",
type: "uint256",
value: EVMParam.EVM_AMOUNT,
notInPayload: true,
renParam: true,
},
{
name: "nHash",
type: "bytes32",
value: EVMParam.EVM_NHASH,
notInPayload: true,
renParam: true,
},
{
name: "signature",
type: "bytes",
value: EVMParam.EVM_SIGNATURE,
notInPayload: true,
renParam: true,
},

See EVMParam below.

TxConfig

When calling .submit() for an EVM transaction, you can provide an optional txConfig parameter of type ethers.PayableOverrides from the ethers.js library.

gateway.in.submit({
txConfig: {
gasLimit: 1000000,
gasPrice: 21e9, // 21 GWEI
nonce: 12,
},
});

EVMParam

When specifying a Contract payload, you may provide a EVMParam instead of a value for parameters. These will get replaced by the EVMParam's associated logic once available.

EVMParam

EMVParam

EVM_INPUT_TYPE - whether the input is a "lock" or a "burn"

EVM_OUTPUT_TYPE - whether the output is a "mint" or a "release"

EVM_TRANSACTION_TYPE - whether the transaction is a "setup", "mint", "burn", "lock" or "release

EVM_TOKEN_ADDRESS - the address of the token being transferred - either the ren-asset or the lock-asset

EVM_TOKEN_DECIMALS - the decimals of the token

EVM_GATEWAY_IS_DEPOSIT_ASSET - whether the funds need to be transferred to a gateway address using TransferWithLog

EVM_GATEWAY_DEPOSIT_ADDRESS - the gateway address for native assets (e.g. ETH)

EVM_TRANSFER_WITH_LOG_CONTRACT - the address of the TransferWithLog contract

EVM_ACCOUNT - the connected account

EVM_ACCOUNT_IS_CONTRACT - whether the account has code deployed to it

EVM_GATEWAY - the address of the relevant gateway

EVM_ASSET - the asset being transacted

EVM_AMOUNT - the amount signed by RenVM (mints and releases)

EVM_NHASH - the RenVM transaction's nHash

EVM_PHASH - the RenVM transaction's pHash

EVM_SIGNATURE - the signature generated by RenVM (mints and releases)

EVM_SIGNATURE_R - the `r` component of the signature

EVM_SIGNATURE_S - the `s` component of the signature

EVM_SIGNATURE_V - the `v` component of the signature

EVM_TO_CHAIN - the target chain

EVM_TO_ADDRESS - the target recipient

EVM_TO_ADDRESS_BYTES - the target recipient, decoded into bytes

EVM_TO_PAYLOAD - the target paylaod

Things to note

  • Locking ERC20s requires an approval transaction before calling gateway.in. See Setup Transactions.

Migrating from Kovan to Görli

The Kovan Ethereum testnet is in the process of being shut down. The RenJS tutorial has been updated to use Görli and any existing integrations that have been deployed on Kovan need to migrate to Görli as well. After redeploying any required contracts on Görli, you can update RenJS to point to Görli by:

  1. Initializing Ethereum with the defaultTestnet parameter set to "goerli":
const ethereum = new Ethereum({ network: RenNetwork, provider: ..., defaultTestnet: "goerli" })

or by switching to the Goerli class:

const goerli = new Goerli({ network: RenNetwork, provider: ... })
  1. When bridging Ethereum assets on testnet, specify Görli assets instead of Ethereum assets. For DAI, this can be done as "DAI_Goerli", Ethereum.assets.DAI_Goerli or Goerli.assets.DAI.
const gateway = await renJS.gateway({
asset: Goerli.assets.DAI,
from: ethereum.Account(),
to: bsc.Account(),
});

If you are accessing Ethereum.configMap you may need to use Goerli.configMap instead for testnet.

While integrations are being migrated, Kovan will continue to be the default testnet in RenJS, which means that you may need additional logic to write an integration that seamlessly switched between Ethereum on mainnet and Görli on testnet.

Other chains

A list of other chains that implement this same interface are: