Currently, this library supports signing transactions by inputting account credentials to sign with or by using this library inside of a wallet so the wallet can sign transactions and display transaction details of the payload to the user even if it's on another chain.
Whilst it is preferable for a user to be able to see the transaction details before signing and we should recommend that wallets integrate this, any NEAR wallet should be able to sign multichain transactions with this library without supporting it in the wallet (they just won't be able to display the transaction details properly to the user).
Additionally, when setting up a chain object (EVM, bitcoin, etc.) the user must input a provider which isn't the best DevEx. Getting balance also requires this provider.
Here is a suggested list of methods for EVM, (note that other chains will likely have to be different, especially bitcoin). Optional arguments are given in square brackets.
Construct chain object
Initiates the chain object, sets the near network (mainnet/testnet), chain ID, key version, RPC URL, and the MPC contract. If not provided, the key version and MPC contract will be set to default values. If an RPC URL is not provided then they will not be able to use many methods here but the user may want to just derive addresses and public keys.
new EVM(nearNetwork, chainId, [keyVerion], [rpcUrl], [mpcContract])
Derive address
Derives an address on the target chain from a provided path and NEAR account.
deriveAddress(path, nearAccount)
Returns address.
Derive public key
Derives a public key on the target chain from a provided path and NEAR account. This is especially useful in the NEAR case.
derviePublicKey(path, nearAccount)
Returns public key.
Get account balance
Gets the native token balance of an account on the target chain.
getBalance(address)
Returns balance.
Construct transaction
This will allow the user to create any type of transaction for the target chain. This will include things like a simple transfer of funds, a contract call, contract deployment, etc.
I really like the way this is done in omni-transaction-rs and think a similar approach should be taken here. It would be good to be able to build specific data for each chain like is done for NEAR in the omni-transaction-rs library but this will take a fair bit of work.
Returns a transaction object.
Store transaction
Stores a transaction object in session storage as the object will be lost upon wallet redirect. A prefix is specified as the user may want to store multiple transactions.
storeTransaction(transaction, prefix)
Get stored transaction
Gets the stored transaction object from session storage.
getStoredTransaction(prefix)
Returns a transaction object.
Sign a transaction and reconstruct signature
Sign a transaction object by making a call to the MPC contract. The signature is then reconstructed and added to the transaction object. The user can either pass in a NEAR account object, wallet-selector wallet object, or a credentials object (if used inside of a wallet) to sign the transaction.
signTransaction(transaction, path, [object])
Returns a signed transaction object.
Reconstruct signature
Adds a signature to a transaction. This will be used when a web wallet is used or in an indexer to fetch transactions and signatures and relay them. The signature object will have the same structure as the return type of the MPC.
reconstructSignature(transaction, signature)
Returns a signed transaction object.
Broadcast transaction
Relays a signed transaction object to the target chain.
broadcastTransaction(signedTransaction)
Returns a transaction hash on the target chain.
Make a view call to a contract
Makes a view call to a contract on the target chain.
viewCall(contractAddress, methodName, [args])
Returns the result of the view call.
Additional methods that could be useful:
Sign with mtx relayer
Sign the transaction with a NEAR meta-transactions relayer.
Sign and send transaction
A single method to sign and broadcast a transaction.
Transfer funds
A single method to transfer the native token of the chain to another address.
Thoughts:
Upon wallet redirect, the path being used would be lost, and the user would likely want to retain this. Maybe we should have a method to store the path in local storage also, this could be implemented as an option in store transaction.
We may want to have a simplified method for reconstructing the signature in the case of a web wallet where the method just takes a transaction and fetches the tx hash from the URL, gets the signature, and then reconstructs.
This all looks good to me and I think provide the basics that we want from this library.
A couple of things:
let's strive for consistency and shortness when naming e.g. setTx, getTx (I can't imagine having names similar).
let's explain the approach of constructing a transaction using a transaction builder in more detail.
I think a transaction builder should be constructing a transaction from unsigned JSON e.g. ethers uses the concept of a "base transaction" which is pure JSON, not a javascript instance or anything.
distinguish between what methods are chain specific and what methods are global to the library e.g. broadcastTx would be a method of each chain object or would it be a global method that takes a hash produced by a method from a chain object?
rename additional methods to a "Future Work" section, so it's clear we are not going to work on or discuss these now.
Currently, this library supports signing transactions by inputting account credentials to sign with or by using this library inside of a wallet so the wallet can sign transactions and display transaction details of the payload to the user even if it's on another chain.
Whilst it is preferable for a user to be able to see the transaction details before signing and we should recommend that wallets integrate this, any NEAR wallet should be able to sign multichain transactions with this library without supporting it in the wallet (they just won't be able to display the transaction details properly to the user).
Additionally, when setting up a chain object (EVM, bitcoin, etc.) the user must input a provider which isn't the best DevEx. Getting balance also requires this provider.
Here is a suggested list of methods for EVM, (note that other chains will likely have to be different, especially bitcoin). Optional arguments are given in square brackets.
Construct chain object Initiates the chain object, sets the near network (mainnet/testnet), chain ID, key version, RPC URL, and the MPC contract. If not provided, the key version and MPC contract will be set to default values. If an RPC URL is not provided then they will not be able to use many methods here but the user may want to just derive addresses and public keys.
Derive address Derives an address on the target chain from a provided path and NEAR account.
Returns address.
Derive public key Derives a public key on the target chain from a provided path and NEAR account. This is especially useful in the NEAR case.
Returns public key.
Get account balance Gets the native token balance of an account on the target chain.
Returns balance.
Construct transaction This will allow the user to create any type of transaction for the target chain. This will include things like a simple transfer of funds, a contract call, contract deployment, etc.
I really like the way this is done in omni-transaction-rs and think a similar approach should be taken here. It would be good to be able to build specific data for each chain like is done for NEAR in the omni-transaction-rs library but this will take a fair bit of work.
Returns a transaction object.
Store transaction Stores a transaction object in session storage as the object will be lost upon wallet redirect. A prefix is specified as the user may want to store multiple transactions.
Get stored transaction Gets the stored transaction object from session storage.
Returns a transaction object.
Sign a transaction and reconstruct signature Sign a transaction object by making a call to the MPC contract. The signature is then reconstructed and added to the transaction object. The user can either pass in a NEAR account object, wallet-selector wallet object, or a credentials object (if used inside of a wallet) to sign the transaction.
Returns a signed transaction object.
Reconstruct signature Adds a signature to a transaction. This will be used when a web wallet is used or in an indexer to fetch transactions and signatures and relay them. The signature object will have the same structure as the return type of the MPC.
Returns a signed transaction object.
Broadcast transaction Relays a signed transaction object to the target chain.
Returns a transaction hash on the target chain.
Make a view call to a contract Makes a view call to a contract on the target chain.
Returns the result of the view call.
Additional methods that could be useful:
Sign with mtx relayer Sign the transaction with a NEAR meta-transactions relayer.
Sign and send transaction A single method to sign and broadcast a transaction.
Transfer funds A single method to transfer the native token of the chain to another address.
Thoughts: