-
Notifications
You must be signed in to change notification settings - Fork 138
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ethereum wallet & transaction support #498
Comments
Having Metamask users will be a huge help in user acquisition. |
To compare this with Snaps: this offers not just Metamask support but all possible Ethereum wallets and existing tooling that can work with Ethereum transactions. Specifying more and splitting into actionable items: NEP 1: Ethereum address implicit accountsEthereum addresses of 0x[\w\d]32 are extremely popular way people have accounts on-chain. This proposal is to add support for such addresses as extension of existing implicit accounts. Implicit accounts are accounts that have inferable key from the address. In the case of Ethereum address, the key can be verified ( Special rule will be added that if account matches Ethereum address, it can be accessed by the respective key even if it's not explicitly added on-chain into KEYS. Flow:
NEP 2 Ethereum transaction format for Meta TransactionEthereum transaction format is a very popular format supported by many wallets. It's also a very generic format, that supports a way to introduce any arbitrary data. The proposal is to add support for Meta Transactions to include signed Ethereum transaction messages as an alternative to When meta transaction is being processed, if the internal format matches Ethereum transaction - a different processing to unpack is applied. The Ethereum transaction format (encoded in RLP) that will be acceptable:
Ethereum JSON RPC RelayerRelayer provides Ethereum endpoints that wrap NEAR's RPC for NEAR state and smart contracts. Not all RPC end points are going to be supported, only ones required for work of Ethereum wallets. Relayer also receives Ethereum formatted transactions and sends them on-chain as meta transactions. List of supported endpoints:
The idea that NEAR fees initially will be paid by relayer, but to make this sustainable, there should be a way to pay back from relaid account. For example user can be paying with stablecoin or in some other way to reduce need to have $NEAR token initially. To implement that Wallet Selector must attach respective Action to transfer to relayer account a fee amount in desired currency. Relayer would then on Initially, this can be omitted, but design should include this to ensure anyone can run a relayer. Wallet Selector extensionWallet Selector adding support for Ethereum wallets and provide a way to inject the Relayer API to relay transaction. Work similar to near/wallet-selector#773 must be implemented to add directly Metamask and other popular wallets or WalletConnect. Implementing |
Hmm how does the conversion between two formats actually work? Ethereum transactions are serialized in RLP and on chain we need to check that the signature is valid, so some RLP encoding/decoding will need to happen when we process those transactions. |
The Ethereum transaction is encoded in RLP and stored into |
Thanks for starting this discussion @ilblackdragon . Enabling Metamask to be used directly with Near apps is an appealing way to onboard existing web3 users from EVM-compatible chains. The Protocol Working Group met today and we discussed this issue. We are thinking about ways we can have the desired user journey while minimizing the protocol changes needed. One idea is to use a contract to handle the RLP encoded transaction instead of making the protocol aware of RLP. The deployment of this contract to an Ethereum address-like Near account could be done automatically by the Relayer, and this could even be free by combining zero balance accounts with the shared contracts feature (the latter is not yet implemented though). Another issue raised concerned the design of using the data field of a normal Ethereum transaction to store the Near function call arguments (Borsh-encoded). This design could make it difficult for Metamask users to verify the contents of the transaction they are signing, which may create opportunities for phishing attacks. The trouble is that Borsh is not an Ethereum ecosystem standard so wallets will not know how to display the transaction data in a human-readable way. An alternative design is to leverage EIP-712 and provide a schema for Near transactions so that Metamask could display the transaction data clearly; similar to how Near wallets would display the transaction details. I think that using EIP-712 is technically different from submitting a normal Ethereum transaction, so the user flow might not be exactly as described in the initial post for this issue. But it should be possible to create a reasonably seamless UX by filling in the gaps on the tooling side (which was already a part of the proposal here with the Wallet Selector extension). What do you think about these ideas @ilblackdragon ? |
I love this proposal, regardless of how we implement it. @birchmd I think EIP-712 has some benefits and some drawbacks vs the Ethereum TX signing flow, given the complications I'll point out below. The main downsides are:
Some points to figure out if we use the TX signing flow instead of the Typed Data flow: Ethereum JSON-RPC CompatibilityWe'll have to audit MetaMask and maybe a few other popular wallets to see what JSON-RPC methods they call during the transaction preview, sign, send, and monitoring steps. I think we'll have to add a few to the Ethereum JSON-RPC shim, such as:
In addition, we'll have to add sufficient RPC calls to ensure the main Metamask UI shows reasonable values and doesn't crash during the course of normal operation. For instance, we'll probably need an implementation of Post-broadcast monitoring might be a challenge. I'm not sure if Metamask pings GasUsing
So I think those values should reflect what the fees that the relayer is going to charge the user, which is initially 0. In other words If that fails some validation within Metamask (b/c 0-fee transactions are unusual), we could fake it out by having a very small |
@ewiner Re. gas: while it is true that gas is set on different levels, it is possible to calculate on the transaction level how much gas a NEAR transaction attaches overall. In addition, it is fairly uncommon for a user to have multiple function calls in one transaction since they have to call the same smart contract. As far as I know, that feature today is mostly used by large application like SweatCoin to batch many user transactions together. The balance check you mentioned is also similar to how a transaction is checked on NEAR, so I think it could work fine if gas limit and gas price are set to the NEAR transaction gas limit and NEAR gas price. I am not sure how |
Thanks for the comment @ewiner ! I agree EIP-712 has pros and cons. Another option to make it easier for users to decode the data in the transactions they sign would be to make a tool that converts Near contract ABIs into Solidity ABIs and have the front-ends encode the data in the common Ethereum way. Then this Solidity ABI encoded data could be automatically decoded into JSON (or Borsh) data when the Ethereum transaction is converted into a Near contract call (this could be done as part of the same contract that handles the RLP decoding). The downside to this approach would be a requirement on contract developers to publish an ABI for their contracts if they wanted it to work with Ethereum-compatible wallets. @bowenwang1996 the This padding is an issue because it would mean 1M yoctoNEAR is the smallest quantity that can be attached to such calls, but there are standards in the Near ecosystem that require exactly 1 yoctoNEAR attached (e.g. NEP-141 fungible tokens). One work around for this issue would be to assume that 1 WEI maps to 1 yoctoNear and values greater than 1 have the zeros padded, but that feels pretty hacky. I'm open to other suggestions about how to address this issue! |
I have a small suggestion to for the "NEP 1: Ethereum address implicit accounts". Let's use the cc @staffik |
The challenge with using |
In the interest of pushing this project forward, I am proposing a more detailed specification below. It is still not 100% complete, but does fill in more details than previous posts on this issue. This spec is based on the suggestions of @ilblackdragon above, but with a few key modifications.
SpecificationSummary of protocol changes20-byte addresses as implicit accounts on NearAccount Ids matching the regex If there is a Near transaction where the sender is of the form '0x' + keccak256(pub_key)[12:32].hex() == account_id If this check passes then This means that future transactions for that account will be able to be checked following the usual Near procedure of checking the public key is added to the account. RLP-encoded transactions as actions on NearA new variant is added to the struct RlpTransactionAction {
payload: Vec<u8>,
} The gas cost of converting a transaction including an This kind of action has the following validity rules:
When a receipt containing valid To prevent replaying transactions, the nonce of the access key corresponding to the public key which hashes to the address for the account will also be updated to the largest nonce present in any of the Ethereum transactions in the Note: unless a new host function is added to the Wasm runtime, it will not be possible to create Note: The Ethereum RPC relayer serviceThis is separate from the Near protocol, but is needed for Metamask to have something to connect to. This is a service exposing (a minimal subset of) the Ethereum JSON RPC interface at some URL. This URL is included by users in a custom network added to Metamask. The service requires a Near account to operate because it will be submitting transactions to the network on behalf of Metamask users. What follows is a brief description of how to implement the core RPC methods.
Note: A drawback of using the Near transaction hash as the hash returned by |
@birchmd I have a couple of concerns regarding this change:
|
It's a little extra complexity, but I don't think it's too much. It's a transfer from the user account to the relayer account (as opposed to a system receipt), and the amount should be easy to compute (the only variable is the size of the payload, so it will simply be something like
I agree a smooth on-boarding experience is important. This can be handled on the relayer side. For example relayer operators could give a number of free transactions to a new address by including the |
NonceCurrently, a 64-length hex (NEAR-implicit) account is created upon a transfer to that address, and an access key is added with its nonce set to For addresses that start with ’0x’ and are followed by a 40-length hex (ETH-implicit), an account will be created when there's a transfer to this address. No access key will be added at this point. When a transaction originates from this account, an access key will be added (if it doesn't exist yet) with its nonce set to match the transaction’s nonce. Should a transaction be sent from an ETH-implicit account, resulting in the addition of an access key to this account, should
That approach appears to solve the problem for
Won't this result in a problem related to replaying transactions for transactions other than |
Thanks for bringing this up @staffik . We could make the default value (for when the key is not yet added) equal to |
Hello, Protocol NEP moderator here. Do we plan to replace this NEP with #518? If so, shall we close this one? cc. @alexauroradev , @birchmd , @bowenwang1996 |
I think it is reasonable to close this issue in favor of #518 . The new issue links to this one for those that want to come back to it for context. |
Proposal to support using Ethereum wallets & transactions on NEAR.
This opens up an existing broader Ethereum user base to interact with NEAR apps in a familiar way.
Reduces some of the integration work on adding NEAR support for infrastructure partners (at least for Ethereum formatted addresses).
User journey
The desired user journey, is a user coming to a NEAR app like https://app.ref.finance or https://mintbase.io, connect with their Metamask or other Ethereum wallet. The wallet would pop up to switch networks to "NEAR" and allow user to transact by signing with their Ethereum wallet.
Users are familiar with finding a bridge to move assets from Ethereum Mainnet or other existing network to NEAR if they can connect with Metamask. Additionally, if user doesn't have any assets, a Bridge UI can be shown to suggest to bridge (or deposit directly for something like dex.woo.org) assets automatically.
Technical details
near-api-js should support to add NEAR network with a RPC that supports Ethereum endpoints that Ethereum Wallet needs.
Special RPC endpoints are needed to be added that respond with required information: chainId, blockNumber and account information.
Transaction signing in this case happens by packaging NEAR transaction information into an Ethereum transaction format. The NEAR information will go into
calldata
field.from
- signer address,gasLimit
andvalue
are used for respective values. The rest are ignored.Addresses
New implicit account format will need to be added that fits Ethereum address format "0x[\w\d]32". These addresses can be accesses by a public key that matches
keccak(public_key)[:20]
. These will still be a normal NEAR accounts, as it's a valid account ID under current rules.One caveat to keep in mind is that Ethereum is using capitalization as a way to do check sums, and all tooling will need to be able to handle that.
Handling legacy accounts
There are a number of legacy 0x[\w\d]32 accounts that are not matching to user's key. From user experience perspective, it's important to block recieval of assets to these accounts.
The text was updated successfully, but these errors were encountered: