2022-03-07 19:54:36 +01:00
import EthQuery from 'ethjs-query' ;
import { createTestProviderTools } from '../../test/stub/provider' ;
2023-01-18 15:47:29 +01:00
import { TransactionType } from '../constants/transaction' ;
2022-03-07 19:54:36 +01:00
import {
determineTransactionType ,
isEIP1559Transaction ,
isLegacyTransaction ,
2022-03-17 19:35:40 +01:00
parseStandardTokenTransactionData ,
2022-03-07 19:54:36 +01:00
} from './transaction.utils' ;
2021-06-28 17:23:17 +02:00
describe ( 'Transaction.utils' , function ( ) {
2022-03-17 19:35:40 +01:00
describe ( 'parseStandardTokenTransactionData' , ( ) => {
it ( 'should return token data' , ( ) => {
const tokenData = parseStandardTokenTransactionData (
'0xa9059cbb00000000000000000000000050a9d56c2b8ba9a5c7f2c08c3d26e0499f23a7060000000000000000000000000000000000000000000000000000000000004e20' ,
) ;
expect ( tokenData ) . toStrictEqual ( expect . anything ( ) ) ;
const { name , args } = tokenData ;
2023-01-18 15:47:29 +01:00
expect ( name ) . toStrictEqual ( TransactionType . tokenMethodTransfer ) ;
2022-03-17 19:35:40 +01:00
const to = args . _to ;
const value = args . _value . toString ( ) ;
expect ( to ) . toStrictEqual ( '0x50A9D56C2B8BA9A5c7f2C08C3d26E0499F23a706' ) ;
expect ( value ) . toStrictEqual ( '20000' ) ;
} ) ;
it ( 'should not throw errors when called without arguments' , ( ) => {
expect ( ( ) => parseStandardTokenTransactionData ( ) ) . not . toThrow ( ) ;
} ) ;
} ) ;
2021-06-28 17:23:17 +02:00
describe ( 'isEIP1559Transaction' , function ( ) {
it ( 'should return true if both maxFeePerGas and maxPriorityFeePerGas are hex strings' , ( ) => {
expect (
isEIP1559Transaction ( {
txParams : { maxFeePerGas : '0x1' , maxPriorityFeePerGas : '0x1' } ,
} ) ,
) . toBe ( true ) ;
} ) ;
it ( 'should return false if either maxFeePerGas and maxPriorityFeePerGas are non-hex strings' , ( ) => {
expect (
isEIP1559Transaction ( {
txParams : { maxFeePerGas : 0 , maxPriorityFeePerGas : '0x1' } ,
} ) ,
) . toBe ( false ) ;
expect (
isEIP1559Transaction ( {
txParams : { maxFeePerGas : '0x1' , maxPriorityFeePerGas : 'fail' } ,
} ) ,
) . toBe ( false ) ;
} ) ;
it ( 'should return false if either maxFeePerGas or maxPriorityFeePerGas are not supplied' , ( ) => {
expect (
isEIP1559Transaction ( {
txParams : { maxPriorityFeePerGas : '0x1' } ,
} ) ,
) . toBe ( false ) ;
expect (
isEIP1559Transaction ( {
txParams : { maxFeePerGas : '0x1' } ,
} ) ,
) . toBe ( false ) ;
} ) ;
} ) ;
describe ( 'isLegacyTransaction' , function ( ) {
it ( 'should return true if no gas related fields are supplied' , ( ) => {
expect (
isLegacyTransaction ( {
txParams : { } ,
} ) ,
) . toBe ( true ) ;
} ) ;
it ( 'should return true if gasPrice is solely provided' , ( ) => {
expect (
isLegacyTransaction ( {
txParams : { gasPrice : '0x1' } ,
} ) ,
) . toBe ( true ) ;
} ) ;
it ( 'should return false if gasPrice is not a hex string' , ( ) => {
expect (
isLegacyTransaction ( {
txParams : { gasPrice : 100 } ,
} ) ,
) . toBe ( false ) ;
} ) ;
it ( 'should return false if either maxFeePerGas or maxPriorityFeePerGas are supplied' , ( ) => {
expect (
isLegacyTransaction ( {
txParams : {
maxFeePerGas : '0x1' ,
} ,
} ) ,
) . toBe ( false ) ;
expect (
isLegacyTransaction ( {
txParams : {
maxPriorityFeePerGas : 'any data' ,
} ,
} ) ,
) . toBe ( false ) ;
} ) ;
} ) ;
2022-03-07 19:54:36 +01:00
describe ( 'determineTransactionType' , function ( ) {
const genericProvider = createTestProviderTools ( ) . provider ;
const query = new EthQuery ( genericProvider ) ;
2022-07-12 19:20:20 +02:00
it ( 'should return a simple send type when to is truthy and is not a contract address' , async function ( ) {
const _providerResultStub = {
// 1 gwei
eth _gasPrice : '0x0de0b6b3a7640000' ,
// by default, all accounts are external accounts (not contracts)
eth _getCode : '0x' ,
} ;
const _provider = createTestProviderTools ( {
scaffold : _providerResultStub ,
} ) . provider ;
2022-03-07 19:54:36 +01:00
const result = await determineTransactionType (
{
to : '0xabc' ,
data : '' ,
} ,
2022-07-12 19:20:20 +02:00
new EthQuery ( _provider ) ,
2022-03-07 19:54:36 +01:00
) ;
expect ( result ) . toMatchObject ( {
2023-01-18 15:47:29 +01:00
type : TransactionType . simpleSend ,
2022-03-07 19:54:36 +01:00
getCodeResponse : null ,
} ) ;
} ) ;
2023-04-21 15:30:44 +02:00
it ( 'should return a token transfer type when the recipient is a contract, there is no value passed, and data is for the respective method call' , async function ( ) {
2022-07-12 19:20:20 +02:00
const _providerResultStub = {
// 1 gwei
eth _gasPrice : '0x0de0b6b3a7640000' ,
// by default, all accounts are external accounts (not contracts)
eth _getCode : '0xab' ,
} ;
const _provider = createTestProviderTools ( {
scaffold : _providerResultStub ,
} ) . provider ;
2022-03-07 19:54:36 +01:00
const result = await determineTransactionType (
{
2022-07-12 19:20:20 +02:00
to : '0x9e673399f795D01116e9A8B2dD2F156705131ee9' ,
2022-07-31 20:26:40 +02:00
data : '0xa9059cbb0000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C970000000000000000000000000000000000000000000000000000000000000000a' ,
2022-03-07 19:54:36 +01:00
} ,
2022-07-12 19:20:20 +02:00
new EthQuery ( _provider ) ,
2022-03-07 19:54:36 +01:00
) ;
expect ( result ) . toMatchObject ( {
2023-01-18 15:47:29 +01:00
type : TransactionType . tokenMethodTransfer ,
2022-07-12 19:20:20 +02:00
getCodeResponse : '0xab' ,
2022-03-07 19:54:36 +01:00
} ) ;
} ) ;
2023-04-21 15:30:44 +02:00
it (
'should NOT return a token transfer type and instead return contract interaction' +
' when the recipient is a contract, the data matches the respective method call, but there is a value passed' ,
async function ( ) {
const _providerResultStub = {
// 1 gwei
eth _gasPrice : '0x0de0b6b3a7640000' ,
// by default, all accounts are external accounts (not contracts)
eth _getCode : '0xab' ,
} ;
const _provider = createTestProviderTools ( {
scaffold : _providerResultStub ,
} ) . provider ;
const resultWithEmptyValue = await determineTransactionType (
{
value : '0x0' ,
to : '0x9e673399f795D01116e9A8B2dD2F156705131ee9' ,
data : '0xa9059cbb0000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C970000000000000000000000000000000000000000000000000000000000000000a' ,
} ,
new EthQuery ( _provider ) ,
) ;
expect ( resultWithEmptyValue ) . toMatchObject ( {
type : TransactionType . tokenMethodTransfer ,
getCodeResponse : '0xab' ,
} ) ;
2023-07-07 01:48:38 +02:00
const resultWithEmptyValue2 = await determineTransactionType (
{
value : '0x0000' ,
to : '0x9e673399f795D01116e9A8B2dD2F156705131ee9' ,
data : '0xa9059cbb0000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C970000000000000000000000000000000000000000000000000000000000000000a' ,
} ,
new EthQuery ( _provider ) ,
) ;
expect ( resultWithEmptyValue2 ) . toMatchObject ( {
type : TransactionType . tokenMethodTransfer ,
getCodeResponse : '0xab' ,
} ) ;
2023-04-21 15:30:44 +02:00
const resultWithValue = await determineTransactionType (
{
value : '0x12345' ,
to : '0x9e673399f795D01116e9A8B2dD2F156705131ee9' ,
data : '0xa9059cbb0000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C970000000000000000000000000000000000000000000000000000000000000000a' ,
} ,
new EthQuery ( _provider ) ,
) ;
expect ( resultWithValue ) . toMatchObject ( {
type : TransactionType . contractInteraction ,
getCodeResponse : '0xab' ,
} ) ;
} ,
) ;
2022-07-12 19:20:20 +02:00
it ( 'should NOT return a token transfer type when the recipient is not a contract but the data matches the respective method call' , async function ( ) {
const _providerResultStub = {
// 1 gwei
eth _gasPrice : '0x0de0b6b3a7640000' ,
// by default, all accounts are external accounts (not contracts)
eth _getCode : '0x' ,
} ;
const _provider = createTestProviderTools ( {
scaffold : _providerResultStub ,
} ) . provider ;
2022-03-07 19:54:36 +01:00
const result = await determineTransactionType (
{
2022-07-12 19:20:20 +02:00
to : '0x9e673399f795D01116e9A8B2dD2F156705131ee9' ,
2022-07-31 20:26:40 +02:00
data : '0xa9059cbb0000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C970000000000000000000000000000000000000000000000000000000000000000a' ,
2022-07-12 19:20:20 +02:00
} ,
new EthQuery ( _provider ) ,
) ;
expect ( result ) . toMatchObject ( {
2023-01-18 15:47:29 +01:00
type : TransactionType . simpleSend ,
2022-07-12 19:20:20 +02:00
getCodeResponse : '0x' ,
} ) ;
} ) ;
it ( 'should return a token approve type when when the recipient is a contract and data is for the respective method call' , async function ( ) {
const _providerResultStub = {
// 1 gwei
eth _gasPrice : '0x0de0b6b3a7640000' ,
// by default, all accounts are external accounts (not contracts)
eth _getCode : '0xab' ,
} ;
const _provider = createTestProviderTools ( {
scaffold : _providerResultStub ,
} ) . provider ;
const result = await determineTransactionType (
{
to : '0x9e673399f795D01116e9A8B2dD2F156705131ee9' ,
2022-07-31 20:26:40 +02:00
data : '0x095ea7b30000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C9700000000000000000000000000000000000000000000000000000000000000005' ,
2022-03-07 19:54:36 +01:00
} ,
2022-07-12 19:20:20 +02:00
new EthQuery ( _provider ) ,
2022-03-07 19:54:36 +01:00
) ;
expect ( result ) . toMatchObject ( {
2023-01-18 15:47:29 +01:00
type : TransactionType . tokenMethodApprove ,
2022-07-12 19:20:20 +02:00
getCodeResponse : '0xab' ,
2022-03-07 19:54:36 +01:00
} ) ;
} ) ;
it ( 'should return a contract deployment type when to is falsy and there is data' , async function ( ) {
const result = await determineTransactionType (
{
to : '' ,
data : '0xabd' ,
} ,
query ,
) ;
expect ( result ) . toMatchObject ( {
2023-01-18 15:47:29 +01:00
type : TransactionType . deployContract ,
2022-03-07 19:54:36 +01:00
getCodeResponse : undefined ,
} ) ;
} ) ;
it ( 'should return a simple send type with a 0x getCodeResponse when there is data and but the to address is not a contract address' , async function ( ) {
const result = await determineTransactionType (
{
to : '0x9e673399f795D01116e9A8B2dD2F156705131ee9' ,
data : '0xabd' ,
} ,
query ,
) ;
expect ( result ) . toMatchObject ( {
2023-01-18 15:47:29 +01:00
type : TransactionType . simpleSend ,
2022-03-07 19:54:36 +01:00
getCodeResponse : '0x' ,
} ) ;
} ) ;
it ( 'should return a simple send type with a null getCodeResponse when to is truthy and there is data and but getCode returns an error' , async function ( ) {
2022-07-12 19:20:20 +02:00
const _providerResultStub = {
// 1 gwei
eth _gasPrice : '0x0de0b6b3a7640000' ,
// by default, all accounts are external accounts (not contracts)
eth _getCode : null ,
} ;
const _provider = createTestProviderTools ( {
scaffold : _providerResultStub ,
} ) . provider ;
2022-03-07 19:54:36 +01:00
const result = await determineTransactionType (
{
2022-07-12 19:20:20 +02:00
to : '0x9e673399f795D01116e9A8B2dD2F156705131ee9' ,
2022-03-07 19:54:36 +01:00
data : '0xabd' ,
} ,
2022-07-12 19:20:20 +02:00
new EthQuery ( _provider ) ,
2022-03-07 19:54:36 +01:00
) ;
expect ( result ) . toMatchObject ( {
2023-01-18 15:47:29 +01:00
type : TransactionType . simpleSend ,
2022-03-07 19:54:36 +01:00
getCodeResponse : null ,
} ) ;
} ) ;
it ( 'should return a contract interaction type with the correct getCodeResponse when to is truthy and there is data and it is not a token transaction' , async function ( ) {
const _providerResultStub = {
// 1 gwei
eth _gasPrice : '0x0de0b6b3a7640000' ,
// by default, all accounts are external accounts (not contracts)
eth _getCode : '0xa' ,
} ;
const _provider = createTestProviderTools ( {
scaffold : _providerResultStub ,
} ) . provider ;
const result = await determineTransactionType (
{
to : '0x9e673399f795D01116e9A8B2dD2F156705131ee9' ,
data : 'abd' ,
} ,
new EthQuery ( _provider ) ,
) ;
expect ( result ) . toMatchObject ( {
2023-01-18 15:47:29 +01:00
type : TransactionType . contractInteraction ,
2022-03-07 19:54:36 +01:00
getCodeResponse : '0x0a' ,
} ) ;
} ) ;
it ( 'should return a contract interaction type with the correct getCodeResponse when to is a contract address and data is falsy' , async function ( ) {
const _providerResultStub = {
// 1 gwei
eth _gasPrice : '0x0de0b6b3a7640000' ,
// by default, all accounts are external accounts (not contracts)
eth _getCode : '0xa' ,
} ;
const _provider = createTestProviderTools ( {
scaffold : _providerResultStub ,
} ) . provider ;
const result = await determineTransactionType (
{
to : '0x9e673399f795D01116e9A8B2dD2F156705131ee9' ,
data : '' ,
} ,
new EthQuery ( _provider ) ,
) ;
expect ( result ) . toMatchObject ( {
2023-01-18 15:47:29 +01:00
type : TransactionType . contractInteraction ,
2022-03-07 19:54:36 +01:00
getCodeResponse : '0x0a' ,
} ) ;
} ) ;
2023-02-16 15:52:59 +01:00
it ( 'should return contractInteraction for send with approve' , async function ( ) {
const _providerResultStub = {
// 1 gwei
eth _gasPrice : '0x0de0b6b3a7640000' ,
// by default, all accounts are external accounts (not contracts)
eth _getCode : '0xa' ,
} ;
const _provider = createTestProviderTools ( {
scaffold : _providerResultStub ,
} ) . provider ;
const result = await determineTransactionType (
{
to : '0x9e673399f795D01116e9A8B2dD2F156705131ee9' ,
value : '0x5af3107a4000' ,
data : '0x095ea7b30000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C9700000000000000000000000000000000000000000000000000000000000000005' ,
} ,
new EthQuery ( _provider ) ,
) ;
expect ( result ) . toMatchObject ( {
type : TransactionType . contractInteraction ,
getCodeResponse : '0x0a' ,
} ) ;
} ) ;
2022-03-07 19:54:36 +01:00
} ) ;
2021-06-28 17:23:17 +02:00
} ) ;