UNPKG

@0xpolygonid/js-sdk

Version:
194 lines (193 loc) 8.76 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.EthStateStorage = exports.defaultEthConnectionConfig = void 0; const ethers_1 = require("ethers"); const circuits_1 = require("../../circuits"); const utils_1 = require("../../utils"); const State_json_1 = __importDefault(require("./abi/State.json")); const js_iden3_core_1 = require("@iden3/js-iden3-core"); const blockchain_1 = require("../../blockchain"); const common_1 = require("./common"); exports.defaultEthConnectionConfig = { url: 'http://localhost:8545', defaultGasLimit: 600000, minGasPrice: '0', maxGasPrice: '100000000000', confirmationBlockCount: 5, confirmationTimeout: 600000, contractAddress: '', receiptTimeout: 600000, rpcResponseTimeout: 5000, waitReceiptCycleTime: 30000, waitBlockCycleTime: 3000 }; /** * * * @public * @class EthStateStorage * @implements implements IStateStorage interface */ class EthStateStorage { /** * Creates an instance of EthStateStorage. * @param {EthConnectionConfig} [ethConfig=defaultEthConnectionConfig] */ constructor(ethConfig) { this.ethConfig = ethConfig; const config = Array.isArray(ethConfig) ? ethConfig[0] : ethConfig; this.provider = new ethers_1.JsonRpcProvider(config.url); this.stateContract = new ethers_1.Contract(config.contractAddress, State_json_1.default, this.provider); this._transactionService = new blockchain_1.TransactionService(this.getRpcProvider()); } /** {@inheritdoc IStateStorage.getLatestStateById} */ async getLatestStateById(id) { const { stateContract } = this.getStateContractAndProviderForId(id); const rawData = await stateContract.getStateInfoById(id); const stateInfo = { id: BigInt(rawData[0]), state: BigInt(rawData[1]), replacedByState: BigInt(rawData[2]), createdAtTimestamp: BigInt(rawData[3]), replacedAtTimestamp: BigInt(rawData[4]), createdAtBlock: BigInt(rawData[5]), replacedAtBlock: BigInt(rawData[6]) }; return stateInfo; } /** {@inheritdoc IStateStorage.getStateInfoByIdAndState} */ async getStateInfoByIdAndState(id, state) { const { stateContract } = this.getStateContractAndProviderForId(id); const rawData = await stateContract.getStateInfoByIdAndState(id, state); const stateInfo = { id: BigInt(rawData[0]), state: BigInt(rawData[1]), replacedByState: BigInt(rawData[2]), createdAtTimestamp: BigInt(rawData[3]), replacedAtTimestamp: BigInt(rawData[4]), createdAtBlock: BigInt(rawData[5]), replacedAtBlock: BigInt(rawData[6]) }; return stateInfo; } /** {@inheritdoc IStateStorage.publishState} */ async publishState(proof, signer) { const stateTransitionPubSig = new circuits_1.StateTransitionPubSignals(); stateTransitionPubSig.pubSignalsUnmarshal(utils_1.byteEncoder.encode(JSON.stringify(proof.pub_signals))); const { userId, oldUserState, newUserState, isOldStateGenesis } = stateTransitionPubSig; const { stateContract, provider } = this.getStateContractAndProviderForId(userId.bigInt()); const contract = stateContract.connect(signer); const preparedZkpProof = (0, common_1.prepareZkpProof)(proof.proof); const payload = [ userId.bigInt().toString(), oldUserState.bigInt().toString(), newUserState.bigInt().toString(), isOldStateGenesis, preparedZkpProof.a, preparedZkpProof.b, preparedZkpProof.c ]; const feeData = await provider.getFeeData(); const maxFeePerGas = exports.defaultEthConnectionConfig.maxFeePerGas ? BigInt(exports.defaultEthConnectionConfig.maxFeePerGas) : feeData.maxFeePerGas; const maxPriorityFeePerGas = exports.defaultEthConnectionConfig.maxPriorityFeePerGas ? BigInt(exports.defaultEthConnectionConfig.maxPriorityFeePerGas) : feeData.maxPriorityFeePerGas; const gasLimit = await contract.transitState.estimateGas(...payload); const txData = await contract.transitState.populateTransaction(...payload); const request = { to: txData.to, data: txData.data, gasLimit, maxFeePerGas, maxPriorityFeePerGas }; const { txnHash } = await this._transactionService.sendTransactionRequest(signer, request); return txnHash; } /** {@inheritdoc IStateStorage.publishStateGeneric} */ async publishStateGeneric(signer, userStateTransitionInfo) { const { userId, oldUserState, newUserState, isOldStateGenesis, methodId, methodParams } = userStateTransitionInfo; const { stateContract, provider } = this.getStateContractAndProviderForId(userId.bigInt()); const contract = stateContract.connect(signer); const feeData = await provider.getFeeData(); const maxFeePerGas = exports.defaultEthConnectionConfig.maxFeePerGas ? BigInt(exports.defaultEthConnectionConfig.maxFeePerGas) : feeData.maxFeePerGas; const maxPriorityFeePerGas = exports.defaultEthConnectionConfig.maxPriorityFeePerGas ? BigInt(exports.defaultEthConnectionConfig.maxPriorityFeePerGas) : feeData.maxPriorityFeePerGas; const payload = [ userId.bigInt().toString(), oldUserState.bigInt().toString(), newUserState.bigInt().toString(), isOldStateGenesis, methodId, methodParams //'0x' ]; const gasLimit = await contract.transitStateGeneric.estimateGas(...payload); const txData = await contract.transitStateGeneric.populateTransaction(...payload); const request = { to: txData.to, data: txData.data, gasLimit, maxFeePerGas, maxPriorityFeePerGas }; const { txnHash } = await this._transactionService.sendTransactionRequest(signer, request); return txnHash; } /** {@inheritdoc IStateStorage.getGISTProof} */ async getGISTProof(id) { const { stateContract } = this.getStateContractAndProviderForId(id); const data = await stateContract.getGISTProof(id); return { root: BigInt(data.root.toString()), existence: data.existence, siblings: data.siblings?.map((sibling) => BigInt(sibling.toString())), index: BigInt(data.index.toString()), value: BigInt(data.value.toString()), auxExistence: data.auxExistence, auxIndex: BigInt(data.auxIndex.toString()), auxValue: BigInt(data.auxValue.toString()) }; } /** {@inheritdoc IStateStorage.getGISTRootInfo} */ async getGISTRootInfo(root, id) { const { stateContract } = this.getStateContractAndProviderForId(id); const data = await stateContract.getGISTRootInfo(root); return { root: BigInt(data.root.toString()), replacedByRoot: BigInt(data.replacedByRoot.toString()), createdAtTimestamp: BigInt(data.createdAtTimestamp.toString()), replacedAtTimestamp: BigInt(data.replacedAtTimestamp.toString()), createdAtBlock: BigInt(data.createdAtBlock.toString()), replacedAtBlock: BigInt(data.replacedAtBlock.toString()) }; } /** {@inheritdoc IStateStorage.getRpcProvider} */ getRpcProvider() { return this.provider; } getStateContractAndProviderForId(id) { const idTyped = js_iden3_core_1.Id.fromBigInt(id); const chainId = (0, js_iden3_core_1.getChainId)(js_iden3_core_1.DID.blockchainFromId(idTyped), js_iden3_core_1.DID.networkIdFromId(idTyped)); const config = this.networkByChainId(chainId); const provider = new ethers_1.JsonRpcProvider(config.url); const stateContract = new ethers_1.Contract(config.contractAddress, State_json_1.default, provider); return { stateContract, provider }; } networkByChainId(chainId) { const config = Array.isArray(this.ethConfig) ? this.ethConfig : [this.ethConfig]; const network = config.find((c) => c.chainId === chainId); if (!network) { throw new Error(`chainId "${chainId}" not supported`); } return network; } } exports.EthStateStorage = EthStateStorage;