@leofcoin/chain 1.3.9 → 1.3.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/demo/chain.browser.js +7663 -570
- package/demo/workers/machine-worker.js +28 -566
- package/dist/865.browser.js +10 -0
- package/dist/browser/workers/machine-worker.js +1 -1
- package/dist/chain.browser.js +66838 -0
- package/dist/chain.js +467 -283
- package/dist/generate-account.browser.js +50 -0
- package/dist/messages.browser.js +328 -0
- package/dist/module/chain.js +462 -279
- package/dist/module/workers/machine-worker.js +1 -1
- package/dist/multi-wallet.browser.js +15 -0
- package/dist/node.browser.js +9858 -0
- package/dist/pako.browser.js +6900 -0
- package/dist/peernet-swarm.browser.js +839 -0
- package/dist/storage.browser.js +3724 -0
- package/dist/workers/machine-worker.js +1 -1
- package/dist/wrtc.browser.js +28 -0
- package/package.json +4 -3
- package/rollup.config.js +17 -27
- package/src/chain.js +119 -253
- package/src/contract.js +51 -0
- package/src/machine.js +10 -5
- package/src/protocol.js +3 -0
- package/src/state.js +2 -2
- package/src/transaction.js +233 -0
- package/src/type.index.d.ts +21 -0
- package/test/chain.js +16 -14
- package/webpack.config.js +2 -1
package/dist/module/chain.js
CHANGED
|
@@ -3,10 +3,11 @@ import _BN from 'bn.js';
|
|
|
3
3
|
import '@ethersproject/bytes';
|
|
4
4
|
import { Logger } from '@ethersproject/logger';
|
|
5
5
|
import '@ethersproject/bignumber';
|
|
6
|
-
import { randomBytes } from '
|
|
7
|
-
import { join } from '
|
|
6
|
+
import { randomBytes } from 'crypto';
|
|
7
|
+
import { join } from 'path';
|
|
8
8
|
import EasyWorker from '@vandeurenglenn/easy-worker';
|
|
9
9
|
import { FormatInterface } from '@leofcoin/codec-format-interface';
|
|
10
|
+
import pako from 'pako';
|
|
10
11
|
import MultiWallet from '@leofcoin/multi-wallet';
|
|
11
12
|
import { CodecHash } from '@leofcoin/codec-format-interface/dist/index';
|
|
12
13
|
import bs32 from '@vandeurenglenn/base32';
|
|
@@ -15,17 +16,17 @@ var contractFactory$2 = "ihny2gqg6c6mwy5mhbrs5ulkkozsgwtk5vuz5krjidouy4mbwfdbjnb
|
|
|
15
16
|
var nativeToken$2 = "ihny2gqhoockyg7yg4n5bpxuldahfavpqnmpoe2bn4ivnxmk7redc2ltwkb";
|
|
16
17
|
var nameService$2 = "ihny2gqgztp3vj6qy7fgrfer7y5c5hxnp6imdz6v5spi4edkwtm5fkd5z2h";
|
|
17
18
|
var validators$2 = "ihny2gqh4e2pr4pbtpkamhj3htsvuoydy3wotaudoeaktgcdwmoij66pecp";
|
|
18
|
-
var addresses = {
|
|
19
|
+
var addresses$1 = {
|
|
19
20
|
contractFactory: contractFactory$2,
|
|
20
21
|
nativeToken: nativeToken$2,
|
|
21
22
|
nameService: nameService$2,
|
|
22
23
|
validators: validators$2
|
|
23
24
|
};
|
|
24
25
|
|
|
25
|
-
const contractFactory$1 = addresses.contractFactory;
|
|
26
|
-
const nameService$1 = addresses.nameService;
|
|
27
|
-
const nativeToken$1 = addresses.nativeToken;
|
|
28
|
-
const validators$1 = addresses.validators;
|
|
26
|
+
const contractFactory$1 = addresses$1.contractFactory;
|
|
27
|
+
const nameService$1 = addresses$1.nameService;
|
|
28
|
+
const nativeToken$1 = addresses$1.nativeToken;
|
|
29
|
+
const validators$1 = addresses$1.validators;
|
|
29
30
|
|
|
30
31
|
const version$1 = "bignumber/5.6.2";
|
|
31
32
|
|
|
@@ -125,7 +126,7 @@ message BlockMessage {
|
|
|
125
126
|
}
|
|
126
127
|
`;
|
|
127
128
|
|
|
128
|
-
class BlockMessage extends FormatInterface {
|
|
129
|
+
class BlockMessage$1 extends FormatInterface {
|
|
129
130
|
get keys() {
|
|
130
131
|
return ['index', 'previousHash', 'timestamp', 'reward', 'fees', 'transactions', 'validators']
|
|
131
132
|
}
|
|
@@ -289,22 +290,27 @@ class Machine {
|
|
|
289
290
|
|
|
290
291
|
}
|
|
291
292
|
|
|
293
|
+
/**
|
|
294
|
+
*
|
|
295
|
+
* @param {Address} contract
|
|
296
|
+
* @param {String} method
|
|
297
|
+
* @param {Array} parameters
|
|
298
|
+
* @returns Promise<message>
|
|
299
|
+
*/
|
|
292
300
|
async execute(contract, method, parameters) {
|
|
293
|
-
/** */
|
|
294
301
|
try {
|
|
295
302
|
if (contract === contractFactory$1 && method === 'registerContract') {
|
|
296
303
|
if (this.#contracts[parameters[0]]) throw new Error(`duplicate contract @${parameters[0]}`)
|
|
297
304
|
let message;
|
|
298
|
-
if (!contractStore.has(parameters[0])) {
|
|
305
|
+
if (!await contractStore.has(parameters[0])) {
|
|
299
306
|
message = await peernet.get(parameters[0], 'contract');
|
|
300
|
-
message = new ContractMessage(message);
|
|
307
|
+
message = await new ContractMessage(message);
|
|
301
308
|
await contractStore.put(await message.hash, message.encoded);
|
|
302
309
|
}
|
|
303
310
|
if (!message) {
|
|
304
311
|
message = await contractStore.get(parameters[0]);
|
|
305
|
-
message = new ContractMessage(message);
|
|
312
|
+
message = await new ContractMessage(message);
|
|
306
313
|
}
|
|
307
|
-
|
|
308
314
|
if (!this.#contracts[await message.hash]) await this.#runContract(message);
|
|
309
315
|
}
|
|
310
316
|
} catch (error) {
|
|
@@ -418,24 +424,397 @@ const calculateFee = async transaction => {
|
|
|
418
424
|
return Number.parseFloat(fee.toString()).toFixed(decimals)
|
|
419
425
|
};
|
|
420
426
|
|
|
427
|
+
class State {
|
|
428
|
+
constructor() {
|
|
429
|
+
// return this.#init()
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// async #init() {
|
|
433
|
+
// const state = await stateStore.get()
|
|
434
|
+
// for (const [key, value] of Object.entries(state)) {
|
|
435
|
+
//
|
|
436
|
+
// }
|
|
437
|
+
//
|
|
438
|
+
// return this
|
|
439
|
+
// }
|
|
440
|
+
|
|
441
|
+
async put(key, value, isCompressed = true) {
|
|
442
|
+
value = isCompressed ? value : await pako.deflate(value);
|
|
443
|
+
await stateStore.put(key, value);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
async get(key, isCompressed = true) {
|
|
447
|
+
const value = await stateStore.get(key);
|
|
448
|
+
return isCompressed = pako.inflate(value)
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
updateState(block) {
|
|
452
|
+
// block.decoded.index
|
|
453
|
+
// this.#isUpdateNeeded()
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
class Protocol {
|
|
458
|
+
limit = 1800
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
class Transaction extends Protocol {
|
|
462
|
+
constructor() {
|
|
463
|
+
super();
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
*
|
|
468
|
+
* @param {Address[]} transactions
|
|
469
|
+
* @returns transactions to include
|
|
470
|
+
*/
|
|
471
|
+
async getTransactions (transactions) {
|
|
472
|
+
return new Promise(async (resolve, reject) => {
|
|
473
|
+
let size = 0;
|
|
474
|
+
const _transactions = [];
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
await Promise.all(transactions
|
|
478
|
+
.map(async tx => {
|
|
479
|
+
tx = await new TransactionMessage(tx);
|
|
480
|
+
size += tx.encoded.length;
|
|
481
|
+
if (!formatBytes(size).includes('MB') || formatBytes(size).includes('MB') && Number(formatBytes(size).split(' MB')[0]) <= 0.75) _transactions.push({...tx.decoded, hash: await tx.hash});
|
|
482
|
+
else resolve(_transactions);
|
|
483
|
+
}));
|
|
484
|
+
|
|
485
|
+
return resolve(_transactions)
|
|
486
|
+
})
|
|
487
|
+
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
*
|
|
492
|
+
* @param {Transaction[]} transactions An array containing Transactions
|
|
493
|
+
* @returns {TransactionMessage}
|
|
494
|
+
*/
|
|
495
|
+
async promiseTransactions(transactions) {
|
|
496
|
+
transactions = await Promise.all(transactions.map(tx => new TransactionMessage(tx)));
|
|
497
|
+
return transactions
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
*
|
|
502
|
+
* @param {Transaction[]} transactions An array containing Transactions
|
|
503
|
+
* @returns {Object} {transaction.decoded, transaction.hash}
|
|
504
|
+
*/
|
|
505
|
+
async promiseTransactionsContent(transactions) {
|
|
506
|
+
transactions = await Promise.all(transactions.map(tx => new Promise(async (resolve, reject) => {
|
|
507
|
+
resolve({ ...tx.decoded, hash: await tx.hash });
|
|
508
|
+
})));
|
|
509
|
+
|
|
510
|
+
return transactions
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* When a nonce isn't found for an address fallback to just checking the transactionnPoolStore
|
|
515
|
+
* @param {Address} address
|
|
516
|
+
* @returns {Number} nonce
|
|
517
|
+
*/
|
|
518
|
+
async #getNonceFallback(address) {
|
|
519
|
+
let transactions = await transactionPoolStore.values();
|
|
520
|
+
transactions = await this.promiseTransactions(transactions);
|
|
521
|
+
transactions = transactions.filter(tx => tx.decoded.from === address);
|
|
522
|
+
transactions = await this.promiseTransactionsContent(transactions);
|
|
523
|
+
|
|
524
|
+
if (this.lastBlock?.hash && transactions.length === 0 && this.lastBlock.hash !== '0x0') {
|
|
525
|
+
|
|
526
|
+
let block = await peernet.get(this.lastBlock.hash);
|
|
527
|
+
block = await new BlockMessage(block);
|
|
528
|
+
|
|
529
|
+
// for (let tx of block.decoded?.transactions) {
|
|
530
|
+
// tx = await peernet.get(tx, 'transaction')
|
|
531
|
+
// transactions.push(new TransactionMessage(tx))
|
|
532
|
+
// }
|
|
533
|
+
transactions = transactions.filter(tx => tx.from === address);
|
|
534
|
+
while (transactions.length === 0 && block.decoded.index !== 0 && block.decoded.previousHash !== '0x0') {
|
|
535
|
+
block = await blockStore.get(block.decoded.previousHash);
|
|
536
|
+
block = await new BlockMessage(block);
|
|
537
|
+
transactions = block.decoded.transactions.filter(tx => tx.from === address);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
}
|
|
541
|
+
if (transactions.length === 0) return 0
|
|
542
|
+
|
|
543
|
+
transactions = transactions.sort((a, b) => a.timestamp - b.timestamp);
|
|
544
|
+
return transactions[transactions.length - 1].nonce
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/**
|
|
548
|
+
* Get amount of transactions by address
|
|
549
|
+
* @param {Address} address The address to get the nonce for
|
|
550
|
+
* @returns {Number} nonce
|
|
551
|
+
*/
|
|
552
|
+
async getNonce(address) {
|
|
553
|
+
if (!await accountsStore.has(address)) {
|
|
554
|
+
const nonce = await this.#getNonceFallback(address);
|
|
555
|
+
await accountsStore.put(address, new TextEncoder().encode(String(nonce)));
|
|
556
|
+
}
|
|
557
|
+
// todo: are those in the pool in cluded also ? they need to be included!!!
|
|
558
|
+
let nonce = await accountsStore.get(address);
|
|
559
|
+
nonce = new TextDecoder().decode(nonce);
|
|
560
|
+
return Number(nonce)
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* whenever method = createContract params should hold the contract hash
|
|
565
|
+
*
|
|
566
|
+
* example: [hash]
|
|
567
|
+
* createTransaction('0x0', 'createContract', [hash])
|
|
568
|
+
*
|
|
569
|
+
* @param {String} to - the contract address for the contract to interact with
|
|
570
|
+
* @param {String} method - the method/function to run
|
|
571
|
+
* @param {Array} params - array of paramters to apply to the contract method
|
|
572
|
+
* @param {Number} nonce - total transaction count [optional]
|
|
573
|
+
*/
|
|
574
|
+
async createTransaction(to, method, parameters, nonce, signature) {
|
|
575
|
+
return this.createTransactionFrom(peernet.selectedAccount, to, method, parameters, nonce)
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
*
|
|
580
|
+
* @param {Transaction} transaction
|
|
581
|
+
* @param {String} transaction.from address
|
|
582
|
+
* @param {String} transaction.to address
|
|
583
|
+
* @param {Object} transaction.params {}
|
|
584
|
+
* @param {String} transaction.params.method get, call
|
|
585
|
+
* @param {Buffer} transaction.params.data
|
|
586
|
+
* @returns
|
|
587
|
+
*/
|
|
588
|
+
async createTransactionHash(transaction) {
|
|
589
|
+
// todo: validate
|
|
590
|
+
const peernetHash = await new CodecHash(transaction, {name: 'transaction-message'});
|
|
591
|
+
return peernetHash.digest
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* @param {Transaction} transaction
|
|
596
|
+
* @param {object} wallet any wallet/signer that supports sign(RAWtransaction)
|
|
597
|
+
*/
|
|
598
|
+
async #signTransaction (transaction, wallet) {
|
|
599
|
+
return wallet.sign(await this.createTransactionHash(transaction))
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
*
|
|
604
|
+
* @param {RawTransaction} transaction
|
|
605
|
+
* @param {Signer} signer
|
|
606
|
+
* @returns {Transaction} a signed transaction
|
|
607
|
+
*/
|
|
608
|
+
async signTransaction(transaction, signer) {
|
|
609
|
+
let identity = await walletStore.get('identity');
|
|
610
|
+
identity = JSON.parse(new TextDecoder().decode(identity));
|
|
611
|
+
const wallet = new MultiWallet(peernet.network);
|
|
612
|
+
wallet.recover(identity.mnemonic);
|
|
613
|
+
const account = wallet.account(0).external(0);
|
|
614
|
+
transaction.signature = await this.#signTransaction(transaction, account);
|
|
615
|
+
transaction.signature = bs32.encode(transaction.signature);
|
|
616
|
+
return transaction
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
*
|
|
621
|
+
* @param {Transaction} transaction
|
|
622
|
+
* @param {Address} transaction.from
|
|
623
|
+
* @param {Address} transaction.to
|
|
624
|
+
* @param {String} transaction.method
|
|
625
|
+
* @param {Array} transaction.params
|
|
626
|
+
* @param {Number} transaction.nonce
|
|
627
|
+
*
|
|
628
|
+
* @returns {RawTransaction} transaction
|
|
629
|
+
*/
|
|
630
|
+
async ensureNonce(transaction) {
|
|
631
|
+
if (!transaction.from) transaction.from = peernet.selectedAccount;
|
|
632
|
+
transaction.timestamp = Date.now();
|
|
633
|
+
|
|
634
|
+
if (transaction.nonce === undefined) {
|
|
635
|
+
transaction.nonce = await this.getNonce(transaction.from);
|
|
636
|
+
} else {
|
|
637
|
+
let nonce = await accountsStore.get(transaction.from);
|
|
638
|
+
nonce = new TextDecoder().decode(nonce);
|
|
639
|
+
if (transaction.nonce < nonce) throw new Error(`a transaction with a higher nonce already exists`)
|
|
640
|
+
if (transaction.nonce === nonce) throw new Error(`a transaction with the same nonce already exists`)
|
|
641
|
+
}
|
|
642
|
+
return transaction
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
* every tx done is trough contracts so no need for amount
|
|
647
|
+
* data is undefined when nothing is returned
|
|
648
|
+
* error is thrown on error so undefined data doesn't mean there is an error...
|
|
649
|
+
*
|
|
650
|
+
* @param {Address} from - the sender address
|
|
651
|
+
* @param {Address} to - the contract address for the contract to interact with
|
|
652
|
+
* @param {String} method - the method/function to run
|
|
653
|
+
* @param {Array} params - array of paramters to apply to the contract method
|
|
654
|
+
* @param {Number} nonce - total transaction count [optional]
|
|
655
|
+
*/
|
|
656
|
+
async createTransactionFrom(from, to, method, parameters, nonce) {
|
|
657
|
+
try {
|
|
658
|
+
const rawTransaction = await this.ensureNonce({from, to, nonce, method, params: parameters});
|
|
659
|
+
const transaction = await this.signTransaction(rawTransaction, from);
|
|
660
|
+
const message = await new TransactionMessage(transaction);
|
|
661
|
+
|
|
662
|
+
let data;
|
|
663
|
+
const wait = () => new Promise(async (resolve, reject) => {
|
|
664
|
+
if (pubsub.subscribers[`transaction.completed.${await message.hash}`]) {
|
|
665
|
+
const result = pubsub.subscribers[`transaction.completed.${await message.hash}`].value;
|
|
666
|
+
result.status === 'fulfilled' ? resolve(await result.hash) : reject({hash: await result.hash, error: result.error});
|
|
667
|
+
} else {
|
|
668
|
+
const completed = async result => {
|
|
669
|
+
result.status === 'fulfilled' ? resolve(await result.hash) : reject({hash: await result.hash, error: result.error});
|
|
670
|
+
|
|
671
|
+
setTimeout(async () => {
|
|
672
|
+
pubsub.unsubscribe(`transaction.completed.${await message.hash}`, completed);
|
|
673
|
+
}, 10_000);
|
|
674
|
+
};
|
|
675
|
+
pubsub.subscribe(`transaction.completed.${await message.hash}`, completed);
|
|
676
|
+
}
|
|
677
|
+
});
|
|
678
|
+
await transactionPoolStore.put(await message.hash, message.encoded);
|
|
679
|
+
peernet.publish('add-transaction', message.encoded);
|
|
680
|
+
return {hash: await message.hash, data, fee: await calculateFee(message.decoded), wait, message}
|
|
681
|
+
} catch (error) {
|
|
682
|
+
console.log(error);
|
|
683
|
+
throw error
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* @extends {Transaction}
|
|
690
|
+
*/
|
|
691
|
+
class Contract extends Transaction {
|
|
692
|
+
constructor() {
|
|
693
|
+
super();
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
/**
|
|
697
|
+
*
|
|
698
|
+
* @param {Address} creator
|
|
699
|
+
* @param {String} contract
|
|
700
|
+
* @param {Array} constructorParameters
|
|
701
|
+
* @returns lib.createContractMessage
|
|
702
|
+
*/
|
|
703
|
+
async createContractMessage(creator, contract, constructorParameters = []) {
|
|
704
|
+
return createContractMessage(creator, contract, constructorParameters)
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
/**
|
|
708
|
+
*
|
|
709
|
+
* @param {Address} creator
|
|
710
|
+
* @param {String} contract
|
|
711
|
+
* @param {Array} constructorParameters
|
|
712
|
+
* @returns {Address}
|
|
713
|
+
*/
|
|
714
|
+
async createContractAddress(creator, contract, constructorParameters = []) {
|
|
715
|
+
contract = await this.createContractMessage(creator, contract, constructorParameters);
|
|
716
|
+
return contract.hash
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
/**
|
|
720
|
+
*
|
|
721
|
+
* @param {String} contract
|
|
722
|
+
* @param {Array} parameters
|
|
723
|
+
* @returns
|
|
724
|
+
*/
|
|
725
|
+
async deployContract(contract, constructorParameters = []) {
|
|
726
|
+
const message = await createContractMessage(peernet.selectedAccount, contract, constructorParameters);
|
|
727
|
+
try {
|
|
728
|
+
await contractStore.put(await message.hash, message.encoded);
|
|
729
|
+
} catch (error) {
|
|
730
|
+
throw error
|
|
731
|
+
}
|
|
732
|
+
return this.createTransactionFrom(peernet.selectedAccount, addresses.contractFactory, 'registerContract', [await message.hash])
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
}
|
|
736
|
+
|
|
421
737
|
globalThis.BigNumber = BigNumber;
|
|
422
738
|
|
|
423
739
|
// check if browser or local
|
|
424
|
-
class Chain {
|
|
740
|
+
class Chain extends Contract {
|
|
741
|
+
/** {Address[]} */
|
|
425
742
|
#validators = []
|
|
743
|
+
/** {Block[]} */
|
|
426
744
|
#blocks = []
|
|
745
|
+
|
|
427
746
|
#machine
|
|
747
|
+
/** {Boolean} */
|
|
428
748
|
#runningEpoch = false
|
|
749
|
+
|
|
750
|
+
/** {Boolean} */
|
|
429
751
|
#chainSyncing = false
|
|
752
|
+
|
|
753
|
+
/** {Number} */
|
|
754
|
+
#totalSize = 0
|
|
755
|
+
|
|
756
|
+
/**
|
|
757
|
+
* {Block} {index, hash, previousHash}
|
|
758
|
+
*/
|
|
430
759
|
#lastBlock = {index: 0, hash: '0x0', previousHash: '0x0'}
|
|
760
|
+
|
|
761
|
+
/**
|
|
762
|
+
* amount the native token has been iteracted with
|
|
763
|
+
*/
|
|
764
|
+
#nativeCalls = 0
|
|
765
|
+
|
|
766
|
+
/**
|
|
767
|
+
* amount the native token has been iteracted with
|
|
768
|
+
*/
|
|
769
|
+
#nativeTransfers = 0
|
|
770
|
+
|
|
771
|
+
/**
|
|
772
|
+
* amount of native token burned
|
|
773
|
+
* {Number}
|
|
774
|
+
*/
|
|
775
|
+
#nativeBurns = 0
|
|
776
|
+
|
|
777
|
+
/**
|
|
778
|
+
* amount of native tokens minted
|
|
779
|
+
* {Number}
|
|
780
|
+
*/
|
|
781
|
+
#nativeMints = 0
|
|
782
|
+
|
|
783
|
+
/**
|
|
784
|
+
* total amount of transactions
|
|
785
|
+
* {Number}
|
|
786
|
+
*/
|
|
787
|
+
#totalTransactions = 0
|
|
788
|
+
|
|
431
789
|
#participants = []
|
|
432
790
|
#participating = false
|
|
433
791
|
#jail = []
|
|
434
792
|
|
|
435
793
|
constructor() {
|
|
794
|
+
super();
|
|
436
795
|
return this.#init()
|
|
437
796
|
}
|
|
438
797
|
|
|
798
|
+
get nativeMints() {
|
|
799
|
+
return this.#nativeMints
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
get nativeBurns() {
|
|
803
|
+
return this.#nativeBurns
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
get nativeTransfers() {
|
|
807
|
+
return this.#nativeTransfers
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
get totalTransactions() {
|
|
811
|
+
return this.#totalTransactions
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
get totalSize() {
|
|
815
|
+
return this.#totalSize
|
|
816
|
+
}
|
|
817
|
+
|
|
439
818
|
get lib() {
|
|
440
819
|
return lib
|
|
441
820
|
}
|
|
@@ -445,7 +824,7 @@ class Chain {
|
|
|
445
824
|
}
|
|
446
825
|
|
|
447
826
|
get nativeToken() {
|
|
448
|
-
return addresses.nativeToken
|
|
827
|
+
return addresses$1.nativeToken
|
|
449
828
|
}
|
|
450
829
|
|
|
451
830
|
get validators() {
|
|
@@ -465,10 +844,9 @@ class Chain {
|
|
|
465
844
|
async #runEpoch() {
|
|
466
845
|
this.#runningEpoch = true;
|
|
467
846
|
console.log('epoch');
|
|
468
|
-
const validators = await this.staticCall(addresses.validators, 'validators');
|
|
847
|
+
const validators = await this.staticCall(addresses$1.validators, 'validators');
|
|
469
848
|
console.log(validators);
|
|
470
849
|
if (!validators[peernet.selectedAccount]?.active) return
|
|
471
|
-
|
|
472
850
|
const start = Date.now();
|
|
473
851
|
try {
|
|
474
852
|
await this.#createBlock();
|
|
@@ -487,16 +865,16 @@ class Chain {
|
|
|
487
865
|
async #setup() {
|
|
488
866
|
|
|
489
867
|
const contracts = [{
|
|
490
|
-
address: addresses.contractFactory,
|
|
868
|
+
address: addresses$1.contractFactory,
|
|
491
869
|
message: contractFactoryMessage
|
|
492
870
|
}, {
|
|
493
|
-
address: addresses.nativeToken,
|
|
871
|
+
address: addresses$1.nativeToken,
|
|
494
872
|
message: nativeTokenMessage
|
|
495
873
|
}, {
|
|
496
|
-
address: addresses.validators,
|
|
874
|
+
address: addresses$1.validators,
|
|
497
875
|
message: validatorsMessage
|
|
498
876
|
}, {
|
|
499
|
-
address: addresses.nameService,
|
|
877
|
+
address: addresses$1.nameService,
|
|
500
878
|
message: nameServiceMessage
|
|
501
879
|
}];
|
|
502
880
|
|
|
@@ -554,7 +932,7 @@ class Chain {
|
|
|
554
932
|
|
|
555
933
|
if (latest.hash && latest.hash !== '0x0') {
|
|
556
934
|
latest = await peernet.get(latest.hash, block);
|
|
557
|
-
latest = await new BlockMessage(latest);
|
|
935
|
+
latest = await new BlockMessage$1(latest);
|
|
558
936
|
}
|
|
559
937
|
|
|
560
938
|
return latest
|
|
@@ -564,11 +942,13 @@ class Chain {
|
|
|
564
942
|
// this.node = await new Node()
|
|
565
943
|
this.#participants = [];
|
|
566
944
|
this.#participating = false;
|
|
567
|
-
const initialized = await contractStore.has(addresses.contractFactory);
|
|
945
|
+
const initialized = await contractStore.has(addresses$1.contractFactory);
|
|
568
946
|
if (!initialized) await this.#setup();
|
|
569
947
|
|
|
570
948
|
|
|
571
949
|
this.utils = { BigNumber, formatUnits, parseUnits };
|
|
950
|
+
|
|
951
|
+
this.state = new State();
|
|
572
952
|
|
|
573
953
|
try {
|
|
574
954
|
let localBlock;
|
|
@@ -581,7 +961,7 @@ class Chain {
|
|
|
581
961
|
localBlock = new TextDecoder().decode(localBlock);
|
|
582
962
|
if (localBlock && localBlock !== '0x0') {
|
|
583
963
|
localBlock = await peernet.get(localBlock, 'block');
|
|
584
|
-
localBlock = await new BlockMessage(localBlock);
|
|
964
|
+
localBlock = await new BlockMessage$1(localBlock);
|
|
585
965
|
this.#lastBlock = {...localBlock.decoded, hash: await localBlock.hash};
|
|
586
966
|
} else {
|
|
587
967
|
const latestBlock = await this.#getLatestBlock();
|
|
@@ -652,16 +1032,6 @@ class Chain {
|
|
|
652
1032
|
|
|
653
1033
|
#epochTimeout
|
|
654
1034
|
|
|
655
|
-
async #addTransaction(transaction) {
|
|
656
|
-
try {
|
|
657
|
-
transaction = await new TransactionMessage(transaction);
|
|
658
|
-
const has = await transactionPoolStore.has(await transaction.hash);
|
|
659
|
-
if (!has) await transactionPoolStore.put(await transaction.hash, transaction.encoded);
|
|
660
|
-
if (this.#participating && !this.#runningEpoch) this.#runEpoch();
|
|
661
|
-
} catch {
|
|
662
|
-
throw new Error('invalid transaction')
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
1035
|
|
|
666
1036
|
async #lastBlockHandler() {
|
|
667
1037
|
return new peernet.protos['peernet-response']({response: { hash: this.#lastBlock?.hash, index: this.#lastBlock?.index }})
|
|
@@ -670,9 +1040,10 @@ async #lastBlockHandler() {
|
|
|
670
1040
|
async resolveBlock(hash) {
|
|
671
1041
|
if (!hash) throw new Error(`expected hash, got: ${hash}`)
|
|
672
1042
|
let block = await peernet.get(hash, 'block');
|
|
673
|
-
block = await new BlockMessage(block);
|
|
1043
|
+
block = await new BlockMessage$1(block);
|
|
674
1044
|
if (!await peernet.has(hash, 'block')) await peernet.put(hash, block.encoded, 'block');
|
|
675
1045
|
const size = block.encoded.length > 0 ? block.encoded.length : block.encoded.byteLength;
|
|
1046
|
+
this.#totalSize += size;
|
|
676
1047
|
block = {...block.decoded, hash};
|
|
677
1048
|
if (this.#blocks[block.index] && this.#blocks[block.index].hash !== block.hash) throw `invalid block ${hash} @${block.index}`
|
|
678
1049
|
this.#blocks[block.index] = block;
|
|
@@ -698,37 +1069,29 @@ async resolveBlock(hash) {
|
|
|
698
1069
|
}
|
|
699
1070
|
}
|
|
700
1071
|
|
|
1072
|
+
/**
|
|
1073
|
+
*
|
|
1074
|
+
* @param {Block[]} blocks
|
|
1075
|
+
*/
|
|
701
1076
|
async #loadBlocks(blocks) {
|
|
702
1077
|
for (const block of blocks) {
|
|
703
1078
|
if (block && !block.loaded) {
|
|
704
1079
|
for (const transaction of block.transactions) {
|
|
705
1080
|
try {
|
|
706
1081
|
await this.#machine.execute(transaction.to, transaction.method, transaction.params);
|
|
707
|
-
|
|
1082
|
+
if (transaction.to === nativeToken$1) {
|
|
1083
|
+
this.#nativeCalls += 1;
|
|
1084
|
+
if (transaction.method === 'burn') this.#nativeBurns += 1;
|
|
1085
|
+
if (transaction.method === 'mint') this.#nativeMints += 1;
|
|
1086
|
+
if (transaction.method === 'transfer') this.#nativeTransfers += 1;
|
|
1087
|
+
}
|
|
1088
|
+
this.#totalTransactions += 1;
|
|
708
1089
|
} catch (error) {
|
|
709
1090
|
console.log(error);
|
|
710
1091
|
}
|
|
711
1092
|
}
|
|
712
1093
|
this.#blocks[block.index].loaded = true;
|
|
713
|
-
|
|
714
|
-
// let message = await peernet.get(block.hash, 'block')
|
|
715
|
-
|
|
716
|
-
// const compressed = pako.deflate(message);
|
|
717
|
-
// const result = pako.inflate(compressed);
|
|
718
|
-
// console.log(result.length, compressed.length);
|
|
719
|
-
//
|
|
720
|
-
// console.log(result.length - compressed.length);
|
|
721
|
-
|
|
722
|
-
// message = new BlockMessage(message)
|
|
723
|
-
// for (const transaction of message.decoded.transactions) {
|
|
724
|
-
// try {
|
|
725
|
-
// await this.#machine.execute(transaction.to, transaction.method, transaction.params)
|
|
726
|
-
//
|
|
727
|
-
// } catch (e) {
|
|
728
|
-
// // console.log(e);
|
|
729
|
-
// }
|
|
730
|
-
// }
|
|
731
|
-
// block.loaded = true
|
|
1094
|
+
debug(`loaded block: ${block.hash} @${block.index}`);
|
|
732
1095
|
}
|
|
733
1096
|
}
|
|
734
1097
|
}
|
|
@@ -747,26 +1110,10 @@ async resolveBlock(hash) {
|
|
|
747
1110
|
|
|
748
1111
|
async #addBlock(block) {
|
|
749
1112
|
// console.log(block);
|
|
750
|
-
const blockMessage = await new BlockMessage(new Uint8Array(Object.values(block)));
|
|
751
|
-
// if (!Buffer.isBuffer(block)) block = Buffer.from(block, 'hex')
|
|
752
|
-
// const transactionJob = async transaction => {
|
|
753
|
-
// try {
|
|
754
|
-
// transaction = await transactionPoolStore.get(transaction)
|
|
755
|
-
// } catch (e) {
|
|
756
|
-
// try {
|
|
757
|
-
// transaction = await peernet.get(transaction, 'transaction')
|
|
758
|
-
// } catch (e) {
|
|
759
|
-
// console.warn(`couldn't resolve ${transaction}`);
|
|
760
|
-
// }
|
|
761
|
-
// }
|
|
762
|
-
// transaction = new TransactionMessage(transaction)
|
|
763
|
-
// return transaction
|
|
764
|
-
// }
|
|
1113
|
+
const blockMessage = await new BlockMessage$1(new Uint8Array(Object.values(block)));
|
|
765
1114
|
await Promise.all(blockMessage.decoded.transactions
|
|
766
1115
|
.map(async transaction => transactionPoolStore.delete(await transaction.hash)));
|
|
767
1116
|
const hash = await blockMessage.hash;
|
|
768
|
-
// let transactions = blockMessage.decoded.transactions.map(tx => transactionJob(tx))
|
|
769
|
-
// transactions = await Promise.all(transactions)
|
|
770
1117
|
|
|
771
1118
|
await blockStore.put(hash, blockMessage.encoded);
|
|
772
1119
|
|
|
@@ -809,6 +1156,7 @@ async resolveBlock(hash) {
|
|
|
809
1156
|
async #updateState(message) {
|
|
810
1157
|
const hash = await message.hash;
|
|
811
1158
|
this.#lastBlock = { hash, ...message.decoded };
|
|
1159
|
+
await this.state.updateState(message);
|
|
812
1160
|
await chainStore.put('lastBlock', hash);
|
|
813
1161
|
}
|
|
814
1162
|
|
|
@@ -822,14 +1170,8 @@ async resolveBlock(hash) {
|
|
|
822
1170
|
// peerReputation(peerId)
|
|
823
1171
|
// {bandwith: {up, down}, uptime}
|
|
824
1172
|
this.#participating = true;
|
|
825
|
-
if (!await this.staticCall(addresses.validators, 'has', [address])) await this.createTransactionFrom(address, addresses.validators, 'addValidator', [address]);
|
|
1173
|
+
if (!await this.staticCall(addresses$1.validators, 'has', [address])) await this.createTransactionFrom(address, addresses$1.validators, 'addValidator', [address]);
|
|
826
1174
|
if (await this.hasTransactionToHandle() && !this.#runningEpoch) await this.#runEpoch();
|
|
827
|
-
|
|
828
|
-
// const runEpoch = () => setTimeout(async () => {
|
|
829
|
-
// if (await this.hasTransactionToHandle() && !this.#runningEpoch) await this.#runEpoch()
|
|
830
|
-
// runEpoch()
|
|
831
|
-
// }, 5000)
|
|
832
|
-
// runEpoch()
|
|
833
1175
|
}
|
|
834
1176
|
|
|
835
1177
|
calculateFee(transaction) {
|
|
@@ -839,25 +1181,6 @@ async resolveBlock(hash) {
|
|
|
839
1181
|
return (transaction.encoded.length / 1024) / 1e-6
|
|
840
1182
|
}
|
|
841
1183
|
|
|
842
|
-
async getTransactions (transactions) {
|
|
843
|
-
return new Promise(async (resolve, reject) => {
|
|
844
|
-
let size = 0;
|
|
845
|
-
const _transactions = [];
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
await Promise.all(transactions
|
|
849
|
-
.map(async tx => {
|
|
850
|
-
tx = await new TransactionMessage(tx);
|
|
851
|
-
size += tx.encoded.length;
|
|
852
|
-
if (!formatBytes(size).includes('MB') || formatBytes(size).includes('MB') && Number(formatBytes(size).split(' MB')[0]) <= 0.75) _transactions.push({...tx.decoded, hash: await tx.hash});
|
|
853
|
-
else resolve(_transactions);
|
|
854
|
-
}));
|
|
855
|
-
|
|
856
|
-
return resolve(_transactions)
|
|
857
|
-
})
|
|
858
|
-
|
|
859
|
-
}
|
|
860
|
-
|
|
861
1184
|
// todo filter tx that need to wait on prev nonce
|
|
862
1185
|
async #createBlock(limit = 1800) {
|
|
863
1186
|
// vote for transactions
|
|
@@ -890,7 +1213,7 @@ async resolveBlock(hash) {
|
|
|
890
1213
|
}
|
|
891
1214
|
// don't add empty block
|
|
892
1215
|
if (block.transactions.length === 0) return
|
|
893
|
-
const validators = await this.staticCall(addresses.validators, 'validators');
|
|
1216
|
+
const validators = await this.staticCall(addresses$1.validators, 'validators');
|
|
894
1217
|
console.log({validators});
|
|
895
1218
|
// block.validators = Object.keys(block.validators).reduce((set, key) => {
|
|
896
1219
|
// if (block.validators[key].active) {
|
|
@@ -965,7 +1288,7 @@ async resolveBlock(hash) {
|
|
|
965
1288
|
.map(async transaction => transactionPoolStore.delete(await transaction.hash)));
|
|
966
1289
|
|
|
967
1290
|
|
|
968
|
-
let blockMessage = await new BlockMessage(block);
|
|
1291
|
+
let blockMessage = await new BlockMessage$1(block);
|
|
969
1292
|
const hash = await blockMessage.hash;
|
|
970
1293
|
|
|
971
1294
|
|
|
@@ -983,58 +1306,18 @@ async resolveBlock(hash) {
|
|
|
983
1306
|
// transactionStore.put(message.hash, message.encoded)
|
|
984
1307
|
}
|
|
985
1308
|
|
|
986
|
-
|
|
987
|
-
transactions = await Promise.all(transactions.map(tx => new TransactionMessage(tx)));
|
|
988
|
-
return transactions
|
|
989
|
-
}
|
|
990
|
-
|
|
991
|
-
async promiseTransactionsContent(transactions) {
|
|
992
|
-
transactions = await Promise.all(transactions.map(tx => new Promise(async (resolve, reject) => {
|
|
993
|
-
resolve({ ...tx.decoded, hash: await tx.hash });
|
|
994
|
-
})));
|
|
995
|
-
|
|
996
|
-
return transactions
|
|
997
|
-
}
|
|
998
|
-
|
|
999
|
-
async #getNonceFallback(address) {
|
|
1000
|
-
let transactions = await transactionPoolStore.values();
|
|
1001
|
-
transactions = await this.promiseTransactions(transactions);
|
|
1002
|
-
transactions = transactions.filter(tx => tx.decoded.from === address);
|
|
1003
|
-
transactions = await this.promiseTransactionsContent(transactions);
|
|
1004
|
-
|
|
1005
|
-
if (this.lastBlock?.hash && transactions.length === 0 && this.lastBlock.hash !== '0x0') {
|
|
1006
|
-
|
|
1007
|
-
let block = await peernet.get(this.lastBlock.hash);
|
|
1008
|
-
block = await new BlockMessage(block);
|
|
1009
|
-
|
|
1010
|
-
// for (let tx of block.decoded?.transactions) {
|
|
1011
|
-
// tx = await peernet.get(tx, 'transaction')
|
|
1012
|
-
// transactions.push(new TransactionMessage(tx))
|
|
1013
|
-
// }
|
|
1014
|
-
transactions = transactions.filter(tx => tx.from === address);
|
|
1015
|
-
while (transactions.length === 0 && block.decoded.index !== 0 && block.decoded.previousHash !== '0x0') {
|
|
1016
|
-
block = await blockStore.get(block.decoded.previousHash);
|
|
1017
|
-
block = await new BlockMessage(block);
|
|
1018
|
-
transactions = block.decoded.transactions.filter(tx => tx.from === address);
|
|
1019
|
-
}
|
|
1020
|
-
|
|
1021
|
-
}
|
|
1022
|
-
if (transactions.length === 0) return 0
|
|
1023
|
-
|
|
1024
|
-
transactions = transactions.sort((a, b) => a.timestamp - b.timestamp);
|
|
1025
|
-
return transactions[transactions.length - 1].nonce
|
|
1026
|
-
}
|
|
1309
|
+
|
|
1027
1310
|
|
|
1028
|
-
async
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
await
|
|
1311
|
+
async #addTransaction(transaction) {
|
|
1312
|
+
try {
|
|
1313
|
+
transaction = await new TransactionMessage(transaction);
|
|
1314
|
+
const has = await transactionPoolStore.has(await transaction.hash);
|
|
1315
|
+
if (!has) await transactionPoolStore.put(await transaction.hash, transaction.encoded);
|
|
1316
|
+
if (this.#participating && !this.#runningEpoch) this.#runEpoch();
|
|
1317
|
+
} catch {
|
|
1318
|
+
throw new Error('invalid transaction')
|
|
1032
1319
|
}
|
|
1033
|
-
let nonce = await accountsStore.get(address);
|
|
1034
|
-
nonce = new TextDecoder().decode(nonce);
|
|
1035
|
-
return Number(nonce)
|
|
1036
1320
|
}
|
|
1037
|
-
|
|
1038
1321
|
/**
|
|
1039
1322
|
* whenever method = createContract params should hold the contract hash
|
|
1040
1323
|
*
|
|
@@ -1046,146 +1329,31 @@ async resolveBlock(hash) {
|
|
|
1046
1329
|
* @param {Array} params - array of paramters to apply to the contract method
|
|
1047
1330
|
* @param {Number} nonce - total transaction count [optional]
|
|
1048
1331
|
*/
|
|
1049
|
-
|
|
1332
|
+
async createTransaction(to, method, parameters, nonce, signature) {
|
|
1050
1333
|
return this.createTransactionFrom(peernet.selectedAccount, to, method, parameters, nonce)
|
|
1051
|
-
}
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
/**
|
|
1056
|
-
*
|
|
1057
|
-
* @param {Object} transaction {}
|
|
1058
|
-
* @param {String} transaction.from address
|
|
1059
|
-
* @param {String} transaction.to address
|
|
1060
|
-
* @param {Object} transaction.params {}
|
|
1061
|
-
* @param {String} transaction.params.method get, call
|
|
1062
|
-
* @param {Buffer} transaction.params.data
|
|
1063
|
-
* @returns
|
|
1064
|
-
*/
|
|
1065
|
-
async createTransactionHash(transaction) {
|
|
1066
|
-
// todo: validate
|
|
1067
|
-
const peernetHash = await new CodecHash(transaction, {name: 'transaction-message'});
|
|
1068
|
-
return peernetHash.digest
|
|
1069
|
-
}
|
|
1070
|
-
|
|
1071
|
-
/**
|
|
1072
|
-
* @params {object} transaction -
|
|
1073
|
-
* @params {object} wallet - any wallet/signer that supports sign(RAWtransaction)
|
|
1074
|
-
*/
|
|
1075
|
-
async #signTransaction (transaction, wallet) {
|
|
1076
|
-
return wallet.sign(await this.createTransactionHash(transaction))
|
|
1077
|
-
}
|
|
1078
|
-
|
|
1079
|
-
async signTransaction(transaction, signer) {
|
|
1080
|
-
let identity = await walletStore.get('identity');
|
|
1081
|
-
identity = JSON.parse(new TextDecoder().decode(identity));
|
|
1082
|
-
const wallet = new MultiWallet(peernet.network);
|
|
1083
|
-
wallet.recover(identity.mnemonic);
|
|
1084
|
-
const account = wallet.account(0).external(0);
|
|
1085
|
-
transaction.signature = await this.#signTransaction(transaction, account);
|
|
1086
|
-
transaction.signature = bs32.encode(transaction.signature);
|
|
1087
|
-
return transaction
|
|
1088
|
-
}
|
|
1089
|
-
|
|
1090
|
-
/**
|
|
1091
|
-
*
|
|
1092
|
-
* @param {Object} transaction
|
|
1093
|
-
* @param {Address} transaction.from
|
|
1094
|
-
* @param {Address} transaction.to
|
|
1095
|
-
* @param {String} transaction.method
|
|
1096
|
-
* @param {Array} transaction.params
|
|
1097
|
-
* @param {Number} transaction.nonce
|
|
1098
|
-
*
|
|
1099
|
-
* @returns {Object} transaction
|
|
1100
|
-
*/
|
|
1101
|
-
async createRawTransaction(transaction) {
|
|
1102
|
-
if (!transaction.from) transaction.from = peernet.selectedAccount;
|
|
1103
|
-
transaction.timestamp = Date.now();
|
|
1104
|
-
|
|
1105
|
-
if (transaction.nonce === undefined) {
|
|
1106
|
-
transaction.nonce = await this.getNonce(transaction.from);
|
|
1107
|
-
} else {
|
|
1108
|
-
let nonce = await accountsStore.get(transaction.from);
|
|
1109
|
-
nonce = new TextDecoder().decode(nonce);
|
|
1110
|
-
if (transaction.nonce < nonce) throw new Error(`a transaction with a higher nonce already exists`)
|
|
1111
|
-
if (transaction.nonce === nonce) throw new Error(`a transaction with the same nonce already exists`)
|
|
1112
|
-
}
|
|
1113
|
-
return transaction
|
|
1114
|
-
}
|
|
1334
|
+
}
|
|
1115
1335
|
/**
|
|
1116
1336
|
* every tx done is trough contracts so no need for amount
|
|
1117
1337
|
* data is undefined when nothing is returned
|
|
1118
1338
|
* error is thrown on error so undefined data doesn't mean there is an error...
|
|
1119
1339
|
*
|
|
1120
|
-
* @param {
|
|
1121
|
-
* @param {
|
|
1340
|
+
* @param {Address} from - the sender address
|
|
1341
|
+
* @param {Address} to - the contract address for the contract to interact with
|
|
1122
1342
|
* @param {String} method - the method/function to run
|
|
1123
1343
|
* @param {Array} params - array of paramters to apply to the contract method
|
|
1124
1344
|
* @param {Number} nonce - total transaction count [optional]
|
|
1125
1345
|
*/
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
const transaction = await this.signTransaction(rawTransaction, from);
|
|
1131
|
-
const message = await new TransactionMessage(transaction);
|
|
1132
|
-
|
|
1133
|
-
let data;
|
|
1134
|
-
// await transactionPoolStore.put(message.hash, new TextEncoder().encode(JSON.stringify({signature, message: message.encoded})))
|
|
1135
|
-
const wait = () => new Promise(async (resolve, reject) => {
|
|
1136
|
-
if (pubsub.subscribers[`transaction.completed.${await message.hash}`]) {
|
|
1137
|
-
const result = pubsub.subscribers[`transaction.completed.${await message.hash}`].value;
|
|
1138
|
-
result.status === 'fulfilled' ? resolve(await result.hash) : reject({hash: await result.hash, error: result.error});
|
|
1139
|
-
} else {
|
|
1140
|
-
const completed = async result => {
|
|
1141
|
-
result.status === 'fulfilled' ? resolve(await result.hash) : reject({hash: await result.hash, error: result.error});
|
|
1142
|
-
|
|
1143
|
-
setTimeout(async () => {
|
|
1144
|
-
pubsub.unsubscribe(`transaction.completed.${await message.hash}`, completed);
|
|
1145
|
-
}, 10_000);
|
|
1146
|
-
};
|
|
1147
|
-
pubsub.subscribe(`transaction.completed.${await message.hash}`, completed);
|
|
1148
|
-
}
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
});
|
|
1152
|
-
|
|
1153
|
-
await transactionPoolStore.put(await message.hash, message.encoded);
|
|
1154
|
-
peernet.publish('add-transaction', message.encoded);
|
|
1155
|
-
this.#addTransaction(message.encoded);
|
|
1156
|
-
return {hash: await message.hash, data, fee: await calculateFee(message.decoded), wait}
|
|
1157
|
-
} catch (error) {
|
|
1158
|
-
console.log(error);
|
|
1159
|
-
throw error
|
|
1160
|
-
}
|
|
1161
|
-
|
|
1162
|
-
}
|
|
1163
|
-
|
|
1164
|
-
async createContractMessage(creator, contract, constructorParameters = []) {
|
|
1165
|
-
return createContractMessage(creator, contract, constructorParameters)
|
|
1166
|
-
}
|
|
1167
|
-
|
|
1168
|
-
async createContractAddress(creator, contract, constructorParameters = []) {
|
|
1169
|
-
contract = await this.createContractMessage(creator, contract, constructorParameters);
|
|
1170
|
-
return contract.hash
|
|
1346
|
+
async createTransactionFrom(from, to, method, parameters, nonce) {
|
|
1347
|
+
const event = await super.createTransactionFrom(from, to, method, parameters, nonce);
|
|
1348
|
+
this.#addTransaction(event.message.encoded);
|
|
1349
|
+
return event
|
|
1171
1350
|
}
|
|
1172
1351
|
|
|
1173
1352
|
/**
|
|
1174
1353
|
*
|
|
1175
|
-
* @param {
|
|
1176
|
-
* @
|
|
1177
|
-
* @returns
|
|
1354
|
+
* @param {Address} sender
|
|
1355
|
+
* @returns {globalMessage}
|
|
1178
1356
|
*/
|
|
1179
|
-
async deployContract(contract, constructorParameters = []) {
|
|
1180
|
-
const message = await createContractMessage(peernet.selectedAccount, contract, constructorParameters);
|
|
1181
|
-
try {
|
|
1182
|
-
await contractStore.put(await message.hash, message.encoded);
|
|
1183
|
-
} catch (error) {
|
|
1184
|
-
throw error
|
|
1185
|
-
}
|
|
1186
|
-
return this.createTransactionFrom(peernet.selectedAccount, addresses.contractFactory, 'registerContract', [await message.hash])
|
|
1187
|
-
}
|
|
1188
|
-
|
|
1189
1357
|
#createMessage(sender = peernet.selectedAccount) {
|
|
1190
1358
|
return {
|
|
1191
1359
|
sender,
|
|
@@ -1196,12 +1364,27 @@ async #signTransaction (transaction, wallet) {
|
|
|
1196
1364
|
}
|
|
1197
1365
|
}
|
|
1198
1366
|
|
|
1367
|
+
/**
|
|
1368
|
+
*
|
|
1369
|
+
* @param {Address} sender
|
|
1370
|
+
* @param {Address} contract
|
|
1371
|
+
* @param {String} method
|
|
1372
|
+
* @param {Array} parameters
|
|
1373
|
+
* @returns
|
|
1374
|
+
*/
|
|
1199
1375
|
internalCall(sender, contract, method, parameters) {
|
|
1200
1376
|
globalThis.msg = this.#createMessage(sender);
|
|
1201
1377
|
|
|
1202
1378
|
return this.#machine.execute(contract, method, parameters)
|
|
1203
1379
|
}
|
|
1204
1380
|
|
|
1381
|
+
/**
|
|
1382
|
+
*
|
|
1383
|
+
* @param {Address} contract
|
|
1384
|
+
* @param {String} method
|
|
1385
|
+
* @param {Array} parameters
|
|
1386
|
+
* @returns
|
|
1387
|
+
*/
|
|
1205
1388
|
call(contract, method, parameters) {
|
|
1206
1389
|
globalThis.msg = this.#createMessage();
|
|
1207
1390
|
|
|
@@ -1226,19 +1409,19 @@ async #signTransaction (transaction, wallet) {
|
|
|
1226
1409
|
}
|
|
1227
1410
|
|
|
1228
1411
|
mint(to, amount) {
|
|
1229
|
-
return this.call(addresses.nativeToken, 'mint', [to, amount])
|
|
1412
|
+
return this.call(addresses$1.nativeToken, 'mint', [to, amount])
|
|
1230
1413
|
}
|
|
1231
1414
|
|
|
1232
1415
|
transfer(from, to, amount) {
|
|
1233
|
-
return this.call(addresses.nativeToken, 'transfer', [from, to, amount])
|
|
1416
|
+
return this.call(addresses$1.nativeToken, 'transfer', [from, to, amount])
|
|
1234
1417
|
}
|
|
1235
1418
|
|
|
1236
1419
|
get balances() {
|
|
1237
|
-
return this.staticCall(addresses.nativeToken, 'balances')
|
|
1420
|
+
return this.staticCall(addresses$1.nativeToken, 'balances')
|
|
1238
1421
|
}
|
|
1239
1422
|
|
|
1240
1423
|
get contracts() {
|
|
1241
|
-
return this.staticCall(addresses.contractFactory, 'contracts')
|
|
1424
|
+
return this.staticCall(addresses$1.contractFactory, 'contracts')
|
|
1242
1425
|
}
|
|
1243
1426
|
|
|
1244
1427
|
deleteAll() {
|
|
@@ -1255,7 +1438,7 @@ async #signTransaction (transaction, wallet) {
|
|
|
1255
1438
|
* @example chain.lookup('myCoolContractName') // qmqsfddfdgfg...
|
|
1256
1439
|
*/
|
|
1257
1440
|
lookup(name) {
|
|
1258
|
-
return this.call(addresses.nameService, 'lookup', [name])
|
|
1441
|
+
return this.call(addresses$1.nameService, 'lookup', [name])
|
|
1259
1442
|
}
|
|
1260
1443
|
}
|
|
1261
1444
|
|