Skip to content

Commit

Permalink
feat: add getErc20Approvals
Browse files Browse the repository at this point in the history
  • Loading branch information
ErnoW committed Mar 21, 2023
1 parent 24af111 commit 4ad1518
Show file tree
Hide file tree
Showing 19 changed files with 854 additions and 3 deletions.
6 changes: 6 additions & 0 deletions .changeset/nasty-wolves-shop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@moralisweb3/common-evm-utils': minor
'@moralisweb3/evm-api': minor
---

Add `getErc20Approvals` endpoint at `Moralis.EvmApi.token.getErc20Approvals()`
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { Core } from '@moralisweb3/common-core';
import { Erc20Approval } from './Erc20Approval';
import { setupEvmUtils } from '../../test/setup';
import { Erc20ApprovalInput } from './types';

const exampleInput: Erc20ApprovalInput = {
chain: '0x1',
toWallet: '0x09f4fc6081026c85070886599e83f599ecf82405',
fromWallet: '0xaabc2c22426993f3d219d94a5ee6e95d4954f3bf',
contractAddress: '0xa0e8fed3426391fdb446516799c4d6248e2b2860',
blockHash: '0xa5f87d4341642b89e3ccb81449e3083032c36fface2c2042941b8bd9afe83f79',
blockNumber: '16868690',
blockTimestamp: '2023-03-20T11:48:59.000Z',
transactionHash: '0xb7b4d321e2ab26c1cde1a2ef49413e21b65dcc663d6de8f75ddbdd868b98b4bf',
transactionIndex: 4,
logIndex: 25,
value: '100000000000000000000000000000',
};

describe('Erc20Approval', () => {
let core: Core;

beforeAll(() => {
core = setupEvmUtils();
});

beforeEach(() => {
core.config.reset();
});

/**
* Creation
*/
it('should create a new Erc20Approval', () => {
const erc20Approval = Erc20Approval.create(exampleInput);

expect(erc20Approval.chain.hex).toBe('0x1');
expect(erc20Approval.toWallet.lowercase).toBe('0x09f4fc6081026c85070886599e83f599ecf82405');
expect(erc20Approval.fromWallet.lowercase).toBe('0xaabc2c22426993f3d219d94a5ee6e95d4954f3bf');
expect(erc20Approval.contractAddress.lowercase).toBe('0xa0e8fed3426391fdb446516799c4d6248e2b2860');
expect(erc20Approval.blockNumber.toString()).toBe('16868690');
expect(erc20Approval.blockTimestamp.toISOString()).toBe('2023-03-20T11:48:59.000Z');
expect(erc20Approval.transactionHash).toBe('0xb7b4d321e2ab26c1cde1a2ef49413e21b65dcc663d6de8f75ddbdd868b98b4bf');
expect(erc20Approval.transactionIndex).toBe(4);
expect(erc20Approval.logIndex).toBe(25);
expect(erc20Approval.value.toString()).toBe('100000000000000000000000000000');
});

/**
* Formatting
*/
it('should return formatting in json', () => {
const erc20Approval = Erc20Approval.create(exampleInput);

const value = erc20Approval.toJSON();

expect(value).toStrictEqual({
chain: '0x1',
toWallet: '0x09f4fc6081026c85070886599e83f599ecf82405',
fromWallet: '0xaabc2c22426993f3d219d94a5ee6e95d4954f3bf',
contractAddress: '0xa0e8fed3426391fdb446516799c4d6248e2b2860',
blockHash: '0xa5f87d4341642b89e3ccb81449e3083032c36fface2c2042941b8bd9afe83f79',
blockNumber: '16868690',
blockTimestamp: new Date('2023-03-20T11:48:59.000Z'),
transactionHash: '0xb7b4d321e2ab26c1cde1a2ef49413e21b65dcc663d6de8f75ddbdd868b98b4bf',
transactionIndex: 4,
logIndex: 25,
value: '100000000000000000000000000000',
});
});

/**
* Methods
*/
it('should check equality of 2 erc20Approvals of the same value', () => {
const erc20ApprovalA = Erc20Approval.create(exampleInput);
const erc20ApprovalB = Erc20Approval.create(exampleInput);

expect(erc20ApprovalA.equals(erc20ApprovalB)).toBeTruthy();
});

it('should check equality of 2 erc20Approvals of the same value via a static method', () => {
const erc20ApprovalA = Erc20Approval.create(exampleInput);
const erc20ApprovalB = Erc20Approval.create(exampleInput);

expect(Erc20Approval.equals(erc20ApprovalA, erc20ApprovalB)).toBeTruthy();
});

it('should check inequality when chain is different', () => {
const erc20ApprovalA = Erc20Approval.create(exampleInput);
const erc20ApprovalB = Erc20Approval.create({ ...exampleInput, chain: '0x2' });

expect(erc20ApprovalA.equals(erc20ApprovalB)).toBeFalsy();
});
});
192 changes: 192 additions & 0 deletions packages/common/evmUtils/src/dataTypes/Erc20Approval/Erc20Approval.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import Core, { MoralisDataObject, BigNumber, dateInputToDate, CoreProvider } from '@moralisweb3/common-core';
import { EvmAddress } from '../EvmAddress';
import { EvmChain } from '../EvmChain';
import { Erc20ApprovalInput, Erc20ApprovalData } from './types';

/**
* The Erc20Approval is a representation of an Erc20 token approval.
*
* @category DataType
*/
export class Erc20Approval implements MoralisDataObject {
/**
* Create a new instance of Erc20Approval from any valid input
* @param data - Erc20Approval instance or valid Erc20ApprovalInput
* @example
* ```
* const approval = Erc20Approval.create(data);
*```
*/
static create(data: Erc20Approval | Erc20ApprovalInput, core?: Core) {
if (data instanceof Erc20Approval) {
return data;
}

const finalCore = core ?? CoreProvider.getDefault();
return new Erc20Approval(data, finalCore);
}

private _data: Erc20ApprovalData;

constructor(data: Erc20ApprovalInput, core: Core) {
this._data = Erc20Approval.parse(data, core);
}

static parse = (data: Erc20ApprovalInput, core: Core): Erc20ApprovalData => ({
...data,
chain: EvmChain.create(data.chain, core),
contractAddress: EvmAddress.create(data.contractAddress, core),
fromWallet: EvmAddress.create(data.fromWallet, core),
toWallet: EvmAddress.create(data.toWallet, core),
blockTimestamp: dateInputToDate(data.blockTimestamp),
blockNumber: BigNumber.create(data.blockNumber),
value: BigNumber.create(data.value),
transactionIndex: Number(data.transactionIndex),
logIndex: Number(data.logIndex),
});

/**
* Check the equality between two Erc20 approvals
* @param dataA - The first approval to compare
* @param dataB - The second approval to compare
* @example Erc20Approval.equals(dataA, dataB)
* @returns true if the approvals are equal, false otherwise
*/
static equals(dataA: Erc20Approval | Erc20ApprovalInput, dataB: Erc20Approval | Erc20ApprovalInput) {
const approvalA = Erc20Approval.create(dataA);
const approvalB = Erc20Approval.create(dataB);

return JSON.stringify(approvalA.toJSON()) === JSON.stringify(approvalB.toJSON());
}

/**
* Checks the equality of the current approval with another erc20 approval
* @param data - the approval to compare with
* @example approval.equals(data)
* @returns true if the approvals are equal, false otherwise
*/
equals(data: Erc20Approval | Erc20ApprovalInput): boolean {
return Erc20Approval.equals(this, data);
}

/**
* @returns a JSON representation of the approval.
* @example approval.toJSON()
*/
toJSON() {
const data = this._data;
return {
...data,
chain: data.chain.format(),
contractAddress: data.contractAddress.format(),
blockNumber: data.blockNumber.toString(),
toWallet: data.toWallet.format(),
fromWallet: data.fromWallet.format(),
value: data.value.toString(),
};
}

/**
* @returns a JSON representation of the approval.
* @example approval.format()
*/
format() {
return this.toJSON();
}

/**
* @returns all the data without casting it to JSON.
* @example approval.result
*/
get result() {
return this._data;
}

/**
* @returns the toWallet of the approval
* @example approval.toWallet // EvmAddress
*/
get toWallet() {
return this._data.toWallet;
}

/**
* @returns the fromWallet of the approval
* @example approval.fromWallet // EvmAddress
*/
get fromWallet() {
return this._data.fromWallet;
}

/**
* @returns the contractAddress of the approval
* @example approval.contractAddress // EvmAddress
*/
get contractAddress() {
return this._data.contractAddress;
}

/**
* @returns the block hash of the approval
* @example approval.blockHash // "0x0372c302e3c52e8f2e15d155e2c545e6d802e479236564af052759253b20fd86"
*/
get blockHash() {
return this._data.blockHash;
}

/**
* @returns the block number of the approval
* @example approval.blockNumber // BigNumber
*/
get blockNumber() {
return this._data.blockNumber;
}

/**
* @returns the block timestamp of the approval
* @example approval.blockTimestamp // Date
*/
get blockTimestamp() {
return this._data.blockTimestamp;
}

/**
* @returns the chain of the approval
* @example approval.chain // EvmChain
*/
get chain() {
return this._data.chain;
}

/**
* @returns the transaction hash of the approval
* @example approval.transactionHash // "0x0372c302e3c52e8f2e15d155e2c545e6d802e479236564af052759253b20fd86"
*/
get transactionHash() {
return this._data.transactionHash;
}

/**
* @returns the value of the approval
* @example approval.value // BigNumber
*/
get value() {
return this._data.value;
}

/**
* @returns the transactionIndex of the approval
* @example approval.transactionIndex // 3
*/
get transactionIndex() {
return this._data.transactionIndex;
}

/**
* @returns the logIndex of the approval
* @example approval.logIndex // 2
*/
get logIndex() {
return this._data.logIndex;
}
}
2 changes: 2 additions & 0 deletions packages/common/evmUtils/src/dataTypes/Erc20Approval/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './Erc20Approval';
export * from './types';
52 changes: 52 additions & 0 deletions packages/common/evmUtils/src/dataTypes/Erc20Approval/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { BigNumber, BigNumberish, DateInput } from '@moralisweb3/common-core';
import { EvmAddressish, EvmAddress } from '../EvmAddress';
import { EvmChain, EvmChainish } from '../EvmChain';

/**
* This can be any object with valid erc20 approval data.
* @example
* ```
* const input = {
* chain: 1,
* toWallet: "0x09f4fc6081026c85070886599e83f599ecf82405",
* contractAddress: "0xa0e8fed3426391fdb446516799c4d6248e2b2860",
* blockHash: "0xa5f87d4341642b89e3ccb81449e3083032c36fface2c2042941b8bd9afe83f79",
* blockNumber: "16868690",
* blockTimestamp: "2023-03-20T11:48:59.000Z",
* transactionHash: "0xb7b4d321e2ab26c1cde1a2ef49413e21b65dcc663d6de8f75ddbdd868b98b4bf",
* transactionIndex: "4",
* logIndex: "25",
* value: "100000000000000000000000000000"
* }
* ```
*/
export interface Erc20ApprovalInput {
chain: EvmChainish;
fromWallet: EvmAddressish;
toWallet: EvmAddressish;
contractAddress: EvmAddressish;
blockHash: string;
blockNumber: BigNumberish;
blockTimestamp: DateInput;
transactionHash: string;
transactionIndex: number;
logIndex: number;
value: BigNumberish;
}

/**
* This is the return type of Erc20Approval
*/
export interface Erc20ApprovalData {
chain: EvmChain;
fromWallet: EvmAddress;
toWallet: EvmAddress;
contractAddress: EvmAddress;
blockHash: string;
blockNumber: BigNumber;
blockTimestamp: Date;
transactionHash: string;
transactionIndex: number;
logIndex: number;
value: BigNumber;
}
1 change: 1 addition & 0 deletions packages/common/evmUtils/src/dataTypes/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './Erc20';
export * from './Erc20Approval';
export * from './Erc20Mint';
export * from './Erc20Transfer';
export * from './Erc20Value';
Expand Down
Loading

0 comments on commit 4ad1518

Please sign in to comment.