diff --git a/.gitignore b/.gitignore index 600d2d3..d44bc08 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -.vscode \ No newline at end of file +.vscode +yarn.lock \ No newline at end of file diff --git a/applications/subswap/contract/deploy.config.json b/applications/subswap/contract/deploy.config.json index 260714a..eb23eb2 100644 --- a/applications/subswap/contract/deploy.config.json +++ b/applications/subswap/contract/deploy.config.json @@ -1,5 +1,4 @@ { - "parentnetendpoint": "0x89D933dFBd879DA78643530Bf413c81F94A73c31", - "subnetendpoint": "0x0B1795ccA8E4eC4df02346a082df54D437F8D9aF", - "subnettoken": { "name": "test", "symbol": "test", "initSupply": "1000" } -} + "subnetendpoint": "0xBd0D59f41c7e80012E30cd35Af2375f9A15940A3", + "parentnetendpoint": "0x4381e4c455B35c2894CCDb90164225A5A2c08bbB" +} \ No newline at end of file diff --git a/applications/subswap/contract/network.config.json b/applications/subswap/contract/network.config.json index 0dee208..2131bfc 100644 --- a/applications/subswap/contract/network.config.json +++ b/applications/subswap/contract/network.config.json @@ -1,4 +1,4 @@ { - "xdcparentnet": "https://devnetstats.apothem.network/devnet", - "xdcsubnet": "https://devnetstats.apothem.network/subnet" -} + "xdcsubnet": "http://localhost:8545", + "xdcparentnet": "https://erpc.apothem.network/" +} \ No newline at end of file diff --git a/applications/subswap/contract/scripts/simpletokendeploy.js b/applications/subswap/contract/scripts/simpletokendeploy.js index 0f59723..619ff48 100644 --- a/applications/subswap/contract/scripts/simpletokendeploy.js +++ b/applications/subswap/contract/scripts/simpletokendeploy.js @@ -23,8 +23,9 @@ async function main() { token.initSupply ); + const [deployer] = await hre.ethers.getSigners(); + console.log("SimpleToken deploy start, deployer address:", deployer.address) await simpleToken.deployed(); - console.log("ERC20 " + token.name + " deploy to ", simpleToken.address); } diff --git a/cicd/.env.example b/cicd/.env.example index 50c814f..b1f5f9a 100644 --- a/cicd/.env.example +++ b/cicd/.env.example @@ -1,8 +1,8 @@ SUBNET_PK=0x1111111111111111111111111111111111111111111111111111111111111111 PARENTNET_PK=0x2222222222222222222222222222222222222222222222222222222222222222 -CSC=0x3333333333333333333333333333333333333333 -REVERSE_CSC=0x4444444444444444444444444444444444444444 +CHECKPOINT_CONTRACT=0x3333333333333333333333333333333333333333 +REVERSE_CHECKPOINT_CONTRACT=0x4444444444444444444444444444444444444444 # PARENTNET_URL: full url or devnet,testnet # devnet : https://devnetstats.apothem.network/devnet/ diff --git a/cicd/Dockerfile b/cicd/Dockerfile index 4ddb818..41f4124 100644 --- a/cicd/Dockerfile +++ b/cicd/Dockerfile @@ -1,14 +1,12 @@ FROM node:20-alpine COPY . /app - WORKDIR /app/cicd RUN yarn WORKDIR /app/endpoint RUN yarn WORKDIR /app/applications/subswap/contract RUN yarn - WORKDIR /app/cicd ENTRYPOINT ["node"] \ No newline at end of file diff --git a/cicd/README.md b/cicd/README.md index 116ab6c..0313662 100644 --- a/cicd/README.md +++ b/cicd/README.md @@ -11,8 +11,8 @@ Based on the provided `.env.example`, create your own `.env` file with the follo - **`PARENTNET_URL`**: RPC URL for the parentnet endpoint. - **`SUBNET_URL`**: RPC URL for the subnet. - **`SUBNET_PK`**: Private key for the deploy subnet XDC Zero wallet. -- **`CSC`**: Checkpoint smart contract address within the subnet chain (deployed to parentnet). -- **`REVERSE_CSC`**: Checkpoint smart contract address within the parentnet chain (deployed to subnet). +- **`CHECKPOINT_CONTRACT`**: Checkpoint smart contract address within the subnet chain (deployed to parentnet). +- **`REVERSE_CHECKPOINT_CONTRACT`**: Checkpoint smart contract address within the parentnet chain (deployed to subnet). #### Step 2: Deploy Endpoints and Register Chain @@ -78,8 +78,8 @@ Based on the provided `.env.example`, create your own `.env` file with the follo - **`PARENTNET_URL`**: RPC URL for the parentnet endpoint. - **`SUBNET_URL`**: RPC URL for the subnet. - **`SUBNET_PK`**: Private key for the deploy subnet XDC Zero wallet. -- **`CSC`**: Checkpoint smart contract address within the subnet chain (deployed to parentnet). -- **`REVERSE_CSC`**: Checkpoint smart contract address within the parentnet chain (deployed to subnet). +- **`CHECKPOINT_CONTRACT`**: Checkpoint smart contract address within the subnet chain (deployed to parentnet). +- **`REVERSE_CHECKPOINT_CONTRACT`**: Checkpoint smart contract address within the parentnet chain (deployed to subnet). ### Step 3: Deploy Endpoint and Register Chain diff --git a/cicd/applicationregister.js b/cicd/applicationregister.js index 22fe08c..4740dfc 100755 --- a/cicd/applicationregister.js +++ b/cicd/applicationregister.js @@ -1,19 +1,21 @@ process.chdir(__dirname); -const { execSync } = require("child_process"); const fs = require("node:fs"); -const env = require("dotenv").config({ path: "mount/.env" }); -const config = { - relativePath: "../endpoint/", -}; +const config = { relativePath: "../endpoint/" }; const endpointConfig = {}; - -const { ethers } = require("ethers"); const u = require("./util.js"); +u.loadContractENV(); -main(); +if (require.main === module) { + main(); +} async function main() { + await applicationRegister(); +} + +async function applicationRegister() { console.log("start application register"); + u.loadContractENV(); importEndpointJson(); initApplicationRegister(); await u.getNetworkID(config); @@ -81,6 +83,7 @@ function initApplicationRegister() { "incomplete ENVs, require SUBNET_PK, PARENTNET_PK, SUBNET_APP, PARENTNET_APP, SUBNET_URL" ); } + subnetPK = process.env.SUBNET_PK.startsWith("0x") ? process.env.SUBNET_PK : `0x${process.env.SUBNET_PK}`; @@ -192,3 +195,7 @@ function exportEndpointJson() { console.log("SUCCESS register application, endpointconfig:"); console.log(ep); } + +module.exports = { + applicationRegister, +}; diff --git a/cicd/endpointandregisterchain.js b/cicd/endpointandregisterchain.js index fe51c89..4c98a30 100644 --- a/cicd/endpointandregisterchain.js +++ b/cicd/endpointandregisterchain.js @@ -1,25 +1,31 @@ process.chdir(__dirname); -const { execSync } = require("child_process"); const fs = require("node:fs"); -const env = require("dotenv").config({ path: "mount/.env" }); -const config = { - relativePath: "../endpoint/", -}; +const config = { relativePath: "../endpoint/" }; const endpointConfig = {}; - -const { ethers } = require("ethers"); const u = require("./util.js"); +u.loadContractENV(); -main(); - +if (require.main === module) { + main(); +} async function main() { + const newENV = await endpointAndRegisterChain(); + for (const [key, value] of Object.entries(newENV)) { + u.replaceOrAddENV("./mount/contract_deploy.env", key, value); + u.replaceOrAddENV("./mount/common.env", key, value); + } + u.loadContractENV(); +} + +async function endpointAndRegisterChain() { console.log("start endpoint deploy and register chain"); initEndpointDeploy(); await u.getNetworkID(config); deployEndpoint(); configureEndpointJson(); registerEndpoint(); - exportEndpointJson(); + const newENV = exportEndpointJson(); + return newENV; } function initEndpointDeploy() { @@ -33,18 +39,17 @@ function initEndpointDeploy() { throw Error("PARENTNET_URL not found"); } - const reqENV = [ "SUBNET_PK", "PARENTNET_PK", "SUBNET_URL", - "CSC", - "REVERSE_CSC", + "CHECKPOINT_CONTRACT", + "REVERSE_CHECKPOINT_CONTRACT", ]; const isEnabled = reqENV.every((envVar) => envVar in process.env); if (!isEnabled) { throw Error( - "incomplete ENVs, require SUBNET_PK, PARENTNET_PK, SUBNET_URL, CSC, REVERSE_CSC" + "incomplete ENVs, require SUBNET_PK, PARENTNET_PK, SUBNET_URL, CHECKPOINT_CONTRACT, REVERSE_CHECKPOINT_CONTRACT" ); } subnetPK = process.env.SUBNET_PK.startsWith("0x") @@ -53,12 +58,12 @@ function initEndpointDeploy() { parentnetPK = process.env.PARENTNET_PK.startsWith("0x") ? process.env.PARENTNET_PK : `0x${process.env.PARENTNET_PK}`; - csc = process.env.CSC.startsWith("0x") - ? process.env.CSC - : `0x${process.env.CSC}`; - reverseCSC = process.env.REVERSE_CSC.startsWith("0x") - ? process.env.REVERSE_CSC - : `0x${process.env.REVERSE_CSC}`; + csc = process.env.CHECKPOINT_CONTRACT.startsWith("0x") + ? process.env.CHECKPOINT_CONTRACT + : `0x${process.env.CHECKPOINT_CONTRACT}`; + reverseCSC = process.env.REVERSE_CHECKPOINT_CONTRACT.startsWith("0x") + ? process.env.REVERSE_CHECKPOINT_CONTRACT + : `0x${process.env.REVERSE_CHECKPOINT_CONTRACT}`; subnetURL = process.env.SUBNET_URL; // return subnetURL, parentnetURL, subnetPK, parentnetPK, csc, reverseCSC @@ -119,6 +124,11 @@ function exportEndpointJson() { console.log("SUCCESS deploy endpoint and register chain, env:"); console.log("SUBNET_ZERO_CONTRACT=" + config.subnetEndpoint); console.log("PARENTNET_ZERO_CONTRACT=" + config.parentnetEndpoint); + + return { + SUBNET_ZERO_CONTRACT: config.subnetEndpoint, + PARENTNET_ZERO_CONTRACT: config.parentnetEndpoint, + }; } function deployEndpoint() { @@ -181,3 +191,7 @@ function parseEndpointOutput(outString) { throw Error("invalid output string: " + outString); } } + +module.exports = { + endpointAndRegisterChain, +}; diff --git a/cicd/subswap.js b/cicd/subswap.js index 5cd3552..d344b85 100644 --- a/cicd/subswap.js +++ b/cicd/subswap.js @@ -1,23 +1,32 @@ process.chdir(__dirname); -const { execSync } = require("child_process"); const fs = require("node:fs"); -const env = require("dotenv").config({ path: "mount/.env" }); -const config = { - relativePath: "../applications/subswap/contract/", -}; -const endpointConfig = {}; - -const { ethers } = require("ethers"); +const config = { relativePath: "../applications/subswap/contract/" }; const u = require("./util.js"); +u.loadContractENV(); -main(); +if (require.main === module) { + main(); +} async function main() { + const newENV = await subswap(); + for (const [key, value] of Object.entries(newENV)) { + u.replaceOrAddENV("./mount/contract_deploy.env", key, value); + u.replaceOrAddENV("./mount/common.env", key, value); + } + u.loadContractENV(); +} + +async function subswap() { console.log("start subswap deploy"); + u.loadContractENV(); checkEndpointConfig(); - initSubswapDeploy(); + await initSubswapDeploy(); deploySubswap(); - exportSubswap(); + deploySampleToken(); + writeSubswapConfigJson(); + const newENV = exportSubswap(); + return newENV; } function checkEndpointConfig() { @@ -46,7 +55,7 @@ function checkEndpointConfig() { throw Error("endpoints not found in mount/endpointconfig.json"); } -function initSubswapDeploy() { +async function initSubswapDeploy() { if (process.env.PARENTNET_URL) { parentnetURL = process.env.PARENTNET_URL; if (parentnetURL == "devnet") @@ -74,6 +83,7 @@ function initSubswapDeploy() { config["parentnetPK"] = parentnetPK; config["subnetURL"] = subnetURL; config["parentnetURL"] = parentnetURL; + await u.getNetworkID(config); } function deploySubswap() { @@ -111,11 +121,35 @@ function exportSubswap() { ); console.log(finalSubnet); console.log(finalParentnet); + + return { + SUBNET_APP: config.subnetSubswap, + PARENTNET_APP: config.parentnetSubswap, + }; +} + +function deploySampleToken() { + console.log("writing deploy.config.json"); + writeSubswapDeployJson(); + console.log("configuring PK"); + u.writeEnv(config.subnetPK, config.relativePath); + console.log("deploying subnet sample token on subnet"); + tokenDeployOut = u.callExec( + "cd ../applications/subswap/contract; npx hardhat run scripts/simpletokendeploy.js --network xdcsubnet" + ); + tokenAddr = parseEndpointOutput(tokenDeployOut); + config["subnetSampleTokenAddress"] = tokenAddr; } + function writeSubswapDeployJson() { deployJson = { subnetendpoint: config.subnetEndpoint, parentnetendpoint: config.parentnetEndpoint, + subnettoken: { + name: "Subnet Sample Token", + symbol: "SST", + initSupply: 1_000_000, + }, }; fs.writeFileSync( "../applications/subswap/contract/deploy.config.json", @@ -144,3 +178,45 @@ function parseEndpointOutput(outString) { throw Error("invalid output string: " + outString); } } + +function writeSubswapConfigJson() { + // { + // "parentnetUrl":"https://erpc.apothem.network/", + // "parentnetChainId":"51", + // "subnetUrl":"http://localhost:8545", + // "subnetChainId":"999", + // "subnetApp": "0x9777050a8402ac5958aA87631B15e98e26610EB5", + // "parentnetApp": "0xC355520747171Bd75f505E8cd12f935944bD783b", + // "tokens" : [ + // { + // "name": "Token A", + // "address": "0x103BAA273da5C2FEF2d1B8f839044A9bd07Bc1A1" + // } + // ] + // } + const obj = { + parentnetUrl: config["parentnetURL"], + parentnetChainId: config["parentnetID"], + parentnetApp: config["parentnetSubswap"], + subnetUrl: config["subnetURL"], + subnetChainId: config["subnetID"], + subnetApp: config["subnetSubswap"], + tokens: [ + { + name: "Subnet Sample Token", + address: + config["subnetSampleTokenAddress"] || + "0x1111111111111111111111111111111111111111", + }, + ], + }; + + fs.writeFileSync( + "./mount/subswap-frontend.config.json", + JSON.stringify(obj, null, 2) + ); +} + +module.exports = { + subswap, +}; diff --git a/cicd/util.js b/cicd/util.js index d89f934..f70328f 100644 --- a/cicd/util.js +++ b/cicd/util.js @@ -1,8 +1,7 @@ process.chdir(__dirname); const { execSync } = require("child_process"); const fs = require("node:fs"); -const env = require("dotenv").config({ path: "mount/.env" }); - +const dotenv = require("dotenv"); const { ethers } = require("ethers"); function writeEnv(key, path) { @@ -76,9 +75,129 @@ async function getNetworkID(config) { config["parentnetID"] = parentID; } +function loadContractENV() { + dotenv.config({ path: "mount/contract_deploy.env", override: true }); +} +function loadCommonENV() { + dotenv.config({ path: "mount/common.env", override: true }); +} + +function replaceENV(filepath, replaceENV, replaceValue) { + //check files mounted + if (!fs.existsSync(filepath)) { + throw Error(`could not modify ${filepath}, file not mounted`); + } + const envFileContent = fs.readFileSync(filepath, "utf8"); + const regex = new RegExp(`^${replaceENV}=.*`, "gm"); + let matches = envFileContent.match(regex); + matches = matches === null ? [] : matches; + + if (matches.length > 1) { + console.log( + "Warning: found more than one instance of", + replaceENV, + "in", + filepath + ); + console.log(matches); + } + let matchesCount = 0; + const updatedContent = envFileContent.replace(regex, (match) => { + let replaceString = `# Commented old value by deployer +# ${matches[matchesCount]}`; + + if (matchesCount == matches.length - 1) { + replaceString += `\n${replaceENV}=${replaceValue}`; + } + matchesCount++; + console.log(`Updated ${filepath} file: \n${replaceString}`); + return replaceString; + }); + + fs.writeFileSync(filepath, updatedContent); + return updatedContent !== envFileContent; +} + +function addENV(filepath, envName, envValue) { + //check files mounted + if (!fs.existsSync(filepath)) { + throw Error(`could not modify ${filepath}, file not mounted`); + } + const envFileContent = fs.readFileSync(filepath, "utf8"); + const appendString = `${envName}=${envValue}`; + const updatedContent = envFileContent + "\n" + appendString; + + fs.writeFileSync(filepath, updatedContent); +} + +function replaceOrAddENV(filepath, envKey, envValue) { + replaced = replaceENV(filepath, envKey, envValue); + !replaced && addENV(filepath, envKey, envValue); +} + +async function transferTokens(url, fromPK, toPK, amount) { + console.log(url); + const provider = new ethers.providers.JsonRpcProvider(url); + const fromWallet = new ethers.Wallet(fromPK, provider); + const toWallet = new ethers.Wallet(toPK, provider); + let tx = { + to: toWallet.address, + value: ethers.utils.parseEther(amount.toString()), + }; + + try { + await provider.detectNetwork(); + } catch (error) { + throw Error("Cannot connect to RPC"); + } + + let sendPromise = fromWallet.sendTransaction(tx); + txHash = await sendPromise.then((tx) => { + return tx.hash; + }); + console.log("TX submitted, confirming TX execution, txhash:", txHash); + + let receipt; + let count = 0; + while (!receipt) { + count++; + // console.log("tx receipt check loop", count); + if (count > 60) { + throw Error("Timeout: transaction did not execute after 60 seconds"); + } + await sleep(1000); + let receipt = await provider.getTransactionReceipt(txHash); + if (receipt && receipt.status == 1) { + console.log("Successfully transferred", amount, "subnet token"); + let fromBalance = await provider.getBalance(fromWallet.address); + fromBalance = ethers.utils.formatEther(fromBalance); + let toBalance = await provider.getBalance(toWallet.address); + toBalance = ethers.utils.formatEther(toBalance); + console.log("Current balance"); + console.log(`${fromWallet.address}: ${fromBalance}`); + console.log(`${toWallet.address}: ${toBalance}`); + return { + fromBalance: fromBalance, + toBalance: toBalance, + txHash: txHash, + }; + } + } +} + +function sleep(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + module.exports = { getNetworkID, callExec, writeEnv, writeNetworkJson, + loadContractENV, + loadCommonENV, + replaceENV, + addENV, + replaceOrAddENV, + transferTokens, }; diff --git a/cicd/zeroandsubswap.js b/cicd/zeroandsubswap.js new file mode 100644 index 0000000..e19412a --- /dev/null +++ b/cicd/zeroandsubswap.js @@ -0,0 +1,60 @@ +process.chdir(__dirname); +const { ethers } = require("ethers"); +const fs = require("node:fs"); +const u = require("./util.js"); +u.loadContractENV(); +const e = require("./endpointandregisterchain.js"); +const s = require("./subswap.js"); +const a = require("./applicationregister.js"); + +main(); + +async function main() { + const step1ENV = await e.endpointAndRegisterChain(); + for (const [key, value] of Object.entries(step1ENV)) { + u.replaceOrAddENV("./mount/contract_deploy.env", key, value); + u.replaceOrAddENV("./mount/common.env", key, value); + } + + const step2ENV = await s.subswap(); + for (const [key, value] of Object.entries(step2ENV)) { + u.replaceOrAddENV("./mount/contract_deploy.env", key, value); + u.replaceOrAddENV("./mount/common.env", key, value); + } + + await a.applicationRegister(); + + await setupSubnetWallets(); +} + +async function setupSubnetWallets() { + u.loadCommonENV(); + if (!fs.existsSync("./mount/keys.json")) { + throw Error(`could not modify ${filepath}, file not mounted`); + } + const grandmasterPK = JSON.parse(fs.readFileSync("./mount/keys.json", "utf8")) + .Grandmaster.PrivateKey; + + try { + new ethers.Wallet(process.env.SUBNET_WALLET_PK); + new ethers.Wallet(process.env.SUBNET_ZERO_WALLET_PK); + new ethers.Wallet(grandmasterPK); + } catch (error) { + console.log(error); + console.log("failed to setup wallets, invalid PK"); + process.exit(); + } + + await u.transferTokens( + process.env.SUBNET_URL, + grandmasterPK, + process.env.SUBNET_WALLET_PK, + 10_000_000 + ); + await u.transferTokens( + process.env.SUBNET_URL, + grandmasterPK, + process.env.SUBNET_ZERO_WALLET_PK, + 1_000_000 + ); +} diff --git a/endpoint/contracts/Endpoint.sol b/endpoint/contracts/Endpoint.sol index 68fb0fe..b94a159 100644 --- a/endpoint/contracts/Endpoint.sol +++ b/endpoint/contracts/Endpoint.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity =0.8.23; +import {RLPReader} from "./libraries/RLPReader.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {MerklePatricia} from "@polytope-labs/solidity-merkle-trees/src/MerklePatricia.sol"; import {IFullCheckpoint} from "./interfaces/IFullCheckpoint.sol"; -import {RLPReader} from "./libraries/RLPReader.sol"; import {Address} from "@openzeppelin/contracts/utils/Address.sol"; import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; @@ -306,9 +306,14 @@ contract Endpoint is Ownable, ReentrancyGuard { bytes memory transactionRlp ) public pure returns (Transaction memory) { RLPReader.RLPItem[] memory items = transactionRlp.toRlpItem().toList(); - Transaction memory transaction; - transaction.to = items[3].toAddress(); + + if (items[3].len == 21) { + transaction.to = items[3].toAddress(); + } else { + transaction.to = items[5].toAddress(); + } + return transaction; } @@ -319,7 +324,8 @@ contract Endpoint is Ownable, ReentrancyGuard { function getReceipt( bytes memory receiptRlp ) public pure returns (Receipt memory) { - RLPReader.RLPItem[] memory items = receiptRlp.toRlpItem().toList(); + RLPReader.RLPItem[] memory items; + items = receiptRlp.toRlpItem().toList(); Receipt memory receipt; receipt.postStateOrStatus = items[0].toBytes(); @@ -343,7 +349,7 @@ contract Endpoint is Ownable, ReentrancyGuard { return receipt; } - function sliceBytes(bytes memory data) private pure returns (bytes memory) { + function sliceBytes(bytes memory data) public pure returns (bytes memory) { require(data.length >= 64, "Data must be at least 64 bytes long"); bytes memory slicedData = new bytes(data.length - 64); diff --git a/endpoint/contracts/libraries/RLPReader.sol b/endpoint/contracts/libraries/RLPReader.sol index 890720c..51e6f3a 100644 --- a/endpoint/contracts/libraries/RLPReader.sol +++ b/endpoint/contracts/libraries/RLPReader.sol @@ -102,11 +102,9 @@ library RLPReader { /* * @param the RLP item containing the encoded list. */ - function toList( + function toLegacyList( RLPItem memory item ) internal pure returns (RLPItem[] memory) { - require(isList(item)); - uint256 items = numItems(item); RLPItem[] memory result = new RLPItem[](items); @@ -121,6 +119,23 @@ library RLPReader { return result; } + function toEip2718List( + RLPItem memory item + ) internal pure returns (RLPItem[] memory) { + RLPItem[] memory items = toLegacyList(item); + return toLegacyList(items[1]); + } + + function toList( + RLPItem memory item + ) internal pure returns (RLPItem[] memory) { + if (isList(item)) { + return toLegacyList(item); + } else { + return toEip2718List(item); + } + } + // @return indicator whether encoded payload is a list. negate this function call for isData. function isList(RLPItem memory item) internal pure returns (bool) { if (item.len == 0) return false; diff --git a/endpoint/endpointconfig.json b/endpoint/endpointconfig.json index ea6f507..89eeebd 100644 --- a/endpoint/endpointconfig.json +++ b/endpoint/endpointconfig.json @@ -1,36 +1,36 @@ { - "xdcparentnet": { - "endpoint": "0xB575c682301e20935B8C5846313a01E6f0Bd9f4B", + "xdcsubnet": { + "endpoint": "0xBd0D59f41c7e80012E30cd35Af2375f9A15940A3", "registers": [ { - "csc": "0x3C714ffDB5A13d8d7EF0bE5f41F12bd840DA9ef1", - "endpoint": "0x0bb5a292b13C7983BFDCd62538e0e81603793342", - "chainId": "953" + "csc": "0x172cf9c1d0F263Bd338bc64aa9FE2CF62716b3Dd", + "endpoint": "0x4381e4c455B35c2894CCDb90164225A5A2c08bbB", + "chainId": "51" } ], "applications": [ { - "rid": "953", - "rua": "0xdfc2cD2b6AA7fD236e3A4Efa255A9b81c94B3fF4", - "sua": "0x40DC79697399686cd4003Ab9B7B87115bA945397" + "rid": "51", + "rua": "0x14937E491F30B563f93f3aAa37F298330faBFb01", + "sua": "0x1a38735Ad20503c857d9EcFB7585E8d75F13Ec6f" } ] }, - "xdcsubnet": { - "endpoint": "0x0bb5a292b13C7983BFDCd62538e0e81603793342", + "xdcparentnet": { + "endpoint": "0x4381e4c455B35c2894CCDb90164225A5A2c08bbB", "registers": [ { - "csc": "0x720A33E9c54dDf240D42f822E8b20D9C70226AAC", - "endpoint": "0xB575c682301e20935B8C5846313a01E6f0Bd9f4B", - "chainId": "551" + "csc": "0xF48C8f2C44B99F1c9F54DB8d5781CB47d5449A05", + "endpoint": "0xBd0D59f41c7e80012E30cd35Af2375f9A15940A3", + "chainId": "48651" } ], "applications": [ { - "rid": "551", - "rua": "0x40DC79697399686cd4003Ab9B7B87115bA945397", - "sua": "0xdfc2cD2b6AA7fD236e3A4Efa255A9b81c94B3fF4" + "rid": "48651", + "rua": "0x1a38735Ad20503c857d9EcFB7585E8d75F13Ec6f", + "sua": "0x14937E491F30B563f93f3aAa37F298330faBFb01" } ] } -} +} \ No newline at end of file diff --git a/endpoint/network.config.json b/endpoint/network.config.json index 0dee208..2131bfc 100644 --- a/endpoint/network.config.json +++ b/endpoint/network.config.json @@ -1,4 +1,4 @@ { - "xdcparentnet": "https://devnetstats.apothem.network/devnet", - "xdcsubnet": "https://devnetstats.apothem.network/subnet" -} + "xdcsubnet": "http://localhost:8545", + "xdcparentnet": "https://erpc.apothem.network/" +} \ No newline at end of file diff --git a/endpoint/test/endpoint.js b/endpoint/test/endpoint.js index 7bad622..e74a465 100644 --- a/endpoint/test/endpoint.js +++ b/endpoint/test/endpoint.js @@ -60,6 +60,17 @@ describe("xdc zero endpoint", () => { }); describe("test endpoint", () => { + it("test rlp resolve", async () => { + const res1 = await endpoint.getReceipt( + "0xb9048402f9048001830169a8b9010000000000000000000000000000000000000000000000001000000002000000000000000000800000000000100000400000000000000000000000000000000000004000800000000000000008000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000012000000000080000000000000000000000000000000000000280000000200000000000000000000002000000000000001000000000000000000000000000000000000000000000002000000020000004000000000000000000000000000000000000020000000000002000000000000000000000000000000000000008000000000000000f90375f89b94faa9365d018d7f3984a4fce381be157d8801b6aef863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000d602735eaeb1e81b673e456c631209c95fac446aa00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000002d5d0d5669e6e9dc0000f901da94200760f7380b93dec8dfe03a23c38fa8d46e3949e1a0e9bded5f24a4168e4f3bf44e00298c993b22376aad8c58c7dda9718a54cbea82b901a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000003300000000000000000000000046638164b514b9d19a4ab3e35c62df5e107e7f27000000000000000000000000000000000000000000000000000000000000174b000000000000000000000000d6ae154a2901722031a8ed023851296bff7e9e3d00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000648bc392070000000000000000000000007589d4667b9bd10a93bf918e4eb459f1274bdf93000000000000000000000000000000000000000000002d5d0d5669e6e9dc0000000000000000000000000000d602735eaeb1e81b673e456c631209c95fac446a00000000000000000000000000000000000000000000000000000000f8f99446638164b514b9d19a4ab3e35c62df5e107e7f27e1a0f94f9ef28e17557f777d13ad02f21c0b557bdab8cded7835d95551ba17e25e3eb8c0000000000000000000000000000000000000000000000000000000000000174b000000000000000000000000d6ae154a2901722031a8ed023851296bff7e9e3d0000000000000000000000007589d4667b9bd10a93bf918e4eb459f1274bdf93000000000000000000000000faa9365d018d7f3984a4fce381be157d8801b6ae000000000000000000000000000000000000000000002d5d0d5669e6e9dc0000000000000000000000000000d602735eaeb1e81b673e456c631209c95fac446a" + ); + console.log(res1); + + const res2 = await endpoint.getTransaction( + "0xb9013602f9013233018502e90edd008502e90edd008301692894e29059ff09aa10a27b2421ef1009f85b4ff8387480b8c44cc9a5920000000000000000000000000000000000000000000000000000000000004b9c0000000000000000000000004ac7ec88de85f81400208257981a9e775fb7721e000000000000000000000000885113939950fd55597cbc30e33bde371a9a2b740000000000000000000000008bfbb31a1a5ab001f5f204d3eb85d7b16a9e60c0000000000000000000000000000000000000000000005554737f4bb7a6dc000000000000000000000000000000da8c65e0b80946dbe884c924c9c6c03f7acc6cc001a097a9e809292ffde59923b9f7ef35292f3e6c3fcfcc6ac2313c91afe2398c4c00a06147bf2f05cadf58052f2eab75a32066c25d068ce143f5b6b3fb700821d8473d" + ); + console.log(res2); + }); it("shold be able to send message", async () => { await sua.simpleCall(chainId, rua.address);