First commit
This commit is contained in:
		
							
								
								
									
										12
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  |  | ||||||
|  | src/js/metacoin-config.js | ||||||
|  | node_modules | ||||||
|  | build | ||||||
|  | .env | ||||||
|  | tmp | ||||||
|  | _old | ||||||
|  | .venv | ||||||
|  | *.mnemonic | ||||||
|  | *_wallet.json | ||||||
|  | *.log | ||||||
|  | _contracts_old | ||||||
							
								
								
									
										24
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | { | ||||||
|  |   "editor.bracketPairColorization.enabled": true, | ||||||
|  |   "editor.fontFamily": "'Cascadia Code PL', Consolas, 'Courier New', monospace", | ||||||
|  |   "editor.fontLigatures": true, | ||||||
|  |   "editor.guides.bracketPairs": true, | ||||||
|  |   "editor.linkedEditing": true, | ||||||
|  |   "editor.minimap.enabled": false, | ||||||
|  |   "editor.tabSize": 2, | ||||||
|  |   "editor.useTabStops": true, | ||||||
|  |   "editor.formatOnSave": true, | ||||||
|  |   "editor.formatOnPaste": true, | ||||||
|  |   "files.trimTrailingWhitespace": true, | ||||||
|  |   "github.copilot.enable": { | ||||||
|  |     "*": true, | ||||||
|  |     "markdown": false, | ||||||
|  |     "plaintext": false, | ||||||
|  |     "scminput": false | ||||||
|  |   }, | ||||||
|  |   "prettier.semi": false, | ||||||
|  |   "prettier.singleQuote": true, | ||||||
|  |   "prettier.trailingComma": "none", | ||||||
|  |   "terminal.integrated.defaultProfile.linux": "JavaScript Debug Terminal", | ||||||
|  |   "terminal.integrated.defaultProfile.windows": "JavaScript Debug Terminal" | ||||||
|  | } | ||||||
							
								
								
									
										21
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | MIT License Copyright (c) 2025 Toni Ramiro <sargatxet@gmail.com> | ||||||
|  |  | ||||||
|  | Permission is hereby granted, free of | ||||||
|  | charge, to any person obtaining a copy of this software and associated | ||||||
|  | documentation files (the "Software"), to deal in the Software without | ||||||
|  | restriction, including without limitation the rights to use, copy, modify, merge, | ||||||
|  | publish, distribute, sublicense, and/or sell copies of the Software, and to | ||||||
|  | permit persons to whom the Software is furnished to do so, subject to the | ||||||
|  | following conditions: | ||||||
|  |  | ||||||
|  | The above copyright notice and this permission notice | ||||||
|  | (including the next paragraph) shall be included in all copies or substantial | ||||||
|  | portions of the Software. | ||||||
|  |  | ||||||
|  | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF | ||||||
|  | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||||
|  | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO | ||||||
|  | EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||||||
|  | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||||||
|  | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||||
|  | THE SOFTWARE. | ||||||
							
								
								
									
										19
									
								
								contracts/Migrations.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								contracts/Migrations.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | // SPDX-License-Identifier: MIT | ||||||
|  | pragma solidity >=0.4.22 <0.9.0; | ||||||
|  |  | ||||||
|  | contract Migrations { | ||||||
|  |   address public owner = msg.sender; | ||||||
|  |   uint public last_completed_migration; | ||||||
|  |  | ||||||
|  |   modifier restricted() { | ||||||
|  |     require( | ||||||
|  |       msg.sender == owner, | ||||||
|  |       "This function is restricted to the contract's owner" | ||||||
|  |     ); | ||||||
|  |     _; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   function setCompleted(uint completed) public restricted { | ||||||
|  |     last_completed_migration = completed; | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										31
									
								
								contracts/SargaTrxUsdPrice.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								contracts/SargaTrxUsdPrice.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | |||||||
|  | // SPDX-License-Identifier: MIT | ||||||
|  | pragma solidity ^0.8.20; | ||||||
|  |  | ||||||
|  | import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol"; | ||||||
|  |  | ||||||
|  | contract SargaTrxUsdPrice { | ||||||
|  |     AggregatorV3Interface internal _priceFeed; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Network: Tron | ||||||
|  |      * Aggregator: TRX/USD | ||||||
|  |      * Address: TC6o8AakUg4Xz9nHY9qXpJNsgF7CQkwBqF | ||||||
|  |      */ | ||||||
|  |     constructor(address priceFeedAddress) { | ||||||
|  |         _priceFeed = AggregatorV3Interface(priceFeedAddress); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns the latest price | ||||||
|  |      */ | ||||||
|  |     function getLatestPrice() public view returns (int) { | ||||||
|  |         ( | ||||||
|  |             , | ||||||
|  |             /* uint80 roundID */ int price /* uint startedAt */ /* uint timeStamp */ /* uint80 answeredInRound */, | ||||||
|  |             , | ||||||
|  |             , | ||||||
|  |  | ||||||
|  |         ) = _priceFeed.latestRoundData(); | ||||||
|  |         return price; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										8
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | services: | ||||||
|  |   tron: | ||||||
|  |     image: tronbox/tre | ||||||
|  |     restart: unless-stopped | ||||||
|  |     ports: | ||||||
|  |       - 9090:9090 | ||||||
|  |     # volumes: | ||||||
|  |     #   - ./accounts-data:/config    # node will load these keys | ||||||
							
								
								
									
										13
									
								
								lib/logger.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								lib/logger.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | 'use strict' | ||||||
|  |  | ||||||
|  | // Log | ||||||
|  | const logMessage = (source, msg) => { | ||||||
|  |   console.log(new Date(), `[${source}]`, msg) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Error | ||||||
|  | const errorMessage = (source, msg) => { | ||||||
|  |   console.error(new Date(), `[${source}]`, msg) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | module.exports = { logMessage, errorMessage } | ||||||
							
								
								
									
										84
									
								
								lib/tron.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								lib/tron.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | |||||||
|  | 'use strict' | ||||||
|  |  | ||||||
|  | // Environment | ||||||
|  | require('dotenv').config() | ||||||
|  |  | ||||||
|  | // Libraries | ||||||
|  | const path = require('path') | ||||||
|  | const fs = require('fs') | ||||||
|  | const { decryptString } = require('./utils') | ||||||
|  |  | ||||||
|  | // Connect to Tron network | ||||||
|  | const TronWeb = require('tronweb') | ||||||
|  |  | ||||||
|  | // Set Tron connection | ||||||
|  | const API_URL = | ||||||
|  |   process.env.DEBUG === '1' | ||||||
|  |     ? process.env.TRON_NILE_API | ||||||
|  |     : process.env.DEBUG === '2' | ||||||
|  |     ? process.env.TRON_LOCAL_API | ||||||
|  |     : process.env.TRON_MAINNET_API | ||||||
|  | const HttpProvider = TronWeb.providers.HttpProvider | ||||||
|  | const fullNode = new HttpProvider(API_URL) | ||||||
|  | const solidityNode = new HttpProvider(API_URL) | ||||||
|  | const eventServer = API_URL | ||||||
|  | const tronWeb = new TronWeb(fullNode, solidityNode, eventServer) | ||||||
|  | const feeLimit = parseInt(process.env.FEE_LIMIT) | ||||||
|  |  | ||||||
|  | // Set contract data | ||||||
|  | const contractPath = path.join( | ||||||
|  |   __dirname, | ||||||
|  |   `../build/contracts/${process.env.CONTRACT_NAME}.json` | ||||||
|  | ) | ||||||
|  | const contractData = JSON.parse(fs.readFileSync(contractPath)) | ||||||
|  | const contract = tronWeb.contract( | ||||||
|  |   contractData.abi, | ||||||
|  |   process.env.CONTRACT_ADDRESS | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // TRX to SUN conversion | ||||||
|  | function trxToSun(trx) { | ||||||
|  |   const sun = +(+trx * 1e6).toFixed(0) | ||||||
|  |   return sun | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SUN to TRX conversion | ||||||
|  | function sunToTrx(sun) { | ||||||
|  |   const trx = +(+sun / 1e6).toFixed(6) | ||||||
|  |   return trx | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Address to base58 conversion | ||||||
|  | function addressToBase58(address) { | ||||||
|  |   return tronWeb.address.fromHex(address) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Set default private key | ||||||
|  | function setDefaultPrivateKey(pk) { | ||||||
|  |   // Decrypt private key | ||||||
|  |   const decPK = | ||||||
|  |     pk || | ||||||
|  |     decryptString(process.env.PRIVATE_KEY_MAINNET, process.env.SEED_PASSWORD) | ||||||
|  |   // Set private key in TronWeb | ||||||
|  |   tronWeb.setPrivateKey(decPK.substring(2)) | ||||||
|  |  | ||||||
|  |   return decPK | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get TRX balance | ||||||
|  | const getTrxBalance = async (address) => { | ||||||
|  |   const balance = sunToTrx(await tronWeb.trx.getBalance(address)) | ||||||
|  |   return balance | ||||||
|  | } | ||||||
|  |  | ||||||
|  | module.exports = { | ||||||
|  |   tronWeb, | ||||||
|  |   setDefaultPrivateKey, | ||||||
|  |   feeLimit, | ||||||
|  |   contractData, | ||||||
|  |   contract, | ||||||
|  |   trxToSun, | ||||||
|  |   sunToTrx, | ||||||
|  |   addressToBase58, | ||||||
|  |   getTrxBalance | ||||||
|  | } | ||||||
							
								
								
									
										73
									
								
								lib/utils.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								lib/utils.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | |||||||
|  | 'use strict' | ||||||
|  |  | ||||||
|  | // Libraries | ||||||
|  | const { customAlphabet } = require('nanoid') | ||||||
|  | const StringCrypto = require('string-crypto') | ||||||
|  | const path = require('path') | ||||||
|  |  | ||||||
|  | // NanoId with custom alphabet | ||||||
|  | const newId = (len) => { | ||||||
|  |   const nanoid = customAlphabet( | ||||||
|  |     'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', | ||||||
|  |     len || 21 | ||||||
|  |   ) | ||||||
|  |   return nanoid() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Remove all _id | ||||||
|  | const removeFieldByName = (o, fieldName) => { | ||||||
|  |   delete o[fieldName] | ||||||
|  |   for (let v of Object.values(o)) | ||||||
|  |     if (v instanceof Object) removeFieldByName(v, fieldName) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Clean object from unnecesary fields | ||||||
|  | const fieldsToRemove = ['_id'] | ||||||
|  | const cleanObject = (o) => { | ||||||
|  |   const obj = JSON.parse(JSON.stringify(o)) | ||||||
|  |   fieldsToRemove.forEach((f) => { | ||||||
|  |     removeFieldByName(obj, f) | ||||||
|  |   }) | ||||||
|  |   return obj | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Securize sensible data | ||||||
|  | const cryptoOptions = { | ||||||
|  |   salt: process.env.CRYPTO_SALT, | ||||||
|  |   iterations: parseInt(process.env.CRYPTO_ITERATIONS), | ||||||
|  |   digest: process.env.CRYPTO_DIGEST // one of: 'blake2b512' | 'blake2s256' | 'md4' | 'md5' | 'md5-sha1' | 'mdc2' | 'ripemd160' | 'sha1' | 'sha224' | 'sha256' | 'sha3-224' | 'sha3-256' | 'sha3-384' | 'sha3-512' | 'sha384' | 'sha512' | 'sha512-224' | 'sha512-256' | 'sm3' | 'whirlpool'; | ||||||
|  | } | ||||||
|  | const stringCypto = new StringCrypto(cryptoOptions) | ||||||
|  | const encryptString = (value, password) => { | ||||||
|  |   return stringCypto.encryptString(value, password) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const decryptString = (value, password) => { | ||||||
|  |   return stringCypto.decryptString(value, password) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Split array into pieces | ||||||
|  | const chunk = (arr, size) => | ||||||
|  |   arr.reduce( | ||||||
|  |     (acc, _, i) => (i % size ? acc : [...acc, arr.slice(i, i + size)]), | ||||||
|  |     [] | ||||||
|  |   ) | ||||||
|  |  | ||||||
|  | // Sleep | ||||||
|  | const sleep = (segundos) => { | ||||||
|  |   return new Promise((resolve) => setTimeout(resolve, segundos * 1000)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get file name | ||||||
|  | const getFileName = (f) => path.basename(f, '.js') | ||||||
|  |  | ||||||
|  | module.exports = { | ||||||
|  |   newId, | ||||||
|  |   removeFieldByName, | ||||||
|  |   cleanObject, | ||||||
|  |   encryptString, | ||||||
|  |   decryptString, | ||||||
|  |   chunk, | ||||||
|  |   sleep, | ||||||
|  |   getFileName | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								migrations/1_initial_migration.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								migrations/1_initial_migration.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | require('dotenv').config() | ||||||
|  |  | ||||||
|  | var Migrations = artifacts.require('./Migrations.sol') | ||||||
|  |  | ||||||
|  | module.exports = function (deployer) { | ||||||
|  |   deployer.deploy(Migrations) | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								migrations/2_deploy_contracts.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								migrations/2_deploy_contracts.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | require('dotenv').config() | ||||||
|  |  | ||||||
|  | var MyContract = artifacts.require('./SargaTrxUsdPrice.sol') | ||||||
|  |  | ||||||
|  | module.exports = function (deployer) { | ||||||
|  |   deployer.deploy(MyContract) | ||||||
|  | } | ||||||
							
								
								
									
										22
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | { | ||||||
|  |   "name": "sarga_tron_usd_price", | ||||||
|  |   "version": "0.1.0", | ||||||
|  |   "description": "Contract to get TRX/USD value", | ||||||
|  |   "main": "index.js", | ||||||
|  |   "author": "Toni Ramiro <sargatxet@gmail.com>", | ||||||
|  |   "license": "MIT", | ||||||
|  |   "private": true, | ||||||
|  |   "dependencies": { | ||||||
|  |     "@chainlink/contracts": "1.4.0", | ||||||
|  |     "@noble/secp256k1": "1.7.1", | ||||||
|  |     "dotenv": "16.4.7", | ||||||
|  |     "solc": "0.8.20", | ||||||
|  |     "string-crypto": "2.0.2", | ||||||
|  |     "tronbox": "4.1.1", | ||||||
|  |     "tronweb": "5.3.0" | ||||||
|  |   }, | ||||||
|  |   "devDependencies": { | ||||||
|  |     "@openzeppelin/test-helpers": "0.5.16", | ||||||
|  |     "chai": "5.2.0" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										1
									
								
								sample-env
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								sample-env
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | export PRIVATE_KEY_SHASTA=0000000000000000000000000000000000000000000000000000000000000001 | ||||||
							
								
								
									
										93
									
								
								scripts/1_deploy_on_mainnet.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								scripts/1_deploy_on_mainnet.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | |||||||
|  | require('dotenv').config() | ||||||
|  |  | ||||||
|  | // Mainnet | ||||||
|  | process.env.DEBUG = '0' | ||||||
|  |  | ||||||
|  | const fs = require('fs') | ||||||
|  | const { logMessage, errorMessage } = require('../lib/logger') | ||||||
|  | const { | ||||||
|  |   tronWeb, | ||||||
|  |   setDefaultPrivateKey, | ||||||
|  |   contractData, | ||||||
|  |   feeLimit, | ||||||
|  |   sunToTrx, | ||||||
|  |   addressToBase58 | ||||||
|  | } = require('../lib/tron') | ||||||
|  | const { sleep } = require('../lib/utils') | ||||||
|  |  | ||||||
|  | // Binary data of the contract and ABI | ||||||
|  | const bytecode = contractData.bytecode | ||||||
|  | const abi = contractData.abi | ||||||
|  | logMessage('1_deploy_on_mainnet', 'Bytecode and ABI loaded') | ||||||
|  |  | ||||||
|  | // Get TRX balance | ||||||
|  | const getTrxBalance = async (address) => { | ||||||
|  |   const balance = sunToTrx(await tronWeb.trx.getBalance(address)) | ||||||
|  |   logMessage('1_deploy_on_mainnet', `TRX balance: ${balance} TRX`) | ||||||
|  |   return balance | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function deployContract() { | ||||||
|  |   try { | ||||||
|  |     setDefaultPrivateKey() | ||||||
|  |  | ||||||
|  |     logMessage('1_deploy_on_mainnet', 'Deploying contract...') | ||||||
|  |  | ||||||
|  |     // Get TRX balance | ||||||
|  |     const address = tronWeb.defaultAddress.base58 | ||||||
|  |     const balance = await getTrxBalance(address) | ||||||
|  |     if (balance < 200) { | ||||||
|  |       throw new Error('Insufficient TRX balance to deploy the contract') | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Sign transaction | ||||||
|  |     const unsignedTxn = await tronWeb.transactionBuilder.createSmartContract({ | ||||||
|  |       abi, | ||||||
|  |       bytecode, | ||||||
|  |       feeLimit, | ||||||
|  |       callValue: 0, // TRX sent to the contract | ||||||
|  |       parameters: [process.env.CHAINLINK_USD_PRICE_FEED] | ||||||
|  |     }) | ||||||
|  |     const signedTxn = await tronWeb.trx.sign(unsignedTxn) | ||||||
|  |     logMessage('1_deploy_on_mainnet', 'Transaction signed') | ||||||
|  |  | ||||||
|  |     // Broadcast transaction | ||||||
|  |     const tx = await tronWeb.trx.sendRawTransaction(signedTxn) | ||||||
|  |     logMessage('1_deploy_on_mainnet', `Transaction ID: ${tx.txid}`) | ||||||
|  |     logMessage('1_deploy_on_mainnet', 'Contract deployed') | ||||||
|  |  | ||||||
|  |     // Get contract address | ||||||
|  |     let contractAddress = {} | ||||||
|  |     do { | ||||||
|  |       await sleep(5) // Wait 5 seconds | ||||||
|  |       contractAddress = await tronWeb.trx.getTransactionInfo(tx.txid) | ||||||
|  |     } while (!contractAddress.contract_address) | ||||||
|  |     logMessage( | ||||||
|  |       '1_deploy_on_mainnet', | ||||||
|  |       `Contract address: ${contractAddress.contract_address}` | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  |     // Add/Change into .env | ||||||
|  |     let envContent = fs.readFileSync('.env', 'utf8') | ||||||
|  |     if (/CONTRACT_ADDRESS=/.test(envContent)) { | ||||||
|  |       envContent = envContent.replace( | ||||||
|  |         /CONTRACT_ADDRESS=.*/, | ||||||
|  |         `CONTRACT_ADDRESS=${addressToBase58(contractAddress.contract_address)}` | ||||||
|  |       ) | ||||||
|  |     } else { | ||||||
|  |       envContent += `\n\n# Contract address\nCONTRACT_ADDRESS=${addressToBase58( | ||||||
|  |         contractAddress.contract_address | ||||||
|  |       )}` | ||||||
|  |     } | ||||||
|  |     fs.writeFileSync('.env', envContent) | ||||||
|  |  | ||||||
|  |     process.exit(0) | ||||||
|  |   } catch (error) { | ||||||
|  |     errorMessage( | ||||||
|  |       '1_deploy_on_mainnet', | ||||||
|  |       `ERROR: ${error.message || JSON.stringify(error)}` | ||||||
|  |     ) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | deployContract() | ||||||
							
								
								
									
										1
									
								
								test/.git-folder-keeper
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/.git-folder-keeper
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | This is a placeholder file to ensure the parent directory in the git repository. Feel free to remove. | ||||||
							
								
								
									
										41
									
								
								test/SargaTrxUsdPrice.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								test/SargaTrxUsdPrice.test.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | |||||||
|  | // test/SargaTrxUsdPrice.test.js | ||||||
|  |  | ||||||
|  | require('dotenv').config() | ||||||
|  |  | ||||||
|  | const TronWeb = require('tronweb') | ||||||
|  | const HttpProvider = TronWeb.providers.HttpProvider | ||||||
|  | const API_URL = process.env.TRON_API | ||||||
|  | const fullNode = new HttpProvider(API_URL) | ||||||
|  | const solidityNode = new HttpProvider(API_URL) | ||||||
|  | const eventServer = API_URL | ||||||
|  | const tronWeb = new TronWeb(fullNode, solidityNode, eventServer) | ||||||
|  |  | ||||||
|  | let assert | ||||||
|  |  | ||||||
|  | const SargaTrxUsdPrice = artifacts.require('SargaTrxUsdPrice') | ||||||
|  |  | ||||||
|  | contract('SargaTrxUsdPrice', () => { | ||||||
|  |   it('get TRX/USD value', async () => { | ||||||
|  |     // carga Chai como ESM y extrae assert | ||||||
|  |     const chaiModule = await import('chai') | ||||||
|  |     assert = chaiModule.assert | ||||||
|  |  | ||||||
|  |     // 1) Load already deployed contract | ||||||
|  |     const distributor = await SargaTrxUsdPrice.at(process.env.CONTRACT_ADDRESS) | ||||||
|  |  | ||||||
|  |     // 2) Call the getTrxUsdPrice function | ||||||
|  |     const trxUsdPrice = await distributor.getLatestPrice().call() | ||||||
|  |     console.log( | ||||||
|  |       'TRX/USD price:', | ||||||
|  |       parseFloat(trxUsdPrice.toString()) / 10 ** 8, | ||||||
|  |       'USD' | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  |     // 3) Assert the value is greater than 0 | ||||||
|  |     assert.isAbove( | ||||||
|  |       parseFloat(trxUsdPrice), | ||||||
|  |       0, | ||||||
|  |       'TRX/USD price should be greater than 0' | ||||||
|  |     ) | ||||||
|  |   }) | ||||||
|  | }) | ||||||
							
								
								
									
										3
									
								
								tronbox-config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								tronbox-config.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | module.exports = { | ||||||
|  |  | ||||||
|  | }; | ||||||
							
								
								
									
										44
									
								
								tronbox-evm-config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								tronbox-evm-config.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | module.exports = { | ||||||
|  |   networks: { | ||||||
|  |     bttc: { | ||||||
|  |       // Don't put your private key here: | ||||||
|  |       privateKey: process.env.PRIVATE_KEY_BTTC, | ||||||
|  |       /* | ||||||
|  | Create a .env file (it must be gitignored) containing something like | ||||||
|  |  | ||||||
|  |   export PRIVATE_KEY_BTTC=4E7FEC...656243 | ||||||
|  |  | ||||||
|  | Then, run the migration with: | ||||||
|  |  | ||||||
|  |   source .env && tronbox migrate --network bttc --evm | ||||||
|  |       */ | ||||||
|  |       fullHost: 'https://rpc.bt.io', | ||||||
|  |       // gas: 8500000, // Gas sent with each transaction | ||||||
|  |       // gasPrice: '500000000000000', // 500,000 gwei (in wei) | ||||||
|  |       network_id: '1' | ||||||
|  |     }, | ||||||
|  |     donau: { | ||||||
|  |       privateKey: process.env.PRIVATE_KEY_DONAU, | ||||||
|  |       fullHost: 'https://pre-rpc.bt.io', | ||||||
|  |       network_id: '2' | ||||||
|  |     }, | ||||||
|  |     development: { | ||||||
|  |       privateKey: process.env.PRIVATE_KEY_DEV, | ||||||
|  |       fullHost: 'http://127.0.0.1:8545', | ||||||
|  |       network_id: '9' | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   compilers: { | ||||||
|  |     solc: { | ||||||
|  |       version: '0.8.7', | ||||||
|  |       settings: { | ||||||
|  |         // optimizer: { | ||||||
|  |         //   enabled: true, | ||||||
|  |         //   runs: 200 | ||||||
|  |         // }, | ||||||
|  |         // evmVersion: 'istanbul', | ||||||
|  |         // viaIR: true, | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | }; | ||||||
							
								
								
									
										66
									
								
								tronbox.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								tronbox.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | |||||||
|  | const port = process.env.HOST_PORT || 9090 | ||||||
|  |  | ||||||
|  | module.exports = { | ||||||
|  |   networks: { | ||||||
|  |     mainnet: { | ||||||
|  |       // Don't put your private key here: | ||||||
|  |       privateKey: process.env.PRIVATE_KEY_MAINNET, | ||||||
|  |       /* | ||||||
|  | Create a .env file (it must be gitignored) containing something like | ||||||
|  |  | ||||||
|  |   export PRIVATE_KEY_MAINNET=4E7FEC...656243 | ||||||
|  |  | ||||||
|  | Then, run the migration with: | ||||||
|  |  | ||||||
|  |   source .env && tronbox migrate --network mainnet | ||||||
|  |  | ||||||
|  |       */ | ||||||
|  |       userFeePercentage: 100, | ||||||
|  |       feeLimit: 1000 * 1e6, | ||||||
|  |       fullHost: 'https://api.trongrid.io', | ||||||
|  |       network_id: '1' | ||||||
|  |     }, | ||||||
|  |     shasta: { | ||||||
|  |       privateKey: process.env.PRIVATE_KEY_SHASTA, | ||||||
|  |       userFeePercentage: 50, | ||||||
|  |       feeLimit: 1000 * 1e6, | ||||||
|  |       fullHost: 'https://api.shasta.trongrid.io', | ||||||
|  |       network_id: '2' | ||||||
|  |     }, | ||||||
|  |     nile: { | ||||||
|  |       privateKey: process.env.PRIVATE_KEY_NILE, | ||||||
|  |       userFeePercentage: 100, | ||||||
|  |       feeLimit: 1000 * 1e6, | ||||||
|  |       fullHost: 'https://nile.trongrid.io', | ||||||
|  |       network_id: '3' | ||||||
|  |     }, | ||||||
|  |     development: { | ||||||
|  |       // For tronbox/tre docker image | ||||||
|  |       privateKey: '0000000000000000000000000000000000000000000000000000000000000001', | ||||||
|  |       userFeePercentage: 0, | ||||||
|  |       feeLimit: 1000 * 1e6, | ||||||
|  |       fullHost: 'http://127.0.0.1:' + port, | ||||||
|  |       network_id: '9' | ||||||
|  |     }, | ||||||
|  |     compilers: { | ||||||
|  |       solc: { | ||||||
|  |         version: "0.8.20",      // Specify a Solidity version >= 0.8.20 | ||||||
|  |         settings: { | ||||||
|  |           optimizer: { | ||||||
|  |             enabled: true, | ||||||
|  |             runs: 200 | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   // solc compiler optimize | ||||||
|  |   solc: { | ||||||
|  |     optimizer: { | ||||||
|  |       enabled: true, | ||||||
|  |       runs: 200 | ||||||
|  |     }, | ||||||
|  |     evmVersion: 'istanbul', | ||||||
|  |     viaIR: true, | ||||||
|  |   } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user