|
|
|
import { RPCMethod, Messenger, ResponseMiddleware } from '@harmony/network';
|
|
|
|
|
|
|
|
import {
|
|
|
|
assertObject,
|
|
|
|
AssertType,
|
|
|
|
HarmonyCore,
|
|
|
|
ChainType,
|
|
|
|
DefaultBlockParams,
|
|
|
|
} from '@harmony/utils';
|
|
|
|
|
|
|
|
import { Transaction } from '@harmony/transaction';
|
|
|
|
|
|
|
|
class Blockchain extends HarmonyCore {
|
|
|
|
messenger: Messenger;
|
|
|
|
chainType: ChainType;
|
|
|
|
|
|
|
|
constructor(messenger: Messenger, chainType: ChainType = ChainType.Harmony) {
|
|
|
|
super(chainType);
|
|
|
|
this.messenger = messenger;
|
|
|
|
this.chainType = chainType;
|
|
|
|
}
|
|
|
|
setMessenger(messenger: Messenger) {
|
|
|
|
this.messenger = messenger;
|
|
|
|
}
|
|
|
|
getRpcResult(result: any) {
|
|
|
|
if (result instanceof ResponseMiddleware) {
|
|
|
|
return result.getRaw;
|
|
|
|
} else {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
@assertObject({
|
|
|
|
address: ['isAddress', AssertType.required],
|
|
|
|
blockNumber: ['isBlockNumber', AssertType.optional],
|
|
|
|
})
|
|
|
|
async getBalance({
|
|
|
|
address,
|
|
|
|
blockNumber = DefaultBlockParams.latest,
|
|
|
|
}: {
|
|
|
|
address: string;
|
|
|
|
blockNumber?: string;
|
|
|
|
}) {
|
|
|
|
const result = await this.messenger.send(
|
|
|
|
RPCMethod.GetBalance,
|
|
|
|
[address, blockNumber],
|
|
|
|
this.chainPrefix,
|
|
|
|
);
|
|
|
|
return this.getRpcResult(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
@assertObject({
|
|
|
|
blockHash: ['isHash', AssertType.required],
|
|
|
|
returnObject: ['isBoolean', AssertType.optional],
|
|
|
|
})
|
|
|
|
async getBlockByHash({
|
|
|
|
blockHash,
|
|
|
|
returnObject = true,
|
|
|
|
}: {
|
|
|
|
blockHash: string;
|
|
|
|
returnObject?: boolean;
|
|
|
|
}) {
|
|
|
|
const result = await this.messenger.send(
|
|
|
|
RPCMethod.GetBlockByHash,
|
|
|
|
[blockHash, returnObject],
|
|
|
|
this.chainPrefix,
|
|
|
|
);
|
|
|
|
return this.getRpcResult(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
@assertObject({
|
|
|
|
blockNumber: ['isBlockNumber', AssertType.optional],
|
|
|
|
returnObject: ['isBoolean', AssertType.optional],
|
|
|
|
})
|
|
|
|
async getBlockByNumber({
|
|
|
|
blockNumber = DefaultBlockParams.latest,
|
|
|
|
returnObject = true,
|
|
|
|
}: {
|
|
|
|
blockNumber?: string;
|
|
|
|
returnObject?: boolean;
|
|
|
|
}) {
|
|
|
|
const result = await this.messenger.send(
|
|
|
|
RPCMethod.GetBlockByNumber,
|
|
|
|
[blockNumber, returnObject],
|
|
|
|
this.chainPrefix,
|
|
|
|
);
|
|
|
|
return this.getRpcResult(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
@assertObject({
|
|
|
|
blockHash: ['isHash', AssertType.required],
|
|
|
|
})
|
|
|
|
async getBlockTransactionCountByHash({ blockHash }: { blockHash: string }) {
|
|
|
|
const result = await this.messenger.send(
|
|
|
|
RPCMethod.GetBlockTransactionCountByHash,
|
|
|
|
[blockHash],
|
|
|
|
this.chainPrefix,
|
|
|
|
);
|
|
|
|
return this.getRpcResult(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
@assertObject({
|
|
|
|
blockNumber: ['isBlockNumber', AssertType.required],
|
|
|
|
})
|
|
|
|
async getBlockTransactionCountByNumber({
|
|
|
|
blockNumber,
|
|
|
|
}: {
|
|
|
|
blockNumber: string;
|
|
|
|
}) {
|
|
|
|
const result = await this.messenger.send(
|
|
|
|
RPCMethod.GetBlockTransactionCountByNumber,
|
|
|
|
[blockNumber],
|
|
|
|
this.chainPrefix,
|
|
|
|
);
|
|
|
|
return this.getRpcResult(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
@assertObject({
|
|
|
|
blockHash: ['isHash', AssertType.required],
|
|
|
|
index: ['isHex', AssertType.required],
|
|
|
|
})
|
|
|
|
async getTransactionByBlockHashAndIndex({
|
|
|
|
blockHash,
|
|
|
|
index,
|
|
|
|
}: {
|
|
|
|
blockHash: string;
|
|
|
|
index: string;
|
|
|
|
}) {
|
|
|
|
const result = await this.messenger.send(
|
|
|
|
RPCMethod.GetTransactionByBlockHashAndIndex,
|
|
|
|
[blockHash, index],
|
|
|
|
this.chainPrefix,
|
|
|
|
);
|
|
|
|
return this.getRpcResult(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
@assertObject({
|
|
|
|
blockNumber: ['isBlockNumber', AssertType.optional],
|
|
|
|
index: ['isHex', AssertType.required],
|
|
|
|
})
|
|
|
|
async getTransactionByBlockNumberAndIndex({
|
|
|
|
blockNumber = DefaultBlockParams.latest,
|
|
|
|
index,
|
|
|
|
}: {
|
|
|
|
blockNumber?: string;
|
|
|
|
index: string;
|
|
|
|
}) {
|
|
|
|
const result = await this.messenger.send(
|
|
|
|
RPCMethod.GetTransactionByBlockNumberAndIndex,
|
|
|
|
[blockNumber, index],
|
|
|
|
this.chainPrefix,
|
|
|
|
);
|
|
|
|
return this.getRpcResult(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
@assertObject({
|
|
|
|
txnHash: ['isHash', AssertType.required],
|
|
|
|
})
|
|
|
|
async getTransactionByHash({ txnHash }: { txnHash: string }) {
|
|
|
|
const result = await this.messenger.send(
|
|
|
|
RPCMethod.GetTransactionByHash,
|
|
|
|
[txnHash],
|
|
|
|
this.chainPrefix,
|
|
|
|
);
|
|
|
|
return this.getRpcResult(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
@assertObject({
|
|
|
|
txnHash: ['isString', AssertType.required],
|
|
|
|
})
|
|
|
|
async getTransactionReceipt({ txnHash }: { txnHash: string }) {
|
|
|
|
const result = await this.messenger.send(
|
|
|
|
RPCMethod.GetTransactionReceipt,
|
|
|
|
[txnHash],
|
|
|
|
this.chainPrefix,
|
|
|
|
);
|
|
|
|
return this.getRpcResult(result);
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
@assertObject({
|
|
|
|
address: ['isAddress', AssertType.required],
|
|
|
|
blockNumber: ['isBlockNumber', AssertType.optional],
|
|
|
|
})
|
|
|
|
async getCode({
|
|
|
|
address,
|
|
|
|
blockNumber = DefaultBlockParams.latest,
|
|
|
|
}: {
|
|
|
|
address: string;
|
|
|
|
blockNumber?: string;
|
|
|
|
}) {
|
|
|
|
const result = await this.messenger.send(
|
|
|
|
RPCMethod.GetCode,
|
|
|
|
[address, blockNumber],
|
|
|
|
this.chainPrefix,
|
|
|
|
);
|
|
|
|
return this.getRpcResult(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
async syncing() {
|
|
|
|
const result = await this.messenger.send(
|
|
|
|
RPCMethod.Syncing,
|
|
|
|
[],
|
|
|
|
this.chainPrefix,
|
|
|
|
);
|
|
|
|
|
|
|
|
return this.getRpcResult(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
async net_peerCount() {
|
|
|
|
const result = await this.messenger.send(RPCMethod.PeerCount, [], 'net');
|
|
|
|
|
|
|
|
return this.getRpcResult(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
@assertObject({
|
|
|
|
address: ['isAddress', AssertType.required],
|
|
|
|
position: ['isHex', AssertType.required],
|
|
|
|
blockNumber: ['isBlockNumber', AssertType.optional],
|
|
|
|
})
|
|
|
|
async getStorageAt({
|
|
|
|
address,
|
|
|
|
position,
|
|
|
|
blockNumber = DefaultBlockParams.latest,
|
|
|
|
}: {
|
|
|
|
address: string;
|
|
|
|
position: string;
|
|
|
|
blockNumber?: string;
|
|
|
|
}) {
|
|
|
|
const result = await this.messenger.send(
|
|
|
|
RPCMethod.GetStorageAt,
|
|
|
|
[address, position, blockNumber],
|
|
|
|
this.chainPrefix,
|
|
|
|
);
|
|
|
|
return this.getRpcResult(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
@assertObject({
|
|
|
|
address: ['isAddress', AssertType.required],
|
|
|
|
blockNumber: ['isBlockNumber', AssertType.optional],
|
|
|
|
})
|
|
|
|
async getTransactionCount({
|
|
|
|
address,
|
|
|
|
blockNumber = DefaultBlockParams.latest,
|
|
|
|
}: {
|
|
|
|
address: string;
|
|
|
|
blockNumber?: string;
|
|
|
|
}) {
|
|
|
|
const result = await this.messenger.send(
|
|
|
|
RPCMethod.GetTransactionCount,
|
|
|
|
[address, blockNumber],
|
|
|
|
this.chainPrefix,
|
|
|
|
);
|
|
|
|
return this.getRpcResult(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
async sendTransaction(transaction: Transaction) {
|
|
|
|
if (!transaction.isSigned() || !transaction) {
|
|
|
|
throw new Error('transaction is not signed or not exist');
|
|
|
|
}
|
|
|
|
const result = await this.messenger.send(
|
|
|
|
RPCMethod.SendTransaction,
|
|
|
|
[transaction.txPayload],
|
|
|
|
this.chainPrefix,
|
|
|
|
);
|
|
|
|
return this.getRpcResult(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
async sendRawTransaction(transaction: Transaction) {
|
|
|
|
if (!transaction.isSigned() || !transaction) {
|
|
|
|
throw new Error('transaction is not signed or not exist');
|
|
|
|
}
|
|
|
|
const [txn, result] = await transaction.sendTransaction();
|
|
|
|
if (txn.isPending) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export { Blockchain };
|