forked from DAVFoundation/dav-js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Contracts.js
161 lines (160 loc) · 7.69 KB
/
Contracts.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Web3 = require("web3");
const common_enums_1 = require("./common-enums");
const rxjs_1 = require("rxjs");
const sdkLogger_1 = require("./sdkLogger");
let contracts = {
Identity: require('./contracts/Identity'),
DAVToken: require('./contracts/DAVToken'),
BasicMission: require('./contracts/BasicMission'),
};
const REGISTRATION_REQUEST_HASH = new Web3().utils.sha3('DAV Identity Registration');
const TOKEN_AMOUNT = '1500000000000000000'; // TODO: TOKEN_AMOUNT need to be set by basicMission contract.
class Contracts {
static initWeb3(config) {
return new Web3(new Web3.providers.HttpProvider(config.ethNodeUrl));
}
static getContract(contractType, web3, config) {
if (config.contracts) {
contracts = config.contracts;
}
const abi = contracts[contractType].abi;
const contractAddress = contracts[contractType].networks[config.blockchainType].address;
const contract = new web3.eth.Contract(abi, contractAddress);
return { abi, contractAddress, contract };
}
static sendSignedTransaction(web3, rawTransaction) {
return new Promise((resolve, reject) => {
const transaction = web3.eth.sendSignedTransaction(rawTransaction);
transaction.once('receipt', receipt => {
sdkLogger_1.default(`Web3 transaction succeeded: ${JSON.stringify(receipt)}`);
resolve(receipt);
});
transaction.once('transactionHash', hash => {
sdkLogger_1.default(`Web3 transaction sent: ${hash}`);
});
transaction.on('error', err => {
sdkLogger_1.default(`Web3 transaction failed: ${JSON.stringify(err)}`);
reject(err);
});
});
}
static async checkContractPastEvents(contract /* , filterParam: string */) {
// TODO: Filter getPastEvents by sellerId or by missionId.
const event = await contract.getPastEvents('allEvents');
return event;
}
static toSafeGasLimit(gasAmount) {
return Math.min(gasAmount + 100, 4000000);
}
static calculatePrice(price) {
return '150000000000000000';
}
static generateMissionId(config) {
const web3 = Contracts.initWeb3(config);
const { address } = web3.eth.accounts.create();
return address;
}
static async isIdentityRegistered(davId, config) {
const web3 = Contracts.initWeb3(config);
const { contract } = Contracts.getContract(common_enums_1.ContractTypes.identity, web3, config);
const receipt = await contract.methods.isRegistered(davId).call();
return receipt;
}
static async registerIdentity(davId, identityPrivateKey, walletAddress, walletPrivateKey, config) {
const isAlreadyRegistered = await Contracts.isIdentityRegistered(davId, config);
if (isAlreadyRegistered) {
return 'ALREADY_REGISTERED';
}
const web3 = Contracts.initWeb3(config);
const { contract, contractAddress } = Contracts.getContract(common_enums_1.ContractTypes.identity, web3, config);
const { sign } = web3.eth.accounts.privateKeyToAccount(identityPrivateKey);
const { v, r, s } = sign(REGISTRATION_REQUEST_HASH);
const { encodeABI, estimateGas } = await contract.methods.register(davId, v, r, s);
const tx = {
data: encodeABI(),
to: contractAddress,
from: walletAddress,
gas: Contracts.toSafeGasLimit(await estimateGas({ from: walletAddress })),
gasPrice: await web3.eth.getGasPrice(),
};
const { rawTransaction } = await web3.eth.accounts.signTransaction(tx, walletPrivateKey);
const transactionReceipt = await Contracts.sendSignedTransaction(web3, rawTransaction);
return transactionReceipt.transactionHash;
}
static async approveMission(davId, walletPrivateKey, config) {
const web3 = Contracts.initWeb3(config);
const { contract, contractAddress } = Contracts.getContract(common_enums_1.ContractTypes.davToken, web3, config);
const missionContract = Contracts.getContract(common_enums_1.ContractTypes.basicMission, web3, config);
const { encodeABI, estimateGas } = await contract.methods.approve(missionContract.contractAddress, TOKEN_AMOUNT);
const tx = {
data: encodeABI(),
to: contractAddress,
from: davId,
gas: Contracts.toSafeGasLimit(await estimateGas({ from: davId, to: contractAddress })),
gasPrice: await web3.eth.getGasPrice(),
};
const { rawTransaction } = await web3.eth.accounts.signTransaction(tx, walletPrivateKey);
const transactionReceipt = await Contracts.sendSignedTransaction(web3, rawTransaction);
return transactionReceipt;
}
static async startMission(missionId, davId, walletPrivateKey, vehicleId, price, config) {
const fullPrice = Contracts.calculatePrice(price);
const web3 = Contracts.initWeb3(config);
const { contract, contractAddress } = Contracts.getContract(common_enums_1.ContractTypes.basicMission, web3, config);
const { encodeABI, estimateGas } = await contract.methods.create(missionId, vehicleId, davId, TOKEN_AMOUNT);
const tx = {
data: encodeABI(),
to: contractAddress,
from: davId,
gas: Contracts.toSafeGasLimit(await estimateGas({
from: davId,
to: contractAddress,
value: fullPrice,
})),
value: fullPrice,
gasPrice: await web3.eth.getGasPrice(),
};
const { rawTransaction } = await web3.eth.accounts.signTransaction(tx, walletPrivateKey);
const transactionReceipt = await Contracts.sendSignedTransaction(web3, rawTransaction);
return transactionReceipt;
}
static async finalizeMission(missionId, davId, walletPrivateKey, config) {
const web3 = Contracts.initWeb3(config);
const { contract, contractAddress } = Contracts.getContract(common_enums_1.ContractTypes.basicMission, web3, config);
const { encodeABI, estimateGas } = await contract.methods.fulfilled(missionId);
const tx = {
data: encodeABI(),
to: contractAddress,
from: davId,
gas: Contracts.toSafeGasLimit(await estimateGas({ from: davId })),
gasPrice: await web3.eth.getGasPrice(),
};
const { rawTransaction } = await web3.eth.accounts.signTransaction(tx, walletPrivateKey);
const transactionReceipt = await Contracts.sendSignedTransaction(web3, rawTransaction);
return transactionReceipt;
}
static watchContract(davId, contractType, config) {
const web3 = Contracts.initWeb3(config);
const { contract } = Contracts.getContract(contractType, web3, config);
let lastBlock = 0;
let lastTransactionIndex = 0;
const events = rxjs_1.Observable.interval(2000)
.map(() => Contracts.checkContractPastEvents(contract /* , davId */))
.map(promise => rxjs_1.Observable.fromPromise(promise))
.map(eventsObservable => eventsObservable.mergeAll())
.map(eventsArray => rxjs_1.Observable.from(eventsArray))
.mergeAll()
.filter(event => event.blockNumber > lastBlock ||
(event.blockNumber === lastBlock &&
event.transactionIndex > lastTransactionIndex))
.do(event => {
lastBlock = event.blockNumber;
lastTransactionIndex = event.transactionIndex;
});
return events;
}
}
exports.default = Contracts;
//# sourceMappingURL=Contracts.js.map