-
Notifications
You must be signed in to change notification settings - Fork 146
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add mirror node contract call and estimate queries
Signed-off-by: Ivaylo Nikolov <[email protected]>
- Loading branch information
1 parent
089e714
commit d7dbae9
Showing
3 changed files
with
260 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import MirrorNodeContractQuery from "./MirrorNodeContractQuery.js"; | ||
|
||
/** | ||
* @typedef {import("../channel/Channel.js").default} Channel | ||
* @typedef {import("../client/Client.js").default<*, *>} Client | ||
*/ | ||
export default class MirrorNodeContractCallQuery extends MirrorNodeContractQuery { | ||
/** | ||
* @returns {Promise<string>} | ||
*/ | ||
async execute() { | ||
if (this.callData == null) { | ||
throw new Error("Call data is required."); | ||
} | ||
|
||
const API_ENDPOINT = "contracts/call"; | ||
const JSON_PAYLOAD = { | ||
data: Buffer.from(this.callData).toString("hex"), | ||
to: this.contractEvmAddress, | ||
estimate: false, | ||
}; | ||
|
||
console.log(JSON_PAYLOAD); | ||
/** | ||
* @type { { data: { result: string } } } | ||
*/ | ||
const mirrorNodeRequest = await this.performMirrorNodeRequest( | ||
API_ENDPOINT, | ||
JSON.stringify(JSON_PAYLOAD), | ||
); | ||
//console.log(mirrorNodeRequest); | ||
/** | ||
* @type {object} | ||
*/ | ||
return mirrorNodeRequest.data.result; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import Long from "long"; | ||
import MirrorNodeContractQuery from "./MirrorNodeContractQuery.js"; | ||
|
||
/** | ||
* @typedef {import("../channel/Channel.js").default} Channel | ||
* @typedef {import("../client/Client.js").default<*, *>} Client | ||
*/ | ||
export default class MirrorNodeContractCallQuery extends MirrorNodeContractQuery { | ||
/** | ||
* @returns {Promise<Long>} | ||
*/ | ||
async execute() { | ||
if (this.callData == null) { | ||
throw new Error("Call data is required."); | ||
} | ||
|
||
const JSON_PAYLOAD = { | ||
data: Buffer.from(this.callData).toString("hex"), | ||
from: this.senderEvmAddress, | ||
to: this.contractEvmAddress, | ||
estimate: true, | ||
value: this.value, | ||
}; | ||
|
||
/** | ||
* @type {{data: {result: string}}} | ||
*/ | ||
const mirrorNodeRequest = await this.performMirrorNodeRequest( | ||
"contracts/call", | ||
JSON.stringify(JSON_PAYLOAD), | ||
); | ||
|
||
console.log(Number(mirrorNodeRequest.data.result)); | ||
return Long.fromNumber(Number(mirrorNodeRequest.data.result)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
import axios from "axios"; | ||
import { ContractFunctionParameters } from "../exports.js"; | ||
|
||
/** | ||
* @typedef {import("../contract/ContractId").default} ContractId | ||
* @typedef {import("../account/AccountId").default} AccountId | ||
* @typedef {import("../client/Client.js").default<*, *>} Client | ||
* @typedef {import("axios").AxiosResponse} AxiosResponse | ||
* | ||
*/ | ||
export default class MirrorNodeContractQuery { | ||
constructor() { | ||
this._contractId = null; | ||
this._contractEvmAddress = null; | ||
this._sender = null; | ||
this._senderEvmAddress = null; | ||
this._functionName = null; | ||
this._functionParameters = null; | ||
this._value = null; | ||
this._gasLimit = null; | ||
this._gasPrice = null; | ||
this._blockNumber = null; | ||
} | ||
|
||
/** | ||
* | ||
* @param {ContractId} contractId | ||
* @returns | ||
*/ | ||
setContractId(contractId) { | ||
this._contractId = contractId; | ||
return this; | ||
} | ||
|
||
/** | ||
* @param {AccountId} sender | ||
* @returns | ||
*/ | ||
setSender(sender) { | ||
this._sender = sender; | ||
return this; | ||
} | ||
|
||
/** | ||
* | ||
* @param {string} name | ||
* @param {ContractFunctionParameters} functionParameters | ||
* @returns | ||
*/ | ||
setFunction(name, functionParameters) { | ||
this._functionParameters = | ||
functionParameters != null | ||
? functionParameters._build(name) | ||
: new ContractFunctionParameters()._build(name); | ||
|
||
return this; | ||
} | ||
|
||
/** | ||
* @param {Long} value | ||
* @returns | ||
*/ | ||
setValue(value) { | ||
this._value = value; | ||
return this; | ||
} | ||
|
||
/** | ||
* @param {Long} gasLimit | ||
* @returns | ||
*/ | ||
setGasLimit(gasLimit) { | ||
this._gasLimit = gasLimit; | ||
return this; | ||
} | ||
|
||
/** | ||
* @param {Long} gasPrice | ||
* @returns | ||
*/ | ||
setGasPrice(gasPrice) { | ||
this._gasPrice = gasPrice; | ||
return this; | ||
} | ||
|
||
/** | ||
* @param {Long} blockNumber | ||
* @returns | ||
*/ | ||
setBlockNumber(blockNumber) { | ||
this._blockNumber = blockNumber; | ||
return this; | ||
} | ||
|
||
/** | ||
* @returns {ContractId?} | ||
*/ | ||
get contractId() { | ||
return this._contractId; | ||
} | ||
|
||
/** | ||
* @returns {string} | ||
*/ | ||
get contractEvmAddress() { | ||
const solidityAddress = this._contractId?.toSolidityAddress(); | ||
if (solidityAddress == null) { | ||
throw new Error("Contract ID is not set"); | ||
} | ||
return solidityAddress; | ||
} | ||
|
||
/** | ||
* @returns {AccountId?} | ||
*/ | ||
get sender() { | ||
return this._sender; | ||
} | ||
|
||
/** | ||
* @returns {string?} | ||
*/ | ||
get senderEvmAddress() { | ||
const solidityAddress = this._sender?.toSolidityAddress(); | ||
if (solidityAddress == null) { | ||
throw new Error("Sender is not set"); | ||
} | ||
return solidityAddress; | ||
} | ||
|
||
/** | ||
* @returns {Uint8Array | null | undefined} | ||
*/ | ||
get callData() { | ||
return this._functionParameters; | ||
} | ||
|
||
/** | ||
* @returns {Long?} | ||
*/ | ||
get value() { | ||
return this._value; | ||
} | ||
|
||
/** | ||
* @returns {Long?} | ||
*/ | ||
get gasLimit() { | ||
return this._gasLimit; | ||
} | ||
|
||
/** | ||
* @returns {Long?} | ||
*/ | ||
get gasPrice() { | ||
return this._gasPrice; | ||
} | ||
|
||
/** | ||
* @returns {Long?} | ||
*/ | ||
get blockNumber() { | ||
return this._blockNumber; | ||
} | ||
|
||
/** | ||
* | ||
* @param {string} apiEndpoint | ||
* @param {string} jsonPayload | ||
* @returns {Promise<AxiosResponse>} | ||
*/ | ||
async performMirrorNodeRequest(apiEndpoint, jsonPayload) { | ||
if (this.contractId == null) { | ||
throw new Error("Contract ID is not set"); | ||
} | ||
|
||
const MIRROR_NETWORK_ADDRESS = | ||
"https://testnet.mirrornode.hedera.com/api/v1/" + apiEndpoint; | ||
|
||
let result = await axios.post(MIRROR_NETWORK_ADDRESS, jsonPayload, { | ||
headers: { | ||
"Content-Type": "application/json", | ||
}, | ||
}); | ||
return result; | ||
} | ||
} |