Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Modify response from submitRetrievePubkey #50

Draft
wants to merge 1 commit into
base: submit-pubkey
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 65 additions & 65 deletions packages/hardhat/contracts/JSONParser.sol
Original file line number Diff line number Diff line change
@@ -1,79 +1,79 @@
// WARNING: The below was generated with AI using claude.ai after asking it:
// given the following function code between the inverted commas <omitted `prepareResultBytesToCallbackData` function>
// if the output of that function is `result` bytes and it was sent to a different function
// `function fulfilledValueCallback(uint256 _requestId, bytes calldata data) external onlyGateway`,
// where its bytes value was in base64 format, which is
// `{"_request_id":{"network":"31337","task_id":"10"},"_key":[78,85,78,89,65],"_code":0,"_nunya_business_contract_address":"0xAFFF311821C3F3AF863C7103BB17BDC1Ba04603D"}`
// when converted to text, then how could i extract the JSON in Solidity and extract only the value of its property
// `"_key"` without the transaction running out of gas?
// // WARNING: The below was generated with AI using claude.ai after asking it:
// // given the following function code between the inverted commas <omitted `prepareResultBytesToCallbackData` function>
// // if the output of that function is `result` bytes and it was sent to a different function
// // `function fulfilledValueCallback(uint256 _requestId, bytes calldata data) external onlyGateway`,
// // where its bytes value was in base64 format, which is
// // `{"_request_id":{"network":"31337","task_id":"10"},"_key":[78,85,78,89,65],"_code":0,"_nunya_business_contract_address":"0xAFFF311821C3F3AF863C7103BB17BDC1Ba04603D"}`
// // when converted to text, then how could i extract the JSON in Solidity and extract only the value of its property
// // `"_key"` without the transaction running out of gas?

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
// // SPDX-License-Identifier: MIT
// pragma solidity ^0.8.26;

contract JSONParser {
// Custom error to save gas
error InvalidJSONFormat();
// contract JSONParser {
// // Custom error to save gas
// error InvalidJSONFormat();

function extractKeyArray(bytes calldata data) public pure returns (uint8[] memory) {
// Skip the base64 decoding as the data is already decoded in this case
// function extractKeyArray(bytes calldata data) public pure returns (uint8[] memory) {
// // Skip the base64 decoding as the data is already decoded in this case

// Find the "_key" property - we know it comes after "_request_id"
// Search for "[" after "_key":" pattern
uint256 startPos;
uint256 endPos;
// // Find the "_key" property - we know it comes after "_request_id"
// // Search for "[" after "_key":" pattern
// uint256 startPos;
// uint256 endPos;

for (uint i = 0; i < data.length - 6; i++) {
// Look for "_key":" pattern
if (data[i] == '_' &&
data[i+1] == 'k' &&
data[i+2] == 'e' &&
data[i+3] == 'y' &&
data[i+4] == '"' &&
data[i+5] == ':') {
// for (uint i = 0; i < data.length - 6; i++) {
// // Look for "_key":" pattern
// if (data[i] == '_' &&
// data[i+1] == 'k' &&
// data[i+2] == 'e' &&
// data[i+3] == 'y' &&
// data[i+4] == '"' &&
// data[i+5] == ':') {

// Find the opening bracket
while (i < data.length && data[i] != '[') {
i++;
}
startPos = i + 1;
// // Find the opening bracket
// while (i < data.length && data[i] != '[') {
// i++;
// }
// startPos = i + 1;

// Find the closing bracket
while (i < data.length && data[i] != ']') {
i++;
}
endPos = i;
break;
}
}
// // Find the closing bracket
// while (i < data.length && data[i] != ']') {
// i++;
// }
// endPos = i;
// break;
// }
// }

if (startPos == 0 || endPos == 0) revert InvalidJSONFormat();
// if (startPos == 0 || endPos == 0) revert InvalidJSONFormat();

// Count the numbers (commas + 1)
uint256 count = 1;
for (uint256 i = startPos; i < endPos; i++) {
if (data[i] == ',') count++;
}
// // Count the numbers (commas + 1)
// uint256 count = 1;
// for (uint256 i = startPos; i < endPos; i++) {
// if (data[i] == ',') count++;
// }

// Create array to store results
uint8[] memory result = new uint8[](count);
uint256 resultIndex = 0;
uint256 currentNum = 0;
// // Create array to store results
// uint8[] memory result = new uint8[](count);
// uint256 resultIndex = 0;
// uint256 currentNum = 0;

// Parse numbers
for (uint256 i = startPos; i < endPos; i++) {
bytes1 char = data[i];
// // Parse numbers
// for (uint256 i = startPos; i < endPos; i++) {
// bytes1 char = data[i];

if (char >= '0' && char <= '9') {
currentNum = currentNum * 10 + uint8(uint8(char) - 48);
}
// if (char >= '0' && char <= '9') {
// currentNum = currentNum * 10 + uint8(uint8(char) - 48);
// }

if (char == ',' || i == endPos - 1) {
result[resultIndex] = uint8(currentNum);
currentNum = 0;
resultIndex++;
}
}
// if (char == ',' || i == endPos - 1) {
// result[resultIndex] = uint8(currentNum);
// currentNum = 0;
// resultIndex++;
// }
// }

return result;
}
}
// return result;
// }
// }
29 changes: 26 additions & 3 deletions packages/hardhat/contracts/NunyaBusiness.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import "hardhat/console.sol";
// import "./IDummyGateway.sol";
import "./IGateway.sol";

// import "./Base64.sol";

import "./JsmnSolLib.sol";

import "./JSONParser.sol";
// import "./JSONParser.sol";

import "./Utils.sol";

Expand All @@ -21,6 +23,7 @@ import "./Ownable.sol";
* @notice Gateway Receiver
* @author
*/
// contract NunyaBusiness is Ownable, Utils, Base64 {
contract NunyaBusiness is Ownable, Utils {

enum FunctionCallType {
Expand Down Expand Up @@ -199,15 +202,35 @@ contract NunyaBusiness is Ownable, Utils {
emit RetrievePubkey(requestId);
}

// TODO: Move to Utils.sol
// https://ethereum.stackexchange.com/a/148341/9680
// https://ethereum.stackexchange.com/a/78560/9680
// function trim(string calldata str, uint start, uint end) external pure returns(string memory) {
// return str[start:end];
// }

/// @notice Callback by the CustomGateway with the requested value
/// @param _requestId requestId of the request that was initally called
// TODO: Add other args to doc comments: _key Public key of the custom Secret contract deployed on the Secret network
function fulfilledSecretContractPubkeyCallback (uint256 _requestId, bytes calldata data) external onlyGateway {
// function fulfilledSecretContractPubkeyCallback (uint256 _requestId, uint256 _key, uint16 _code, address _nunya_business_contract_address) public onlyGateway validateRequest(_requestId, FunctionCallType.GET_KEY) {
console.log("------ NunyaBusiness - fulfilledSecretContractPubkeyCallback - _requestId: ", _requestId);
console.log("------ NunyaBusiness - fulfilledSecretContractPubkeyCallback - data.length: ", data.length);
console.log("------ NunyaBusiness - fulfilledSecretContractPubkeyCallback - data: ");
console.log("------ NunyaBusiness - fulfilledSecretContractPubkeyCallback - data (hex): ");
console.logBytes(data);

// // Strip the `0x` prefix to revert what was done by the Secret Gateway here ./packages/secret-contracts/secret-gateway/src/contract.rs
// string memory dataHexStr = trim(string(data), 2, data.length - 1);
// bytes memory dataBytes = abi.encodePacked(hex"A76A95918C39eE40d4a43CFAF19C35050E32E271")

// `data` is a hex literal (e.g. `hex"..."`) since `0x` was added in the
// Secret Gateway here ./packages/secret-contracts/secret-gateway/src/contract.rs
// bytes memory dataBytes = abi.encodePacked(data);

// string memory dataBytes = this.trim(string(data), 2, data.length - 1);
// bytes memory dataBase64 = Base64.decode(dataBytes);
// console.log("------ NunyaBusiness - fulfilledSecretContractPubkeyCallback - data (base64): ", string(dataBase64));

// Note: `Transaction ran out of gas` error if try to parse JSON response that has been prepared in the private Secret contract.
// To prevent it from out of gas errors then try sending it as the first key and converting the value into a fixed-length hash using Keccak256
// so it is easy to find the start and end of the `result` by index.
Expand All @@ -220,7 +243,7 @@ contract NunyaBusiness is Ownable, Utils {
// }

// emit FulfilledPubkey(_requestId, secretContractPubkey);
emit FulfilledPubkey(_requestId, data);
// emit FulfilledPubkey(_requestId, dataBase64);

// TODO: Implement the below instead when get working with `data` response initially

Expand Down
31 changes: 20 additions & 11 deletions packages/secret-contracts/nunya-contract/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,17 +242,26 @@ fn retrieve_pubkey(

let response_status_code: ResponseStatusCode = 0u16;

let data = ResponseRetrievePubkeyStoreMsg {
_request_id: task.clone(),
_key: my_keys.public_key,
_code: response_status_code,
_nunya_business_contract_address: config.nunya_business_contract_address,
};

let json_string =
serde_json_wasm::to_string(&data).map_err(|err| StdError::generic_err(err.to_string()))?;

let result = general_purpose::STANDARD.encode(json_string);
let newline: String = "\n".to_string();
let result1 = String::from_utf8(my_keys.public_key)?;
let result2 = task.clone().task_id.to_string();
let result3 = response_status_code.to_string();
let result_str = result1 + &newline + &result2 + &newline + &result3;

// convert string to base64
let result = general_purpose::STANDARD.encode(result_str.as_str());

// let data = ResponseRetrievePubkeyStoreMsg {
// _request_id: task.clone(),
// _key: my_keys.public_key,
// _code: response_status_code,
// _nunya_business_contract_address: config.nunya_business_contract_address,
// };

// let json_string =
// serde_json_wasm::to_string(&data).map_err(|err| StdError::generic_err(err.to_string()))?;

// let result = general_purpose::STANDARD.encode(json_string);

// Get the contract's code hash using the gateway address
let gateway_code_hash = get_contract_code_hash(&deps, config.gateway_address.to_string())?;
Expand Down