Skip to content

Commit

Permalink
Feature/19 historic poc (#147)
Browse files Browse the repository at this point in the history
* getTransaction poc is working

* getTransactionLogs poc is working

* getTransactionLogs improvements

* transaction improved

* transaction-search added

* getTransactions is working

* getTransactions typed

* TransactionOptions created

* actions created

* effect is working

* transactions$ is working well

* activity module created

* sidebar includes activity

* TransactionActivityHeaderComponent is working

* ActivityContainerComponent clean

* TransactionActivityTableComponent is working

* table improvements

* price UI improved

* skeleton is working

* Empty message table added

* network changes is working

* minor fixes

* renaming in effect

* changeNetwork improved

* networkChanges$ improved

* before to fix rpcUrls

* wallet_addEthereumChain is fully working

* packages fixes
  • Loading branch information
etsraphael authored Jul 18, 2023
1 parent 327ba3f commit 282da88
Show file tree
Hide file tree
Showing 63 changed files with 1,173 additions and 162 deletions.
36 changes: 36 additions & 0 deletions UI/angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,42 @@
}
}
}
},
"transaction-search": {
"projectType": "library",
"root": "projects/transaction-search",
"sourceRoot": "projects/transaction-search/src",
"prefix": "lib",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:ng-packagr",
"options": {
"project": "projects/transaction-search/ng-package.json"
},
"configurations": {
"production": {
"tsConfig": "projects/transaction-search/tsconfig.lib.prod.json"
},
"development": {
"tsConfig": "projects/transaction-search/tsconfig.lib.json"
}
},
"defaultConfiguration": "production"
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"tsConfig": "projects/transaction-search/tsconfig.spec.json",
"polyfills": ["zone.js", "zone.js/testing"]
}
},
"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
"lintFilePatterns": ["projects/transaction-search/**/*.ts", "projects/transaction-search/**/*.html"]
}
}
}
}
},
"cli": {
Expand Down
42 changes: 42 additions & 0 deletions UI/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion UI/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
"@angular/platform-browser-dynamic": "^15.2.4",
"@angular/router": "^15.2.4",
"@apollo/client": "^3.7.17",
"@chainbrary/web3-login": "^0.0.16",
"@chainbrary/web3-login": "^0.0.17",
"@chainbrary/transaction-search": "^0.0.4",
"@eslint-community/regexpp": "^4.5.1",
"@ngrx/effects": "^15.4.0",
"@ngrx/entity": "^15.4.0",
Expand All @@ -38,6 +39,7 @@
"bootstrap-icons": "^1.10.5",
"graphql": "^16.6.0",
"ngx-device-detector": "^5.0.1",
"ngx-skeleton-loader": "^7.0.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"web3": "^1.10.0",
Expand Down
31 changes: 31 additions & 0 deletions UI/projects/transaction-search/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"extends": "../../.eslintrc.json",
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts"],
"rules": {
"@angular-eslint/directive-selector": [
"error",
{
"type": "attribute",
"prefix": "lib",
"style": "camelCase"
}
],
"@angular-eslint/component-selector": [
"error",
{
"type": "element",
"prefix": "lib",
"style": "kebab-case"
}
]
}
},
{
"files": ["*.html"],
"rules": {}
}
]
}
25 changes: 25 additions & 0 deletions UI/projects/transaction-search/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# TransactionSearch

This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 15.2.0.

## Code scaffolding

Run `ng generate component component-name --project transaction-search` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project transaction-search`.

> Note: Don't forget to add `--project transaction-search` or else it will be added to the default project in your `angular.json` file.
## Build

Run `ng build transaction-search` to build the project. The build artifacts will be stored in the `dist/` directory.

## Publishing

After building your library with `ng build transaction-search`, go to the dist folder `cd dist/transaction-search` and run `npm publish`.

## Running unit tests

Run `ng test transaction-search` to execute the unit tests via [Karma](https://karma-runner.github.io).

## Further help

To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
7 changes: 7 additions & 0 deletions UI/projects/transaction-search/ng-package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../dist/transaction-search",
"lib": {
"entryFile": "src/public-api.ts"
}
}
18 changes: 18 additions & 0 deletions UI/projects/transaction-search/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "@chainbrary/transaction-search",
"version": "0.0.4",
"peerDependencies": {
"@angular/common": "^15.2.0",
"@angular/core": "^15.2.0",
"web3": "^1.8.2"
},
"dependencies": {
"tslib": "^2.3.0"
},
"sideEffects": false,
"repository": {
"type": "git",
"url": "https://github.com/etsraphael/ChainBrary.git"
},
"homepage": "https://github.com/etsraphael/ChainBrary/tree/release/dev/UI/projects/transaction-search"
}
1 change: 1 addition & 0 deletions UI/projects/transaction-search/src/lib/models/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './transaction.model';
39 changes: 39 additions & 0 deletions UI/projects/transaction-search/src/lib/models/transaction.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Transaction, BlockTransactionString } from 'web3-eth';
import Web3 from 'web3';

export interface ITransactionLog {
role: TransactionRole;
transaction: Transaction;
block: BlockTransactionString;
submittedDate: Date;
amount: number;
}

export interface ITransactionPayload {
address: string;
data: string;
topics: string[];
logIndex: number;
transactionIndex: number;
transactionHash: string;
blockHash: string;
blockNumber: number;
removed: boolean;
}

export interface TransactionOptions {
web3: Web3;
pagination: {
page: number;
limit: number;
};
address: {
smartContractAddress: string;
accountAddress: string;
};
}

export enum TransactionRole {
Sender = 'As Sender',
Receiver = 'As Receiver'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';

import { TransactionService } from './transaction.service';

describe('TransactionService', () => {
let service: TransactionService;

beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(TransactionService);
});

it('should be created', () => {
expect(service).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { Injectable } from '@angular/core';
import Web3 from 'web3';
import { ITransactionLog, ITransactionPayload, TransactionOptions, TransactionRole } from '../models/transaction.model';
import { Transaction, BlockTransactionString } from 'web3-eth';
@Injectable({
providedIn: 'root'
})
export class TransactionService {
async getTransactions(options: TransactionOptions): Promise<ITransactionLog[]> {
const latestBlock: number = await options.web3.eth.getBlockNumber();
const { page, limit } = options.pagination;
const fromBlock: number = latestBlock - page * limit;
const transferEventSignature: string = options.web3.utils.sha3(
'Transfer(address,address,uint256,uint256)'
) as string;
const myAddressPadded: string = options.web3.utils.padLeft(options.address.accountAddress, 64);

const senderTopics: (string | null)[] = [transferEventSignature, null, myAddressPadded];
const receiverTopics: (string | null)[] = [transferEventSignature, myAddressPadded, null];

const [senderLogs, receiverLogs] = await Promise.all([
this.getTransactionLogs(
options.web3,
fromBlock,
senderTopics as string[],
TransactionRole.Sender,
options.address.smartContractAddress
),
this.getTransactionLogs(
options.web3,
fromBlock,
receiverTopics as string[],
TransactionRole.Receiver,
options.address.smartContractAddress
)
]);

const allLogs: ITransactionLog[] = [...senderLogs, ...receiverLogs];
const sortedLogs: ITransactionLog[] = allLogs.sort((a, b) => b.submittedDate.getTime() - a.submittedDate.getTime());

return sortedLogs;
}

async getTransactionLogs(
web3: Web3,
fromBlock: number,
topics: string[],
role: TransactionRole,
contractAddress: string
): Promise<ITransactionLog[]> {
try {
const res: ITransactionPayload[] = await web3.eth.getPastLogs({
fromBlock,
address: contractAddress,
topics
});

const processedLogs: ITransactionLog[] = await Promise.all(
res.map(async (rec: ITransactionPayload) => {
const transaction: Transaction = await web3.eth.getTransaction(rec.transactionHash);
const block: BlockTransactionString = await web3.eth.getBlock(rec.blockNumber);
const submittedDate: string | number = (await web3.eth.getBlock(rec.blockNumber)).timestamp;
const submittedDateFormatted = new Date((submittedDate as number) * 1000);

return {
role,
transaction,
block,
submittedDate: submittedDateFormatted,
amount: Number(web3.utils.fromWei(transaction.value, 'ether'))
};
})
);

return processedLogs;
} catch {
return [];
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { TransactionSearchComponent } from './transaction-search.component';

describe('TransactionSearchComponent', () => {
let component: TransactionSearchComponent;
let fixture: ComponentFixture<TransactionSearchComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [TransactionSearchComponent]
}).compileComponents();

fixture = TestBed.createComponent(TransactionSearchComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Component } from '@angular/core';

@Component({
selector: 'lib-transaction-search',
template: ` <p>transaction-search works!</p> `,
styles: []
})
export class TransactionSearchComponent {}
Loading

0 comments on commit 282da88

Please sign in to comment.