import { web3 } from 'src/app/services/web3-instance';
import { CampaignList } from './../models/campaign-list';
import { Injectable } from '@angular/core';
import CampaignFactoryContract from './campaign-factory';
import Campaign from './campaign';
import {
BehaviorSubject,
from,
map,
Observable,
ObservableInput,
Subject,
} from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class CampaignService {
private web3js: any;
CampaignFactoryContract: any;
CampaignContract: any;
account!: string;
private txHash: BehaviorSubject<string> = new BehaviorSubject<string>('');
public txHash$ = this.txHash.asObservable();
private stopTxHash: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(
false
);
public get stopTxHash$() {
return this.stopTxHash;
}
constructor() {
this.web3js = web3;
this.CampaignFactoryContract = CampaignFactoryContract;
this.getAccounts().subscribe((acc) => (this.account = acc));
}
public getAccounts() {
return from<string>(this.web3js.eth.getAccounts()).pipe(
map((accounts) => {
return accounts[0];
})
);
}
/**
* CampaignFactory create a Campaign
* @param libelle
* @param minimumContribution
*/
public createCampaign(
libelle: string,
minimumContribution: number
): Observable<any> {
return from(
this.CampaignFactoryContract.methods
.createCampaign(this.web3js.utils.toWei(minimumContribution), libelle)
.send({ from: this.account })
.on('transactionHash', (hash: string) => {
this.txHash.next(hash);
})
);
}
/**
* Returns a list of deployed campaigns
* @returns CampaignList[]
*/
public async getDeployedCampaigns(): Promise<CampaignList[]> {
const campaignsCount = await this.CampaignFactoryContract.methods
.getDeployedCampaignsCount()
.call();
const campaigns = await Promise.all(
Array(parseInt(campaignsCount))
.fill(campaignsCount)
.map((element, index) => {
return this.CampaignFactoryContract.methods
.deployedCampaigns(index)
.call();
})
);
return campaigns;
}
public getSummary(address: string): Observable<any> {
this.instantiateCampaignContract(address);
return from<ObservableInput<any>>(
this.CampaignContract.methods.getSummary().call()
).pipe(
map((summary: any) => {
return {
libelle: summary[0],
minimumContribution: this.web3js.utils.fromWei(summary[1]),
balance: this.web3js.utils.fromWei(summary[2]),
requests: summary[3],
approversCount: summary[4],
manager: summary[5],
};
})
);
}
public contribute(address: string, amount: number): Observable<any> {
this.instantiateCampaignContract(address);
return from(
this.CampaignContract.methods
.contribute()
.send({ from: this.account, value: web3.utils.toWei(amount, 'ether') })
.on('transactionHash', (hash: string) => {
this.txHash.next(hash);
})
);
}
public getRequestsCount(address: string): Observable<string> {
this.instantiateCampaignContract(address);
return from<string>(
this.CampaignContract.methods
.getRequestsCount()
.call({ from: this.account })
);
}
public getApproversCount(address: string): Observable<string> {
this.instantiateCampaignContract(address);
return from<string>(
this.CampaignContract.methods
.approversCount()
.call({ from: this.account })
);
}
public getRequests(address: string): Observable<Request[]> {
let requests = null;
let subject = new Subject<Request[]>();
this.getRequestsCount(address).subscribe(async (count) => {
requests = await Promise.all(
Array(parseInt(count))
.fill(count)
.map((element, index) => {
return this.CampaignContract.methods.requests(index).call();
})
);
subject.next(requests);
});
return subject.asObservable();
}
public createRequest(
address: string,
description: string,
value: number,
recipient: string
): Observable<any> {
this.instantiateCampaignContract(address);
return from(
this.CampaignContract.methods
.createRequest(description, web3.utils.toWei(value, 'ether'), recipient)
.send({ from: this.account })
.on('transactionHash', (hash: string) => {
this.txHash.next(hash);
})
);
}
public approveRequest(address: string, requestId: number): Observable<any> {
this.instantiateCampaignContract(address);
return from(
this.CampaignContract.methods
.approveRequest(requestId)
.send({ from: this.account })
.on('transactionHash', (hash: string) => {
this.txHash.next(hash);
})
);
}
public finalizeRequest(address: string, requestId: number): Observable<any> {
this.instantiateCampaignContract(address);
return from(
this.CampaignContract.methods
.finalizeRequest(requestId)
.send({ from: this.account })
.on('transactionHash', (hash: string) => {
this.txHash.next(hash);
})
);
}
public getManager(address: string): Observable<string> {
this.instantiateCampaignContract(address);
return from<string>(this.CampaignContract.methods.manager().call());
}
private instantiateCampaignContract(address: string) {
this.CampaignContract = Campaign(address);
}
public getBalanceOfAddress(address: string):Observable<string> {
return from<string>(this.web3js.eth.getBalance(address)).pipe(map(bal => {return this.web3js.utils.fromWei(bal)}));
}
public isAnApprover(campaignAddress: string, userAddress: string): Observable<any> {
this.instantiateCampaignContract(campaignAddress);
return from<any>(this.CampaignContract.methods.approvers(userAddress).call());
}
}