Skip to content

Commit

Permalink
feat(evm): validate optional chain (#453)
Browse files Browse the repository at this point in the history
* feat(evm): validate optional chain

When calling transferNative, and any other Evm functionalities, we can
let the user provide a chain (EvmChainish). When they do, we check if
the provided chain corresponds the current chain. If that is not the
case we throw an error.

* perf(evm): code improvement

better function naming and more readable code

* chore: add changeset

Co-authored-by: Erno Wever <[email protected]>
  • Loading branch information
sogunshola and ErnoW authored Jul 5, 2022
1 parent 68e9fbe commit ba6fd72
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 10 deletions.
7 changes: 7 additions & 0 deletions .changeset/strange-cherries-develop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@moralisweb3/core": minor
"@moralisweb3/evm": minor
"@morlaisweb3/test-app-all": minor
---

Add optional chain validation for chain interactions
5 changes: 3 additions & 2 deletions demos/test-app-all/src/Evm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ export const Evm = () => {
onClick={async () => {
console.log('Transfer native');
const txResponse = await Moralis.Evm.transferNative({
to: '0x295522b61890c3672D12eFbFf4358a6411CE996F',
value: EvmNative.create('0.0001'),
to: '0x992eCcC191D6F74E8Be187ed6B6AC196b08314f7',
value: EvmNative.create('0.00001'),
chain: '0x4'
});

console.log('TX', txResponse);
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/Error/ErrorCode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export enum NetworkErrorCode {
WALLET_NOT_FOUND = 'N0006',
CONTRACT_NOT_SET = 'N0007',
NO_CHAIN_SET = 'N0008',
CHAIN_MISMATCH = 'N0009',

NOT_IMPLEMENTED = 'N9000',
}
Expand Down
15 changes: 14 additions & 1 deletion packages/evm/src/assert/assertChain.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EvmChain, MoralisNetworkError, NetworkErrorCode } from '@moralisweb3/core';
import { EvmChain, EvmChainish, MoralisNetworkError, NetworkErrorCode } from '@moralisweb3/core';

const isValidChain = (chain: unknown): chain is EvmChain => {
if (chain instanceof EvmChain) {
Expand All @@ -18,3 +18,16 @@ export const assertChain = (chain: unknown, message?: string) => {

return chain;
};

/**
* @param {EvmChain} providedChain The chain provided from function call.
* @param {EvmChain} chain The evm chain.
*/
export const assertChainEquality = (providedChain: EvmChainish, chain: EvmChain): void => {
if (!chain.equals(providedChain)) {
throw new MoralisNetworkError({
code: NetworkErrorCode.CHAIN_MISMATCH,
message: `Expected chain ${chain.apiHex}, but got ${EvmChain.create(providedChain).apiHex}`,
});
}
};
8 changes: 6 additions & 2 deletions packages/evm/src/chainMethods/transferErc1155.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { EvmAddress, EvmAddressish, EvmChainish } from '@moralisweb3/core';
import { BigNumber, BigNumberish, BytesLike, ethers } from 'ethers';
import { assertAddress } from '../assert/assertAddress';
import { assertChain, assertChainEquality } from '../assert/assertChain';
import { assertProvider } from '../assert/assertProvider';
import { Erc1155__factory } from '../Contract';
import { wrapEthersTransactionResponse } from '../utils/wrapEthersTransactionResponse';
Expand All @@ -19,8 +20,11 @@ export const makeTransferErc1155 =
async (options: TransferErc1155Options) => {
const provider = assertProvider(_provider);
const fromAddress = assertAddress(_account, 'No account is connected');
const chain = assertChain(_chain, 'Chain is not set on MoralisEvm. Make sure to be properly connected');

// TODO: validate that provided chain is current chain
if (options.chain) {
assertChainEquality(options.chain, chain);
}

const contractAddress = EvmAddress.create(options.contractAddress);
const toAddress = EvmAddress.create(options.to);
Expand All @@ -32,5 +36,5 @@ export const makeTransferErc1155 =

const response = await token.safeTransferFrom(fromAddress.checksum, toAddress.checksum, tokenId, value, data);

return wrapEthersTransactionResponse(response, _chain);
return wrapEthersTransactionResponse(response, chain);
};
6 changes: 5 additions & 1 deletion packages/evm/src/chainMethods/transferErc20.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Erc20Value, Erc20Valueish, EvmAddress, EvmAddressish, EvmChainish } from '@moralisweb3/core';
import { ethers } from 'ethers';
import { assertChain, assertChainEquality } from '../assert/assertChain';
import { assertProvider } from '../assert/assertProvider';
import { Erc20__factory } from '../Contract';
import { wrapEthersTransactionResponse } from '../utils/wrapEthersTransactionResponse';
Expand All @@ -16,7 +17,10 @@ export const makeTransferErc20 =
async (options: TransferErc20Options) => {
const provider = assertProvider(_provider);

// TODO: validate that provided chain is current chain
const chain = assertChain(_chain, 'Chain is not set on MoralisEvm. Make sure to be properly connected');
if (options.chain) {
assertChainEquality(options.chain, chain);
}

const contractAddress = EvmAddress.create(options.contractAddress);
const toAddress = EvmAddress.create(options.to);
Expand Down
8 changes: 6 additions & 2 deletions packages/evm/src/chainMethods/transferErc721.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { EvmAddress, EvmAddressish, EvmChainish } from '@moralisweb3/core';
import { BigNumberish, ethers } from 'ethers';
import { assertAddress } from '../assert/assertAddress';
import { assertChain, assertChainEquality } from '../assert/assertChain';
import { assertProvider } from '../assert/assertProvider';
import { Erc721__factory } from '../Contract';
import { wrapEthersTransactionResponse } from '../utils/wrapEthersTransactionResponse';
Expand All @@ -18,7 +19,10 @@ export const makeTransferErc721 =
const provider = assertProvider(_provider);
const fromAddress = assertAddress(_account, 'No account is connected');

// TODO: validate that provided chain is current chain
const chain = assertChain(_chain, 'Chain is not set on MoralisEvm. Make sure to be properly connected');
if (options.chain) {
assertChainEquality(options.chain, chain);
}

const contractAddress = EvmAddress.create(options.contractAddress);
const toAddress = EvmAddress.create(options.to);
Expand All @@ -32,5 +36,5 @@ export const makeTransferErc721 =
tokenId,
);

return wrapEthersTransactionResponse(response, _chain);
return wrapEthersTransactionResponse(response, chain);
};
6 changes: 4 additions & 2 deletions packages/evm/src/chainMethods/transferNative.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
EvmTransactionInput,
EvmTransactionResponse,
} from '@moralisweb3/core';
import { assertChain } from '../assert/assertChain';
import { assertChain, assertChainEquality } from '../assert/assertChain';

export interface TransferNativeOptions {
to: EvmAddressish;
Expand All @@ -21,8 +21,10 @@ export const makeTransferNative =
async (options: TransferNativeOptions) => {
const to = EvmAddress.create(options.to);
const value = EvmNative.create(options.value);
// TODO: check if provided chain is same as current chain, otherwise throw error
const chain = assertChain(_chain, 'Chain is not set on MoralisEvm. Make sure to be properly connected');
if (options.chain) {
assertChainEquality(options.chain, chain);
}

const transaction = await sendTransaction({
to: to.checksum,
Expand Down

0 comments on commit ba6fd72

Please sign in to comment.