nft-folder-blockchain-connector-besu
Version:
A NestJS-based blockchain connector that communicates with specific smart contracts from the NFT Folder project.
120 lines • 5.8 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
var BlockchainService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.BlockchainService = void 0;
const common_1 = require("@nestjs/common");
const ethers_1 = require("ethers");
const configuration_service_1 = require("../configuration/configuration.service");
const error_const_1 = require("./error.const");
let BlockchainService = BlockchainService_1 = class BlockchainService {
provider;
configurationService;
logger = new common_1.Logger(BlockchainService_1.name);
blockTime;
contractInstances = {};
constructor(provider, configurationService) {
this.provider = provider;
this.configurationService = configurationService;
this.blockTime = this.configurationService.getBlockchainConfiguration().blockTime + 100;
}
returnSignerAddress() {
return this.returnSignerWallet().address;
}
returnSignerWallet() {
return new ethers_1.Wallet(this.configurationService.getBlockchainConfiguration().privateKey, this.provider);
}
getContractInstance(contractAddress, abi) {
const wallet = this.returnSignerWallet();
let contractInstance = this.contractInstances[contractAddress];
if (!contractInstance) {
contractInstance = new ethers_1.Contract(contractAddress, abi, wallet);
this.contractInstances[contractAddress] = contractInstance;
}
return contractInstance;
}
async fetchTransactionTimestamp(transactionHash) {
const transaction = await this.provider.getTransaction(transactionHash);
if (!transaction || !transaction.blockNumber) {
throw new common_1.BadRequestException('Transaction not found or not yet confirmed.');
}
const block = await this.provider.getBlock(transaction.blockNumber);
if (!block || !block.timestamp) {
throw new common_1.BadRequestException('Block not found or timestamp is missing.');
}
const timestamp = new Date(block.timestamp * 1000);
return timestamp.toISOString();
}
async waitForTheNextBlock() {
await new Promise((resolve) => setTimeout(resolve, this.blockTime));
}
handleError(error, contractAddress) {
this.logger.warn(error);
const contractInstance = this.contractInstances[contractAddress];
if (!contractInstance) {
throw new common_1.InternalServerErrorException(`Contract instance not found for address ${contractAddress}`);
}
const callError = error?.revert?.name;
const encodedTransactionError = error.info?.error?.data;
const decodedTransactionError = encodedTransactionError
? contractInstance.interface.parseError(encodedTransactionError)
: null;
const transactionError = decodedTransactionError?.name;
const errorMessage = callError ? callError : transactionError;
if (errorMessage) {
this.handleBlockchainError(errorMessage);
}
else {
this.handleOtherError(error);
}
}
handleBlockchainError(errorMessage) {
if (error_const_1.NOT_FOUND_CUSTOM_ERRORS.includes(errorMessage)) {
throw new common_1.NotFoundException(errorMessage);
}
else if (error_const_1.ALREADY_EXISTS_CUSTOM_ERRORS.includes(errorMessage)) {
throw new common_1.ConflictException(errorMessage);
}
else if (error_const_1.NOT_ALLOWED_CUSTOM_ERRORS.includes(errorMessage)) {
throw new common_1.ForbiddenException(errorMessage);
}
else {
throw new common_1.BadRequestException(errorMessage);
}
}
handleOtherError(error) {
switch (error.code) {
case 'BAD_DATA':
throw new common_1.InternalServerErrorException('Cannot find a Smart Contract at this address.');
case 'CALL_EXCEPTION':
throw new common_1.InternalServerErrorException('An unknown CALL_EXCEPTION occurred.');
case 'ECONNREFUSED':
throw new common_1.InternalServerErrorException('Cannot connect to Blockchain.');
default:
if (error.code || error.message) {
throw new common_1.InternalServerErrorException(error.code || error.message);
}
else {
throw new common_1.InternalServerErrorException('An unknown error occurred.');
}
}
}
};
exports.BlockchainService = BlockchainService;
exports.BlockchainService = BlockchainService = BlockchainService_1 = __decorate([
(0, common_1.Injectable)(),
__param(0, (0, common_1.Inject)('EthersProvider')),
__metadata("design:paramtypes", [Object, configuration_service_1.ConfigurationService])
], BlockchainService);
//# sourceMappingURL=blockchain.service.js.map