diff --git a/public/articles/addressing-the-stablecoin-trilemma.md b/public/articles/addressing-the-stablecoin-trilemma.md index 50d8c33..14bde91 100644 --- a/public/articles/addressing-the-stablecoin-trilemma.md +++ b/public/articles/addressing-the-stablecoin-trilemma.md @@ -32,7 +32,10 @@ It’s important to note that the attributes in stablecoins aren’t binary. Ins The real question isn’t if a stablecoin fully achieves these attributes, but whether it does so to a sufficient degree. ## Exploring the Types of Stablecoins -![stablecoins as the backbone of our digital economy](/images/stablecoins-as-the-backbone-of-digital-economy.webp) +
+ Stablecoins as the backbone of our digital economy +
Stablecoins as the backbone of the digital economy
+
Stablecoins are the backbone of our digital economy — according to CoinGecko, the current total market cap of stablecoins is valued at $151 billion with daily trading volume amounting close to $80 billion. @@ -40,7 +43,10 @@ Most of these stablecoins can fall under one of 4 categories below: ## Fiat-Backed Stablecoins -![Fiat-Backed Stablecoins](/images/fiat-backed-stablecoins.webp) +
+ Fiat-Backed Stablecoins +
Fiat-Backed Stablecoins
+
Fiat-backed stablecoins mirror the value of fiat currencies, like USDC and USDT, which are the most used stablecoins. Pegged to traditional currencies, they are both stable and capital efficient but fall short on decentralization as they generally rely on a centralized structure with regulated entities. Given the centralized nature, these institutions can be susceptible to censorship, can engage in censorship, and notably, their actions raise concerns regarding transparency. Furthermore, their existence depends on the financial health of their operators. @@ -48,7 +54,10 @@ USDT, by Tether, is a [notable example](https://blockworks.co/news/us-judge-orde ## Crypto-Collateralized Stablecoins -![Crypto-Collateralized Stablecoins](/images//Crypto-Collateralized%20Stablecoins.webp) +
+ Crypto-Collateralized Stablecoins +
Crypto-Collateralized Stablecoins
+
Crypto-collateralized stablecoins achieve decentralization often at the cost of stability and capital efficiency. These stablecoins are created and issued as loans collateralized by top-performing digital assets (e.g.,ETH), locked in smart contracts. Because the collateral-to-loan ratio needs to be high to absorb price shocks, the excess collateral remains unused until the borrower repays the loan or faces liquidation. This leads to capital inefficiency. Moreover, stablecoin holders can only convert their stablecoins back into collateral during liquidation or when repaying loans, which further compromises their price stability. @@ -56,7 +65,10 @@ The most popular example of this type is undoubtedly DAI by MakerDAO. ## Unbacked Stablecoins -![Unbacked Stablecoins](/images//Unbacked%20Stablecoins.webp) +
+ Unbacked Stablecoins +
Unbacked Stablecoins
+
Unbacked stablecoins attempt to eliminate the need for collateral or reserves through mechanisms that adjust supply based on price fluctuation. If the stablecoin’s price exceeds its target, the algorithm triggers to expand the supply, for instance, by minting new coins. If the price drops below the target, the algorithm encourages supply contraction — either by incentivizing users to burn or lock up their stablecoins — to push the price back up. @@ -66,7 +78,10 @@ UST (and LUNA) on the Terra blockchain exemplifies this type of stablecoin. It c ## Crypto-Backed (Decentralized Reserve Protocols) -![Crypto-Backed (Decentralized Reserve Protocols)](/images//Crypto-Backed%20(Decentralized%20Reserve%20Protocols).webp) +
+ Crypto-Backed (Decentralized Reserve Protocols) +
Crypto-Backed (Decentralized Reserve Protocols)
+
This newer model, which is often confused with the _crypto-collateralized_ stablecoins, offers a unique blend of decentralization and stability through backing, and mechanisms such as reserve tokenization which ensure capital efficiency. diff --git a/public/articles/deploy-next-app-to-github-pages-guide.md b/public/articles/deploy-next-app-to-github-pages-guide.md index 1351299..3914a22 100644 --- a/public/articles/deploy-next-app-to-github-pages-guide.md +++ b/public/articles/deploy-next-app-to-github-pages-guide.md @@ -39,16 +39,22 @@ Here’s how to configure your `next.config.mjs`: ``` const nextConfig = { -output: 'export', // Tells Next.js to export the app statically -distDir: 'out', // Output directory for the static files -images: { -unoptimized: true, // Disables Next.js image optimization (required for static export) -loader: "custom", // Custom image loader for specific handling -loaderFile: "./src/loaders/cloudinary-loader.ts", // Path to the custom image loader -}, -reactStrictMode: true, // Optional: Enables React Strict Mode -basePath: "/your-repository-name", // GitHub Pages requires the basePath for deployment under a repository. In case of custom domain name the basePath is not required + output: "export", // Tells Next.js to export the app statically + distDir: "out", // Output directory for the static files + + images: { + unoptimized: true, // Disables Next.js image optimization (required for static export) + loader: "custom", // Custom image loader for specific handling + loaderFile: "./src/loaders/cloudinary-loader.ts", // Path to the custom image loader + }, + + reactStrictMode: true, // Optional: Enables React Strict Mode + + basePath: "/your-repository-name", + // GitHub Pages requires the basePath for deployment under a repository. + // In case of custom domain name the basePath is not required }; + export default nextConfig; ``` @@ -75,8 +81,11 @@ For a dynamic route like https://example.com/id/[param], where param can be any ``` export async function generateStaticParams() { -const params = Array.from({ length: 100 }, (_, i) => i.toString()); // IDs 0 to 99 -return params.map((param) => ({ param })); + const params = Array.from({ length: 100 }, (_, i) => i.toString()); // IDs 0 to 99 + + return params.map((param) => ({ + param, + })); } ``` @@ -84,8 +93,12 @@ For dynamic IDs fetched from an API: ``` export async function generateStaticParams() { -const data = await fetch('https://example.com/api/ids').then((res) => res.json()); -return data.map((id: string) => ({ param: id })); + const data = await fetch("https://example.com/api/ids") + .then((res) => res.json()); + + return data.map((id: string) => ({ + param: id, + })); } ``` @@ -136,13 +149,16 @@ Example: yaml jobs: build: runs-on: ubuntu-latest + steps: - name: Checkout code uses: actions/checkout@v4 + - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: "20" + - name: Build the Next.js app env: ETHERSCAN_API_KEY: ${{ secrets.ETHERSCAN_API_KEY }} @@ -161,15 +177,19 @@ Example: yaml jobs: build: runs-on: ubuntu-latest + env: NEXT_PUBLIC_API_URL: https://api.example.com + steps: - name: Checkout code uses: actions/checkout@v4 + - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: "20" + - name: Build the Next.js app run: npm run build ``` @@ -209,10 +229,12 @@ If the exposed key is too risky, route requests through your backend to keep the ``` export default async function handler(req, res) { -const API_KEY = process.env.PRIVATE_API_KEY; // Kept private -const response = await fetch(`https://api.example.com?apikey=${API_KEY}`); -const data = await response.json(); -res.status(200).json(data); + const API_KEY = process.env.PRIVATE_API_KEY; // Kept private + + const response = await fetch(`https://api.example.com?apikey=${API_KEY}`); + const data = await response.json(); + + res.status(200).json(data); } ``` @@ -233,8 +255,8 @@ name: Deploy Next.js site to Pages ``` on: push: - branches: ["main"] # Trigger deployment on push to the 'main' branch - workflow_dispatch: # Manually trigger the deployment from GitHub Actions tab + branches: ["main"] # Trigger deployment on push to the 'main' branch + workflow_dispatch: # Manually trigger the deployment from GitHub Actions tab permissions: contents: read @@ -248,9 +270,11 @@ concurrency: jobs: build: runs-on: ubuntu-latest + defaults: run: - working-directory: ./web # Specify the directory of your Next.js app + working-directory: ./web # Specify the directory of your Next.js app + steps: - name: Checkout code uses: actions/checkout@v4 @@ -302,14 +326,16 @@ jobs: - name: Upload static files uses: actions/upload-pages-artifact@v3 with: - path: ./web/out # Specify the output directory for static files + path: ./web/out # Specify the output directory for static files deploy: + needs: build + runs-on: ubuntu-latest + environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - needs: build + steps: - name: Deploy to GitHub Pages id: deployment diff --git a/public/articles/deploy-react-app-to-github-pages-guide.md b/public/articles/deploy-react-app-to-github-pages-guide.md index b49ddcb..eef0646 100644 --- a/public/articles/deploy-react-app-to-github-pages-guide.md +++ b/public/articles/deploy-react-app-to-github-pages-guide.md @@ -34,10 +34,11 @@ Here’s how to configure your vite.config.ts: ``` import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; + // https://vite.dev/config/ export default defineConfig({ -plugins: [react()], -base: '/your-base-path/', + plugins: [react()], + base: "/your-base-path/", }); ``` @@ -86,10 +87,11 @@ Add the following scripts in your package.json: ``` "scripts": { -+ "predeploy": "npm run build", -+ "deploy": "gh-pages -d build", -"start": "react-scripts start", -"build": "react-scripts build", + "predeploy": "npm run build", + "deploy": "gh-pages -d build", + "start": "react-scripts start", + "build": "react-scripts build" +} ``` The predeploy script will run automatically before deploy is run. @@ -107,50 +109,61 @@ Here is the sample workflow for deploying a React.js app to GitHub Pages: ``` # Simple workflow for deploying static content to GitHub Pages name: Deploy static content to Pages + on: -# Runs on pushes targeting the default branch -push: -branches: ["main"] -# Allows you to run this workflow manually from the Actions tab -workflow_dispatch: + # Runs on pushes targeting the default branch + push: + branches: ["main"] + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + # Sets the GITHUB_TOKEN permissions to allow deployment to GitHub Pages permissions: -contents: read -pages: write -id-token: write + contents: read + pages: write + id-token: write + # Allow one concurrent deployment concurrency: -group: "pages" -cancel-in-progress: true + group: "pages" + cancel-in-progress: true + jobs: -# Single deploy job since we're just deploying -deploy: -environment: -name: github-pages -url: ${{ steps.deployment.outputs.page_url }} -runs-on: ubuntu-latest -steps: -- name: Checkout -uses: actions/checkout@v4 -- name: Set up Node -uses: actions/setup-node@v4 -with: -node-version: 20 -cache: "npm" -- name: Install dependencies -run: npm ci -- name: Build -run: npm run build -- name: Setup Pages -uses: actions/configure-pages@v4 -- name: Upload artifact -uses: actions/upload-pages-artifact@v3 -with: -# Upload dist folder -path: "./dist" -- name: Deploy to GitHub Pages -id: deployment -uses: actions/deploy-pages@v4 + # Single deploy job since we're just deploying + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: "npm" + + - name: Install dependencies + run: npm ci + + - name: Build + run: npm run build + + - name: Setup Pages + uses: actions/configure-pages@v4 + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + # Upload dist folder + path: "./dist" + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 ``` #### Key Steps in the Workflow diff --git a/public/articles/deploying-smart-contracts-mordor-ethereum-classic-foundry.md b/public/articles/deploying-smart-contracts-mordor-ethereum-classic-foundry.md index 0f7a813..ea1c327 100644 --- a/public/articles/deploying-smart-contracts-mordor-ethereum-classic-foundry.md +++ b/public/articles/deploying-smart-contracts-mordor-ethereum-classic-foundry.md @@ -45,10 +45,10 @@ Modify your foundry.toml file to set evm_version to “paris”: ``` [profile.default] -src = “src” -out = “out” -libs = [“lib”] -evm_version = “paris” # Ensures compatibility with Mordor & Ethereum Classic +src = "src" +out = "out" +libs = ["lib"] +evm_version = "paris" # Ensures compatibility with Mordor & Ethereum Classic ``` After updating, verify the EVM version by running: @@ -84,19 +84,24 @@ If you already have a deployment script, you can reuse it. Otherwise, create a D ``` // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; + import "forge-std/Script.sol"; import "../src/YourContract.sol"; + contract DeployContract is Script { - function setUp() public {} - function run() external { - vm.startBroadcast(); - - // Deploy your contract - YourContract contractInstance = new YourContract(); - //Replace with your contract -vm.stopBroadcast(); - console.log("Contract deployed at:", address(contractInstance)); - } + function setUp() public {} + + function run() external { + vm.startBroadcast(); + + // Deploy your contract + YourContract contractInstance = new YourContract(); + // Replace with your contract + + vm.stopBroadcast(); + + console.log("Contract deployed at:", address(contractInstance)); + } } ``` @@ -109,11 +114,11 @@ Run the deployment script with: ``` forge script script/Deploy.s.sol:DeployContract \ - --rpc-url $MORDOR_RPC_URL \ - --private-key $PRIVATE_KEY \ - --broadcast \ - --evm_version paris \ - --legacy + --rpc-url $MORDOR_RPC_URL \ + --private-key $PRIVATE_KEY \ + --broadcast \ + --evm-version paris \ + --legacy ``` ### Deploying to Ethereum Classic @@ -122,12 +127,12 @@ Run the deployment script with: ``` forge script script/Deploy.s.sol:DeployContract \ - --rpc-url $ETC_RPC_URL \ - --private-key $PRIVATE_KEY \ - --broadcast \ - --evm_version paris \ - --legacy -+ ``` + --rpc-url $ETC_RPC_URL \ + --private-key $PRIVATE_KEY \ + --broadcast \ + --evm-version paris \ + --legacy +``` Make sure you have PRIVATE_KEY set in your .env file before running the deployment script. diff --git a/public/articles/gluon-sdk-tutorial.md b/public/articles/gluon-sdk-tutorial.md index ca0436d..09adce7 100644 --- a/public/articles/gluon-sdk-tutorial.md +++ b/public/articles/gluon-sdk-tutorial.md @@ -26,8 +26,8 @@ npm install gluon-gold-sdk@1.0.0 To use the SDK in a browser environment, you can dynamically import it as follows: ``` -if (typeof window !== 'undefined') { - gluon = import('gluon-gold-sdk'); +if (typeof window !== "undefined") { + const gluon = await import("gluon-gold-sdk"); } ``` @@ -51,15 +51,19 @@ const config = new Config(); ``` // Set the network to the desired environment (e.g., 'mainnet' or 'testnet') -config.NETWORK = 'mainnet'; // or 'testnet' +config.NETWORK = "mainnet"; // or 'testnet' + // Set the miner fee (in nanoERGs) config.MINER_FEE = 1000000; // Example: 0.001 ERG + // Set the node URL for connecting to the Ergo blockchain -config.NODE_URL = 'https://ergo-node.example.com'; +config.NODE_URL = "https://ergo-node.example.com"; + // Set the UI fee percentage: 1000 means 1% of the value of each operation that users perform will be sent to the UI devs config.UI_FEE = 1000; // Example: 1% fee + // Set the UI tree where a predefined percentage of each operation will be sent to -config.UI_TREE = 'your-ui-tree-value-here'; +config.UI_TREE = "your-ui-tree-value-here"; ``` By configuring these parameters, you ensure that the SDK is tailored to your application’s requirements, allowing for seamless interaction with the Gluon protocol. Adjust these values according to your specific needs and the environment in which your application will operate. @@ -74,6 +78,7 @@ Here’s how you can set up the environment by fetching the required boxes: ``` // Fetch the current unspent Gold Oracle Box const oracleBoxJs = await gluonInstance.getGoldOracleBox(); + // Fetch the current unspent Gluon Box const gluonBoxJs = await gluonInstance.getGluonBox(); ``` @@ -99,7 +104,8 @@ It is desired to use as few boxes as possible to construct our necessary transac Fission is the process of converting ERGs into Neutrons (GAUs, stable coins) and Protons (GAUCs, volatile coins). Here’s how you can perform a fission operation: ``` -const amountToFission = ... // amount in nanoERGs +const amountToFission = ...; // amount in nanoERGs + const unsignedTransaction = await gluonInstance.fissionForEip12(gluonBoxJs, oracleBoxJs, userBoxes, amountToFission); ``` @@ -108,6 +114,7 @@ Fusion is the reverse process, where Neutrons (GAUs, stable coins) and Protons ( ``` const amountToFusion = ... // amount in nanoERGs + const unsignedTransaction = await gluonInstance.fusionForEip12(gluonBoxJs, oracleBoxJs, userBoxes, amountToFusion); ``` @@ -116,8 +123,14 @@ This operation involves sending Protons (GAUCs) to the reactor to receive Neutro ``` const protonsToTransmute = 5000000; // Example amount -const height = await nodeService.getNetworkHeight(); // Get current network height + +// Get current network height +const height = await nodeService.getNetworkHeight(); + +// Fetch the Oracle BuyBack Box const oracleBuyBackJs = await gluonInstance.getOracleBuyBackBoxJs(); + +// Create an unsigned transaction for transmuting to Gold const unsignedTransaction = await gluonInstance.transmuteToGoldForEip12(gluonBoxJs, oracleBoxJs, userBoxes, oracleBuyBackJs, protonsToTransmute, height); ``` @@ -126,6 +139,7 @@ This operation involves sending Neutrons (GAUs) to the reactor to receive Proton ``` const neutronsToDecay = 2700000; // Example amount + const unsignedTransaction = await gluonInstance.transmuteFromGoldForEip12(gluonBoxJs, oracleBoxJs, userBoxes, oracleBuyBackJs, neutronsToDecay, height); ``` @@ -155,6 +169,7 @@ For each operation, you can calculate the total fees and their breakdown: ``` const fees = await gluonInstance.getTotalFeeAmountFission(gluonBoxJs, amountToFission); + console.log(`Developer Fee: ${fees.devFee}, UI Fee: ${fees.uiFee}, Oracle Fee: ${fees.oracleFee}, Total Fee: ${fees.totalFee}`); ``` @@ -169,8 +184,12 @@ You can also display the current prices of Neutrons and Protons as well as the o ``` const neutronPrice = await gluonInstance.neutronPrice(oracleBoxJs); const protonPrice = await gluonInstance.protonPrice(oracleBoxJs); + +// Fetch Gold prices from the Oracle Box const oracleGoldPricePerKg = await oracleBoxJs.getPrice(); const oracleGoldPricePerGram = await oracleBoxJs.getPricePerGram(); + +// Log the current prices console.log(`Neutron Price: ${neutronPrice}, Proton Price: ${protonPrice}, Gold Price: ${oracleGoldPricePerKg}, Gold Price Per Gram: ${oracleGoldPricePerGram}`); ``` @@ -180,11 +199,16 @@ These values should be displayed in the website to users so they know what the c The SDK provides methods to calculate volume of gold conversions over a specified number of days (up to 14 days). You can calculate the volume of protons to neutrons or neutrons to protons. ``` -// Calculate the n-day volume of protons to neutrons -const n = 7; // specify the number of days, up to 14 days +// Specify the number of days for volume calculation (up to 14 days) +const n = 7; + +// Calculate the n-day volume of protons → neutrons const volumeProtonsToNeutrons = await gluon.accumulateVolumeProtonsToNeutrons(n); -// Calculate the n-day volume of neutrons to protons + +// Calculate the n-day volume of neutrons → protons const volumeNeutronsToProtons = await gluon.accumulateVolumeNeutronsToProtons(n); + +// Log the calculated volumes console.log(`Volume of protons to neutrons over ${n} days:`, volumeProtonsToNeutrons); console.log(`Volume of neutrons to protons over ${n} days:`, volumeNeutronsToProtons); ``` diff --git a/public/images/Crypto-Backed (Decentralized Reserve Protocols).webp b/public/images/Crypto-Backed-Decentralized-Reserve-Protocols.webp similarity index 100% rename from public/images/Crypto-Backed (Decentralized Reserve Protocols).webp rename to public/images/Crypto-Backed-Decentralized-Reserve-Protocols.webp diff --git a/public/images/Crypto-Collateralized Stablecoins.webp b/public/images/Crypto-Collateralized-Stablecoins.webp similarity index 100% rename from public/images/Crypto-Collateralized Stablecoins.webp rename to public/images/Crypto-Collateralized-Stablecoins.webp diff --git a/public/images/Unbacked Stablecoins.webp b/public/images/Unbacked-Stablecoins.webp similarity index 100% rename from public/images/Unbacked Stablecoins.webp rename to public/images/Unbacked-Stablecoins.webp